@rizom/brain 0.2.0-alpha.53 → 0.2.0-alpha.54
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 +29 -29
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/plugins.d.ts +2 -2
- package/dist/site.js +4 -4
- package/dist/site.js.map +1 -1
- package/package.json +1 -1
package/dist/brain.js
CHANGED
|
@@ -568,7 +568,7 @@ ${F}`,args:{...$,...Y,id:I.id,confirmed:!0,contentHash:I.contentHash}}},{visibil
|
|
|
568
568
|
hash text NOT NULL,
|
|
569
569
|
created_at numeric
|
|
570
570
|
)
|
|
571
|
-
`;await A.session.run($);let I=(await A.values(PA`SELECT id, hash, created_at FROM ${PA.identifier(w)} ORDER BY created_at DESC LIMIT 1`))[0]??void 0,Y=[];for(let X of B)if(!I||Number(I[2])<X.folderMillis){for(let H of X.sql)Y.push(A.run(PA.raw(H)));Y.push(A.run(PA`INSERT INTO ${PA.identifier(w)} ("hash", "created_at") VALUES(${X.hash}, ${X.folderMillis})`))}await A.session.migrate(Y)}var Ly=c(()=>{jnA();v6()});async function _nA(A,Q){let B=Q?.child("entity-migrate")??T2.getInstance().child("entity-migrate"),{db:w,client:$,url:D}=nS(A);B.debug("Running entity database migrations...");try{await oS($,D);let Y=import.meta.url.includes("/dist/")?new URL("./migrations/entity-service",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await kf(w,{migrationsFolder:Y}),await sS($),B.debug("Entity database migrations completed successfully")}catch(I){throw B.error("Entity database migration failed:",I),I}finally{$.close()}}var xnA=c(()=>{Ly();D0A();KA()});async function vnA(A,Q){let B=Q?.child("job-queue-migrate")??T2.getInstance().child("job-queue-migrate"),{db:w,client:$,url:D}=dS(A);B.debug("Running job queue migrations...");try{await iS($,D);let Y=import.meta.url.includes("/dist/")?new URL("./migrations/job-queue",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await kf(w,{migrationsFolder:Y}),B.debug("Job queue migrations completed successfully")}catch(I){throw B.error("Job queue migration failed:",I),I}finally{$.close()}}var TnA=c(()=>{Ly();nAA();KA()});async function SnA(A,Q){let B=Q?.child("conversation-migrate")??T2.getInstance().child("conversation-migrate"),{db:w,client:$,url:D}=Ig(A);B.debug("Running conversation database migrations...");try{if(D.startsWith("file:"))await $.execute("PRAGMA journal_mode = WAL");let Y=import.meta.url.includes("/dist/")?new URL("./migrations/conversation-service",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await kf(w,{migrationsFolder:Y}),B.debug("Conversation database migrations completed successfully")}catch(I){throw B.error("Conversation database migration failed:",I),I}finally{$.close()}}var gnA=c(()=>{Ly();y0A();KA()});class $b{logger;migrations;constructor(A,Q){this.logger=A,this.migrations=Q??{getStandardConfigWithDirectories:SO,migrateEntities:_nA,migrateJobQueue:vnA,migrateConversations:SnA}}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 x5A=c(()=>{Ny();xnA();TnA();gnA()});var Cy;var v5A=c(()=>{KA();Cy=J.object({theme:J.object({primaryColor:J.string().describe("Primary color for the CLI theme").default("#0066cc"),accentColor:J.string().describe("Accent color for the CLI theme").default("#ff6600")}).describe("Theme configuration for the CLI interface").default({primaryColor:"#0066cc",accentColor:"#ff6600"})})});var ynA;var hnA=c(()=>{ynA={name:"@brains/chat-repl",private:!0,version:"0.2.0-alpha.53",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 qQ=_((QN1,Ey)=>{(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=sA&&QA[sA]||QA["@@iterator"],typeof QA==="function"?QA:null}function B(QA,FA){QA=(QA=QA.constructor)&&(QA.displayName||QA.name)||"ReactClass";var nA=QA+"."+FA;JA[nA]||(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),JA[nA]=!0)}function w(QA,FA,nA){this.props=QA,this.context=FA,this.refs=TA,this.updater=nA||CA}function $(){}function D(QA,FA,nA){this.props=QA,this.context=FA,this.refs=TA,this.updater=nA||CA}function I(){}function Y(QA){return""+QA}function X(QA){try{Y(QA);var FA=!1}catch(m0){FA=!0}if(FA){FA=console;var nA=FA.error,y0=typeof Symbol==="function"&&Symbol.toStringTag&&QA[Symbol.toStringTag]||QA.constructor.name||"Object";return nA.call(FA,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",y0),Y(QA)}}function H(QA){if(QA==null)return null;if(typeof QA==="function")return QA.$$typeof===Q0?null:QA.displayName||QA.name||null;if(typeof QA==="string")return QA;switch(QA){case e:return"Fragment";case WA:return"Profiler";case i:return"StrictMode";case g0:return"Suspense";case NA:return"SuspenseList";case fA: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 HA:return QA.displayName||"Context";case gA:return(QA._context.displayName||"Context")+".Consumer";case X0:var FA=QA.render;return QA=QA.displayName,QA||(QA=FA.displayName||FA.name||"",QA=QA!==""?"ForwardRef("+QA+")":"ForwardRef"),QA;case j0:return FA=QA.displayName||null,FA!==null?FA:H(QA.type)||"Memo";case H0:FA=QA._payload,QA=QA._init;try{return H(QA(FA))}catch(nA){}}return null}function U(QA){if(QA===e)return"<>";if(typeof QA==="object"&&QA!==null&&QA.$$typeof===H0)return"<...>";try{var FA=H(QA);return FA?"<"+FA+">":"<...>"}catch(nA){return"<...>"}}function F(){var QA=rA.A;return QA===null?null:QA.getOwner()}function Z(){return Error("react-stack-top-frame")}function z(QA){if(MA.call(QA,"key")){var FA=Object.getOwnPropertyDescriptor(QA,"key").get;if(FA&&FA.isReactWarning)return!1}return QA.key!==void 0}function f(QA,FA){function nA(){AA||(AA=!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))}nA.isReactWarning=!0,Object.defineProperty(QA,"key",{get:nA,configurable:!0})}function E(){var QA=H(this.type);return c0[QA]||(c0[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,nA,y0,m0,U1){var E0=nA.ref;return QA={$$typeof:s,type:QA,key:FA,props:nA,_owner:y0},(E0!==void 0?E0: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:m0}),Object.defineProperty(QA,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:U1}),Object.freeze&&(Object.freeze(QA.props),Object.freeze(QA)),QA}function P(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 x(QA){k(QA)?QA._store&&(QA._store.validated=1):typeof QA==="object"&&QA!==null&&QA.$$typeof===H0&&(QA._payload.status==="fulfilled"?k(QA._payload.value)&&QA._payload.value._store&&(QA._payload.value._store.validated=1):QA._store&&(QA._store.validated=1))}function k(QA){return typeof QA==="object"&&QA!==null&&QA.$$typeof===s}function o(QA){var FA={"=":"=0",":":"=2"};return"$"+QA.replace(/[=:]/g,function(nA){return FA[nA]})}function r(QA,FA){return typeof QA==="object"&&QA!==null&&QA.key!=null?(X(QA.key),o(""+QA.key)):FA.toString(36)}function u(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 v(QA,FA,nA,y0,m0){var U1=typeof QA;if(U1==="undefined"||U1==="boolean")QA=null;var E0=!1;if(QA===null)E0=!0;else switch(U1){case"bigint":case"string":case"number":E0=!0;break;case"object":switch(QA.$$typeof){case s:case d:E0=!0;break;case H0:return E0=QA._init,v(E0(QA._payload),FA,nA,y0,m0)}}if(E0){E0=QA,m0=m0(E0);var E1=y0===""?"."+r(E0,0):y0;return I0(m0)?(nA="",E1!=null&&(nA=E1.replace(jA,"$&/")+"/"),v(m0,FA,nA,"",function(R2){return R2})):m0!=null&&(k(m0)&&(m0.key!=null&&(E0&&E0.key===m0.key||X(m0.key)),nA=P(m0,nA+(m0.key==null||E0&&E0.key===m0.key?"":(""+m0.key).replace(jA,"$&/")+"/")+E1),y0!==""&&E0!=null&&k(E0)&&E0.key==null&&E0._store&&!E0._store.validated&&(nA._store.validated=2),m0=nA),FA.push(m0)),1}if(E0=0,E1=y0===""?".":y0+":",I0(QA))for(var L1=0;L1<QA.length;L1++)y0=QA[L1],U1=E1+r(y0,L1),E0+=v(y0,FA,nA,U1,m0);else if(L1=Q(QA),typeof L1==="function")for(L1===QA.entries&&(vA||console.warn("Using Maps as children is not supported. Use an array of keyed ReactElements instead."),vA=!0),QA=L1.call(QA),L1=0;!(y0=QA.next()).done;)y0=y0.value,U1=E1+r(y0,L1++),E0+=v(y0,FA,nA,U1,m0);else if(U1==="object"){if(typeof QA.then==="function")return v(u(QA),FA,nA,y0,m0);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 E0}function S(QA,FA,nA){if(QA==null)return QA;var y0=[],m0=0;return v(QA,y0,"","",function(U1){return FA.call(nA,U1,m0++)}),y0}function h(QA){if(QA._status===-1){var FA=QA._ioInfo;FA!=null&&(FA.start=FA.end=performance.now()),FA=QA._result;var nA=FA();if(nA.then(function(m0){if(QA._status===0||QA._status===-1){QA._status=1,QA._result=m0;var U1=QA._ioInfo;U1!=null&&(U1.end=performance.now()),nA.status===void 0&&(nA.status="fulfilled",nA.value=m0)}},function(m0){if(QA._status===0||QA._status===-1){QA._status=2,QA._result=m0;var U1=QA._ioInfo;U1!=null&&(U1.end=performance.now()),nA.status===void 0&&(nA.status="rejected",nA.reason=m0)}}),FA=QA._ioInfo,FA!=null){FA.value=nA;var y0=nA.displayName;typeof y0==="string"&&(FA.name=y0)}QA._status===-1&&(QA._status=0,QA._result=nA)}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
|
|
571
|
+
`;await A.session.run($);let I=(await A.values(PA`SELECT id, hash, created_at FROM ${PA.identifier(w)} ORDER BY created_at DESC LIMIT 1`))[0]??void 0,Y=[];for(let X of B)if(!I||Number(I[2])<X.folderMillis){for(let H of X.sql)Y.push(A.run(PA.raw(H)));Y.push(A.run(PA`INSERT INTO ${PA.identifier(w)} ("hash", "created_at") VALUES(${X.hash}, ${X.folderMillis})`))}await A.session.migrate(Y)}var Ly=c(()=>{jnA();v6()});async function _nA(A,Q){let B=Q?.child("entity-migrate")??T2.getInstance().child("entity-migrate"),{db:w,client:$,url:D}=nS(A);B.debug("Running entity database migrations...");try{await oS($,D);let Y=import.meta.url.includes("/dist/")?new URL("./migrations/entity-service",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await kf(w,{migrationsFolder:Y}),await sS($),B.debug("Entity database migrations completed successfully")}catch(I){throw B.error("Entity database migration failed:",I),I}finally{$.close()}}var xnA=c(()=>{Ly();D0A();KA()});async function vnA(A,Q){let B=Q?.child("job-queue-migrate")??T2.getInstance().child("job-queue-migrate"),{db:w,client:$,url:D}=dS(A);B.debug("Running job queue migrations...");try{await iS($,D);let Y=import.meta.url.includes("/dist/")?new URL("./migrations/job-queue",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await kf(w,{migrationsFolder:Y}),B.debug("Job queue migrations completed successfully")}catch(I){throw B.error("Job queue migration failed:",I),I}finally{$.close()}}var TnA=c(()=>{Ly();nAA();KA()});async function SnA(A,Q){let B=Q?.child("conversation-migrate")??T2.getInstance().child("conversation-migrate"),{db:w,client:$,url:D}=Ig(A);B.debug("Running conversation database migrations...");try{if(D.startsWith("file:"))await $.execute("PRAGMA journal_mode = WAL");let Y=import.meta.url.includes("/dist/")?new URL("./migrations/conversation-service",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await kf(w,{migrationsFolder:Y}),B.debug("Conversation database migrations completed successfully")}catch(I){throw B.error("Conversation database migration failed:",I),I}finally{$.close()}}var gnA=c(()=>{Ly();y0A();KA()});class $b{logger;migrations;constructor(A,Q){this.logger=A,this.migrations=Q??{getStandardConfigWithDirectories:SO,migrateEntities:_nA,migrateJobQueue:vnA,migrateConversations:SnA}}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 x5A=c(()=>{Ny();xnA();TnA();gnA()});var Cy;var v5A=c(()=>{KA();Cy=J.object({theme:J.object({primaryColor:J.string().describe("Primary color for the CLI theme").default("#0066cc"),accentColor:J.string().describe("Accent color for the CLI theme").default("#ff6600")}).describe("Theme configuration for the CLI interface").default({primaryColor:"#0066cc",accentColor:"#ff6600"})})});var ynA;var hnA=c(()=>{ynA={name:"@brains/chat-repl",private:!0,version:"0.2.0-alpha.54",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 qQ=_((QN1,Ey)=>{(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=sA&&QA[sA]||QA["@@iterator"],typeof QA==="function"?QA:null}function B(QA,FA){QA=(QA=QA.constructor)&&(QA.displayName||QA.name)||"ReactClass";var nA=QA+"."+FA;JA[nA]||(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),JA[nA]=!0)}function w(QA,FA,nA){this.props=QA,this.context=FA,this.refs=TA,this.updater=nA||CA}function $(){}function D(QA,FA,nA){this.props=QA,this.context=FA,this.refs=TA,this.updater=nA||CA}function I(){}function Y(QA){return""+QA}function X(QA){try{Y(QA);var FA=!1}catch(m0){FA=!0}if(FA){FA=console;var nA=FA.error,y0=typeof Symbol==="function"&&Symbol.toStringTag&&QA[Symbol.toStringTag]||QA.constructor.name||"Object";return nA.call(FA,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",y0),Y(QA)}}function H(QA){if(QA==null)return null;if(typeof QA==="function")return QA.$$typeof===Q0?null:QA.displayName||QA.name||null;if(typeof QA==="string")return QA;switch(QA){case e:return"Fragment";case WA:return"Profiler";case i:return"StrictMode";case g0:return"Suspense";case NA:return"SuspenseList";case fA: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 HA:return QA.displayName||"Context";case gA:return(QA._context.displayName||"Context")+".Consumer";case X0:var FA=QA.render;return QA=QA.displayName,QA||(QA=FA.displayName||FA.name||"",QA=QA!==""?"ForwardRef("+QA+")":"ForwardRef"),QA;case j0:return FA=QA.displayName||null,FA!==null?FA:H(QA.type)||"Memo";case H0:FA=QA._payload,QA=QA._init;try{return H(QA(FA))}catch(nA){}}return null}function U(QA){if(QA===e)return"<>";if(typeof QA==="object"&&QA!==null&&QA.$$typeof===H0)return"<...>";try{var FA=H(QA);return FA?"<"+FA+">":"<...>"}catch(nA){return"<...>"}}function F(){var QA=rA.A;return QA===null?null:QA.getOwner()}function Z(){return Error("react-stack-top-frame")}function z(QA){if(MA.call(QA,"key")){var FA=Object.getOwnPropertyDescriptor(QA,"key").get;if(FA&&FA.isReactWarning)return!1}return QA.key!==void 0}function f(QA,FA){function nA(){AA||(AA=!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))}nA.isReactWarning=!0,Object.defineProperty(QA,"key",{get:nA,configurable:!0})}function E(){var QA=H(this.type);return c0[QA]||(c0[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,nA,y0,m0,U1){var E0=nA.ref;return QA={$$typeof:s,type:QA,key:FA,props:nA,_owner:y0},(E0!==void 0?E0: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:m0}),Object.defineProperty(QA,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:U1}),Object.freeze&&(Object.freeze(QA.props),Object.freeze(QA)),QA}function P(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 x(QA){k(QA)?QA._store&&(QA._store.validated=1):typeof QA==="object"&&QA!==null&&QA.$$typeof===H0&&(QA._payload.status==="fulfilled"?k(QA._payload.value)&&QA._payload.value._store&&(QA._payload.value._store.validated=1):QA._store&&(QA._store.validated=1))}function k(QA){return typeof QA==="object"&&QA!==null&&QA.$$typeof===s}function o(QA){var FA={"=":"=0",":":"=2"};return"$"+QA.replace(/[=:]/g,function(nA){return FA[nA]})}function r(QA,FA){return typeof QA==="object"&&QA!==null&&QA.key!=null?(X(QA.key),o(""+QA.key)):FA.toString(36)}function u(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 v(QA,FA,nA,y0,m0){var U1=typeof QA;if(U1==="undefined"||U1==="boolean")QA=null;var E0=!1;if(QA===null)E0=!0;else switch(U1){case"bigint":case"string":case"number":E0=!0;break;case"object":switch(QA.$$typeof){case s:case d:E0=!0;break;case H0:return E0=QA._init,v(E0(QA._payload),FA,nA,y0,m0)}}if(E0){E0=QA,m0=m0(E0);var E1=y0===""?"."+r(E0,0):y0;return I0(m0)?(nA="",E1!=null&&(nA=E1.replace(jA,"$&/")+"/"),v(m0,FA,nA,"",function(R2){return R2})):m0!=null&&(k(m0)&&(m0.key!=null&&(E0&&E0.key===m0.key||X(m0.key)),nA=P(m0,nA+(m0.key==null||E0&&E0.key===m0.key?"":(""+m0.key).replace(jA,"$&/")+"/")+E1),y0!==""&&E0!=null&&k(E0)&&E0.key==null&&E0._store&&!E0._store.validated&&(nA._store.validated=2),m0=nA),FA.push(m0)),1}if(E0=0,E1=y0===""?".":y0+":",I0(QA))for(var L1=0;L1<QA.length;L1++)y0=QA[L1],U1=E1+r(y0,L1),E0+=v(y0,FA,nA,U1,m0);else if(L1=Q(QA),typeof L1==="function")for(L1===QA.entries&&(vA||console.warn("Using Maps as children is not supported. Use an array of keyed ReactElements instead."),vA=!0),QA=L1.call(QA),L1=0;!(y0=QA.next()).done;)y0=y0.value,U1=E1+r(y0,L1++),E0+=v(y0,FA,nA,U1,m0);else if(U1==="object"){if(typeof QA.then==="function")return v(u(QA),FA,nA,y0,m0);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 E0}function S(QA,FA,nA){if(QA==null)return QA;var y0=[],m0=0;return v(QA,y0,"","",function(U1){return FA.call(nA,U1,m0++)}),y0}function h(QA){if(QA._status===-1){var FA=QA._ioInfo;FA!=null&&(FA.start=FA.end=performance.now()),FA=QA._result;var nA=FA();if(nA.then(function(m0){if(QA._status===0||QA._status===-1){QA._status=1,QA._result=m0;var U1=QA._ioInfo;U1!=null&&(U1.end=performance.now()),nA.status===void 0&&(nA.status="fulfilled",nA.value=m0)}},function(m0){if(QA._status===0||QA._status===-1){QA._status=2,QA._result=m0;var U1=QA._ioInfo;U1!=null&&(U1.end=performance.now()),nA.status===void 0&&(nA.status="rejected",nA.reason=m0)}}),FA=QA._ioInfo,FA!=null){FA.value=nA;var y0=nA.displayName;typeof y0==="string"&&(FA.name=y0)}QA._status===-1&&(QA._status=0,QA._result=nA)}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
|
|
572
572
|
|
|
573
573
|
Your code should look like:
|
|
574
574
|
const MyComponent = lazy(() => import('./MyComponent'))
|
|
@@ -1709,7 +1709,7 @@ Example bad output: "A dreamlike crystal formation glowing with ethereal light i
|
|
|
1709
1709
|
Title: "${A.entityTitle??Y}"
|
|
1710
1710
|
|
|
1711
1711
|
Content:
|
|
1712
|
-
${A.entityContent}`,BV1);X=w+P.imagePrompt}catch(P){this.logger.warn("AI prompt distillation failed, using fallback",{error:L0(P)})}}await this.reportProgress(B,{progress:Z2.PROCESS,message:"Generating image"});let H=this.context.identity.get(),U=this.context.identity.getProfile(),Z=AA0(H,U)+X,z;try{z=await this.context.ai.generateImage(Z,{...$&&{aspectRatio:$}})}catch(P){return this.logger.error("Image generation failed",{jobId:Q,error:L0(P)}),F8.failure(P)}await this.reportProgress(B,{progress:Z2.GENERATE,message:"Creating image entity"});let f=t1(Y),E=YG.createImageEntity({dataUrl:z.dataUrl,title:Y});if(await this.context.entityService.getEntity({entityType:"image",id:f}))this.logger.debug("Deleting existing image for regeneration",{imageId:f}),await this.context.entityService.deleteEntity({entityType:"image",id:f});if(await this.context.entityService.createEntity({entity:{...E,id:f}}),this.logger.debug("Created image entity",{imageId:f}),D&&I){await this.reportProgress(B,{progress:Z2.SAVE,message:`Updating ${D} with cover image`});let P=await Bg(this.context.entityService,D,I,this.logger);if(!P)return F8.failure(Error(`Target entity not found: ${D}/${I}`));let x=DN(P,f);await this.context.entities.update(x),this.logger.debug("Updated target entity with cover image",{targetEntityType:D,targetEntityId:I,imageId:f})}return await this.reportProgress(B,{progress:Z2.COMPLETE,message:"Image generation complete"}),this.logger.info("Image generation job complete",{jobId:Q,imageId:f,targetEntityType:D,targetEntityId:I}),{success:!0,imageId:f}}catch(X){return this.logger.error("Image generation job failed",{jobId:Q,error:L0(X)}),F8.failure(X)}}summarizeDataForLog(A){return{title:A.title,promptLength:A.prompt.length,aspectRatio:A.aspectRatio,targetEntityType:A.targetEntityType,targetEntityId:A.targetEntityId}}}var QA0={name:"@brains/image-plugin",private:!0,version:"0.2.0-alpha.53",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/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 DV1=J.object({defaultAspectRatio:J.enum(["1:1","16:9","9:16","4:3","3:4"]).default("16:9").describe("Default aspect ratio for generated images")});class o$A extends n2{entityType=YG.entityType;schema=ob;adapter=YG;constructor(A={}){super("image",QA0,A,DV1)}getEntityTypeConfig(){return{embeddable:!1}}async interceptCreate(A,Q,B){if(!A.targetEntityType||!A.targetEntityId)return{kind:"continue",input:A};let w=await sD(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 um(A,this.logger)}async onRegister(A){let Q=new um(A,this.logger);A.jobs.registerHandler("image-generate",Q)}}function sb(A){return new o$A(A)}tA();import{StdioServerTransport as IV1}from"@modelcontextprotocol/sdk/server/stdio.js";function BA0(){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 s$A(){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 cm(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 s$A()}class h4{static instance=null;mcpServer=null;transport=null;config;logger;static getInstance(A){return h4.instance??=new h4(A),h4.instance}static resetInstance(){if(h4.instance)h4.instance.stop(),h4.instance=null}static createFresh(A){return new h4(A)}constructor(A={}){this.config=A,this.logger=this.config.logger?cm(this.config.logger):BA0()}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 IV1,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 wA0}from"crypto";import{WebStandardStreamableHTTPServerTransport as YV1}from"@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";import{isInitializeRequest as XV1}from"@modelcontextprotocol/sdk/types.js";var HV1={"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, DELETE, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization, MCP-Session-Id","X-Content-Type-Options":"nosniff"};class MK{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?cm(this.config.logger):s$A(),this.authConfig=A.auth??{},!this.authConfig.disabled&&!this.authConfig.token)throw Error("MCP HTTP transport requires an auth token. Set MCP_AUTH_TOKEN in your environment, or pass auth: { disabled: true } for local dev.")}static getInstance(A){return MK.instance??=new MK(A),MK.instance}static resetInstance(){MK.instance=null}static createFresh(A){return new MK(A)}withCors(A){let Q=new Headers(A.headers);for(let[B,w]of Object.entries(HV1))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"}}))}getUnauthorizedResponse(A){return this.createJsonResponse({jsonrpc:"2.0",error:{code:-32001,message:A},id:null},401)}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||!this.authConfig.token)return null;let B=A.headers.get("authorization");if(!B?.startsWith("Bearer "))return this.logger.warn("Authentication failed: Missing Bearer token"),this.getUnauthorizedResponse("Unauthorized: Bearer token required");if(B.substring(7)!==this.authConfig.token)return this.logger.warn("Authentication failed: Invalid token"),this.getUnauthorizedResponse("Unauthorized: Invalid token");return this.logger.debug("Authentication successful"),null}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&&XV1(B))w=new YV1({sessionIdGenerator:()=>wA0(),onsessioninitialized:(D)=>{this.logger.info(`Session initialized: ${D}`),this.transports[D]=w},onsessionclosed:(D)=>{this.logger.info(`Session closed: ${D}`),delete this.transports[D]}}),await(this.mcpTransport?this.mcpTransport.createMcpServer():this.mcpServer).connect(w);else return this.createJsonResponse({jsonrpc:"2.0",error:{code:-32000,message:"Bad Request: Server not initialized"},id:null},400);return this.withCors(await w.handleRequest(A,{parsedBody:B}))}catch(w){return this.logger.error("MCP transport error:",w),this.createJsonResponse({jsonrpc:"2.0",error:{code:-32603,message:"Internal error"}},500)}}async handleAgentChatRequest(A){if(!this.agentService)return this.createJsonResponse({error:"Agent service not connected"},503);let{message:Q,conversationId:B}=await A.json();if(!Q||typeof Q!=="string")return this.createJsonResponse({error:"Missing or invalid 'message' field"},400);let w=B??wA0();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=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}}KA();var a$A=J.object({transport:J.enum(["stdio","http"]).default("http"),httpPort:J.number().describe("Port for HTTP transport (only used when transport is 'http')").default(3333),authToken:J.string().describe("Bearer token for HTTP transport authentication").optional()});function $A0(A,Q){return[]}tA();function t$A(A,Q){A.messaging.subscribe("job-progress",async(B)=>{let w=LN.safeParse(B.payload);if(!w.success)return Q.warn("Received invalid job-progress message",{error:w.error.message}),{success:!1};let $=w.data,D=$.type,I=$.status,Y=$.id;if(Q.debug(`${D} ${Y} - ${I}:`,{id:$.id,message:$.message,progress:$.progress,metadata:$.metadata}),$.batchDetails)Q.debug(`Batch details for ${Y}:`,{totalOperations:$.batchDetails.totalOperations,completedOperations:$.batchDetails.completedOperations,failedOperations:$.batchDetails.failedOperations,currentOperation:$.batchDetails.currentOperation,errors:$.batchDetails.errors});if($.jobDetails)Q.debug(`Job details for ${Y}:`,{jobType:$.jobDetails.jobType,priority:$.jobDetails.priority,retryCount:$.jobDetails.retryCount});return{success:!0}}),Q.debug("Subscribed to job progress events")}var DA0={name:"@brains/mcp",private:!0,version:"0.2.0-alpha.53",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/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 XG extends QX{mcpTransport;stdioServer;httpServer;domain;constructor(A={}){let Q={...A,authToken:A.authToken??process.env.MCP_AUTH_TOKEN};super("mcp",DA0,Q,a$A)}async getTools(){return $A0(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});t$A(A,this.logger)}getOrCreateHttpServer(){if(this.httpServer)return this.httpServer;return this.httpServer=MK.createFresh({port:this.config.httpPort,logger:this.logger,auth:this.config.authToken?{token:this.config.authToken}:{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)B="anchor",this.logger.debug("HTTP auth token 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=h4.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(){h4.resetInstance(),MK.resetInstance()}}tA();KA();var ZI=o0(ML0(),1);KA();tA();var vHA=J.object({botToken:J.string().min(1).describe("Discord bot token"),allowedChannels:J.array(J.string()).default([]),requireMention:J.boolean().default(!0),allowDMs:J.boolean().default(!0),showTypingIndicator:J.boolean().default(!0),statusMessage:J.string().default("Mention me to chat"),useThreads:J.boolean().default(!0),threadAutoArchive:J.union([J.literal(60),J.literal(1440),J.literal(4320),J.literal(10080)]).default(1440),..._O.shape,captureUrlEmoji:J.string().default("\uD83D\uDD16")});var VL0={name:"@brains/discord",private:!0,version:"0.2.0-alpha.53",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 THA=2000,V82=8000,O82=100;function nl(A){return!!A&&typeof A==="object"&&"send"in A&&"sendTyping"in A}class lG extends tF{client=null;fetchText;pendingConfirmations=new Map;typingIntervals=new Map;constructor(A,Q={}){super("discord",VL0,A,vHA);this.fetchText=Q.fetchText??GS}async onRegister(A){await super.onRegister(A),this.client=new ZI.Client({intents:[ZI.GatewayIntentBits.Guilds,ZI.GatewayIntentBits.GuildMessages,ZI.GatewayIntentBits.MessageContent,ZI.GatewayIntentBits.DirectMessages],partials:[ZI.Partials.Channel]}),this.client.on(ZI.Events.MessageCreate,(Q)=>{this.handleMessage(Q)}),this.client.once(ZI.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(!nl(B))return;let w=iV(Q,THA);for(let $ of w)B.send($).catch((D)=>this.logger.error("Failed to send message",{error:D}))}async sendMessageWithId({channelId:A,message:Q}){if(!A||!this.client)return;let B=this.client.channels.cache.get(A);if(!nl(B))return;let w=iV(Q,THA),$;for(let D of w)$=(await B.send(D)).id;return $}async editMessage({channelId:A,messageId:Q,newMessage:B}){if(!A||!this.client)return!1;let w=this.client.channels.cache.get(A);if(!nl(w))return!1;try{return await(await w.messages.fetch(Q)).edit(B.slice(0,THA)),!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;if(this.config.allowedChannels.length>0&&!Q&&!this.config.allowedChannels.includes(A.channel.id))return;if(!Q&&!$&&this.config.requireMention&&!w){if(this.config.captureUrls){let Y=this.extractCaptureableUrls(A.content,this.config.blockedUrlDomains);if(Y.length>0){await A.react(this.config.captureUrlEmoji).catch((X)=>this.logger.debug("React failed",{error:X}));for(let X of Y)await this.captureUrlViaAgent(X,A.channel.id,A.author.id,"discord").catch((H)=>this.logger.error("URL capture failed",{error:H,url:X}))}}return}let D=this.stripMention(A.content);if(A.attachments.size>0){let Y=this.context.permissions.getUserLevel("discord",A.author.id);if(Y==="anchor"||Y==="trusted")for(let H of A.attachments.values()){let U=H.name,F=H.contentType??void 0,Z=H.size;if(!this.isUploadableTextFile(U,F))continue;if(!this.isFileSizeAllowed(Z))continue;try{let z=await this.fetchText(H.url);D+=`
|
|
1712
|
+
${A.entityContent}`,BV1);X=w+P.imagePrompt}catch(P){this.logger.warn("AI prompt distillation failed, using fallback",{error:L0(P)})}}await this.reportProgress(B,{progress:Z2.PROCESS,message:"Generating image"});let H=this.context.identity.get(),U=this.context.identity.getProfile(),Z=AA0(H,U)+X,z;try{z=await this.context.ai.generateImage(Z,{...$&&{aspectRatio:$}})}catch(P){return this.logger.error("Image generation failed",{jobId:Q,error:L0(P)}),F8.failure(P)}await this.reportProgress(B,{progress:Z2.GENERATE,message:"Creating image entity"});let f=t1(Y),E=YG.createImageEntity({dataUrl:z.dataUrl,title:Y});if(await this.context.entityService.getEntity({entityType:"image",id:f}))this.logger.debug("Deleting existing image for regeneration",{imageId:f}),await this.context.entityService.deleteEntity({entityType:"image",id:f});if(await this.context.entityService.createEntity({entity:{...E,id:f}}),this.logger.debug("Created image entity",{imageId:f}),D&&I){await this.reportProgress(B,{progress:Z2.SAVE,message:`Updating ${D} with cover image`});let P=await Bg(this.context.entityService,D,I,this.logger);if(!P)return F8.failure(Error(`Target entity not found: ${D}/${I}`));let x=DN(P,f);await this.context.entities.update(x),this.logger.debug("Updated target entity with cover image",{targetEntityType:D,targetEntityId:I,imageId:f})}return await this.reportProgress(B,{progress:Z2.COMPLETE,message:"Image generation complete"}),this.logger.info("Image generation job complete",{jobId:Q,imageId:f,targetEntityType:D,targetEntityId:I}),{success:!0,imageId:f}}catch(X){return this.logger.error("Image generation job failed",{jobId:Q,error:L0(X)}),F8.failure(X)}}summarizeDataForLog(A){return{title:A.title,promptLength:A.prompt.length,aspectRatio:A.aspectRatio,targetEntityType:A.targetEntityType,targetEntityId:A.targetEntityId}}}var QA0={name:"@brains/image-plugin",private:!0,version:"0.2.0-alpha.54",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/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 DV1=J.object({defaultAspectRatio:J.enum(["1:1","16:9","9:16","4:3","3:4"]).default("16:9").describe("Default aspect ratio for generated images")});class o$A extends n2{entityType=YG.entityType;schema=ob;adapter=YG;constructor(A={}){super("image",QA0,A,DV1)}getEntityTypeConfig(){return{embeddable:!1}}async interceptCreate(A,Q,B){if(!A.targetEntityType||!A.targetEntityId)return{kind:"continue",input:A};let w=await sD(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 um(A,this.logger)}async onRegister(A){let Q=new um(A,this.logger);A.jobs.registerHandler("image-generate",Q)}}function sb(A){return new o$A(A)}tA();import{StdioServerTransport as IV1}from"@modelcontextprotocol/sdk/server/stdio.js";function BA0(){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 s$A(){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 cm(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 s$A()}class h4{static instance=null;mcpServer=null;transport=null;config;logger;static getInstance(A){return h4.instance??=new h4(A),h4.instance}static resetInstance(){if(h4.instance)h4.instance.stop(),h4.instance=null}static createFresh(A){return new h4(A)}constructor(A={}){this.config=A,this.logger=this.config.logger?cm(this.config.logger):BA0()}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 IV1,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 wA0}from"crypto";import{WebStandardStreamableHTTPServerTransport as YV1}from"@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";import{isInitializeRequest as XV1}from"@modelcontextprotocol/sdk/types.js";var HV1={"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, DELETE, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization, MCP-Session-Id","X-Content-Type-Options":"nosniff"};class MK{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?cm(this.config.logger):s$A(),this.authConfig=A.auth??{},!this.authConfig.disabled&&!this.authConfig.token)throw Error("MCP HTTP transport requires an auth token. Set MCP_AUTH_TOKEN in your environment, or pass auth: { disabled: true } for local dev.")}static getInstance(A){return MK.instance??=new MK(A),MK.instance}static resetInstance(){MK.instance=null}static createFresh(A){return new MK(A)}withCors(A){let Q=new Headers(A.headers);for(let[B,w]of Object.entries(HV1))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"}}))}getUnauthorizedResponse(A){return this.createJsonResponse({jsonrpc:"2.0",error:{code:-32001,message:A},id:null},401)}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||!this.authConfig.token)return null;let B=A.headers.get("authorization");if(!B?.startsWith("Bearer "))return this.logger.warn("Authentication failed: Missing Bearer token"),this.getUnauthorizedResponse("Unauthorized: Bearer token required");if(B.substring(7)!==this.authConfig.token)return this.logger.warn("Authentication failed: Invalid token"),this.getUnauthorizedResponse("Unauthorized: Invalid token");return this.logger.debug("Authentication successful"),null}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&&XV1(B))w=new YV1({sessionIdGenerator:()=>wA0(),onsessioninitialized:(D)=>{this.logger.info(`Session initialized: ${D}`),this.transports[D]=w},onsessionclosed:(D)=>{this.logger.info(`Session closed: ${D}`),delete this.transports[D]}}),await(this.mcpTransport?this.mcpTransport.createMcpServer():this.mcpServer).connect(w);else return this.createJsonResponse({jsonrpc:"2.0",error:{code:-32000,message:"Bad Request: Server not initialized"},id:null},400);return this.withCors(await w.handleRequest(A,{parsedBody:B}))}catch(w){return this.logger.error("MCP transport error:",w),this.createJsonResponse({jsonrpc:"2.0",error:{code:-32603,message:"Internal error"}},500)}}async handleAgentChatRequest(A){if(!this.agentService)return this.createJsonResponse({error:"Agent service not connected"},503);let{message:Q,conversationId:B}=await A.json();if(!Q||typeof Q!=="string")return this.createJsonResponse({error:"Missing or invalid 'message' field"},400);let w=B??wA0();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=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}}KA();var a$A=J.object({transport:J.enum(["stdio","http"]).default("http"),httpPort:J.number().describe("Port for HTTP transport (only used when transport is 'http')").default(3333),authToken:J.string().describe("Bearer token for HTTP transport authentication").optional()});function $A0(A,Q){return[]}tA();function t$A(A,Q){A.messaging.subscribe("job-progress",async(B)=>{let w=LN.safeParse(B.payload);if(!w.success)return Q.warn("Received invalid job-progress message",{error:w.error.message}),{success:!1};let $=w.data,D=$.type,I=$.status,Y=$.id;if(Q.debug(`${D} ${Y} - ${I}:`,{id:$.id,message:$.message,progress:$.progress,metadata:$.metadata}),$.batchDetails)Q.debug(`Batch details for ${Y}:`,{totalOperations:$.batchDetails.totalOperations,completedOperations:$.batchDetails.completedOperations,failedOperations:$.batchDetails.failedOperations,currentOperation:$.batchDetails.currentOperation,errors:$.batchDetails.errors});if($.jobDetails)Q.debug(`Job details for ${Y}:`,{jobType:$.jobDetails.jobType,priority:$.jobDetails.priority,retryCount:$.jobDetails.retryCount});return{success:!0}}),Q.debug("Subscribed to job progress events")}var DA0={name:"@brains/mcp",private:!0,version:"0.2.0-alpha.54",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/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 XG extends QX{mcpTransport;stdioServer;httpServer;domain;constructor(A={}){let Q={...A,authToken:A.authToken??process.env.MCP_AUTH_TOKEN};super("mcp",DA0,Q,a$A)}async getTools(){return $A0(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});t$A(A,this.logger)}getOrCreateHttpServer(){if(this.httpServer)return this.httpServer;return this.httpServer=MK.createFresh({port:this.config.httpPort,logger:this.logger,auth:this.config.authToken?{token:this.config.authToken}:{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)B="anchor",this.logger.debug("HTTP auth token 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=h4.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(){h4.resetInstance(),MK.resetInstance()}}tA();KA();var ZI=o0(ML0(),1);KA();tA();var vHA=J.object({botToken:J.string().min(1).describe("Discord bot token"),allowedChannels:J.array(J.string()).default([]),requireMention:J.boolean().default(!0),allowDMs:J.boolean().default(!0),showTypingIndicator:J.boolean().default(!0),statusMessage:J.string().default("Mention me to chat"),useThreads:J.boolean().default(!0),threadAutoArchive:J.union([J.literal(60),J.literal(1440),J.literal(4320),J.literal(10080)]).default(1440),..._O.shape,captureUrlEmoji:J.string().default("\uD83D\uDD16")});var VL0={name:"@brains/discord",private:!0,version:"0.2.0-alpha.54",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 THA=2000,V82=8000,O82=100;function nl(A){return!!A&&typeof A==="object"&&"send"in A&&"sendTyping"in A}class lG extends tF{client=null;fetchText;pendingConfirmations=new Map;typingIntervals=new Map;constructor(A,Q={}){super("discord",VL0,A,vHA);this.fetchText=Q.fetchText??GS}async onRegister(A){await super.onRegister(A),this.client=new ZI.Client({intents:[ZI.GatewayIntentBits.Guilds,ZI.GatewayIntentBits.GuildMessages,ZI.GatewayIntentBits.MessageContent,ZI.GatewayIntentBits.DirectMessages],partials:[ZI.Partials.Channel]}),this.client.on(ZI.Events.MessageCreate,(Q)=>{this.handleMessage(Q)}),this.client.once(ZI.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(!nl(B))return;let w=iV(Q,THA);for(let $ of w)B.send($).catch((D)=>this.logger.error("Failed to send message",{error:D}))}async sendMessageWithId({channelId:A,message:Q}){if(!A||!this.client)return;let B=this.client.channels.cache.get(A);if(!nl(B))return;let w=iV(Q,THA),$;for(let D of w)$=(await B.send(D)).id;return $}async editMessage({channelId:A,messageId:Q,newMessage:B}){if(!A||!this.client)return!1;let w=this.client.channels.cache.get(A);if(!nl(w))return!1;try{return await(await w.messages.fetch(Q)).edit(B.slice(0,THA)),!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;if(this.config.allowedChannels.length>0&&!Q&&!this.config.allowedChannels.includes(A.channel.id))return;if(!Q&&!$&&this.config.requireMention&&!w){if(this.config.captureUrls){let Y=this.extractCaptureableUrls(A.content,this.config.blockedUrlDomains);if(Y.length>0){await A.react(this.config.captureUrlEmoji).catch((X)=>this.logger.debug("React failed",{error:X}));for(let X of Y)await this.captureUrlViaAgent(X,A.channel.id,A.author.id,"discord").catch((H)=>this.logger.error("URL capture failed",{error:H,url:X}))}}return}let D=this.stripMention(A.content);if(A.attachments.size>0){let Y=this.context.permissions.getUserLevel("discord",A.author.id);if(Y==="anchor"||Y==="trusted")for(let H of A.attachments.values()){let U=H.name,F=H.contentType??void 0,Z=H.size;if(!this.isUploadableTextFile(U,F))continue;if(!this.isFileSizeAllowed(Z))continue;try{let z=await this.fetchText(H.url);D+=`
|
|
1713
1713
|
|
|
1714
1714
|
`+this.formatFileUploadMessage(U,z)}catch(z){this.logger.error("Failed to download attachment",{error:z,filename:U})}}}if(D=D.trim(),!D)return;let I=A.channel.id;await this.routeToAgent(D,I,A)}async routeToAgent(A,Q,B){if(!this.context)return;let w=this.context.agent,$=Q;if(this.config.useThreads&&B.guild&&!B.channel.isThread())try{$=(await B.startThread({name:bU(A,O82),autoArchiveDuration:this.config.threadAutoArchive})).id}catch(X){this.logger.error("Failed to create thread",{error:X})}let D=`discord-${$}`,I=this.context.permissions.getUserLevel("discord",B.author.id),Y=B.guild?.name??"DM";this.startProcessingInput($);try{let X=this.client?.channels.cache.get($);if(nl(X))this.startTypingIndicator(X);if(this.pendingConfirmations.has(D)){await this.handleConfirmationResponse(A,D,$);return}let H=await w.chat(A,D,{userPermissionLevel:I,interfaceType:"discord",channelId:$,channelName:Y});if(H.pendingConfirmation)this.pendingConfirmations.set(D,!0);let U=await this.sendMessageWithId({channelId:$,message:H.text});if(U&&H.toolResults){for(let F of H.toolResults)if(F.jobId)this.trackAgentResponseForJob(F.jobId,U,$)}}catch(X){this.logger.error("Error handling message",{error:X,channelId:$}),this.sendMessageToChannel({channelId:$,message:`**Error:** ${X instanceof Error?X.message:"Unknown error"}`})}finally{this.endProcessingInput(),this.stopTypingIndicator($)}}async handleConfirmationResponse(A,Q,B){let w=_N(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}))},V82);this.typingIntervals.set(A.id,Q)}stopTypingIndicator(A){let Q=this.typingIntervals.get(A);if(Q)clearInterval(Q),this.typingIntervals.delete(A)}stripMention(A){if(!this.client?.user)return A;return A.replace(new RegExp(`<@!?${this.client.user.id}>`,"g"),"").trim()}}tA();import{resolve as zC,join as U62}from"path";var SHA=(A,Q,B)=>{return(w,$)=>{let D=-1;return I(0);async function I(Y){if(Y<=D)throw Error("next() called multiple times");D=Y;let X,H=!1,U;if(A[Y])U=A[Y][0][0],w.req.routeIndex=Y;else U=Y===A.length&&$||void 0;if(U)try{X=await U(w,()=>I(Y+1))}catch(F){if(F instanceof Error&&Q)w.error=F,X=await Q(F,w),H=!0;else throw F}else if(w.finalized===!1&&B)X=await B(w);if(X&&(w.finalized===!1||H))w.res=X;return w}}};var OL0=Symbol();var RL0=async(A,Q=Object.create(null))=>{let{all:B=!1,dot:w=!1}=Q,D=(A instanceof ol?A.raw.headers:A.headers).get("Content-Type");if(D?.startsWith("multipart/form-data")||D?.startsWith("application/x-www-form-urlencoded"))return R82(A,{all:B,dot:w});return{}};async function R82(A,Q){let B=await A.formData();if(B)return b82(B,Q);return{}}function b82(A,Q){let B=Object.create(null);if(A.forEach((w,$)=>{if(!(Q.all||$.endsWith("[]")))B[$]=w;else P82(B,$,w)}),Q.dot)Object.entries(B).forEach(([w,$])=>{if(w.includes("."))k82(B,w,$),delete B[w]});return B}var P82=(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]},k82=(A,Q,B)=>{let w=A,$=Q.split(".");$.forEach((D,I)=>{if(I===$.length-1)w[D]=B;else{if(!w[D]||typeof w[D]!=="object"||Array.isArray(w[D])||w[D]instanceof File)w[D]=Object.create(null);w=w[D]}})};var hHA=(A)=>{let Q=A.split("/");if(Q[0]==="")Q.shift();return Q},bL0=(A)=>{let{groups:Q,path:B}=j82(A),w=hHA(B);return _82(w,Q)},j82=(A)=>{let Q=[];return A=A.replace(/\{[^}]+\}/g,(B,w)=>{let $=`@${w}`;return Q.push([$,B]),$}),{groups:Q,path:A}},_82=(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},sl={},PL0=(A,Q)=>{if(A==="*")return"*";let B=A.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);if(B){let w=`${A}#${Q}`;if(!sl[w])if(B[2])sl[w]=Q&&Q[0]!==":"&&Q[0]!=="*"?[w,B[1],new RegExp(`^${B[2]}(?=/${Q})`)]:[A,B[1],new RegExp(`^${B[2]}$`)];else sl[w]=[A,B[1],!0];return sl[w]}return null},al=(A,Q)=>{try{return Q(A)}catch{return A.replace(/(?:%[0-9A-Fa-f]{2})+/g,(B)=>{try{return Q(B)}catch{return B}})}},yHA=(A)=>al(A,decodeURI),mHA=(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 D=Q.indexOf("?",w),I=Q.indexOf("#",w),Y=D===-1?I===-1?void 0:I:I===-1?D:Math.min(D,I),X=Q.slice(B,Y);return yHA(X.includes("%25")?X.replace(/%25/g,"%2525"):X)}else if($===63||$===35)break}return Q.slice(B,w)};var kL0=(A)=>{let Q=mHA(A);return Q.length>1&&Q.at(-1)==="/"?Q.slice(0,-1):Q},P3=(A,Q,...B)=>{if(B.length)Q=P3(Q,...B);return`${A?.[0]==="/"?"":"/"}${A}${Q==="/"?"":`${A?.at(-1)==="/"?"":"/"}${Q?.[0]==="/"?Q.slice(1):Q}`}`},tl=(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 D=$.replace("?","");w+="/"+D,B.push(w)}else w+="/"+$}),B.filter(($,D,I)=>I.indexOf($)===D)},gHA=(A)=>{if(!/[%+]/.test(A))return A;if(A.indexOf("+")!==-1)A=A.replace(/\+/g," ");return A.indexOf("%")!==-1?al(A,uHA):A},jL0=(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 Y=A.charCodeAt(I+Q.length+1);if(Y===61){let X=I+Q.length+2,H=A.indexOf("&",X);return gHA(A.slice(X,H===-1?void 0:H))}else if(Y==38||isNaN(Y))return"";I=A.indexOf(`&${Q}`,I+1)}if(w=/[%+]/.test(A),!w)return}let $={};w??=/[%+]/.test(A);let D=A.indexOf("?",8);while(D!==-1){let I=A.indexOf("&",D+1),Y=A.indexOf("=",D);if(Y>I&&I!==-1)Y=-1;let X=A.slice(D+1,Y===-1?I===-1?void 0:I:Y);if(w)X=gHA(X);if(D=I,X==="")continue;let H;if(Y===-1)H="";else if(H=A.slice(Y+1,I===-1?void 0:I),w)H=gHA(H);if(B){if(!($[X]&&Array.isArray($[X])))$[X]=[];$[X].push(H)}else $[X]??=H}return Q?$[Q]:$},_L0=jL0,xL0=(A,Q)=>{return jL0(A,Q,!0)},uHA=decodeURIComponent;var vL0=(A)=>al(A,uHA),ol=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.#D()}#B(A){let Q=this.#Q[0][this.routeIndex][1][A],B=this.#$(Q);return B&&/\%/.test(B)?vL0(B):B}#D(){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)?vL0(w):w}return A}#$(A){return this.#Q[1]?this.#Q[1][A]:A}query(A){return _L0(this.url,A)}queries(A){return xL0(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 RL0(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((D)=>{if($==="json")D=JSON.stringify(D);return new Response(D)[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[OL0](){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 TL0={Stringify:1,BeforeStream:2,Stream:3},SL0=(A,Q)=>{let B=new String(A);return B.isEscaped=!0,B.callbacks=Q,B};var cHA=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 D=A.callbacks;if(!D?.length)return Promise.resolve(A);if($)$[0]+=A;else $=[A];let I=Promise.all(D.map((Y)=>Y({phase:Q,buffer:$,context:w}))).then((Y)=>Promise.all(Y.filter(Boolean).map((X)=>cHA(X,Q,!1,w,$))).then(()=>$[0]));if(B)return SL0(await I,D);else return I};var x82="text/plain; charset=UTF-8",lHA=(A,Q)=>{return{"Content-Type":A,...Q}},vk=(A,Q)=>new Response(A,Q),gL0=class{#A;#Q;env={};#B;finalized=!1;error;#D;#$;#w;#K;#X;#H;#Y;#W;#U;constructor(A,Q){if(this.#A=A,Q)this.#$=Q.executionCtx,this.env=Q.env,this.#H=Q.notFoundHandler,this.#U=Q.path,this.#W=Q.matchResult}get req(){return this.#Q??=new ol(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||=vk(null,{headers:this.#Y??=new Headers})}set res(A){if(this.#w&&A){A=vk(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.#X??=(Q)=>this.html(Q),this.#X(...A)};setLayout=(A)=>this.#K=A;getLayout=()=>this.#K;setRenderer=(A)=>{this.#X=A};header=(A,Q,B)=>{if(this.finalized)this.#w=vk(this.#w.body,this.#w);let w=this.#w?this.#w.headers:this.#Y??=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.#D=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.#Y??new Headers;if(typeof Q==="object"&&"headers"in Q){let D=Q.headers instanceof Headers?Q.headers:new Headers(Q.headers);for(let[I,Y]of D)if(I.toLowerCase()==="set-cookie")w.append(I,Y);else w.set(I,Y)}if(B)for(let[D,I]of Object.entries(B))if(typeof I==="string")w.set(D,I);else{w.delete(D);for(let Y of I)w.append(D,Y)}let $=typeof Q==="number"?Q:Q?.status??this.#D;return vk(A,{status:$,headers:w})}newResponse=(...A)=>this.#I(...A);body=(A,Q,B)=>this.#I(A,Q,B);text=(A,Q,B)=>{return!this.#Y&&!this.#D&&!Q&&!B&&!this.finalized?new Response(A):this.#I(A,Q,lHA(x82,B))};json=(A,Q,B)=>{return this.#I(JSON.stringify(A),Q,lHA("application/json",B))};html=(A,Q,B)=>{let w=($)=>this.#I($,Q,lHA("text/html; charset=UTF-8",B));return typeof A==="object"?cHA(A,TL0.Stringify,!1,{}).then(w):w(A)};redirect=(A,Q)=>{let B=String(A);return this.header("Location",!/[^\x00-\xFF]/.test(B)?B:encodeURI(B)),this.newResponse(null,Q??302)};notFound=()=>{return this.#H??=()=>vk(),this.#H(this)}};var uB="ALL",hL0="all",yL0=["get","post","put","delete","options","patch"],el="Can not add a route since the matcher is already built.",Ap=class extends Error{};var pHA="__COMPOSED_HANDLER";var v82=(A)=>{return A.text("404 Not Found",404)},mL0=(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)},uL0=class A{get;post;put;delete;options;patch;all;on;use;router;getPath;_basePath="/";#A="/";routes=[];constructor(Q={}){[...yL0,hL0].forEach((D)=>{this[D]=(I,...Y)=>{if(typeof I==="string")this.#A=I;else this.#D(D,this.#A,I);return Y.forEach((X)=>{this.#D(D,this.#A,X)}),this}}),this.on=(D,I,...Y)=>{for(let X of[I].flat()){this.#A=X;for(let H of[D].flat())Y.map((U)=>{this.#D(H.toUpperCase(),this.#A,U)})}return this},this.use=(D,...I)=>{if(typeof D==="string")this.#A=D;else this.#A="*",I.unshift(D);return I.forEach((Y)=>{this.#D(uB,this.#A,Y)}),this};let{strict:w,...$}=Q;Object.assign(this,$),this.getPath=w??!0?Q.getPath??mHA:kL0}#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=v82;errorHandler=mL0;route(Q,B){let w=this.basePath(Q);return B.routes.map(($)=>{let D;if(B.errorHandler===mL0)D=$.handler;else D=async(I,Y)=>(await SHA([],B.errorHandler)(I,()=>$.handler(I,Y))).res,D[pHA]=$.handler;w.#D($.method,$.path,D)}),this}basePath(Q){let B=this.#Q();return B._basePath=P3(this._basePath,Q),B}onError=(Q)=>{return this.errorHandler=Q,this};notFound=(Q)=>{return this.#B=Q,this};mount(Q,B,w){let $,D;if(w)if(typeof w==="function")D=w;else if(D=w.optionHandler,w.replaceRequest===!1)$=(X)=>X;else $=w.replaceRequest;let I=D?(X)=>{let H=D(X);return Array.isArray(H)?H:[H]}:(X)=>{let H=void 0;try{H=X.executionCtx}catch{}return[X.env,H]};$||=(()=>{let X=P3(this._basePath,Q),H=X==="/"?0:X.length;return(U)=>{let F=new URL(U.url);return F.pathname=F.pathname.slice(H)||"/",new Request(F,U)}})();let Y=async(X,H)=>{let U=await B($(X.req.raw),...I(X));if(U)return U;await H()};return this.#D(uB,P3(Q,"*"),Y),this}#D(Q,B,w){Q=Q.toUpperCase(),B=P3(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 D=this.getPath(Q,{env:w}),I=this.router.match($,D),Y=new gL0(Q,{path:D,matchResult:I,env:w,executionCtx:B,notFoundHandler:this.#B});if(I[0].length===1){let H;try{H=I[0][0][0][0](Y,async()=>{Y.res=await this.#B(Y)})}catch(U){return this.#$(U,Y)}return H instanceof Promise?H.then((U)=>U||(Y.finalized?Y.res:this.#B(Y))).catch((U)=>this.#$(U,Y)):H??this.#B(Y)}let X=SHA(I[0],this.errorHandler,this.#B);return(async()=>{try{let H=await X(Y);if(!H.finalized)throw Error("Context is not finalized. Did you forget to return a Response object or `await next()`?");return H.res}catch(H){return this.#$(H,Y)}})()}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${P3("/",Q)}`,B),w,$)};fire=()=>{addEventListener("fetch",(Q)=>{Q.respondWith(this.#w(Q.request,Q,void 0,Q.request.method))})}};var Tk=[];function Qp(A,Q){let B=this.buildAllMatchers(),w=($,D)=>{let I=B[$]||B[uB],Y=I[2][D];if(Y)return Y;let X=D.match(I[0]);if(!X)return[[],Tk];let H=X.indexOf("",1);return[I[1][H],X]};return this.match=w,w(A,Q)}var Bp="[^/]+",Sk=".*",gk="(?:|/.*)",k3=Symbol(),T82=new Set(".\\+*[^]$()");function S82(A,Q){if(A.length===1)return Q.length===1?A<Q?-1:1:-1;if(Q.length===1)return 1;if(A===Sk||A===gk)return 1;else if(Q===Sk||Q===gk)return-1;if(A===Bp)return 1;else if(Q===Bp)return-1;return A.length===Q.length?A<Q?-1:1:Q.length-A.length}var cL0=class A{#A;#Q;#B=Object.create(null);insert(Q,B,w,$,D){if(Q.length===0){if(this.#A!==void 0)throw k3;if(D)return;this.#A=B;return}let[I,...Y]=Q,X=I==="*"?Y.length===0?["","",Sk]:["","",Bp]:I==="/*"?["","",gk]:I.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/),H;if(X){let U=X[1],F=X[2]||Bp;if(U&&X[2]){if(F===".*")throw k3;if(F=F.replace(/^\((?!\?:)(?=[^)]+\)$)/,"(?:"),/\((?!\?:)/.test(F))throw k3}if(H=this.#B[F],!H){if(Object.keys(this.#B).some((Z)=>Z!==Sk&&Z!==gk))throw k3;if(D)return;if(H=this.#B[F]=new A,U!=="")H.#Q=$.varIndex++}if(!D&&U!=="")w.push([U,H.#Q])}else if(H=this.#B[I],!H){if(Object.keys(this.#B).some((U)=>U.length>1&&U!==Sk&&U!==gk))throw k3;if(D)return;H=this.#B[I]=new A}H.insert(Y,B,w,$,D)}buildRegExpStr(){let B=Object.keys(this.#B).sort(S82).map((w)=>{let $=this.#B[w];return(typeof $.#Q==="number"?`(${w})@${$.#Q}`:T82.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 lL0=class{#A={varIndex:0};#Q=new cL0;insert(A,Q,B){let w=[],$=[];for(let I=0;;){let Y=!1;if(A=A.replace(/\{[^}]+\}/g,(X)=>{let H=`@\\${I}`;return $[I]=[H,X],I++,Y=!0,H}),!Y)break}let D=A.match(/(?::[^\/]+)|(?:\/\*$)|./g)||[];for(let I=$.length-1;I>=0;I--){let[Y]=$[I];for(let X=D.length-1;X>=0;X--)if(D[X].indexOf(Y)!==-1){D[X]=D[X].replace(Y,$[I][1]);break}}return this.#Q.insert(D,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,($,D,I)=>{if(D!==void 0)return B[++Q]=Number(D),"$()";if(I!==void 0)return w[Number(I)]=++Q,"";return""}),[new RegExp(`^${A}`),B,w]}};var g82=[/^$/,[],Object.create(null)],pL0=Object.create(null);function dL0(A){return pL0[A]??=new RegExp(A==="*"?"":`^${A.replace(/\/\*$|([.\\+*[^\]$()])/g,(Q,B)=>B?`\\${B}`:"(?:|/.*)")}$`)}function h82(){pL0=Object.create(null)}function y82(A){let Q=new lL0,B=[];if(A.length===0)return g82;let w=A.map((H)=>[!/\*|\/:/.test(H[0]),...H]).sort(([H,U],[F,Z])=>H?1:F?-1:U.length-Z.length),$=Object.create(null);for(let H=0,U=-1,F=w.length;H<F;H++){let[Z,z,f]=w[H];if(Z)$[z]=[f.map(([C])=>[C,Object.create(null)]),Tk];else U++;let E;try{E=Q.insert(z,U,Z)}catch(C){throw C===k3?new Ap(z):C}if(Z)continue;B[U]=f.map(([C,P])=>{let x=Object.create(null);P-=1;for(;P>=0;P--){let[k,o]=E[P];x[k]=o}return[C,x]})}let[D,I,Y]=Q.buildRegExp();for(let H=0,U=B.length;H<U;H++)for(let F=0,Z=B[H].length;F<Z;F++){let z=B[H][F]?.[1];if(!z)continue;let f=Object.keys(z);for(let E=0,C=f.length;E<C;E++)z[f[E]]=Y[z[f[E]]]}let X=[];for(let H in I)X[H]=B[I[H]];return[D,X,$]}function JC(A,Q){if(!A)return;for(let B of Object.keys(A).sort((w,$)=>$.length-w.length))if(dL0(B).test(Q))return[...A[B]];return}var wp=class{name="RegExpRouter";#A;#Q;constructor(){this.#A={[uB]:Object.create(null)},this.#Q={[uB]:Object.create(null)}}add(A,Q,B){let w=this.#A,$=this.#Q;if(!w||!$)throw Error(el);if(!w[A])[w,$].forEach((Y)=>{Y[A]=Object.create(null),Object.keys(Y[uB]).forEach((X)=>{Y[A][X]=[...Y[uB][X]]})});if(Q==="/*")Q="*";let D=(Q.match(/\/:/g)||[]).length;if(/\*$/.test(Q)){let Y=dL0(Q);if(A===uB)Object.keys(w).forEach((X)=>{w[X][Q]||=JC(w[X],Q)||JC(w[uB],Q)||[]});else w[A][Q]||=JC(w[A],Q)||JC(w[uB],Q)||[];Object.keys(w).forEach((X)=>{if(A===uB||A===X)Object.keys(w[X]).forEach((H)=>{Y.test(H)&&w[X][H].push([B,D])})}),Object.keys($).forEach((X)=>{if(A===uB||A===X)Object.keys($[X]).forEach((H)=>Y.test(H)&&$[X][H].push([B,D]))});return}let I=tl(Q)||[Q];for(let Y=0,X=I.length;Y<X;Y++){let H=I[Y];Object.keys($).forEach((U)=>{if(A===uB||A===U)$[U][H]||=[...JC(w[U],H)||JC(w[uB],H)||[]],$[U][H].push([B,D-X+Y+1])})}}match=Qp;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,h82(),A}#B(A){let Q=[],B=A===uB;if([this.#A,this.#Q].forEach((w)=>{let $=w[A]?Object.keys(w[A]).map((D)=>[D,w[A][D]]):[];if($.length!==0)B||=!0,Q.push(...$);else if(A!==uB)Q.push(...Object.keys(w[uB]).map((D)=>[D,w[uB][D]]))}),!B)return null;else return y82(Q)}};var m82=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))}#D(A,Q,B,w,$){let D=this.#A[A];if(!$)D[2][Q][0].push([B,{}]);else w.forEach((I)=>{if(typeof I==="number")D[1][I].push([B,$]);else D[2][I||Q][0].push([B,$])})}add(A,Q,B){if(!this.#A[A]){let $=this.#A[uB],D={};for(let I in $[2])D[I]=[$[2][I][0].slice(),Tk];this.#A[A]=[$[0],$[1].map((I)=>Array.isArray(I)?I.slice():0),D]}if(Q==="/*"||Q==="*"){let $=[B,{}];if(A===uB)for(let D in this.#A)this.#B(D,$);else this.#B(A,$);return}let w=this.#Q[Q];if(!w)throw Error(`Path ${Q} is not registered`);for(let[$,D]of w)if(A===uB)for(let I in this.#A)this.#D(I,Q,B,$,D);else this.#D(A,Q,B,$,D)}buildAllMatchers(){return this.#A}match=Qp};var dHA=class{name="SmartRouter";#A=[];#Q=[];constructor(A){this.#A=A.routers}add(A,Q,B){if(!this.#Q)throw Error(el);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,D=0,I;for(;D<$;D++){let Y=B[D];try{for(let X=0,H=w.length;X<H;X++)Y.add(...w[X]);I=Y.match(A,Q)}catch(X){if(X instanceof Ap)continue;throw X}this.match=Y.match.bind(Y),this.#A=[Y],this.#Q=void 0;break}if(D===$)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 hk=Object.create(null),u82=(A)=>{for(let Q in A)return!0;return!1},iL0=class A{#A;#Q;#B;#D=0;#$=hk;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.#D=++this.#D;let $=this,D=bL0(B),I=[];for(let Y=0,X=D.length;Y<X;Y++){let H=D[Y],U=D[Y+1],F=PL0(H,U),Z=Array.isArray(F)?F[0]:H;if(Z in $.#Q){if($=$.#Q[Z],F)I.push(F[1]);continue}if($.#Q[Z]=new A,F)$.#B.push(F),I.push(F[1]);$=$.#Q[Z]}return $.#A.push({[Q]:{handler:w,possibleKeys:I.filter((Y,X,H)=>H.indexOf(Y)===X),score:this.#D}}),$}#w(Q,B,w,$,D){for(let I=0,Y=B.#A.length;I<Y;I++){let X=B.#A[I],H=X[w]||X[uB],U={};if(H!==void 0){if(H.params=Object.create(null),Q.push(H),$!==hk||D&&D!==hk)for(let F=0,Z=H.possibleKeys.length;F<Z;F++){let z=H.possibleKeys[F],f=U[H.score];H.params[z]=D?.[z]&&!f?D[z]:$[z]??D?.[z],U[H.score]=!0}}}}search(Q,B){let w=[];this.#$=hk;let D=[this],I=hHA(B),Y=[],X=I.length,H=null;for(let U=0;U<X;U++){let F=I[U],Z=U===X-1,z=[];for(let E=0,C=D.length;E<C;E++){let P=D[E],x=P.#Q[F];if(x)if(x.#$=P.#$,Z){if(x.#Q["*"])this.#w(w,x.#Q["*"],Q,P.#$);this.#w(w,x,Q,P.#$)}else z.push(x);for(let k=0,o=P.#B.length;k<o;k++){let r=P.#B[k],u=P.#$===hk?{}:{...P.#$};if(r==="*"){let l=P.#Q["*"];if(l)this.#w(w,l,Q,P.#$),l.#$=u,z.push(l);continue}let[v,S,h]=r;if(!F&&!(h instanceof RegExp))continue;let t=P.#Q[v];if(h instanceof RegExp){if(H===null){H=Array(X);let YA=B[0]==="/"?1:0;for(let b=0;b<X;b++)H[b]=YA,YA+=I[b].length+1}let l=B.substring(H[U]),UA=h.exec(l);if(UA){if(u[S]=UA[0],this.#w(w,t,Q,P.#$,u),u82(t.#Q)){t.#$=u;let YA=UA[0].match(/\//)?.length??0;(Y[YA]||=[]).push(t)}continue}}if(h===!0||h.test(F))if(u[S]=F,Z){if(this.#w(w,t,Q,u,P.#$),t.#Q["*"])this.#w(w,t.#Q["*"],Q,u,P.#$)}else t.#$=u,z.push(t)}}let f=Y.shift();D=f?z.concat(f):z}if(w.length>1)w.sort((U,F)=>{return U.score-F.score});return[w.map(({handler:U,params:F})=>[U,F])]}};var iHA=class{name="TrieRouter";#A;constructor(){this.#A=new iL0}add(A,Q,B){let w=tl(Q);if(w){for(let $=0,D=w.length;$<D;$++)this.#A.insert(A,w[$],B);return}this.#A.insert(A,Q,B)}match(A,Q){return this.#A.search(A,Q)}};var FC=class extends uL0{constructor(A={}){super(A);this.router=A.router??new dHA({routers:[new wp,new iHA]})}};import{stat as i82}from"fs/promises";import{join as r82}from"path";var ZC=/^\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 rHA=(A,Q=l82)=>{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 c82={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"},l82=c82;var rL0=(...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 nL0={br:".br",zstd:".zst",gzip:".gz"},p82=Object.keys(nL0),d82="index.html",oL0=(A)=>{let Q=A.root??"./",B=A.path,w=A.join??rL0;return async($,D)=>{if($.finalized)return D();let I;if(A.path)I=A.path;else try{if(I=yHA($.req.path),/(?:^|[\/\\])\.\.(?:$|[\/\\])/.test(I))throw Error()}catch{return await A.onNotFound?.($.req.path,$),D()}let Y=w(Q,!B&&A.rewriteRequestPath?A.rewriteRequestPath(I):I);if(A.isDir&&await A.isDir(Y))Y=w(Y,d82);let X=A.getContent,H=await X(Y,$);if(H instanceof Response)return $.newResponse(H.body,H);if(H){let U=A.mimes&&rHA(Y,A.mimes)||rHA(Y);if($.header("Content-Type",U||"application/octet-stream"),A.precompressed&&(!U||ZC.test(U))){let F=new Set($.req.header("Accept-Encoding")?.split(",").map((Z)=>Z.trim()));for(let Z of p82){if(!F.has(Z))continue;let z=await X(Y+nL0[Z],$);if(z){H=z,$.header("Content-Encoding",Z),$.header("Vary","Accept-Encoding",{append:!0});break}}}return await A.onFound?.(Y,$),$.body(H)}await A.onNotFound?.(Y,$),await D();return}};var nHA=(A)=>{return async function(B,w){return oL0({...A,getContent:async(I)=>{let Y=Bun.file(I);return await Y.exists()?Y:null},join:r82,isDir:async(I)=>{let Y;try{Y=(await i82(I)).isDirectory()}catch{}return Y}})(B,w)}};var oHA="x-hono-disable-ssg",SnQ=(()=>{try{return new Response("SSG is disabled",{status:404,headers:{[oHA]:"true"}})}catch{return null}})();var{write:zoQ}=Bun;var s82=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 sL0=(A)=>{return(...Q)=>{if(typeof Q[0]==="function"){let[B,w]=Q;return async function(D,I){let Y=await B(D),X=await A(D,Y,w);if(X)return X;await I()}}else{let[B,w,$]=Q;return(async()=>{let D=await A(B,w,$);if(!D)throw Error("Failed to upgrade WebSocket");return D})()}}};var $p=(A)=>("server"in A.env)?A.env.server:A.env;var a82=sL0((A,Q)=>{let B=$p(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 t82=["gzip","deflate"],e82=/(?:^|,)\s*?no-transform\s*?(?:,|$)/i,aL0=(A)=>{let Q=A?.threshold??1024;return async function(w,$){await $();let D=w.res.headers.get("Content-Length");if(w.res.headers.has("Content-Encoding")||w.res.headers.has("Transfer-Encoding")||w.req.method==="HEAD"||D&&Number(D)<Q||!A62(w.res)||!Q62(w.res))return;let I=w.req.header("Accept-Encoding"),Y=A?.encoding??t82.find((H)=>I?.includes(H));if(!Y||!w.res.body)return;let X=new CompressionStream(Y);w.res=new Response(w.res.body.pipeThrough(X),w.res),w.res.headers.delete("Content-Length"),w.res.headers.set("Content-Encoding",Y)}},A62=(A)=>{let Q=A.headers.get("Content-Type");return Q&&ZC.test(Q)},Q62=(A)=>{let Q=A.headers.get("Cache-Control");return!Q||!e82.test(Q)};import{Readable as tL0}from"stream";import{createDeflate as B62,createGzip as w62}from"zlib";var $62=["gzip","deflate"],D62=/(?:^|,)\s*?no-transform\s*?(?:,|$)/i,eL0=(A)=>{if(typeof CompressionStream<"u")return aL0(A);let Q=A?.threshold??1024;return async function(w,$){await $();let D=w.res.headers.get("Content-Length");if(w.res.headers.has("Content-Encoding")||w.res.headers.has("Transfer-Encoding")||w.req.method==="HEAD"||D&&Number(D)<Q||!I62(w.res)||!Y62(w.res))return;let I=w.req.header("Accept-Encoding"),Y=A?.encoding??$62.find((X)=>I?.includes(X));if(!Y||!w.res.body)return;try{let X=Y==="gzip"?w62():B62(),H=w.res.body,F=tL0.fromWeb(H).pipe(X),Z=tL0.toWeb(F);w.res=new Response(Z,w.res),w.res.headers.delete("Content-Length"),w.res.headers.set("Content-Encoding",Y)}catch(X){console.error("Compression error:",X)}}},I62=(A)=>{let Q=A.headers.get("Content-Type");return Q&&ZC.test(Q)},Y62=(A)=>{let Q=A.headers.get("Cache-Control");return!Q||!D62.test(Q)};var X62=(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},AC0=async(A,Q)=>{if(!A)return null;let B=void 0,w=A.getReader();for(;;){let{value:$,done:D}=await w.read();if(D)break;B=await Q(X62(B,$))}if(!B)return null;return Array.prototype.map.call(new Uint8Array(B),($)=>$.toString(16).padStart(2,"0")).join("")};var H62=["cache-control","content-location","date","etag","expires","vary"],QC0=(A)=>A.replace(/^W\//,"");function K62(A,Q){return Q!=null&&Q.split(/,\s*/).some((B)=>QC0(B)===QC0(A))}function W62(A){if(!A){if(crypto&&crypto.subtle)A=(Q)=>crypto.subtle.digest({name:"SHA-1"},Q)}return A}var BC0=(A)=>{let Q=A?.retainedHeaders??H62,B=A?.weak??!1,w=W62(A?.generateDigest);return async function(D,I){let Y=D.req.header("If-None-Match")??null;await I();let X=D.res,H=X.headers.get("ETag");if(!H){if(!w)return;let U=await AC0(X.clone().body,w);if(U===null)return;H=B?`W/"${U}"`:`"${U}"`}if(K62(H,Y))D.res=new Response(null,{status:304,statusText:"Not Modified",headers:{ETag:H}}),D.res.headers.forEach((U,F)=>{if(Q.indexOf(F.toLowerCase())===-1)D.res.headers.delete(F)});else D.res.headers.set("ETag",H)}};tA();function Dp(A,Q){return async(B)=>{let w=B.req.raw,$=w.headers.get("content-type")??"",D=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[f,E]of z.entries())I[f]=E}let Y=`${A.pluginId}_${A.definition.tool}`,X=await Q.send({type:`plugin:${A.pluginId}:tool:execute`,payload:{toolName:Y,args:I,interfaceType:"webserver",userId:"anonymous"},sender:"webserver"}),H=typeof X==="object"&&"data"in X?X.data:X,U=AO.safeParse(H),F=U.success?U.data:H,Z=U.success&&U.data.success===!0;if(D)return B.json(F,Z?200:400);if(Z&&A.definition.successRedirect)return B.redirect(A.definition.successRedirect);if(!Z&&A.definition.errorRedirect)return B.redirect(A.definition.errorRedirect);return B.json(F,Z?200:400)}}var wC0="public, max-age=31536000, immutable";class Ip{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:zC(process.cwd(),A.productionDistDir),sharedImagesDir:zC(process.cwd(),A.sharedImagesDir),...A.previewDistDir&&{previewDistDir:zC(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 FC;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("/*",eL0());return Q.use("/*",BC0()),Q.use("/*",async(B,w)=>{if(await w(),A.immutableExtensions.test(B.req.path))B.header("Cache-Control",wC0);else B.header("Cache-Control",A.defaultCache)}),Q.use("/*",this.createCleanUrlMiddleware(A.distDir)),Q.use("/*",nHA({root:A.distDir})),Q.notFound(async(B)=>{let w=Bun.file(U62(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 Y=I.definition.method??"GET";return I.fullPath===w&&Y===B});if($)return $.definition.handler(A.req.raw);let D=this.getCurrentApiRoutes().find((I)=>{let Y=I.definition.method??"POST";return I.fullPath===w&&Y===B});if(D&&this.options.messageBus)return Dp(D,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=zC(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":wC0}})}createCleanUrlMiddleware(A){return async(Q,B)=>{let w=Q.req.path;if(w.includes(".")||w==="/"){await B();return}let $=zC(A,`.${w}`,"index.html");if(!$.startsWith(A)){await B();return}let D=Bun.file($);if(await D.exists())return Q.html(await D.text());let I=zC(A,`.${w}.html`);if(I.startsWith(A)){let Y=Bun.file(I);if(await Y.exists())return Q.html(await Y.text())}await B()}}}import{existsSync as DC0}from"fs";import{join as IC0}from"path";KA();var sHA=J.object({enablePreview:J.boolean().default(!0).describe("Enable the preview site server when preview assets are configured"),previewDistDir:J.string().default("./dist/site-preview").describe("Directory for preview site files"),productionDistDir:J.string().describe("Directory for production site files").default("./dist/site-production"),sharedImagesDir:J.string().default("./dist/images").describe("Shared directory for optimized images"),previewPort:J.number().default(4321).describe("Port for preview server"),productionPort:J.number().describe("Port for production server").default(8080),apiPort:J.number().describe("Port for API route server (plugin HTTP endpoints)").default(3335)});var aHA=`<!DOCTYPE html>
|
|
1715
1715
|
<html lang="en">
|
|
@@ -1778,7 +1778,7 @@ ${A.entityContent}`,BV1);X=w+P.imagePrompt}catch(P){this.logger.warn("AI prompt
|
|
|
1778
1778
|
<p>Once built, this page will be replaced with your actual website.</p>
|
|
1779
1779
|
</div>
|
|
1780
1780
|
</body>
|
|
1781
|
-
</html>`;var $C0={name:"@brains/webserver",private:!0,version:"0.2.0-alpha.
|
|
1781
|
+
</html>`;var $C0={name:"@brains/webserver",private:!0,version:"0.2.0-alpha.54",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 pG extends QX{serverManager;siteUrl;previewUrl;constructor(A={}){super("webserver",$C0,A,sHA)}async onRegister(A){if(this.siteUrl=A.siteUrl,this.previewUrl=A.previewUrl,this.siteUrl)A.endpoints.register({label:"Site",url:this.siteUrl,priority:10});if(this.config.enablePreview&&this.previewUrl)A.endpoints.register({label:"Preview",url:this.previewUrl,priority:20});this.serverManager=new Ip({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&&!DC0(this.config.previewDistDir))await A(this.config.previewDistDir,{recursive:!0}),await Q(IC0(this.config.previewDistDir,"index.html"),aHA),this.logger.debug(`Created preview directory at ${this.config.previewDistDir}`);if(!DC0(this.config.productionDistDir))await A(this.config.productionDistDir,{recursive:!0}),await Q(IC0(this.config.productionDistDir,"index.html"),aHA),this.logger.debug(`Created production directory at ${this.config.productionDistDir}`)}}tA();KA();var YC0=J.object({port:J.number().default(3334),organization:J.string().optional(),trustedTokens:J.record(J.string()).optional(),outboundTokens:J.record(J.string()).optional()});tA();function J62(A,Q){return`${A.name} is ${Q.name}'s ${A.role}. Its purpose is: ${A.purpose}.`}function XC0(A){let{character:Q,profile:B,version:w,domain:$,organization:D,tools:I}=A,X=`${A.baseUrl??($?`https://${$}`:"http://localhost:8080")}/a2a`,H=A.skills&&A.skills.length>0?A.skills.map((Z)=>({id:Z.name.toLowerCase().replace(/\s+/g,"-"),name:Z.name,description:Z.description,tags:Z.tags,examples:Z.examples})):I.map((Z)=>({id:Z.name,name:Z.name,description:Z.description,tags:[],examples:[]})),U={name:B.name};if(A.kind)U.kind=A.kind;if(B.description)U.description=B.description;if(D)U.organization=D;let F=[{uri:Kg,description:"Anchor (operator) identity for this brain",params:U}];return{name:Q.name,description:J62(Q,B),url:X,version:w,protocolVersion:"0.2.2",capabilities:{streaming:!0,pushNotifications:!1,extensions:F},skills:H,defaultInputModes:["text/plain"],defaultOutputModes:["text/plain"],...D&&{provider:{organization:D,url:X}},...A.authEnabled&&{securitySchemes:{bearerAuth:{type:"http",scheme:"bearer"}},security:[{bearerAuth:[]}]}}}tA();var tHA=new Set(["completed","failed","canceled","rejected"]);class eHA{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(tHA.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(),D={kind:"message",messageId:crypto.randomUUID(),role:"user",parts:[{kind:"text",text:A}],contextId:w,taskId:B},Y={task:{id:B,contextId:w,kind:"task",status:{state:"submitted",timestamp:$},history:[D]},conversationId:`a2a:${B}`,createdAt:$,updatedAt:$};return this.tasks.set(B,Y),Y}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 D={kind:"message",messageId:crypto.randomUUID(),role:"agent",parts:[{kind:"text",text:B}],contextId:w.task.contextId,taskId:A};w.task.status.message=D,w.task.history??=[],w.task.history.push(D)}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}}KA();var HC0=J.array(J.object({kind:J.string(),text:J.string().optional(),data:J.record(J.unknown()).optional()})),F62=J.object({message:J.object({kind:J.literal("message").optional(),messageId:J.string().optional(),role:J.enum(["user","agent"]).optional(),parts:HC0,contextId:J.string().optional(),taskId:J.string().optional()}),configuration:J.object({historyLength:J.number().optional()}).optional()}),KC0=J.object({id:J.string(),historyLength:J.number().optional()});function AKA(A,Q){return{jsonrpc:"2.0",id:A,result:Q}}function xX(A,Q,B){return{jsonrpc:"2.0",id:A,error:{code:Q,message:B}}}var WC0=J.object({jsonrpc:J.string(),id:J.union([J.string(),J.number()]),method:J.string(),params:J.record(J.unknown()).optional()});async function UC0(A,Q){let{id:B,method:w,params:$}=A;switch(w){case"message/send":return Z62(B,$??{},Q);case"tasks/get":return q62(B,$??{},Q);case"tasks/cancel":return N62(B,$??{},Q);default:return xX(B,-32601,`Method not found: ${w}`)}}async function Z62(A,Q,B){let w=F62.safeParse(Q);if(!w.success)return xX(A,-32602,`Invalid params: ${w.error.message}`);let $=w.data.message.parts.filter((U)=>U.kind==="text"&&typeof U.text==="string");if($.length===0)return xX(A,-32602,"Message must contain at least one text part");let D=$.map((U)=>U.text).join(`
|
|
1782
1782
|
`),I=w.data.message.contextId,Y=B.taskManager.createTask(D,I),X=Y.task.id;B.taskManager.updateState(X,"working"),z62(X,D,Y.conversationId,B);let H=B.taskManager.getTask(X);if(!H)return xX(A,-32603,"Internal error: task disappeared");return AKA(A,H.task)}function z62(A,Q,B,w){w.agentService.chat(Q,B,{userPermissionLevel:w.callerPermissionLevel,interfaceType:"a2a"}).then(($)=>{w.taskManager.updateState(A,"completed",$.text)}).catch(($)=>{let D=$ instanceof Error?$.message:"Unknown error";w.taskManager.updateState(A,"failed",`Error: ${D}`)})}var GC0=J.object({message:J.object({kind:J.string(),parts:HC0,contextId:J.string().optional()})});function JC0(A,Q,B){let $=Q.parts.filter((H)=>H.kind==="text"&&typeof H.text==="string").map((H)=>H.text).join(`
|
|
1783
1783
|
`)||"No message text",D=B.taskManager.createTask($,Q.contextId),I=D.task.id;B.taskManager.updateState(I,"working");let Y=new TextEncoder,X=new ReadableStream({start(H){let U=!1;function F(E){if(U)return;try{H.enqueue(Y.encode(`data: ${JSON.stringify(E)}
|
|
1784
1784
|
|
|
@@ -1786,7 +1786,7 @@ ${A.entityContent}`,BV1);X=w+P.imagePrompt}catch(P){this.logger.warn("AI prompt
|
|
|
1786
1786
|
|
|
1787
1787
|
`);w=D.pop()??"";for(let I of D){let Y=I.split(`
|
|
1788
1788
|
`).find((E)=>E.startsWith("data: "));if(!Y)continue;let H=JSON.parse(Y.slice(6)).result;if(!H)continue;if(H.final!==!0)continue;Q.cancel().catch(()=>{});let F=H.status,Z=F?.state??"unknown",f=(F?.message?.parts??[]).filter((E)=>E.kind==="text"&&typeof E.text==="string").map((E)=>E.text).join(`
|
|
1789
|
-
`)||"No response text";return{success:!0,data:{state:Z,response:f}}}$=await Q.read()}return{success:!1,error:"Stream ended without a terminal event"}}function zC0(A={}){let Q=A.fetch??globalThis.fetch;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:FC0,visibility:"anchor",handler:async(B)=>{let w=J.object(FC0).safeParse(B);if(!w.success)return{success:!1,error:`Invalid input: ${w.error.message}`};let{agent:$,message:D}=w.data,I=f62($);if(!I)return{success:!1,error:"Invalid agent id. Use a saved agent id from your directory, not a URL."};if(!A.entityService)return{success:!1,error:"Agent directory is unavailable. Add the agent first, then try again."};let Y=await A.entityService.getEntity({entityType:"agent",id:I});if(!Y)return{success:!1,error:`Agent ${I} is not in your directory. Add it first.`};if(Y.metadata.status!=="approved")return{success:!1,error:`Agent ${I} is discovered but not approved yet. Approve it first.`};let X=`https://${I}`,H=await L62(X,Q);if(!H)return{success:!1,error:`Could not fetch Agent Card from ${X}`};let U=H.url,F;if(A.outboundTokens)try{let Z=new URL(U).hostname;F=A.outboundTokens[Z]}catch{}return C62(U,D,Q,F)}}}var QKA={name:"@brains/a2a",private:!0,version:"0.2.0-alpha.53",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 V62={"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization","X-Content-Type-Options":"nosniff"};class qC extends QX{agentCard;taskManager=new eHA;agentService;permissionContext;app;hasWebserver=!1;constructor(A={}){super("a2a",QKA,A,YC0)}async onRegister(A){if(await super.onRegister(A),this.hasWebserver=A.plugins.has("webserver"),this.agentService=A.agent,this.permissionContext=A.permissions,this.hasWebserver)this.logger.info("A2A interface registered",{domain:A.domain});else this.logger.info("A2A interface registered in tool-only mode",{domain:A.domain})}async onReady(A){await this.rebuildAgentCard(A)}async rebuildAgentCard(A){let Q=A.identity.get(),B=A.identity.getProfile(),w=A.tools.listForPermissionLevel("public"),$=this.config.trustedTokens&&Object.keys(this.config.trustedTokens).length>0,D;if(A.entityService.hasEntityType("skill"))try{let I=await A.entityService.listEntities({entityType:"skill"});if(I.length>0)D=I.map((Y)=>l7.safeParse(Y.metadata)).filter((Y)=>Y.success).map((Y)=>Y.data)}catch{}this.agentCard=XC0({character:Q,profile:B,version:QKA.version,domain:A.domain,organization:this.config.organization,tools:w,skills:D,authEnabled:$}),this.logger.debug("Agent Card rebuilt",{skills:this.agentCard.skills.length})}getAgentCard(){return this.agentCard}resolveCallerPermission(A){if(!A?.startsWith("Bearer ")||!this.config.trustedTokens)return"public";let Q=A.slice(7),B=this.config.trustedTokens[Q];if(!B||!this.permissionContext)return"public";return this.permissionContext.getUserLevel("a2a",B)}withCors(A){let Q=new Headers(A.headers);for(let[B,w]of Object.entries(V62))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 FC;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=WC0.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=GC0.safeParse(w.data.params??{});if(!I.success)return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32602,message:`Invalid params: ${I.error.message}`},id:w.data.id}));let{stream:Y}=JC0(w.data.id,I.data.message,{taskManager:this.taskManager,agentService:this.agentService,callerPermissionLevel:$});return this.withCors(new Response(Y,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}}))}let D=await UC0(w.data,{taskManager:this.taskManager,agentService:this.agentService,callerPermissionLevel:$});return this.withCors(Q.json(D))}),this.app=A,A}getWebRoutes(){if(!this.hasWebserver)return[];let A=(Q)=>Promise.resolve(this.getOrCreateApp().fetch(Q));return[{path:"/.well-known/agent-card.json",method:"GET",public:!0,handler:A},{path:"/a2a",method:"GET",public:!0,handler:A},{path:"/a2a",method:"POST",public:!0,handler:A},{path:"/a2a",method:"OPTIONS",public:!0,handler:A}]}async getTools(){return[zC0({outboundTokens:this.config.outboundTokens,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")}}}}tA();class BKA{logger;handleImport;handleDelete;deleteOnFileRemoval;fileOperations;constructor(A,Q,B,w,$=!0){if(this.logger=A,this.fileOperations=w,this.deleteOnFileRemoval=$,B)this.handleImport=async(D)=>{let I=await B({type:"directory-import",data:{paths:[D]}});this.logger.debug("Queued import job for file change",{jobId:I,path:D})},this.handleDelete=async(D)=>{if(!this.deleteOnFileRemoval){this.logger.warn("File deleted but deleteOnFileRemoval is disabled",{path:D});return}try{let{entityType:I,id:Y}=this.fileOperations.parseEntityFromPath(D),X=await B({type:"directory-delete",data:{entityId:Y,entityType:I,filePath:D}});this.logger.info("Queued delete job for removed file",{jobId:X,path:D,entityId:Y,entityType:I})}catch(I){this.logger.warn("Could not extract entity info from deleted file",{path:D,error:I})}};else this.handleImport=async(D)=>{await Q([D])},this.handleDelete=async(D)=>{this.logger.warn("File deleted but no job queue available",{path:D})}}async handleFileChange(A,Q){this.logger.debug("Processing file change",{event:A,path:Q});try{switch(A){case"add":case"change":await this.handleImport(Q);break;case"delete":case"unlink":await this.handleDelete(Q);break;default:this.logger.debug("Unhandled file event",{event:A,path:Q})}}catch(B){this.logger.error("Failed to handle file change",{event:A,path:Q,error:B})}}}var TM0=o0(_M0(),1);import{extname as ED2}from"path";var Op=[".png",".jpg",".jpeg",".webp",".gif",".svg"];function v3(A){let Q=ED2(A).toLowerCase();return Op.includes(Q)}function xM0(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 QWA(A){switch(A.toLowerCase()){case"jpeg":return".jpg";case"svg+xml":return".svg";default:return`.${A.toLowerCase()}`}}import{isAbsolute as MD2,relative as VD2,sep as vM0,join as OD2}from"path";function zI(A,Q){return MD2(Q)?Q:OD2(A,Q)}function VC(A,Q){let B=zI(A,Q),w=VD2(A,B);return vM0==="/"?w:w.split(vM0).join("/")}function RD2(A,Q){if(!VC(Q,A).startsWith("image/"))return!1;return v3(A)}function bD2(A,Q){if(VC(Q,A).split("/")[0]?.startsWith("_"))return!1;if(A.endsWith(".md"))return!0;return RD2(A,Q)}class BWA{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=TM0.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(!bD2(Q,this.syncPath))return;this.logger.debug("File change detected",{event:A,path:Q});let B=VC(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=zI(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 SM0(A,Q){if(A?.isWatching())return Q.logger.debug("Already watching directory"),A;return PD2(Q)}function gM0(A){if(A)A.stop();return}function hM0(A,Q){if(A)A.setCallback(Q)}async function PD2(A){let{logger:Q,syncPath:B,watchInterval:w,importEntities:$,jobQueueCallback:D,fileOperations:I,deleteOnFileRemoval:Y}=A,X=new BKA(Q,$,D,I,Y),H=new BWA({syncPath:B,watchInterval:w,logger:Q,onFileChange:async(U,F)=>{await X.handleFileChange(U,F)}});return await H.start(),H}async function yM0(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:$}}tA();class wWA{logger;syncPath;constructor(A,Q){this.logger=A,this.syncPath=Q}prepareBatchOperations(A,Q){if(A.length===0)return{operations:[],exportOperationsCount:0,importOperationsCount:0,totalFiles:0};let B=[],w=this.createImportOperations(A);B.push(...w);let $=w.length;if(Q?.includeCleanup)B.push({type:"directory-cleanup",data:{}});let D=A.length;return this.logger.debug("Prepared batch operations",{exportOperationsCount:0,importOperationsCount:$,totalFiles:D}),{operations:B,exportOperationsCount:0,importOperationsCount:$,totalFiles:D}}async queueSyncBatch(A,Q,B,w,$){let D=this.prepareBatchOperations(B,$);if(D.operations.length===0)return this.logger.debug("No sync operations needed",{source:Q}),null;return{batchId:await A.jobs.enqueueBatch(D.operations,{source:Q,rootJobId:w?.rootJobId??S8(),metadata:{progressToken:w?.progressToken,operationType:"file_operations",operationTarget:this.syncPath,pluginId:w?.pluginId??"directory-sync",interfaceType:w?.interfaceType,channelId:w?.channelId}}),operationCount:D.operations.length,exportOperationsCount:D.exportOperationsCount,importOperationsCount:D.importOperationsCount,totalFiles:D.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 $WA{logger;fileOperations;syncInProgress=!1;batchOperationsManager;constructor(A,Q,B){this.logger=A;this.fileOperations=B;this.batchOperationsManager=new wWA(A,Q)}async queueSyncBatch(A,Q,B,w){if(this.syncInProgress)return this.logger.debug("Sync already in progress, skipping",{source:Q}),null;this.syncInProgress=!0;try{let $=await this.fileOperations.getAllSyncFiles();return await this.batchOperationsManager.queueSyncBatch(A,Q,$,B,w)}finally{this.syncInProgress=!1}}}class DWA{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 vD2,extname as TD2}from"path";import{extname as kD2,join as Rp}from"path";function bp(A,Q){let w=VC(A,Q).split("/"),$,D;if(w.length===1)$="base",D=w;else if(w.length>1&&w[0])$=w[0],D=w.slice(1);else $="base",D=w;let I;if(D.length>1){let Y=D[D.length-1];if(Y)D[D.length-1]=mM0(Y);I=D.join(":")}else I=mM0(D[0]??"");return{entityType:$,id:I}}function uM0(A,Q,B,w=".md"){let $=Q.split(":").filter((H)=>H.length>0),D=B==="base";if($.length===1)return D?Rp(A,`${$[0]}${w}`):Rp(A,B,`${$[0]}${w}`);let I=$;if($[0]===B)I=$.slice(1);let Y=I[I.length-1],X=I.slice(0,-1);if(D)return Rp(A,...X,`${Y}${w}`);return Rp(A,B,...X,`${Y}${w}`)}function cM0(A){if(A.entityType!=="image")return".md";let Q=A.metadata.format;if(Q)return QWA(Q);let B=A.content.match(/^data:image\/([a-z+]+);base64,/i);return B?.[1]?QWA(B[1]):".md"}function mM0(A){let Q=kD2(A).toLowerCase();return Q===".md"||Op.includes(Q)?A.slice(0,-Q.length):A}N4();import{mkdir as SD2,readFile as kp,writeFile as nM0,stat as gD2,utimes as hD2}from"fs/promises";import{join as Pp}from"path";import{mkdir as lM0,readdir as _D2,stat as xD2}from"fs/promises";import{access as jD2}from"fs/promises";async function qI(A){try{return await jD2(A),!0}catch{return!1}}async function IWA(A,Q){return rM0(A,Q,{includeImages:!1})}async function pM0(A,Q){return rM0(A,Q,{includeImages:!0})}async function dM0(A,Q){if(!await qI(A))await lM0(A,{recursive:!0});for(let B of Q)if(B!=="base")await lM0(Pp(A,B),{recursive:!0})}async function iM0(A,Q){let B=[],w={totalFiles:0,byEntityType:{}};if(!await qI(A))return{files:B,stats:w};let $=await IWA(A,Q);for(let D of $)try{let I=Pp(A,D),Y=await xD2(I),{entityType:X}=bp(A,D);B.push({path:D,entityType:X,modified:Y.mtime}),w.totalFiles++,w.byEntityType[X]=(w.byEntityType[X]??0)+1}catch{continue}return{files:B,stats:w}}async function rM0(A,Q,B){let w=[];if(!await qI(A))return w;let $=async(D,I="",Y=!1)=>{let X=await _D2(D,{withFileTypes:!0});for(let H of X){let U=I?Pp(I,H.name):H.name;if(H.isFile()&&!H.name.endsWith(".invalid")){if(H.name.endsWith(".md"))w.push(U);else if(B.includeImages&&Y&&v3(H.name))w.push(U)}else if(H.isDirectory()&&!H.name.startsWith(".")){if(I===""&&!Q.hasEntityType(H.name))continue;let F=Pp(D,H.name),Z=H.name==="image"&&I==="";await $(F,U,Y||Z)}}};return await $(A),w}class YWA{syncPath;entityService;constructor(A,Q){this.syncPath=A,this.entityService=Q}parseEntityFromPath(A){return bp(this.syncPath,A)}async readEntity(A){let Q=zI(this.syncPath,A),B=await gD2(Q),{entityType:w,id:$}=this.parseEntityFromPath(A),D=B.birthtime.getTime()>0?B.birthtime:B.mtime,I=B.mtime,Y;if(v3(A)){let H=(await kp(Q)).toString("base64"),U=TD2(A);Y=`data:${xM0(U)};base64,${H}`}else Y=await kp(Q,"utf-8");return{entityType:w,id:$,content:Y,created:D,updated:I}}async writeEntity(A){let Q=this.getEntityFilePath(A),B=A.entityType==="image",w;if(B){let D=A.content.match(/^data:image\/[a-z+]+;base64,(.+)$/i);w=D?.[1]?Buffer.from(D[1],"base64"):Buffer.from(A.content,"base64")}else w=this.entityService.serializeEntity(A);if(await qI(Q)){let D=B?await kp(Q):await kp(Q,"utf-8"),I=Aw(B?D.toString("base64"):D),Y=Aw(B?w.toString("base64"):w);if(I===Y)return}if(A.entityType!=="base")await SD2(vD2(Q),{recursive:!0});if(B)await nM0(Q,w);else await nM0(Q,w,"utf-8");let $=new Date(A.updated);await hD2(Q,$,$)}getFilePath(A,Q,B=".md"){return uM0(this.syncPath,A,Q,B)}getEntityFilePath(A){return this.getFilePath(A.id,A.entityType,cM0(A))}async getAllMarkdownFiles(){return IWA(this.syncPath,this.entityService)}async getAllSyncFiles(){return pM0(this.syncPath,this.entityService)}async ensureDirectoryStructure(A){await dM0(this.syncPath,A)}shouldUpdateEntity(A,Q){let B=Aw(Q.content);return A.contentHash!==B}async gatherFileStatus(){return iM0(this.syncPath,this.entityService)}async syncDirectoryExists(){return qI(this.syncPath)}async fileExists(A){return qI(A)}}KA();async function jp(A,Q,B,w){let{sourceUrl:$}=A,D=await Q.listEntities({entityType:"image",options:{filter:{metadata:{sourceUrl:$}},limit:1}});if(D[0])return w.debug("Reusing existing image entity",{sourceUrl:$,imageId:D[0].id}),D[0].id;let I=await B($),{base64:Y}=DG(I),X=mZ(Y),H=IG(Y);if(!X||!H)throw Error("Could not detect image format or dimensions");let U=await Q.createEntity({entity:{id:A.id,entityType:"image",content:I,metadata:{title:A.title,alt:A.alt,format:X,width:H.width,height:H.height,sourceUrl:$}}});return w.debug("Created image entity from URL",{sourceUrl:$,imageId:U.entityId}),U.entityId}var oM0=J.object({title:J.string(),slug:J.string().optional(),coverImageUrl:J.string().url(),coverImageId:J.string().optional(),coverImageAlt:J.string().optional()});class XWA{entityService;fetcher;logger;constructor(A,Q,B=g$){this.entityService=A;this.fetcher=B;this.logger=Q.child("FrontmatterImageConverter")}detectCoverImageUrl(A){let Q;try{Q=X4(A)}catch{return null}let{frontmatter:B}=Q,w=oM0.safeParse(B);if(!w.success)return null;if(w.data.coverImageId)return null;let{title:$,slug:D,coverImageUrl:I,coverImageAlt:Y}=w.data;if(!aH(I))return null;return{sourceUrl:I,postTitle:$,postSlug:D??t1($),customAlt:Y}}async convert(A){let Q;try{Q=X4(A)}catch(H){return this.logger.debug("Parse failed",{error:H}),{content:A,converted:!1}}let{frontmatter:B}=Q,w=oM0.safeParse(B);if(!w.success)return{content:A,converted:!1};if(w.data.coverImageId)return{content:A,converted:!1};let{title:$,slug:D,coverImageUrl:I,coverImageAlt:Y}=w.data;if(!aH(I))return{content:A,converted:!1};let X={postTitle:$,postSlug:D??t1($),sourceUrl:I,customAlt:Y};try{let H=await this.createImageEntity(X),U={...B};return delete U.coverImageUrl,delete U.coverImageAlt,U.coverImageId=H,{content:gF(U,Q.content),converted:!0,imageId:H}}catch(H){return this.logger.warn("Failed to convert coverImageUrl",{url:I,error:L0(H)}),{content:A,converted:!1}}}async createImageEntity(A){let{postTitle:Q,postSlug:B,sourceUrl:w,customAlt:$}=A,D=`Cover image for ${Q}`;return jp({id:`${B}-cover`,title:D,alt:$??D,sourceUrl:w},this.entityService,this.fetcher,this.logger)}}KA();class tk{entityService;fetcher;logger;constructor(A,Q,B=g$){this.entityService=A;this.fetcher=B;this.logger=Q.child("MarkdownImageConverter")}detectInlineImages(A,Q){let B=[],w=oT(A);for(let $ of w){if(!aH($.url))continue;if($.url.startsWith("entity://"))continue;let D=this.reconstructMarkdown($);B.push({sourceUrl:$.url,alt:$.alt,originalMarkdown:D,postSlug:Q})}return B}reconstructMarkdown(A){if(A.title)return``;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,D=0;for(let I of B)try{let Y=await this.createImageEntity(I,D++),X=``;w=w.replace(I.originalMarkdown,X),$++,this.logger.debug("Converted inline image",{sourceUrl:I.sourceUrl,imageId:Y})}catch(Y){this.logger.warn("Failed to convert inline image",{sourceUrl:I.sourceUrl,error:L0(Y)})}return{content:w,converted:$>0,convertedCount:$}}async createImageEntity(A,Q){let{sourceUrl:B,alt:w,postSlug:$}=A;return jp({id:`${$}-inline-${Q}`,title:w||`Inline image ${Q+1} for ${$}`,alt:w||"",sourceUrl:B},this.entityService,this.fetcher,this.logger)}}class HWA{logger;entityService;fileOperations;constructor(A,Q,B){this.logger=A,this.entityService=Q,this.fileOperations=B}async importEntitiesWithProgress(A,Q,B,w){this.logger.debug("Importing entities with progress reporting");let $={imported:0,skipped:0,failed:0,quarantined:0,quarantinedFiles:[],errors:[],jobIds:[]},D=A??await this.fileOperations.getAllSyncFiles(),I=D.length;await Q.report({progress:0,message:`Starting import of ${I} files`});for(let Y=0;Y<I;Y+=B){let X=D.slice(Y,Y+B),H=await w(X);$.imported+=H.imported,$.skipped+=H.skipped,$.failed+=H.failed,$.quarantined+=H.quarantined,$.errors.push(...H.errors),$.quarantinedFiles.push(...H.quarantinedFiles),$.jobIds.push(...H.jobIds);let U=Math.min(Y+B,I),F=Math.round(U/I*40);await Q.report({progress:F,message:`Imported ${U}/${I} files`})}return $}async exportEntitiesWithProgress(A,Q,B,w){this.logger.debug("Exporting entities with progress reporting");let $=A??this.entityService.getEntityTypes();await Q.report({progress:50,message:`Starting export of ${$.length} entity types`});let D=await w(A);return await Q.report({progress:100,message:`Exported ${D.exported} entities`}),this.logger.debug("Export completed",D),D}}KA();import{rename as yD2,appendFile as mD2,readFile as uD2,writeFile as cD2,access as lD2}from"fs/promises";import{join as sM0}from"path";class KWA{logger;syncPath;constructor(A,Q){this.logger=A;this.syncPath=Q}isValidationError(A){if(A instanceof J.ZodError)return!0;let Q=L0(A);return Q.includes("invalid_type")||Q.includes("invalid_enum_value")||Q.includes("Required")||Q.includes("Invalid frontmatter")||Q.includes("Unknown entity type")}async quarantineInvalidFile(A,Q,B,w){let $=w(A),D=`${$}.invalid`;try{await yD2($,D),B.quarantined++,B.quarantinedFiles.push(A);let I=sM0(this.syncPath,".import-errors.log"),Y=new Date().toISOString(),X=L0(Q),H=`${Y} - ${A}: ${X}
|
|
1789
|
+
`)||"No response text";return{success:!0,data:{state:Z,response:f}}}$=await Q.read()}return{success:!1,error:"Stream ended without a terminal event"}}function zC0(A={}){let Q=A.fetch??globalThis.fetch;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:FC0,visibility:"anchor",handler:async(B)=>{let w=J.object(FC0).safeParse(B);if(!w.success)return{success:!1,error:`Invalid input: ${w.error.message}`};let{agent:$,message:D}=w.data,I=f62($);if(!I)return{success:!1,error:"Invalid agent id. Use a saved agent id from your directory, not a URL."};if(!A.entityService)return{success:!1,error:"Agent directory is unavailable. Add the agent first, then try again."};let Y=await A.entityService.getEntity({entityType:"agent",id:I});if(!Y)return{success:!1,error:`Agent ${I} is not in your directory. Add it first.`};if(Y.metadata.status!=="approved")return{success:!1,error:`Agent ${I} is discovered but not approved yet. Approve it first.`};let X=`https://${I}`,H=await L62(X,Q);if(!H)return{success:!1,error:`Could not fetch Agent Card from ${X}`};let U=H.url,F;if(A.outboundTokens)try{let Z=new URL(U).hostname;F=A.outboundTokens[Z]}catch{}return C62(U,D,Q,F)}}}var QKA={name:"@brains/a2a",private:!0,version:"0.2.0-alpha.54",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 V62={"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization","X-Content-Type-Options":"nosniff"};class qC extends QX{agentCard;taskManager=new eHA;agentService;permissionContext;app;hasWebserver=!1;constructor(A={}){super("a2a",QKA,A,YC0)}async onRegister(A){if(await super.onRegister(A),this.hasWebserver=A.plugins.has("webserver"),this.agentService=A.agent,this.permissionContext=A.permissions,this.hasWebserver)this.logger.info("A2A interface registered",{domain:A.domain});else this.logger.info("A2A interface registered in tool-only mode",{domain:A.domain})}async onReady(A){await this.rebuildAgentCard(A)}async rebuildAgentCard(A){let Q=A.identity.get(),B=A.identity.getProfile(),w=A.tools.listForPermissionLevel("public"),$=this.config.trustedTokens&&Object.keys(this.config.trustedTokens).length>0,D;if(A.entityService.hasEntityType("skill"))try{let I=await A.entityService.listEntities({entityType:"skill"});if(I.length>0)D=I.map((Y)=>l7.safeParse(Y.metadata)).filter((Y)=>Y.success).map((Y)=>Y.data)}catch{}this.agentCard=XC0({character:Q,profile:B,version:QKA.version,domain:A.domain,organization:this.config.organization,tools:w,skills:D,authEnabled:$}),this.logger.debug("Agent Card rebuilt",{skills:this.agentCard.skills.length})}getAgentCard(){return this.agentCard}resolveCallerPermission(A){if(!A?.startsWith("Bearer ")||!this.config.trustedTokens)return"public";let Q=A.slice(7),B=this.config.trustedTokens[Q];if(!B||!this.permissionContext)return"public";return this.permissionContext.getUserLevel("a2a",B)}withCors(A){let Q=new Headers(A.headers);for(let[B,w]of Object.entries(V62))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 FC;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=WC0.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=GC0.safeParse(w.data.params??{});if(!I.success)return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32602,message:`Invalid params: ${I.error.message}`},id:w.data.id}));let{stream:Y}=JC0(w.data.id,I.data.message,{taskManager:this.taskManager,agentService:this.agentService,callerPermissionLevel:$});return this.withCors(new Response(Y,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}}))}let D=await UC0(w.data,{taskManager:this.taskManager,agentService:this.agentService,callerPermissionLevel:$});return this.withCors(Q.json(D))}),this.app=A,A}getWebRoutes(){if(!this.hasWebserver)return[];let A=(Q)=>Promise.resolve(this.getOrCreateApp().fetch(Q));return[{path:"/.well-known/agent-card.json",method:"GET",public:!0,handler:A},{path:"/a2a",method:"GET",public:!0,handler:A},{path:"/a2a",method:"POST",public:!0,handler:A},{path:"/a2a",method:"OPTIONS",public:!0,handler:A}]}async getTools(){return[zC0({outboundTokens:this.config.outboundTokens,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")}}}}tA();class BKA{logger;handleImport;handleDelete;deleteOnFileRemoval;fileOperations;constructor(A,Q,B,w,$=!0){if(this.logger=A,this.fileOperations=w,this.deleteOnFileRemoval=$,B)this.handleImport=async(D)=>{let I=await B({type:"directory-import",data:{paths:[D]}});this.logger.debug("Queued import job for file change",{jobId:I,path:D})},this.handleDelete=async(D)=>{if(!this.deleteOnFileRemoval){this.logger.warn("File deleted but deleteOnFileRemoval is disabled",{path:D});return}try{let{entityType:I,id:Y}=this.fileOperations.parseEntityFromPath(D),X=await B({type:"directory-delete",data:{entityId:Y,entityType:I,filePath:D}});this.logger.info("Queued delete job for removed file",{jobId:X,path:D,entityId:Y,entityType:I})}catch(I){this.logger.warn("Could not extract entity info from deleted file",{path:D,error:I})}};else this.handleImport=async(D)=>{await Q([D])},this.handleDelete=async(D)=>{this.logger.warn("File deleted but no job queue available",{path:D})}}async handleFileChange(A,Q){this.logger.debug("Processing file change",{event:A,path:Q});try{switch(A){case"add":case"change":await this.handleImport(Q);break;case"delete":case"unlink":await this.handleDelete(Q);break;default:this.logger.debug("Unhandled file event",{event:A,path:Q})}}catch(B){this.logger.error("Failed to handle file change",{event:A,path:Q,error:B})}}}var TM0=o0(_M0(),1);import{extname as ED2}from"path";var Op=[".png",".jpg",".jpeg",".webp",".gif",".svg"];function v3(A){let Q=ED2(A).toLowerCase();return Op.includes(Q)}function xM0(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 QWA(A){switch(A.toLowerCase()){case"jpeg":return".jpg";case"svg+xml":return".svg";default:return`.${A.toLowerCase()}`}}import{isAbsolute as MD2,relative as VD2,sep as vM0,join as OD2}from"path";function zI(A,Q){return MD2(Q)?Q:OD2(A,Q)}function VC(A,Q){let B=zI(A,Q),w=VD2(A,B);return vM0==="/"?w:w.split(vM0).join("/")}function RD2(A,Q){if(!VC(Q,A).startsWith("image/"))return!1;return v3(A)}function bD2(A,Q){if(VC(Q,A).split("/")[0]?.startsWith("_"))return!1;if(A.endsWith(".md"))return!0;return RD2(A,Q)}class BWA{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=TM0.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(!bD2(Q,this.syncPath))return;this.logger.debug("File change detected",{event:A,path:Q});let B=VC(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=zI(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 SM0(A,Q){if(A?.isWatching())return Q.logger.debug("Already watching directory"),A;return PD2(Q)}function gM0(A){if(A)A.stop();return}function hM0(A,Q){if(A)A.setCallback(Q)}async function PD2(A){let{logger:Q,syncPath:B,watchInterval:w,importEntities:$,jobQueueCallback:D,fileOperations:I,deleteOnFileRemoval:Y}=A,X=new BKA(Q,$,D,I,Y),H=new BWA({syncPath:B,watchInterval:w,logger:Q,onFileChange:async(U,F)=>{await X.handleFileChange(U,F)}});return await H.start(),H}async function yM0(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:$}}tA();class wWA{logger;syncPath;constructor(A,Q){this.logger=A,this.syncPath=Q}prepareBatchOperations(A,Q){if(A.length===0)return{operations:[],exportOperationsCount:0,importOperationsCount:0,totalFiles:0};let B=[],w=this.createImportOperations(A);B.push(...w);let $=w.length;if(Q?.includeCleanup)B.push({type:"directory-cleanup",data:{}});let D=A.length;return this.logger.debug("Prepared batch operations",{exportOperationsCount:0,importOperationsCount:$,totalFiles:D}),{operations:B,exportOperationsCount:0,importOperationsCount:$,totalFiles:D}}async queueSyncBatch(A,Q,B,w,$){let D=this.prepareBatchOperations(B,$);if(D.operations.length===0)return this.logger.debug("No sync operations needed",{source:Q}),null;return{batchId:await A.jobs.enqueueBatch(D.operations,{source:Q,rootJobId:w?.rootJobId??S8(),metadata:{progressToken:w?.progressToken,operationType:"file_operations",operationTarget:this.syncPath,pluginId:w?.pluginId??"directory-sync",interfaceType:w?.interfaceType,channelId:w?.channelId}}),operationCount:D.operations.length,exportOperationsCount:D.exportOperationsCount,importOperationsCount:D.importOperationsCount,totalFiles:D.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 $WA{logger;fileOperations;syncInProgress=!1;batchOperationsManager;constructor(A,Q,B){this.logger=A;this.fileOperations=B;this.batchOperationsManager=new wWA(A,Q)}async queueSyncBatch(A,Q,B,w){if(this.syncInProgress)return this.logger.debug("Sync already in progress, skipping",{source:Q}),null;this.syncInProgress=!0;try{let $=await this.fileOperations.getAllSyncFiles();return await this.batchOperationsManager.queueSyncBatch(A,Q,$,B,w)}finally{this.syncInProgress=!1}}}class DWA{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 vD2,extname as TD2}from"path";import{extname as kD2,join as Rp}from"path";function bp(A,Q){let w=VC(A,Q).split("/"),$,D;if(w.length===1)$="base",D=w;else if(w.length>1&&w[0])$=w[0],D=w.slice(1);else $="base",D=w;let I;if(D.length>1){let Y=D[D.length-1];if(Y)D[D.length-1]=mM0(Y);I=D.join(":")}else I=mM0(D[0]??"");return{entityType:$,id:I}}function uM0(A,Q,B,w=".md"){let $=Q.split(":").filter((H)=>H.length>0),D=B==="base";if($.length===1)return D?Rp(A,`${$[0]}${w}`):Rp(A,B,`${$[0]}${w}`);let I=$;if($[0]===B)I=$.slice(1);let Y=I[I.length-1],X=I.slice(0,-1);if(D)return Rp(A,...X,`${Y}${w}`);return Rp(A,B,...X,`${Y}${w}`)}function cM0(A){if(A.entityType!=="image")return".md";let Q=A.metadata.format;if(Q)return QWA(Q);let B=A.content.match(/^data:image\/([a-z+]+);base64,/i);return B?.[1]?QWA(B[1]):".md"}function mM0(A){let Q=kD2(A).toLowerCase();return Q===".md"||Op.includes(Q)?A.slice(0,-Q.length):A}N4();import{mkdir as SD2,readFile as kp,writeFile as nM0,stat as gD2,utimes as hD2}from"fs/promises";import{join as Pp}from"path";import{mkdir as lM0,readdir as _D2,stat as xD2}from"fs/promises";import{access as jD2}from"fs/promises";async function qI(A){try{return await jD2(A),!0}catch{return!1}}async function IWA(A,Q){return rM0(A,Q,{includeImages:!1})}async function pM0(A,Q){return rM0(A,Q,{includeImages:!0})}async function dM0(A,Q){if(!await qI(A))await lM0(A,{recursive:!0});for(let B of Q)if(B!=="base")await lM0(Pp(A,B),{recursive:!0})}async function iM0(A,Q){let B=[],w={totalFiles:0,byEntityType:{}};if(!await qI(A))return{files:B,stats:w};let $=await IWA(A,Q);for(let D of $)try{let I=Pp(A,D),Y=await xD2(I),{entityType:X}=bp(A,D);B.push({path:D,entityType:X,modified:Y.mtime}),w.totalFiles++,w.byEntityType[X]=(w.byEntityType[X]??0)+1}catch{continue}return{files:B,stats:w}}async function rM0(A,Q,B){let w=[];if(!await qI(A))return w;let $=async(D,I="",Y=!1)=>{let X=await _D2(D,{withFileTypes:!0});for(let H of X){let U=I?Pp(I,H.name):H.name;if(H.isFile()&&!H.name.endsWith(".invalid")){if(H.name.endsWith(".md"))w.push(U);else if(B.includeImages&&Y&&v3(H.name))w.push(U)}else if(H.isDirectory()&&!H.name.startsWith(".")){if(I===""&&!Q.hasEntityType(H.name))continue;let F=Pp(D,H.name),Z=H.name==="image"&&I==="";await $(F,U,Y||Z)}}};return await $(A),w}class YWA{syncPath;entityService;constructor(A,Q){this.syncPath=A,this.entityService=Q}parseEntityFromPath(A){return bp(this.syncPath,A)}async readEntity(A){let Q=zI(this.syncPath,A),B=await gD2(Q),{entityType:w,id:$}=this.parseEntityFromPath(A),D=B.birthtime.getTime()>0?B.birthtime:B.mtime,I=B.mtime,Y;if(v3(A)){let H=(await kp(Q)).toString("base64"),U=TD2(A);Y=`data:${xM0(U)};base64,${H}`}else Y=await kp(Q,"utf-8");return{entityType:w,id:$,content:Y,created:D,updated:I}}async writeEntity(A){let Q=this.getEntityFilePath(A),B=A.entityType==="image",w;if(B){let D=A.content.match(/^data:image\/[a-z+]+;base64,(.+)$/i);w=D?.[1]?Buffer.from(D[1],"base64"):Buffer.from(A.content,"base64")}else w=this.entityService.serializeEntity(A);if(await qI(Q)){let D=B?await kp(Q):await kp(Q,"utf-8"),I=Aw(B?D.toString("base64"):D),Y=Aw(B?w.toString("base64"):w);if(I===Y)return}if(A.entityType!=="base")await SD2(vD2(Q),{recursive:!0});if(B)await nM0(Q,w);else await nM0(Q,w,"utf-8");let $=new Date(A.updated);await hD2(Q,$,$)}getFilePath(A,Q,B=".md"){return uM0(this.syncPath,A,Q,B)}getEntityFilePath(A){return this.getFilePath(A.id,A.entityType,cM0(A))}async getAllMarkdownFiles(){return IWA(this.syncPath,this.entityService)}async getAllSyncFiles(){return pM0(this.syncPath,this.entityService)}async ensureDirectoryStructure(A){await dM0(this.syncPath,A)}shouldUpdateEntity(A,Q){let B=Aw(Q.content);return A.contentHash!==B}async gatherFileStatus(){return iM0(this.syncPath,this.entityService)}async syncDirectoryExists(){return qI(this.syncPath)}async fileExists(A){return qI(A)}}KA();async function jp(A,Q,B,w){let{sourceUrl:$}=A,D=await Q.listEntities({entityType:"image",options:{filter:{metadata:{sourceUrl:$}},limit:1}});if(D[0])return w.debug("Reusing existing image entity",{sourceUrl:$,imageId:D[0].id}),D[0].id;let I=await B($),{base64:Y}=DG(I),X=mZ(Y),H=IG(Y);if(!X||!H)throw Error("Could not detect image format or dimensions");let U=await Q.createEntity({entity:{id:A.id,entityType:"image",content:I,metadata:{title:A.title,alt:A.alt,format:X,width:H.width,height:H.height,sourceUrl:$}}});return w.debug("Created image entity from URL",{sourceUrl:$,imageId:U.entityId}),U.entityId}var oM0=J.object({title:J.string(),slug:J.string().optional(),coverImageUrl:J.string().url(),coverImageId:J.string().optional(),coverImageAlt:J.string().optional()});class XWA{entityService;fetcher;logger;constructor(A,Q,B=g$){this.entityService=A;this.fetcher=B;this.logger=Q.child("FrontmatterImageConverter")}detectCoverImageUrl(A){let Q;try{Q=X4(A)}catch{return null}let{frontmatter:B}=Q,w=oM0.safeParse(B);if(!w.success)return null;if(w.data.coverImageId)return null;let{title:$,slug:D,coverImageUrl:I,coverImageAlt:Y}=w.data;if(!aH(I))return null;return{sourceUrl:I,postTitle:$,postSlug:D??t1($),customAlt:Y}}async convert(A){let Q;try{Q=X4(A)}catch(H){return this.logger.debug("Parse failed",{error:H}),{content:A,converted:!1}}let{frontmatter:B}=Q,w=oM0.safeParse(B);if(!w.success)return{content:A,converted:!1};if(w.data.coverImageId)return{content:A,converted:!1};let{title:$,slug:D,coverImageUrl:I,coverImageAlt:Y}=w.data;if(!aH(I))return{content:A,converted:!1};let X={postTitle:$,postSlug:D??t1($),sourceUrl:I,customAlt:Y};try{let H=await this.createImageEntity(X),U={...B};return delete U.coverImageUrl,delete U.coverImageAlt,U.coverImageId=H,{content:gF(U,Q.content),converted:!0,imageId:H}}catch(H){return this.logger.warn("Failed to convert coverImageUrl",{url:I,error:L0(H)}),{content:A,converted:!1}}}async createImageEntity(A){let{postTitle:Q,postSlug:B,sourceUrl:w,customAlt:$}=A,D=`Cover image for ${Q}`;return jp({id:`${B}-cover`,title:D,alt:$??D,sourceUrl:w},this.entityService,this.fetcher,this.logger)}}KA();class tk{entityService;fetcher;logger;constructor(A,Q,B=g$){this.entityService=A;this.fetcher=B;this.logger=Q.child("MarkdownImageConverter")}detectInlineImages(A,Q){let B=[],w=oT(A);for(let $ of w){if(!aH($.url))continue;if($.url.startsWith("entity://"))continue;let D=this.reconstructMarkdown($);B.push({sourceUrl:$.url,alt:$.alt,originalMarkdown:D,postSlug:Q})}return B}reconstructMarkdown(A){if(A.title)return``;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,D=0;for(let I of B)try{let Y=await this.createImageEntity(I,D++),X=``;w=w.replace(I.originalMarkdown,X),$++,this.logger.debug("Converted inline image",{sourceUrl:I.sourceUrl,imageId:Y})}catch(Y){this.logger.warn("Failed to convert inline image",{sourceUrl:I.sourceUrl,error:L0(Y)})}return{content:w,converted:$>0,convertedCount:$}}async createImageEntity(A,Q){let{sourceUrl:B,alt:w,postSlug:$}=A;return jp({id:`${$}-inline-${Q}`,title:w||`Inline image ${Q+1} for ${$}`,alt:w||"",sourceUrl:B},this.entityService,this.fetcher,this.logger)}}class HWA{logger;entityService;fileOperations;constructor(A,Q,B){this.logger=A,this.entityService=Q,this.fileOperations=B}async importEntitiesWithProgress(A,Q,B,w){this.logger.debug("Importing entities with progress reporting");let $={imported:0,skipped:0,failed:0,quarantined:0,quarantinedFiles:[],errors:[],jobIds:[]},D=A??await this.fileOperations.getAllSyncFiles(),I=D.length;await Q.report({progress:0,message:`Starting import of ${I} files`});for(let Y=0;Y<I;Y+=B){let X=D.slice(Y,Y+B),H=await w(X);$.imported+=H.imported,$.skipped+=H.skipped,$.failed+=H.failed,$.quarantined+=H.quarantined,$.errors.push(...H.errors),$.quarantinedFiles.push(...H.quarantinedFiles),$.jobIds.push(...H.jobIds);let U=Math.min(Y+B,I),F=Math.round(U/I*40);await Q.report({progress:F,message:`Imported ${U}/${I} files`})}return $}async exportEntitiesWithProgress(A,Q,B,w){this.logger.debug("Exporting entities with progress reporting");let $=A??this.entityService.getEntityTypes();await Q.report({progress:50,message:`Starting export of ${$.length} entity types`});let D=await w(A);return await Q.report({progress:100,message:`Exported ${D.exported} entities`}),this.logger.debug("Export completed",D),D}}KA();import{rename as yD2,appendFile as mD2,readFile as uD2,writeFile as cD2,access as lD2}from"fs/promises";import{join as sM0}from"path";class KWA{logger;syncPath;constructor(A,Q){this.logger=A;this.syncPath=Q}isValidationError(A){if(A instanceof J.ZodError)return!0;let Q=L0(A);return Q.includes("invalid_type")||Q.includes("invalid_enum_value")||Q.includes("Required")||Q.includes("Invalid frontmatter")||Q.includes("Unknown entity type")}async quarantineInvalidFile(A,Q,B,w){let $=w(A),D=`${$}.invalid`;try{await yD2($,D),B.quarantined++,B.quarantinedFiles.push(A);let I=sM0(this.syncPath,".import-errors.log"),Y=new Date().toISOString(),X=L0(Q),H=`${Y} - ${A}: ${X}
|
|
1790
1790
|
\u2192 ${A}.invalid
|
|
1791
1791
|
|
|
1792
1792
|
`;await mD2(I,H),this.logger.warn("Quarantined invalid entity file",{originalPath:A,quarantinePath:`${A}.invalid`,error:X})}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=sM0(this.syncPath,".import-errors.log");try{await lD2(Q)}catch{return}try{let B=await uD2(Q,"utf-8");if(B.includes(A)){let $=`${new Date().toISOString()} - [RECOVERED] ${A}
|
|
@@ -1812,7 +1812,7 @@ ${A.entityContent}`,BV1);X=w+P.imagePrompt}catch(P){this.logger.warn("AI prompt
|
|
|
1812
1812
|
*...and ${A.files.length-10} more files*`)}if(A.exists&&A.stats.totalFiles===0)Q.push(`
|
|
1813
1813
|
## Getting Started
|
|
1814
1814
|
`),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(`
|
|
1815
|
-
`)}}tA();class wd extends VB{directorySync;constructor(A,Q,B){super(A,{schema:HUA,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}}}tA();class $d extends VB{directorySync;constructor(A,Q,B){super(A,{schema:XUA,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}}}tA();class Dd extends VB{directorySync;context;constructor(A,Q,B){super(A,{schema:YUA,jobTypeName:"directory-sync"});this.context=Q,this.directorySync=B}async process(A,Q,B){let w=Date.now(),$=A.syncDirection??"both";this.logger.info("Starting directory sync job",{jobId:Q,operation:A.operation,syncDirection:$});let D={imported:0,skipped:0,failed:0,quarantined:0,quarantinedFiles:[],errors:[],jobIds:[]},I={exported:0,failed:0,errors:[]};if($!=="export")if(await B.report({progress:10,message:"Scanning directory for changes"}),D=await this.importWithProgress(A.paths,B),$==="import")await this.waitForImportJobs(D.jobIds,B),await B.report({progress:100,message:`Import complete: ${D.imported} imported`});else await B.report({progress:50,message:`Imported ${D.imported} entities`}),await this.waitForImportJobs(D.jobIds,B),await B.report({progress:56,message:"Processing complete, starting export"});if($!=="import"){let X=$==="export"?10:60;await B.report({progress:X,message:"Exporting entities to directory"}),I=await this.exportWithProgress(A.entityTypes,B),await B.report({progress:100,message:$==="export"?`Export complete: ${I.exported} exported`:`Sync complete: ${D.imported} imported, ${I.exported} exported`})}let Y=Date.now()-w;return this.logger.info("Directory sync job completed",{jobId:Q,duration:Y,imported:D.imported,exported:I.exported}),{import:D,export:I,duration:Y}}async importWithProgress(A,Q){try{return await this.directorySync.importEntitiesWithProgress(A,Q,10)}catch(B){throw this.logger.error("Import phase failed",{error:B}),B}}async exportWithProgress(A,Q){try{return await this.directorySync.exportEntitiesWithProgress(A,Q,10)}catch(B){throw this.logger.error("Export phase failed",{error:B}),B}}async waitForImportJobs(A,Q){if(A.length===0)return;this.logger.debug(`Waiting for ${A.length} import jobs to complete`);let{entityService:B}=this.context,w=300000,$=500,D=Date.now(),I=async()=>{let X=(await Promise.all(A.map((U)=>B.getAsyncJobStatus(U)))).filter((U)=>U&&(U.status==="completed"||U.status==="failed")).length;if(X===A.length){this.logger.debug("All import jobs completed");return}if(Date.now()-D>w){this.logger.warn(`Timeout waiting for import jobs (${X}/${A.length} completed)`);return}let H=Math.round(X/A.length*100);return await Q.report({progress:50+Math.round(H*0.05),message:`Processing ${X}/${A.length} entities`}),await new Promise((U)=>setTimeout(U,$)),I()};return I()}summarizeDataForLog(A){return{operation:A.operation,syncDirection:A.syncDirection}}}tA();class Id extends VB{context;constructor(A,Q,B){super(A,{schema:Qd,jobTypeName:"directory-delete"});this.context=Q}async process(A,Q,B){let w=Qd.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}}}tA();KA();var _X2=J.object({});class Yd extends VB{directorySync;constructor(A,Q){super(A,{schema:_X2,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}}tA();KA();import{readFile as xX2,writeFile as vX2}from"fs/promises";var TX2=KUA;class Xd extends VB{context;fetcher;constructor(A,Q,B=g$){super(Q,{schema:TX2,jobTypeName:"cover-image-convert"});this.context=A,this.fetcher=B}async process(A,Q,B){let{filePath:w,sourceUrl:$,postTitle:D,postSlug:I,customAlt:Y}=A;this.logger.debug("Starting image conversion job",{jobId:Q,filePath:w,sourceUrl:$,postSlug:I});try{await this.reportProgress(B,{progress:Z2.INIT,message:`Reading file: ${w}`});let X;try{X=await xX2(w,"utf-8")}catch(E){return this.logger.error("Failed to read file",{filePath:w,error:L0(E)}),F8.failure(E)}let H;try{H=X4(X)}catch(E){return this.logger.warn("Failed to parse markdown",{filePath:w,error:L0(E)}),F8.failure(E)}let U=H.frontmatter;if(U.coverImageId)return this.logger.debug("File already has coverImageId, skipping",{filePath:w}),await this.reportProgress(B,{progress:Z2.COMPLETE,message:"Already converted"}),{success:!0,skipped:!0};await this.reportProgress(B,{progress:Z2.FETCH,message:"Checking for existing image"});let F=await this.context.entityService.listEntities({entityType:"image",options:{filter:{metadata:{sourceUrl:$}},limit:1}}),Z;if(F[0])Z=F[0].id,this.logger.debug("Reusing existing image entity",{sourceUrl:$,imageId:Z}),await this.reportProgress(B,{progress:Z2.EXTRACT,message:`Reusing existing image: ${Z}`});else{await this.reportProgress(B,{progress:Z2.PROCESS,message:`Fetching image from ${$}`});let E;try{E=await this.fetcher($)}catch(r){return this.logger.error("Failed to fetch image",{sourceUrl:$,error:L0(r)}),F8.failure(r)}await this.reportProgress(B,{progress:Z2.GENERATE,message:"Creating image entity"});let{base64:C}=DG(E),P=mZ(C),x=IG(C);if(!P||!x)return this.logger.error("Could not detect image format or dimensions",{sourceUrl:$}),F8.failure(Error("Could not detect image format or dimensions"));Z=`${I}-cover`;let k=`Cover image for ${D}`,o=Y??k;await this.context.entityService.createEntity({entity:{id:Z,entityType:"image",content:E,metadata:{title:k,alt:o,format:P,width:x.width,height:x.height,sourceUrl:$}}}),this.logger.debug("Created image entity",{imageId:Z,sourceUrl:$}),await this.reportProgress(B,{progress:Z2.EXTRACT,message:`Created image: ${Z}`})}await this.reportProgress(B,{progress:Z2.SAVE,message:"Updating file"});let z={...U};delete z.coverImageUrl,delete z.coverImageAlt,z.coverImageId=Z;let f=gF(z,H.content);try{await vX2(w,f,"utf-8")}catch(E){return this.logger.error("Failed to write file",{filePath:w,error:L0(E)}),F8.failure(E)}return await this.reportProgress(B,{progress:Z2.COMPLETE,message:"Conversion complete"}),this.logger.info("Image conversion complete",{filePath:w,imageId:Z,sourceUrl:$}),{success:!0,imageId:Z}}catch(X){return this.logger.error("Image conversion job failed",{jobId:Q,filePath:w,error:L0(X)}),F8.failure(X)}}summarizeDataForLog(A){return{filePath:A.filePath,sourceUrl:A.sourceUrl,postSlug:A.postSlug}}}tA();KA();import{readFile as SX2,writeFile as gX2}from"fs/promises";class Hd extends VB{converter;constructor(A,Q,B=g$){super(Q,{schema:WUA,jobTypeName:"inline-image-convert"});this.converter=new tk(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:Z2.INIT,message:`Reading file: ${w}`});let D;try{D=await SX2(w,"utf-8")}catch(X){let H=L0(X);return this.logger.error("Failed to read file",{filePath:w,error:H}),{success:!1,error:H}}await this.reportProgress(B,{progress:Z2.FETCH,message:"Detecting inline images"});let I=this.converter.detectInlineImages(D,$);if(I.length===0)return this.logger.debug("No inline images to convert",{filePath:w}),await this.reportProgress(B,{progress:Z2.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:Z2.PROCESS,message:`Converting ${I.length} images`});let Y=await this.converter.convert(D,$);if(!Y.converted)return this.logger.debug("No images were converted",{filePath:w}),await this.reportProgress(B,{progress:Z2.COMPLETE,message:"No images converted"}),{success:!0,skipped:!0,convertedCount:0};await this.reportProgress(B,{progress:Z2.SAVE,message:"Writing updated file"});try{await gX2(w,Y.content,"utf-8")}catch(X){let H=L0(X);return this.logger.error("Failed to write file",{filePath:w,error:H}),{success:!1,error:H}}return await this.reportProgress(B,{progress:Z2.COMPLETE,message:"Conversion complete"}),this.logger.info("Inline image conversion complete",{filePath:w,convertedCount:Y.convertedCount}),{success:!0,convertedCount:Y.convertedCount}}catch(D){let I=L0(D);return this.logger.error("Inline image conversion job failed",{jobId:Q,filePath:w,error:I}),{success:!1,error:I}}}summarizeDataForLog(A){return{filePath:A.filePath,postSlug:A.postSlug}}}function Ob0(A,Q,B){let w=($)=>B.child($);A.jobs.registerHandler("directory-sync",new Dd(w("DirectorySyncJobHandler"),A,Q)),A.jobs.registerHandler("directory-export",new wd(w("DirectoryExportJobHandler"),A,Q)),A.jobs.registerHandler("directory-import",new $d(w("DirectoryImportJobHandler"),A,Q)),A.jobs.registerHandler("directory-delete",new Id(w("DirectoryDeleteJobHandler"),A,Q)),A.jobs.registerHandler("directory-cleanup",new Yd(w("DirectoryCleanupJobHandler"),Q)),A.jobs.registerHandler("cover-image-convert",new Xd(A,w("CoverImageConversionJobHandler"))),A.jobs.registerHandler("inline-image-convert",new Hd(A,w("InlineImageConversionJobHandler"))),B.debug("Registered async job handlers")}tA();import{unlink as hX2,access as yX2}from"fs/promises";function Rb0(A,Q,B,w){let{subscribe:$}=A.messaging,{entityService:D}=A;$("entity:created",async(I)=>{let{entity:Y}=I.payload;try{await Q.fileOps.writeEntity(Y),B.debug("Auto-exported created entity",{id:Y.id,entityType:Y.entityType})}catch(X){B.error("Auto-export FAILED for created entity",{id:Y.id,entityType:Y.entityType,error:X instanceof Error?X.message:String(X),stack:X instanceof Error?X.stack:void 0})}return{success:!0}}),$("entity:updated",async(I)=>{let{entityType:Y,entityId:X}=I.payload;try{let H=await D.getEntity({entityType:Y,id:X});if(!H)return B.debug("Entity not found in DB, skipping export",{entityType:Y,entityId:X}),{success:!1};await Q.fileOps.writeEntity(H),B.debug("Auto-exported updated entity",{id:H.id,entityType:H.entityType})}catch(H){B.error("Auto-export FAILED for updated entity",{entityType:Y,entityId:X,error:H instanceof Error?H.message:String(H),stack:H instanceof Error?H.stack:void 0})}return{success:!0}}),$("entity:deleted",async(I)=>{let{entityId:Y,entityType:X}=I.payload,H=Q.fileOps.getFilePath(Y,X);if(await yX2(H).then(()=>!0,()=>!1))await hX2(H),B.debug("Auto-deleted entity file",{id:Y,entityType:X,path:H});return{success:!0}}),B.debug("Setup auto-sync for entity events",{entityTypes:w})}function bb0(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:S8(),metadata:{operationType:"file_operations",operationTarget:B,pluginId:"directory-sync"}})})}KA();tA();import{access as mX2,readdir as Pb0,mkdir as uX2,copyFile as cX2}from"fs/promises";import{exec as lX2}from"child_process";import{promisify as pX2}from"util";import{join as GUA,resolve as UUA}from"path";var dX2=pX2(lX2);async function Kd(A){try{return await mX2(A),!0}catch{return!1}}async function iX2(A,Q){if(!await Kd(A))return!0;if((await Pb0(A)).filter(($)=>!$.startsWith(".")&&!$.startsWith("_")).length>0)return!1;if(await rX2(A))return Q.debug("Git repository with remote detected - skipping seed content",{path:A}),!1;return!0}async function rX2(A){let Q=GUA(A,".git");if(!await Kd(Q))return!1;try{let{stdout:B}=await dX2("git remote",{cwd:A});return B.trim().length>0}catch{return!1}}async function kb0(A,Q){let B=await Pb0(A,{withFileTypes:!0});for(let w of B){let $=GUA(A,w.name),D=GUA(Q,w.name);if(w.isDirectory()){if(!await Kd(D))await uX2(D,{recursive:!0});await kb0($,D)}else await cX2($,D)}}async function jb0(A,Q,B){let w=UUA(process.cwd(),A);B=B?UUA(B):UUA(process.cwd(),"seed-content");let $=await iX2(w,Q);if($&&await Kd(B))Q.debug("Copying seed content to brain-data directory"),await kb0(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 _b0(A,Q,B,w,$){let D=!1,I=async()=>{if(D)return;D=!0;let Y=Q();if(B.seedContent){let X=B.syncPath??A.dataDir;await jb0(X,w,B.seedContentPath)}try{if($){w.debug("Git enabled \u2014 pulling before import");let H=await $.pull();if(H.files.length>0)w.info("Pulled changes from remote",{filesChanged:H.files.length})}w.debug("Starting initial sync");let X=await Y.sync();w.debug("Initial sync completed",{imported:X.import.imported,failed:X.import.failed,duration:X.duration}),await A.messaging.send({type:sF.initialSyncCompleted,payload:{success:!0},...{broadcast:!0}})}catch(X){w.error("Initial sync failed",X),await A.messaging.send({type:sF.initialSyncCompleted,payload:{success:!1,error:L0(X)},...{broadcast:!0}})}};A.messaging.subscribe(sF.pluginsRegistered,async()=>{return w.debug("Plugins registered, starting initial sync"),await I(),{success:!0}})}KA();function xb0(A,Q,B,w){let $=new uF(()=>{Q.withLock(async()=>{try{await Q.commit(),await Q.push()}catch(Y){w.error("Git auto-commit failed",{error:Y})}})},B),D=["entity:created","entity:updated","entity:deleted"],I=[];for(let Y of D){let X=A.subscribe(Y,async()=>{return $.trigger(),{success:!0}});I.push(X)}return()=>{$.dispose();for(let Y of I)Y()}}function vb0(A,Q,B,w,$){if(w<=0)return()=>{};let D=w*60*1000,I=!1,Y=async()=>{if(I)return;I=!0;try{let{files:H,result:U}=await A.withLock(async()=>{let F=await A.pull(),Z=await Q.queueSyncBatch(B,"periodic-sync");return{files:F.files,result:Z}});if(H.length>0)$.info("Periodic sync: pulled changes",{filesChanged:H.length});if(U)$.debug("Periodic sync: queued imports",{importOperations:U.importOperationsCount,totalFiles:U.totalFiles})}catch(H){$.error("Periodic git sync failed",{error:H})}finally{I=!1}},X=setInterval(()=>{Y()},D);return $.info("Started periodic git sync",{intervalMinutes:w}),()=>{clearInterval(X)}}import{spawnSync as Sb0}from"child_process";import{cpSync as nX2,existsSync as Tb0,mkdirSync as oX2,mkdtempSync as sX2,rmSync as aX2}from"fs";import{tmpdir as tX2}from"os";import{fileURLToPath as eX2}from"url";import{join as AH2,resolve as QH2}from"path";function rG(A,Q){let B=Sb0("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 BH2(A){return A.startsWith("file://")}function wH2(A){return eX2(A)}function $H2(A,Q){return Sb0("git",["--git-dir",A,"show-ref","--verify","--quiet",`refs/heads/${Q}`]).status===0}async function gb0(A){if(!A.bootstrapFromSeed)return;if(!A.gitUrl||!BH2(A.gitUrl))return;if(!A.seedContentPath)throw Error("directory-sync git.bootstrapFromSeed requires seedContentPath for local file:// remotes");let Q=A.branch??"main",B=wH2(A.gitUrl),w=QH2(A.seedContentPath);if(!Tb0(w))throw Error(`Seed content path not found: ${w}`);if(!Tb0(B))A.logger.debug("Creating local bare content remote",{remotePath:B,branch:Q}),oX2(B,{recursive:!0}),rG(process.cwd(),["init","--bare",`--initial-branch=${Q}`,B]);if($H2(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 $=sX2(AH2(tX2(),"directory-sync-seed-"));try{rG($,["init",`--initial-branch=${Q}`]),rG($,["config","user.name",A.authorName??"Brain"]),rG($,["config","user.email",A.authorEmail??"brain@localhost"]),nX2(w,$,{recursive:!0}),rG($,["add","."]),rG($,["commit","-m","seed content remote"]),rG($,["remote","add","origin",A.gitUrl]),rG($,["push","-u","origin",Q])}finally{aX2($,{recursive:!0,force:!0})}}function hb0(A,Q,B,w,$){let{subscribe:D}=A.messaging;D("entity:export:request",async(I)=>{try{return{success:!0,data:await Q().exportEntities(I.payload.entityTypes)}}catch(Y){return{success:!1,error:Y instanceof Error?Y.message:"Export failed"}}}),D("entity:import:request",async(I)=>{try{let Y=Q(),X=I.payload.paths,H=await Y.importEntities(X);if(X&&X.length>0)await Y.removeOrphanedEntities();return{success:!0,data:H}}catch(Y){return{success:!1,error:Y instanceof Error?Y.message:"Import failed"}}}),D("sync:status:request",async()=>{try{let Y=await Q().getStatus();return{success:!0,data:{syncPath:Y.syncPath,isInitialized:Y.exists,watchEnabled:Y.watching}}}catch(I){return{success:!1,error:I instanceof Error?I.message:"Status check failed"}}}),D("sync:configure:request",async(I)=>{try{return await B({syncPath:I.payload.syncPath}),{success:!0,data:{syncPath:I.payload.syncPath,configured:!0}}}catch(Y){return{success:!1,error:Y instanceof Error?Y.message:"Configuration failed"}}}),D("git-sync:get-repo-info",async()=>{if(!$?.repo)return{success:!1,error:"Git not configured"};return{success:!0,data:{repo:$.repo,branch:$.branch??"main"}}}),w.debug("Registered message handlers")}tA();KA();tA();KA();function yb0(A,Q){return MQ(A,"history","Get version history for an entity from git. Without sha: returns commit list. With sha: returns entity content at that version.",J.object({entityType:J.string().describe("Entity type (e.g. post, note, link)"),id:J.string().describe("Entity ID"),sha:J.string().optional().describe("Commit SHA to retrieve content at. Omit to list commit history."),limit:J.number().int().positive().optional().default(10).describe("Max commits to return (list mode only)")}),async(B)=>{let w=`${B.entityType}/${B.id}.md`;try{if(B.sha){let D=await Q.show(B.sha,w);return _6({sha:B.sha,entityType:B.entityType,id:B.id,content:D},`Content at ${B.sha.slice(0,7)}`)}let $=await Q.log(w,B.limit);if($.length===0)return _6({commits:[]},`No history found for ${B.entityType}/${B.id}`);return _6({commits:$,entityType:B.entityType,id:B.id},`${$.length} version${$.length===1?"":"s"} found`)}catch($){return k5($ instanceof Error?$.message:"History lookup failed")}})}function mb0(A,Q,B,w){let $=[MQ(B,"sync","Sync brain entities with the filesystem. Use this for refresh, pull, sync, or backup-to-git requests. Pulls from git if configured, then imports files. Git commit and push happen automatically after imports complete.",J.object({}),async(D,I)=>{try{let Y=I.channelId?`${I.interfaceType}:${I.channelId}`:`plugin:${B}`,X={interfaceType:I.interfaceType,channelId:I.channelId},H=w!==void 0,U=()=>A.queueSyncBatch(Q,Y,X),F=w?await w.withLock(async()=>{return await w.pull(),U()}):await U();if(!F)return _6({gitPulled:H},"No files to sync");return _6({batchId:F.batchId,importOperations:F.importOperationsCount,totalFiles:F.totalFiles,gitPulled:H},`Sync started: ${F.importOperationsCount} import jobs queued for ${F.totalFiles} files${H?" (pulled from git)":""}`)}catch(Y){return k5(Y instanceof Error?Y.message:"Sync failed")}},{cli:{name:"sync"}}),MQ(B,"status","Get sync and git repository status \u2014 last sync time, watching state, pending git changes. Use this for status questions, not for actually syncing or backing up.",J.object({}),async()=>{try{let D=await A.getStatus(),I={syncPath:D.syncPath,lastSync:D.lastSync?.toISOString(),watching:D.watching};if(w){let Y=await w.getStatus();I.git={isRepo:Y.isRepo,branch:Y.branch,hasChanges:Y.hasChanges,ahead:Y.ahead,behind:Y.behind,remote:Y.remote}}return _6(I)}catch(D){return k5(D instanceof Error?D.message:"Status check failed")}},{visibility:"public"})];if(w)$.push(yb0(B,w));return $}var ub0={name:"@brains/directory-sync",private:!0,version:"0.2.0-alpha.53",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/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 JUA extends Bw{directorySync;gitSync;gitCleanups=[];constructor(A={}){super("directory-sync",ub0,A,Kj)}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:Wj,basePrompt:"",formatter:new Bd,requiredPermission:"anchor"}});let w=this.config.syncPath??A.dataDir;this.directorySync=new ek({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(Rb0(A,$,this.logger,this.config.entityTypes),this.config.autoSync)bb0(A,$,this.config.syncPath??A.dataDir);let D=this.config.git!==void 0&&(this.config.git.repo!==void 0||this.config.git.gitUrl!==void 0);if(this.config.git&&!D)this.logger.debug("Git block present but no repo/gitUrl configured \u2014 git sync disabled");if(D&&this.config.git){await gb0({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 IUA({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(xb0(A.messaging,this.gitSync,this.config.commitDebounce,this.logger.child("GitAutoCommit"))),this.config.autoSync)this.gitCleanups.push(vb0(this.gitSync,this.requireDirectorySync(),A,this.config.syncInterval,this.logger.child("GitPeriodicSync")))}if(this.config.initialSync)_b0(A,()=>this.requireDirectorySync(),this.config,this.logger,this.gitSync);hb0(A,()=>this.requireDirectorySync(),(I)=>this.configure(I),this.logger,this.config.git)}async getTools(){let A=this.requireDirectorySync();return mb0(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 ek({...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){Ob0(A,this.requireDirectorySync(),this.logger)}}function h3(A={}){return new JUA(A)}tA();import{render as xm0}from"preact-render-to-string";import{h as Zz}from"preact";function cb0(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=cb0(A[Q]))&&(w&&(w+=" "),w+=B)}else for(B in A)A[B]&&(w&&(w+=" "),w+=B);return w}function _C(){for(var A,Q,B=0,w="",$=arguments.length;B<$;B++)(A=arguments[B])&&(Q=cb0(A))&&(w&&(w+=" "),w+=Q);return w}var IH2=(A)=>{let Q=XH2(A),{conflictingClassGroups:B,conflictingClassGroupModifiers:w}=A;return{getClassGroupId:(I)=>{let Y=I.split("-");if(Y[0]===""&&Y.length!==1)Y.shift();return rb0(Y,Q)||YH2(I)},getConflictingClassGroupIds:(I,Y)=>{let X=B[I]||[];if(Y&&w[I])return[...X,...w[I]];return X}}},rb0=(A,Q)=>{if(A.length===0)return Q.classGroupId;let B=A[0],w=Q.nextPart.get(B),$=w?rb0(A.slice(1),w):void 0;if($)return $;if(Q.validators.length===0)return;let D=A.join("-");return Q.validators.find(({validator:I})=>I(D))?.classGroupId},lb0=/^\[(.+)\]$/,YH2=(A)=>{if(lb0.test(A)){let Q=lb0.exec(A)[1],B=Q?.substring(0,Q.indexOf(":"));if(B)return"arbitrary.."+B}},XH2=(A)=>{let{theme:Q,prefix:B}=A,w={nextPart:new Map,validators:[]};return KH2(Object.entries(A.classGroups),B).forEach(([D,I])=>{ZUA(I,w,D,Q)}),w},ZUA=(A,Q,B,w)=>{A.forEach(($)=>{if(typeof $==="string"){let D=$===""?Q:pb0(Q,$);D.classGroupId=B;return}if(typeof $==="function"){if(HH2($)){ZUA($(w),Q,B,w);return}Q.validators.push({validator:$,classGroupId:B});return}Object.entries($).forEach(([D,I])=>{ZUA(I,pb0(Q,D),B,w)})})},pb0=(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},HH2=(A)=>A.isThemeGetter,KH2=(A,Q)=>{if(!Q)return A;return A.map(([B,w])=>{let $=w.map((D)=>{if(typeof D==="string")return Q+D;if(typeof D==="object")return Object.fromEntries(Object.entries(D).map(([I,Y])=>[Q+I,Y]));return D});return[B,$]})},WH2=(A)=>{if(A<1)return{get:()=>{return},set:()=>{}};let Q=0,B=new Map,w=new Map,$=(D,I)=>{if(B.set(D,I),Q++,Q>A)Q=0,w=B,B=new Map};return{get(D){let I=B.get(D);if(I!==void 0)return I;if((I=w.get(D))!==void 0)return $(D,I),I},set(D,I){if(B.has(D))B.set(D,I);else $(D,I)}}};var UH2=(A)=>{let{separator:Q,experimentalParseClassName:B}=A,w=Q.length===1,$=Q[0],D=Q.length,I=(Y)=>{let X=[],H=0,U=0,F;for(let C=0;C<Y.length;C++){let P=Y[C];if(H===0){if(P===$&&(w||Y.slice(C,C+D)===Q)){X.push(Y.slice(U,C)),U=C+D;continue}if(P==="/"){F=C;continue}}if(P==="[")H++;else if(P==="]")H--}let Z=X.length===0?Y:Y.substring(U),z=Z.startsWith("!"),f=z?Z.substring(1):Z,E=F&&F>U?F-U:void 0;return{modifiers:X,hasImportantModifier:z,baseClassName:f,maybePostfixModifierPosition:E}};if(B)return(Y)=>B({className:Y,parseClassName:I});return I},GH2=(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},JH2=(A)=>({cache:WH2(A.cacheSize),parseClassName:UH2(A),...IH2(A)}),FH2=/\s+/,ZH2=(A,Q)=>{let{parseClassName:B,getClassGroupId:w,getConflictingClassGroupIds:$}=Q,D=[],I=A.trim().split(FH2),Y="";for(let X=I.length-1;X>=0;X-=1){let H=I[X],{modifiers:U,hasImportantModifier:F,baseClassName:Z,maybePostfixModifierPosition:z}=B(H),f=Boolean(z),E=w(f?Z.substring(0,z):Z);if(!E){if(!f){Y=H+(Y.length>0?" "+Y:Y);continue}if(E=w(Z),!E){Y=H+(Y.length>0?" "+Y:Y);continue}f=!1}let C=GH2(U).join(":"),P=F?C+"!":C,x=P+E;if(D.includes(x))continue;D.push(x);let k=$(E,f);for(let o=0;o<k.length;++o){let r=k[o];D.push(P+r)}Y=H+(Y.length>0?" "+Y:Y)}return Y};function zH2(){let A=0,Q,B,w="";while(A<arguments.length)if(Q=arguments[A++]){if(B=nb0(Q))w&&(w+=" "),w+=B}return w}var nb0=(A)=>{if(typeof A==="string")return A;let Q,B="";for(let w=0;w<A.length;w++)if(A[w]){if(Q=nb0(A[w]))B&&(B+=" "),B+=Q}return B};function db0(A,...Q){let B,w,$,D=I;function I(X){let H=Q.reduce((U,F)=>F(U),A());return B=JH2(H),w=B.cache.get,$=B.cache.set,D=Y,Y(X)}function Y(X){let H=w(X);if(H)return H;let U=ZH2(X,B);return $(X,U),U}return function(){return D(zH2.apply(null,arguments))}}var Vw=(A)=>{let Q=(B)=>B[A]||[];return Q.isThemeGetter=!0,Q},ob0=/^\[(?:([a-z-]+):)?(.+)\]$/i,qH2=/^\d+\/\d+$/,NH2=new Set(["px","full","screen"]),fH2=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,LH2=/\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$/,CH2=/^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/,EH2=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,MH2=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,pK=(A)=>xC(A)||NH2.has(A)||qH2.test(A),nG=(A)=>vC(A,"length",_H2),xC=(A)=>Boolean(A)&&!Number.isNaN(Number(A)),FUA=(A)=>vC(A,"number",xC),Uj=(A)=>Boolean(A)&&Number.isInteger(Number(A)),VH2=(A)=>A.endsWith("%")&&xC(A.slice(0,-1)),XQ=(A)=>ob0.test(A),oG=(A)=>fH2.test(A),OH2=new Set(["length","size","percentage"]),RH2=(A)=>vC(A,OH2,sb0),bH2=(A)=>vC(A,"position",sb0),PH2=new Set(["image","url"]),kH2=(A)=>vC(A,PH2,vH2),jH2=(A)=>vC(A,"",xH2),Gj=()=>!0,vC=(A,Q,B)=>{let w=ob0.exec(A);if(w){if(w[1])return typeof Q==="string"?w[1]===Q:Q.has(w[1]);return B(w[2])}return!1},_H2=(A)=>LH2.test(A)&&!CH2.test(A),sb0=()=>!1,xH2=(A)=>EH2.test(A),vH2=(A)=>MH2.test(A);var ib0=()=>{let A=Vw("colors"),Q=Vw("spacing"),B=Vw("blur"),w=Vw("brightness"),$=Vw("borderColor"),D=Vw("borderRadius"),I=Vw("borderSpacing"),Y=Vw("borderWidth"),X=Vw("contrast"),H=Vw("grayscale"),U=Vw("hueRotate"),F=Vw("invert"),Z=Vw("gap"),z=Vw("gradientColorStops"),f=Vw("gradientColorStopPositions"),E=Vw("inset"),C=Vw("margin"),P=Vw("opacity"),x=Vw("padding"),k=Vw("saturate"),o=Vw("scale"),r=Vw("sepia"),u=Vw("skew"),v=Vw("space"),S=Vw("translate"),h=()=>["auto","contain","none"],t=()=>["auto","hidden","clip","visible","scroll"],l=()=>["auto",XQ,Q],UA=()=>[XQ,Q],YA=()=>["",pK,nG],b=()=>["auto",xC,XQ],R=()=>["bottom","center","left","left-bottom","left-top","right","right-bottom","right-top","top"],j=()=>["solid","dashed","dotted","double","none"],s=()=>["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"],e=()=>["","0",XQ],i=()=>["auto","avoid","all","avoid-page","page","left","right","column"],WA=()=>[xC,XQ];return{cacheSize:500,separator:":",theme:{colors:[Gj],spacing:[pK,nG],blur:["none","",oG,XQ],brightness:WA(),borderColor:[A],borderRadius:["none","","full",oG,XQ],borderSpacing:UA(),borderWidth:YA(),contrast:WA(),grayscale:e(),hueRotate:WA(),invert:e(),gap:UA(),gradientColorStops:[A],gradientColorStopPositions:[VH2,nG],inset:l(),margin:l(),opacity:WA(),padding:UA(),saturate:WA(),scale:WA(),sepia:e(),skew:WA(),space:UA(),translate:UA()},classGroups:{aspect:[{aspect:["auto","square","video",XQ]}],container:["container"],columns:[{columns:[oG]}],"break-after":[{"break-after":i()}],"break-before":[{"break-before":i()}],"break-inside":[{"break-inside":["auto","avoid","avoid-page","avoid-column"]}],"box-decoration":[{"box-decoration":["slice","clone"]}],box:[{box:["border","content"]}],display:["block","inline-block","inline","flex","inline-flex","table","inline-table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row-group","table-row","flow-root","grid","inline-grid","contents","list-item","hidden"],float:[{float:["right","left","none","start","end"]}],clear:[{clear:["left","right","both","none","start","end"]}],isolation:["isolate","isolation-auto"],"object-fit":[{object:["contain","cover","fill","none","scale-down"]}],"object-position":[{object:[...R(),XQ]}],overflow:[{overflow:t()}],"overflow-x":[{"overflow-x":t()}],"overflow-y":[{"overflow-y":t()}],overscroll:[{overscroll:h()}],"overscroll-x":[{"overscroll-x":h()}],"overscroll-y":[{"overscroll-y":h()}],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",Uj,XQ]}],basis:[{basis:l()}],"flex-direction":[{flex:["row","row-reverse","col","col-reverse"]}],"flex-wrap":[{flex:["wrap","wrap-reverse","nowrap"]}],flex:[{flex:["1","auto","initial","none",XQ]}],grow:[{grow:e()}],shrink:[{shrink:e()}],order:[{order:["first","last","none",Uj,XQ]}],"grid-cols":[{"grid-cols":[Gj]}],"col-start-end":[{col:["auto",{span:["full",Uj,XQ]},XQ]}],"col-start":[{"col-start":b()}],"col-end":[{"col-end":b()}],"grid-rows":[{"grid-rows":[Gj]}],"row-start-end":[{row:["auto",{span:[Uj,XQ]},XQ]}],"row-start":[{"row-start":b()}],"row-end":[{"row-end":b()}],"grid-flow":[{"grid-flow":["row","col","dense","row-dense","col-dense"]}],"auto-cols":[{"auto-cols":["auto","min","max","fr",XQ]}],"auto-rows":[{"auto-rows":["auto","min","max","fr",XQ]}],gap:[{gap:[Z]}],"gap-x":[{"gap-x":[Z]}],"gap-y":[{"gap-y":[Z]}],"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:[x]}],px:[{px:[x]}],py:[{py:[x]}],ps:[{ps:[x]}],pe:[{pe:[x]}],pt:[{pt:[x]}],pr:[{pr:[x]}],pb:[{pb:[x]}],pl:[{pl:[x]}],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":[v]}],"space-x-reverse":["space-x-reverse"],"space-y":[{"space-y":[v]}],"space-y-reverse":["space-y-reverse"],w:[{w:["auto","min","max","fit","svw","lvw","dvw",XQ,Q]}],"min-w":[{"min-w":[XQ,Q,"min","max","fit"]}],"max-w":[{"max-w":[XQ,Q,"none","full","min","max","fit","prose",{screen:[oG]},oG]}],h:[{h:[XQ,Q,"auto","min","max","fit","svh","lvh","dvh"]}],"min-h":[{"min-h":[XQ,Q,"min","max","fit","svh","lvh","dvh"]}],"max-h":[{"max-h":[XQ,Q,"min","max","fit","svh","lvh","dvh"]}],size:[{size:[XQ,Q,"auto","min","max","fit"]}],"font-size":[{text:["base",oG,nG]}],"font-smoothing":["antialiased","subpixel-antialiased"],"font-style":["italic","not-italic"],"font-weight":[{font:["thin","extralight","light","normal","medium","semibold","bold","extrabold","black",FUA]}],"font-family":[{font:[Gj]}],"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",XQ]}],"line-clamp":[{"line-clamp":["none",xC,FUA]}],leading:[{leading:["none","tight","snug","normal","relaxed","loose",pK,XQ]}],"list-image":[{"list-image":["none",XQ]}],"list-style-type":[{list:["none","disc","decimal",XQ]}],"list-style-position":[{list:["inside","outside"]}],"placeholder-color":[{placeholder:[A]}],"placeholder-opacity":[{"placeholder-opacity":[P]}],"text-alignment":[{text:["left","center","right","justify","start","end"]}],"text-color":[{text:[A]}],"text-opacity":[{"text-opacity":[P]}],"text-decoration":["underline","overline","line-through","no-underline"],"text-decoration-style":[{decoration:[...j(),"wavy"]}],"text-decoration-thickness":[{decoration:["auto","from-font",pK,nG]}],"underline-offset":[{"underline-offset":["auto",pK,XQ]}],"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:UA()}],"vertical-align":[{align:["baseline","top","middle","bottom","text-top","text-bottom","sub","super",XQ]}],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",XQ]}],"bg-attachment":[{bg:["fixed","local","scroll"]}],"bg-clip":[{"bg-clip":["border","padding","content","text"]}],"bg-opacity":[{"bg-opacity":[P]}],"bg-origin":[{"bg-origin":["border","padding","content"]}],"bg-position":[{bg:[...R(),bH2]}],"bg-repeat":[{bg:["no-repeat",{repeat:["","x","y","round","space"]}]}],"bg-size":[{bg:["auto","cover","contain",RH2]}],"bg-image":[{bg:["none",{"gradient-to":["t","tr","r","br","b","bl","l","tl"]},kH2]}],"bg-color":[{bg:[A]}],"gradient-from-pos":[{from:[f]}],"gradient-via-pos":[{via:[f]}],"gradient-to-pos":[{to:[f]}],"gradient-from":[{from:[z]}],"gradient-via":[{via:[z]}],"gradient-to":[{to:[z]}],rounded:[{rounded:[D]}],"rounded-s":[{"rounded-s":[D]}],"rounded-e":[{"rounded-e":[D]}],"rounded-t":[{"rounded-t":[D]}],"rounded-r":[{"rounded-r":[D]}],"rounded-b":[{"rounded-b":[D]}],"rounded-l":[{"rounded-l":[D]}],"rounded-ss":[{"rounded-ss":[D]}],"rounded-se":[{"rounded-se":[D]}],"rounded-ee":[{"rounded-ee":[D]}],"rounded-es":[{"rounded-es":[D]}],"rounded-tl":[{"rounded-tl":[D]}],"rounded-tr":[{"rounded-tr":[D]}],"rounded-br":[{"rounded-br":[D]}],"rounded-bl":[{"rounded-bl":[D]}],"border-w":[{border:[Y]}],"border-w-x":[{"border-x":[Y]}],"border-w-y":[{"border-y":[Y]}],"border-w-s":[{"border-s":[Y]}],"border-w-e":[{"border-e":[Y]}],"border-w-t":[{"border-t":[Y]}],"border-w-r":[{"border-r":[Y]}],"border-w-b":[{"border-b":[Y]}],"border-w-l":[{"border-l":[Y]}],"border-opacity":[{"border-opacity":[P]}],"border-style":[{border:[...j(),"hidden"]}],"divide-x":[{"divide-x":[Y]}],"divide-x-reverse":["divide-x-reverse"],"divide-y":[{"divide-y":[Y]}],"divide-y-reverse":["divide-y-reverse"],"divide-opacity":[{"divide-opacity":[P]}],"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":[pK,XQ]}],"outline-w":[{outline:[pK,nG]}],"outline-color":[{outline:[A]}],"ring-w":[{ring:YA()}],"ring-w-inset":["ring-inset"],"ring-color":[{ring:[A]}],"ring-opacity":[{"ring-opacity":[P]}],"ring-offset-w":[{"ring-offset":[pK,nG]}],"ring-offset-color":[{"ring-offset":[A]}],shadow:[{shadow:["","inner","none",oG,jH2]}],"shadow-color":[{shadow:[Gj]}],opacity:[{opacity:[P]}],"mix-blend":[{"mix-blend":[...s(),"plus-lighter","plus-darker"]}],"bg-blend":[{"bg-blend":s()}],filter:[{filter:["","none"]}],blur:[{blur:[B]}],brightness:[{brightness:[w]}],contrast:[{contrast:[X]}],"drop-shadow":[{"drop-shadow":["","none",oG,XQ]}],grayscale:[{grayscale:[H]}],"hue-rotate":[{"hue-rotate":[U]}],invert:[{invert:[F]}],saturate:[{saturate:[k]}],sepia:[{sepia:[r]}],"backdrop-filter":[{"backdrop-filter":["","none"]}],"backdrop-blur":[{"backdrop-blur":[B]}],"backdrop-brightness":[{"backdrop-brightness":[w]}],"backdrop-contrast":[{"backdrop-contrast":[X]}],"backdrop-grayscale":[{"backdrop-grayscale":[H]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[U]}],"backdrop-invert":[{"backdrop-invert":[F]}],"backdrop-opacity":[{"backdrop-opacity":[P]}],"backdrop-saturate":[{"backdrop-saturate":[k]}],"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",XQ]}],duration:[{duration:WA()}],ease:[{ease:["linear","in","out","in-out",XQ]}],delay:[{delay:WA()}],animate:[{animate:["none","spin","ping","pulse","bounce",XQ]}],transform:[{transform:["","gpu","none"]}],scale:[{scale:[o]}],"scale-x":[{"scale-x":[o]}],"scale-y":[{"scale-y":[o]}],rotate:[{rotate:[Uj,XQ]}],"translate-x":[{"translate-x":[S]}],"translate-y":[{"translate-y":[S]}],"skew-x":[{"skew-x":[u]}],"skew-y":[{"skew-y":[u]}],"transform-origin":[{origin:["center","top","top-right","right","bottom-right","bottom","bottom-left","left","top-left",XQ]}],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",XQ]}],"caret-color":[{caret:[A]}],"pointer-events":[{"pointer-events":["none","auto"]}],resize:[{resize:["none","y","x",""]}],"scroll-behavior":[{scroll:["auto","smooth"]}],"scroll-m":[{"scroll-m":UA()}],"scroll-mx":[{"scroll-mx":UA()}],"scroll-my":[{"scroll-my":UA()}],"scroll-ms":[{"scroll-ms":UA()}],"scroll-me":[{"scroll-me":UA()}],"scroll-mt":[{"scroll-mt":UA()}],"scroll-mr":[{"scroll-mr":UA()}],"scroll-mb":[{"scroll-mb":UA()}],"scroll-ml":[{"scroll-ml":UA()}],"scroll-p":[{"scroll-p":UA()}],"scroll-px":[{"scroll-px":UA()}],"scroll-py":[{"scroll-py":UA()}],"scroll-ps":[{"scroll-ps":UA()}],"scroll-pe":[{"scroll-pe":UA()}],"scroll-pt":[{"scroll-pt":UA()}],"scroll-pr":[{"scroll-pr":UA()}],"scroll-pb":[{"scroll-pb":UA()}],"scroll-pl":[{"scroll-pl":UA()}],"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",XQ]}],fill:[{fill:[A,"none"]}],"stroke-w":[{stroke:[pK,nG,FUA]}],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"]}}},TH2=(A,{cacheSize:Q,prefix:B,separator:w,experimentalParseClassName:$,extend:D={},override:I={}})=>{Jj(A,"cacheSize",Q),Jj(A,"prefix",B),Jj(A,"separator",w),Jj(A,"experimentalParseClassName",$);for(let Y in I)SH2(A[Y],I[Y]);for(let Y in D)gH2(A[Y],D[Y]);return A},Jj=(A,Q,B)=>{if(B!==void 0)A[Q]=B},SH2=(A,Q)=>{if(Q)for(let B in Q)Jj(A,B,Q[B])},gH2=(A,Q)=>{if(Q)for(let B in Q){let w=Q[B];if(w!==void 0)A[B]=(A[B]||[]).concat(w)}},Wd=(A,...Q)=>typeof A==="function"?db0(ib0,A,...Q):db0(()=>TH2(ib0(),A),...Q);var hH2=Wd({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 m1(...A){return hH2(_C(A))}var ab0=(A)=>typeof A==="boolean"?`${A}`:A===0?"0":A,tb0=_C,cB=(A,Q)=>(B)=>{var w;if((Q===null||Q===void 0?void 0:Q.variants)==null)return tb0(A,B===null||B===void 0?void 0:B.class,B===null||B===void 0?void 0:B.className);let{variants:$,defaultVariants:D}=Q,I=Object.keys($).map((H)=>{let U=B===null||B===void 0?void 0:B[H],F=D===null||D===void 0?void 0:D[H];if(U===null)return null;let Z=ab0(U)||ab0(F);return $[H][Z]}),Y=B&&Object.entries(B).reduce((H,U)=>{let[F,Z]=U;if(Z===void 0)return H;return H[F]=Z,H},{}),X=Q===null||Q===void 0?void 0:(w=Q.compoundVariants)===null||w===void 0?void 0:w.reduce((H,U)=>{let{class:F,className:Z,...z}=U;return Object.entries(z).every((f)=>{let[E,C]=f;return Array.isArray(C)?C.includes({...D,...Y}[E]):{...D,...Y}[E]===C})?[...H,F,Z]:H},[]);return tb0(A,I,X,B===null||B===void 0?void 0:B.class,B===null||B===void 0?void 0:B.className)};import{jsxDEV as zUA}from"preact/jsx-dev-runtime";var eb0=cB("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 qUA({variant:A,title:Q,children:B,className:w}){return zUA("div",{className:m1(eb0({variant:A}),w),role:"alert",children:[Q&&zUA("p",{className:"font-medium text-current opacity-90",children:Q},void 0,!1,void 0,this),zUA("div",{className:m1(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 yH2}from"preact/jsx-dev-runtime";var AP0=cB("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 y3({variant:A,size:Q,className:B,children:w,ssrOnClick:$,type:D="button",...I}){return yH2("button",{type:D,className:m1(AP0({variant:A,size:Q}),B),...I,...$&&{onclick:$},children:w},void 0,!1,void 0,this)}import{jsxDEV as mH2}from"preact/jsx-dev-runtime";var QP0=cB("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 h6({href:A,children:Q,variant:B,size:w,external:$=!1,className:D,"aria-label":I}){let Y=$?{target:"_blank",rel:"noopener noreferrer"}:{};return mH2("a",{href:A,className:m1(QP0({variant:B,size:w}),D),"aria-label":I,...Y,children:Q},void 0,!1,void 0,this)}import{jsxDEV as Ud}from"preact/jsx-dev-runtime";var BP0=cB("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"}}),uH2={sm:"w-4 h-4",md:"w-5 h-5",lg:"w-6 h-6"};function TC({variant:A,size:Q,className:B}){let w=uH2[Q??"md"];return Ud("button",{onclick:"toggleTheme()",type:"button",className:m1(BP0({variant:A,size:Q}),B),"aria-label":"Toggle dark mode",children:Ud("svg",{className:m1(w,"transition-colors"),fill:"none",stroke:"currentColor",strokeWidth:1.6,viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:[Ud("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),Ud("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 NUA}from"preact/jsx-dev-runtime";var wP0=cB("flex flex-wrap",{variants:{orientation:{horizontal:"justify-center gap-6 items-center",vertical:"flex-col gap-2.5"}},defaultVariants:{orientation:"horizontal"}});function Gd({items:A,className:Q,linkClassName:B="hover:text-accent transition-colors",orientation:w,children:$}){if(A.length===0&&!$)return null;let D=[...A].sort((I,Y)=>I.priority-Y.priority);return NUA("ul",{className:m1(wP0({orientation:w}),Q),children:[D.map((I)=>NUA("li",{children:NUA("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 L2B}from"preact/jsx-dev-runtime";import{jsxDEV as M2B}from"preact/jsx-dev-runtime";KA();KA();import{createContext as cH2,h as lH2}from"preact";import{useContext as pH2}from"preact/hooks";var $P0=cH2(null);function Jd({imageRenderer:A,children:Q}){return lH2($P0.Provider,{value:A??null},Q)}function DP0(){return pH2($P0)}function m3(){let A=DP0();return(Q)=>rT(Q,A?{imageRenderer:A}:void 0)}import{jsxDEV as dK}from"preact/jsx-dev-runtime";var fUA=({markdown:A})=>{let Q=m3(),w=A.split(/^---$/gm).map((I)=>I.trim()).map((I)=>{let{attributes:Y,markdown:X}=FS(I),H=ZS(X),U;if(H)U=`<div class="slide-columns">${H.map((Z)=>`<div class="slide-column">${sV(Q(Z.trim()))}</div>`).join("")}</div>`;else U=sV(Q(X));return{attributes:Y,htmlContent:U}}),$=w.some((I)=>I.htmlContent.includes('class="mermaid"')),D=w.map(({attributes:I,htmlContent:Y},X)=>dK("section",{...I,dangerouslySetInnerHTML:{__html:Y}},X,!1,void 0,this));return dK("section",{className:"presentation-section",children:[dK("link",{rel:"stylesheet",href:"https://cdn.jsdelivr.net/npm/reveal.js@5.1.0/dist/reveal.min.css"},void 0,!1,void 0,this),dK("div",{className:"reveal",children:dK("div",{className:"slides",children:D},void 0,!1,void 0,this)},void 0,!1,void 0,this),dK("script",{src:"https://cdn.jsdelivr.net/npm/reveal.js@5.1.0/dist/reveal.min.js",defer:!0},void 0,!1,void 0,this),$&&dK("script",{src:"https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js",defer:!0},void 0,!1,void 0,this),dK("script",{dangerouslySetInnerHTML:{__html:`
|
|
1815
|
+
`)}}tA();class wd extends VB{directorySync;constructor(A,Q,B){super(A,{schema:HUA,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}}}tA();class $d extends VB{directorySync;constructor(A,Q,B){super(A,{schema:XUA,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}}}tA();class Dd extends VB{directorySync;context;constructor(A,Q,B){super(A,{schema:YUA,jobTypeName:"directory-sync"});this.context=Q,this.directorySync=B}async process(A,Q,B){let w=Date.now(),$=A.syncDirection??"both";this.logger.info("Starting directory sync job",{jobId:Q,operation:A.operation,syncDirection:$});let D={imported:0,skipped:0,failed:0,quarantined:0,quarantinedFiles:[],errors:[],jobIds:[]},I={exported:0,failed:0,errors:[]};if($!=="export")if(await B.report({progress:10,message:"Scanning directory for changes"}),D=await this.importWithProgress(A.paths,B),$==="import")await this.waitForImportJobs(D.jobIds,B),await B.report({progress:100,message:`Import complete: ${D.imported} imported`});else await B.report({progress:50,message:`Imported ${D.imported} entities`}),await this.waitForImportJobs(D.jobIds,B),await B.report({progress:56,message:"Processing complete, starting export"});if($!=="import"){let X=$==="export"?10:60;await B.report({progress:X,message:"Exporting entities to directory"}),I=await this.exportWithProgress(A.entityTypes,B),await B.report({progress:100,message:$==="export"?`Export complete: ${I.exported} exported`:`Sync complete: ${D.imported} imported, ${I.exported} exported`})}let Y=Date.now()-w;return this.logger.info("Directory sync job completed",{jobId:Q,duration:Y,imported:D.imported,exported:I.exported}),{import:D,export:I,duration:Y}}async importWithProgress(A,Q){try{return await this.directorySync.importEntitiesWithProgress(A,Q,10)}catch(B){throw this.logger.error("Import phase failed",{error:B}),B}}async exportWithProgress(A,Q){try{return await this.directorySync.exportEntitiesWithProgress(A,Q,10)}catch(B){throw this.logger.error("Export phase failed",{error:B}),B}}async waitForImportJobs(A,Q){if(A.length===0)return;this.logger.debug(`Waiting for ${A.length} import jobs to complete`);let{entityService:B}=this.context,w=300000,$=500,D=Date.now(),I=async()=>{let X=(await Promise.all(A.map((U)=>B.getAsyncJobStatus(U)))).filter((U)=>U&&(U.status==="completed"||U.status==="failed")).length;if(X===A.length){this.logger.debug("All import jobs completed");return}if(Date.now()-D>w){this.logger.warn(`Timeout waiting for import jobs (${X}/${A.length} completed)`);return}let H=Math.round(X/A.length*100);return await Q.report({progress:50+Math.round(H*0.05),message:`Processing ${X}/${A.length} entities`}),await new Promise((U)=>setTimeout(U,$)),I()};return I()}summarizeDataForLog(A){return{operation:A.operation,syncDirection:A.syncDirection}}}tA();class Id extends VB{context;constructor(A,Q,B){super(A,{schema:Qd,jobTypeName:"directory-delete"});this.context=Q}async process(A,Q,B){let w=Qd.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}}}tA();KA();var _X2=J.object({});class Yd extends VB{directorySync;constructor(A,Q){super(A,{schema:_X2,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}}tA();KA();import{readFile as xX2,writeFile as vX2}from"fs/promises";var TX2=KUA;class Xd extends VB{context;fetcher;constructor(A,Q,B=g$){super(Q,{schema:TX2,jobTypeName:"cover-image-convert"});this.context=A,this.fetcher=B}async process(A,Q,B){let{filePath:w,sourceUrl:$,postTitle:D,postSlug:I,customAlt:Y}=A;this.logger.debug("Starting image conversion job",{jobId:Q,filePath:w,sourceUrl:$,postSlug:I});try{await this.reportProgress(B,{progress:Z2.INIT,message:`Reading file: ${w}`});let X;try{X=await xX2(w,"utf-8")}catch(E){return this.logger.error("Failed to read file",{filePath:w,error:L0(E)}),F8.failure(E)}let H;try{H=X4(X)}catch(E){return this.logger.warn("Failed to parse markdown",{filePath:w,error:L0(E)}),F8.failure(E)}let U=H.frontmatter;if(U.coverImageId)return this.logger.debug("File already has coverImageId, skipping",{filePath:w}),await this.reportProgress(B,{progress:Z2.COMPLETE,message:"Already converted"}),{success:!0,skipped:!0};await this.reportProgress(B,{progress:Z2.FETCH,message:"Checking for existing image"});let F=await this.context.entityService.listEntities({entityType:"image",options:{filter:{metadata:{sourceUrl:$}},limit:1}}),Z;if(F[0])Z=F[0].id,this.logger.debug("Reusing existing image entity",{sourceUrl:$,imageId:Z}),await this.reportProgress(B,{progress:Z2.EXTRACT,message:`Reusing existing image: ${Z}`});else{await this.reportProgress(B,{progress:Z2.PROCESS,message:`Fetching image from ${$}`});let E;try{E=await this.fetcher($)}catch(r){return this.logger.error("Failed to fetch image",{sourceUrl:$,error:L0(r)}),F8.failure(r)}await this.reportProgress(B,{progress:Z2.GENERATE,message:"Creating image entity"});let{base64:C}=DG(E),P=mZ(C),x=IG(C);if(!P||!x)return this.logger.error("Could not detect image format or dimensions",{sourceUrl:$}),F8.failure(Error("Could not detect image format or dimensions"));Z=`${I}-cover`;let k=`Cover image for ${D}`,o=Y??k;await this.context.entityService.createEntity({entity:{id:Z,entityType:"image",content:E,metadata:{title:k,alt:o,format:P,width:x.width,height:x.height,sourceUrl:$}}}),this.logger.debug("Created image entity",{imageId:Z,sourceUrl:$}),await this.reportProgress(B,{progress:Z2.EXTRACT,message:`Created image: ${Z}`})}await this.reportProgress(B,{progress:Z2.SAVE,message:"Updating file"});let z={...U};delete z.coverImageUrl,delete z.coverImageAlt,z.coverImageId=Z;let f=gF(z,H.content);try{await vX2(w,f,"utf-8")}catch(E){return this.logger.error("Failed to write file",{filePath:w,error:L0(E)}),F8.failure(E)}return await this.reportProgress(B,{progress:Z2.COMPLETE,message:"Conversion complete"}),this.logger.info("Image conversion complete",{filePath:w,imageId:Z,sourceUrl:$}),{success:!0,imageId:Z}}catch(X){return this.logger.error("Image conversion job failed",{jobId:Q,filePath:w,error:L0(X)}),F8.failure(X)}}summarizeDataForLog(A){return{filePath:A.filePath,sourceUrl:A.sourceUrl,postSlug:A.postSlug}}}tA();KA();import{readFile as SX2,writeFile as gX2}from"fs/promises";class Hd extends VB{converter;constructor(A,Q,B=g$){super(Q,{schema:WUA,jobTypeName:"inline-image-convert"});this.converter=new tk(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:Z2.INIT,message:`Reading file: ${w}`});let D;try{D=await SX2(w,"utf-8")}catch(X){let H=L0(X);return this.logger.error("Failed to read file",{filePath:w,error:H}),{success:!1,error:H}}await this.reportProgress(B,{progress:Z2.FETCH,message:"Detecting inline images"});let I=this.converter.detectInlineImages(D,$);if(I.length===0)return this.logger.debug("No inline images to convert",{filePath:w}),await this.reportProgress(B,{progress:Z2.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:Z2.PROCESS,message:`Converting ${I.length} images`});let Y=await this.converter.convert(D,$);if(!Y.converted)return this.logger.debug("No images were converted",{filePath:w}),await this.reportProgress(B,{progress:Z2.COMPLETE,message:"No images converted"}),{success:!0,skipped:!0,convertedCount:0};await this.reportProgress(B,{progress:Z2.SAVE,message:"Writing updated file"});try{await gX2(w,Y.content,"utf-8")}catch(X){let H=L0(X);return this.logger.error("Failed to write file",{filePath:w,error:H}),{success:!1,error:H}}return await this.reportProgress(B,{progress:Z2.COMPLETE,message:"Conversion complete"}),this.logger.info("Inline image conversion complete",{filePath:w,convertedCount:Y.convertedCount}),{success:!0,convertedCount:Y.convertedCount}}catch(D){let I=L0(D);return this.logger.error("Inline image conversion job failed",{jobId:Q,filePath:w,error:I}),{success:!1,error:I}}}summarizeDataForLog(A){return{filePath:A.filePath,postSlug:A.postSlug}}}function Ob0(A,Q,B){let w=($)=>B.child($);A.jobs.registerHandler("directory-sync",new Dd(w("DirectorySyncJobHandler"),A,Q)),A.jobs.registerHandler("directory-export",new wd(w("DirectoryExportJobHandler"),A,Q)),A.jobs.registerHandler("directory-import",new $d(w("DirectoryImportJobHandler"),A,Q)),A.jobs.registerHandler("directory-delete",new Id(w("DirectoryDeleteJobHandler"),A,Q)),A.jobs.registerHandler("directory-cleanup",new Yd(w("DirectoryCleanupJobHandler"),Q)),A.jobs.registerHandler("cover-image-convert",new Xd(A,w("CoverImageConversionJobHandler"))),A.jobs.registerHandler("inline-image-convert",new Hd(A,w("InlineImageConversionJobHandler"))),B.debug("Registered async job handlers")}tA();import{unlink as hX2,access as yX2}from"fs/promises";function Rb0(A,Q,B,w){let{subscribe:$}=A.messaging,{entityService:D}=A;$("entity:created",async(I)=>{let{entity:Y}=I.payload;try{await Q.fileOps.writeEntity(Y),B.debug("Auto-exported created entity",{id:Y.id,entityType:Y.entityType})}catch(X){B.error("Auto-export FAILED for created entity",{id:Y.id,entityType:Y.entityType,error:X instanceof Error?X.message:String(X),stack:X instanceof Error?X.stack:void 0})}return{success:!0}}),$("entity:updated",async(I)=>{let{entityType:Y,entityId:X}=I.payload;try{let H=await D.getEntity({entityType:Y,id:X});if(!H)return B.debug("Entity not found in DB, skipping export",{entityType:Y,entityId:X}),{success:!1};await Q.fileOps.writeEntity(H),B.debug("Auto-exported updated entity",{id:H.id,entityType:H.entityType})}catch(H){B.error("Auto-export FAILED for updated entity",{entityType:Y,entityId:X,error:H instanceof Error?H.message:String(H),stack:H instanceof Error?H.stack:void 0})}return{success:!0}}),$("entity:deleted",async(I)=>{let{entityId:Y,entityType:X}=I.payload,H=Q.fileOps.getFilePath(Y,X);if(await yX2(H).then(()=>!0,()=>!1))await hX2(H),B.debug("Auto-deleted entity file",{id:Y,entityType:X,path:H});return{success:!0}}),B.debug("Setup auto-sync for entity events",{entityTypes:w})}function bb0(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:S8(),metadata:{operationType:"file_operations",operationTarget:B,pluginId:"directory-sync"}})})}KA();tA();import{access as mX2,readdir as Pb0,mkdir as uX2,copyFile as cX2}from"fs/promises";import{exec as lX2}from"child_process";import{promisify as pX2}from"util";import{join as GUA,resolve as UUA}from"path";var dX2=pX2(lX2);async function Kd(A){try{return await mX2(A),!0}catch{return!1}}async function iX2(A,Q){if(!await Kd(A))return!0;if((await Pb0(A)).filter(($)=>!$.startsWith(".")&&!$.startsWith("_")).length>0)return!1;if(await rX2(A))return Q.debug("Git repository with remote detected - skipping seed content",{path:A}),!1;return!0}async function rX2(A){let Q=GUA(A,".git");if(!await Kd(Q))return!1;try{let{stdout:B}=await dX2("git remote",{cwd:A});return B.trim().length>0}catch{return!1}}async function kb0(A,Q){let B=await Pb0(A,{withFileTypes:!0});for(let w of B){let $=GUA(A,w.name),D=GUA(Q,w.name);if(w.isDirectory()){if(!await Kd(D))await uX2(D,{recursive:!0});await kb0($,D)}else await cX2($,D)}}async function jb0(A,Q,B){let w=UUA(process.cwd(),A);B=B?UUA(B):UUA(process.cwd(),"seed-content");let $=await iX2(w,Q);if($&&await Kd(B))Q.debug("Copying seed content to brain-data directory"),await kb0(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 _b0(A,Q,B,w,$){let D=!1,I=async()=>{if(D)return;D=!0;let Y=Q();if(B.seedContent){let X=B.syncPath??A.dataDir;await jb0(X,w,B.seedContentPath)}try{if($){w.debug("Git enabled \u2014 pulling before import");let H=await $.pull();if(H.files.length>0)w.info("Pulled changes from remote",{filesChanged:H.files.length})}w.debug("Starting initial sync");let X=await Y.sync();w.debug("Initial sync completed",{imported:X.import.imported,failed:X.import.failed,duration:X.duration}),await A.messaging.send({type:sF.initialSyncCompleted,payload:{success:!0},...{broadcast:!0}})}catch(X){w.error("Initial sync failed",X),await A.messaging.send({type:sF.initialSyncCompleted,payload:{success:!1,error:L0(X)},...{broadcast:!0}})}};A.messaging.subscribe(sF.pluginsRegistered,async()=>{return w.debug("Plugins registered, starting initial sync"),await I(),{success:!0}})}KA();function xb0(A,Q,B,w){let $=new uF(()=>{Q.withLock(async()=>{try{await Q.commit(),await Q.push()}catch(Y){w.error("Git auto-commit failed",{error:Y})}})},B),D=["entity:created","entity:updated","entity:deleted"],I=[];for(let Y of D){let X=A.subscribe(Y,async()=>{return $.trigger(),{success:!0}});I.push(X)}return()=>{$.dispose();for(let Y of I)Y()}}function vb0(A,Q,B,w,$){if(w<=0)return()=>{};let D=w*60*1000,I=!1,Y=async()=>{if(I)return;I=!0;try{let{files:H,result:U}=await A.withLock(async()=>{let F=await A.pull(),Z=await Q.queueSyncBatch(B,"periodic-sync");return{files:F.files,result:Z}});if(H.length>0)$.info("Periodic sync: pulled changes",{filesChanged:H.length});if(U)$.debug("Periodic sync: queued imports",{importOperations:U.importOperationsCount,totalFiles:U.totalFiles})}catch(H){$.error("Periodic git sync failed",{error:H})}finally{I=!1}},X=setInterval(()=>{Y()},D);return $.info("Started periodic git sync",{intervalMinutes:w}),()=>{clearInterval(X)}}import{spawnSync as Sb0}from"child_process";import{cpSync as nX2,existsSync as Tb0,mkdirSync as oX2,mkdtempSync as sX2,rmSync as aX2}from"fs";import{tmpdir as tX2}from"os";import{fileURLToPath as eX2}from"url";import{join as AH2,resolve as QH2}from"path";function rG(A,Q){let B=Sb0("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 BH2(A){return A.startsWith("file://")}function wH2(A){return eX2(A)}function $H2(A,Q){return Sb0("git",["--git-dir",A,"show-ref","--verify","--quiet",`refs/heads/${Q}`]).status===0}async function gb0(A){if(!A.bootstrapFromSeed)return;if(!A.gitUrl||!BH2(A.gitUrl))return;if(!A.seedContentPath)throw Error("directory-sync git.bootstrapFromSeed requires seedContentPath for local file:// remotes");let Q=A.branch??"main",B=wH2(A.gitUrl),w=QH2(A.seedContentPath);if(!Tb0(w))throw Error(`Seed content path not found: ${w}`);if(!Tb0(B))A.logger.debug("Creating local bare content remote",{remotePath:B,branch:Q}),oX2(B,{recursive:!0}),rG(process.cwd(),["init","--bare",`--initial-branch=${Q}`,B]);if($H2(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 $=sX2(AH2(tX2(),"directory-sync-seed-"));try{rG($,["init",`--initial-branch=${Q}`]),rG($,["config","user.name",A.authorName??"Brain"]),rG($,["config","user.email",A.authorEmail??"brain@localhost"]),nX2(w,$,{recursive:!0}),rG($,["add","."]),rG($,["commit","-m","seed content remote"]),rG($,["remote","add","origin",A.gitUrl]),rG($,["push","-u","origin",Q])}finally{aX2($,{recursive:!0,force:!0})}}function hb0(A,Q,B,w,$){let{subscribe:D}=A.messaging;D("entity:export:request",async(I)=>{try{return{success:!0,data:await Q().exportEntities(I.payload.entityTypes)}}catch(Y){return{success:!1,error:Y instanceof Error?Y.message:"Export failed"}}}),D("entity:import:request",async(I)=>{try{let Y=Q(),X=I.payload.paths,H=await Y.importEntities(X);if(X&&X.length>0)await Y.removeOrphanedEntities();return{success:!0,data:H}}catch(Y){return{success:!1,error:Y instanceof Error?Y.message:"Import failed"}}}),D("sync:status:request",async()=>{try{let Y=await Q().getStatus();return{success:!0,data:{syncPath:Y.syncPath,isInitialized:Y.exists,watchEnabled:Y.watching}}}catch(I){return{success:!1,error:I instanceof Error?I.message:"Status check failed"}}}),D("sync:configure:request",async(I)=>{try{return await B({syncPath:I.payload.syncPath}),{success:!0,data:{syncPath:I.payload.syncPath,configured:!0}}}catch(Y){return{success:!1,error:Y instanceof Error?Y.message:"Configuration failed"}}}),D("git-sync:get-repo-info",async()=>{if(!$?.repo)return{success:!1,error:"Git not configured"};return{success:!0,data:{repo:$.repo,branch:$.branch??"main"}}}),w.debug("Registered message handlers")}tA();KA();tA();KA();function yb0(A,Q){return MQ(A,"history","Get version history for an entity from git. Without sha: returns commit list. With sha: returns entity content at that version.",J.object({entityType:J.string().describe("Entity type (e.g. post, note, link)"),id:J.string().describe("Entity ID"),sha:J.string().optional().describe("Commit SHA to retrieve content at. Omit to list commit history."),limit:J.number().int().positive().optional().default(10).describe("Max commits to return (list mode only)")}),async(B)=>{let w=`${B.entityType}/${B.id}.md`;try{if(B.sha){let D=await Q.show(B.sha,w);return _6({sha:B.sha,entityType:B.entityType,id:B.id,content:D},`Content at ${B.sha.slice(0,7)}`)}let $=await Q.log(w,B.limit);if($.length===0)return _6({commits:[]},`No history found for ${B.entityType}/${B.id}`);return _6({commits:$,entityType:B.entityType,id:B.id},`${$.length} version${$.length===1?"":"s"} found`)}catch($){return k5($ instanceof Error?$.message:"History lookup failed")}})}function mb0(A,Q,B,w){let $=[MQ(B,"sync","Sync brain entities with the filesystem. Use this for refresh, pull, sync, or backup-to-git requests. Pulls from git if configured, then imports files. Git commit and push happen automatically after imports complete.",J.object({}),async(D,I)=>{try{let Y=I.channelId?`${I.interfaceType}:${I.channelId}`:`plugin:${B}`,X={interfaceType:I.interfaceType,channelId:I.channelId},H=w!==void 0,U=()=>A.queueSyncBatch(Q,Y,X),F=w?await w.withLock(async()=>{return await w.pull(),U()}):await U();if(!F)return _6({gitPulled:H},"No files to sync");return _6({batchId:F.batchId,importOperations:F.importOperationsCount,totalFiles:F.totalFiles,gitPulled:H},`Sync started: ${F.importOperationsCount} import jobs queued for ${F.totalFiles} files${H?" (pulled from git)":""}`)}catch(Y){return k5(Y instanceof Error?Y.message:"Sync failed")}},{cli:{name:"sync"}}),MQ(B,"status","Get sync and git repository status \u2014 last sync time, watching state, pending git changes. Use this for status questions, not for actually syncing or backing up.",J.object({}),async()=>{try{let D=await A.getStatus(),I={syncPath:D.syncPath,lastSync:D.lastSync?.toISOString(),watching:D.watching};if(w){let Y=await w.getStatus();I.git={isRepo:Y.isRepo,branch:Y.branch,hasChanges:Y.hasChanges,ahead:Y.ahead,behind:Y.behind,remote:Y.remote}}return _6(I)}catch(D){return k5(D instanceof Error?D.message:"Status check failed")}},{visibility:"public"})];if(w)$.push(yb0(B,w));return $}var ub0={name:"@brains/directory-sync",private:!0,version:"0.2.0-alpha.54",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/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 JUA extends Bw{directorySync;gitSync;gitCleanups=[];constructor(A={}){super("directory-sync",ub0,A,Kj)}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:Wj,basePrompt:"",formatter:new Bd,requiredPermission:"anchor"}});let w=this.config.syncPath??A.dataDir;this.directorySync=new ek({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(Rb0(A,$,this.logger,this.config.entityTypes),this.config.autoSync)bb0(A,$,this.config.syncPath??A.dataDir);let D=this.config.git!==void 0&&(this.config.git.repo!==void 0||this.config.git.gitUrl!==void 0);if(this.config.git&&!D)this.logger.debug("Git block present but no repo/gitUrl configured \u2014 git sync disabled");if(D&&this.config.git){await gb0({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 IUA({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(xb0(A.messaging,this.gitSync,this.config.commitDebounce,this.logger.child("GitAutoCommit"))),this.config.autoSync)this.gitCleanups.push(vb0(this.gitSync,this.requireDirectorySync(),A,this.config.syncInterval,this.logger.child("GitPeriodicSync")))}if(this.config.initialSync)_b0(A,()=>this.requireDirectorySync(),this.config,this.logger,this.gitSync);hb0(A,()=>this.requireDirectorySync(),(I)=>this.configure(I),this.logger,this.config.git)}async getTools(){let A=this.requireDirectorySync();return mb0(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 ek({...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){Ob0(A,this.requireDirectorySync(),this.logger)}}function h3(A={}){return new JUA(A)}tA();import{render as xm0}from"preact-render-to-string";import{h as Zz}from"preact";function cb0(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=cb0(A[Q]))&&(w&&(w+=" "),w+=B)}else for(B in A)A[B]&&(w&&(w+=" "),w+=B);return w}function _C(){for(var A,Q,B=0,w="",$=arguments.length;B<$;B++)(A=arguments[B])&&(Q=cb0(A))&&(w&&(w+=" "),w+=Q);return w}var IH2=(A)=>{let Q=XH2(A),{conflictingClassGroups:B,conflictingClassGroupModifiers:w}=A;return{getClassGroupId:(I)=>{let Y=I.split("-");if(Y[0]===""&&Y.length!==1)Y.shift();return rb0(Y,Q)||YH2(I)},getConflictingClassGroupIds:(I,Y)=>{let X=B[I]||[];if(Y&&w[I])return[...X,...w[I]];return X}}},rb0=(A,Q)=>{if(A.length===0)return Q.classGroupId;let B=A[0],w=Q.nextPart.get(B),$=w?rb0(A.slice(1),w):void 0;if($)return $;if(Q.validators.length===0)return;let D=A.join("-");return Q.validators.find(({validator:I})=>I(D))?.classGroupId},lb0=/^\[(.+)\]$/,YH2=(A)=>{if(lb0.test(A)){let Q=lb0.exec(A)[1],B=Q?.substring(0,Q.indexOf(":"));if(B)return"arbitrary.."+B}},XH2=(A)=>{let{theme:Q,prefix:B}=A,w={nextPart:new Map,validators:[]};return KH2(Object.entries(A.classGroups),B).forEach(([D,I])=>{ZUA(I,w,D,Q)}),w},ZUA=(A,Q,B,w)=>{A.forEach(($)=>{if(typeof $==="string"){let D=$===""?Q:pb0(Q,$);D.classGroupId=B;return}if(typeof $==="function"){if(HH2($)){ZUA($(w),Q,B,w);return}Q.validators.push({validator:$,classGroupId:B});return}Object.entries($).forEach(([D,I])=>{ZUA(I,pb0(Q,D),B,w)})})},pb0=(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},HH2=(A)=>A.isThemeGetter,KH2=(A,Q)=>{if(!Q)return A;return A.map(([B,w])=>{let $=w.map((D)=>{if(typeof D==="string")return Q+D;if(typeof D==="object")return Object.fromEntries(Object.entries(D).map(([I,Y])=>[Q+I,Y]));return D});return[B,$]})},WH2=(A)=>{if(A<1)return{get:()=>{return},set:()=>{}};let Q=0,B=new Map,w=new Map,$=(D,I)=>{if(B.set(D,I),Q++,Q>A)Q=0,w=B,B=new Map};return{get(D){let I=B.get(D);if(I!==void 0)return I;if((I=w.get(D))!==void 0)return $(D,I),I},set(D,I){if(B.has(D))B.set(D,I);else $(D,I)}}};var UH2=(A)=>{let{separator:Q,experimentalParseClassName:B}=A,w=Q.length===1,$=Q[0],D=Q.length,I=(Y)=>{let X=[],H=0,U=0,F;for(let C=0;C<Y.length;C++){let P=Y[C];if(H===0){if(P===$&&(w||Y.slice(C,C+D)===Q)){X.push(Y.slice(U,C)),U=C+D;continue}if(P==="/"){F=C;continue}}if(P==="[")H++;else if(P==="]")H--}let Z=X.length===0?Y:Y.substring(U),z=Z.startsWith("!"),f=z?Z.substring(1):Z,E=F&&F>U?F-U:void 0;return{modifiers:X,hasImportantModifier:z,baseClassName:f,maybePostfixModifierPosition:E}};if(B)return(Y)=>B({className:Y,parseClassName:I});return I},GH2=(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},JH2=(A)=>({cache:WH2(A.cacheSize),parseClassName:UH2(A),...IH2(A)}),FH2=/\s+/,ZH2=(A,Q)=>{let{parseClassName:B,getClassGroupId:w,getConflictingClassGroupIds:$}=Q,D=[],I=A.trim().split(FH2),Y="";for(let X=I.length-1;X>=0;X-=1){let H=I[X],{modifiers:U,hasImportantModifier:F,baseClassName:Z,maybePostfixModifierPosition:z}=B(H),f=Boolean(z),E=w(f?Z.substring(0,z):Z);if(!E){if(!f){Y=H+(Y.length>0?" "+Y:Y);continue}if(E=w(Z),!E){Y=H+(Y.length>0?" "+Y:Y);continue}f=!1}let C=GH2(U).join(":"),P=F?C+"!":C,x=P+E;if(D.includes(x))continue;D.push(x);let k=$(E,f);for(let o=0;o<k.length;++o){let r=k[o];D.push(P+r)}Y=H+(Y.length>0?" "+Y:Y)}return Y};function zH2(){let A=0,Q,B,w="";while(A<arguments.length)if(Q=arguments[A++]){if(B=nb0(Q))w&&(w+=" "),w+=B}return w}var nb0=(A)=>{if(typeof A==="string")return A;let Q,B="";for(let w=0;w<A.length;w++)if(A[w]){if(Q=nb0(A[w]))B&&(B+=" "),B+=Q}return B};function db0(A,...Q){let B,w,$,D=I;function I(X){let H=Q.reduce((U,F)=>F(U),A());return B=JH2(H),w=B.cache.get,$=B.cache.set,D=Y,Y(X)}function Y(X){let H=w(X);if(H)return H;let U=ZH2(X,B);return $(X,U),U}return function(){return D(zH2.apply(null,arguments))}}var Vw=(A)=>{let Q=(B)=>B[A]||[];return Q.isThemeGetter=!0,Q},ob0=/^\[(?:([a-z-]+):)?(.+)\]$/i,qH2=/^\d+\/\d+$/,NH2=new Set(["px","full","screen"]),fH2=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,LH2=/\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$/,CH2=/^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/,EH2=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,MH2=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,pK=(A)=>xC(A)||NH2.has(A)||qH2.test(A),nG=(A)=>vC(A,"length",_H2),xC=(A)=>Boolean(A)&&!Number.isNaN(Number(A)),FUA=(A)=>vC(A,"number",xC),Uj=(A)=>Boolean(A)&&Number.isInteger(Number(A)),VH2=(A)=>A.endsWith("%")&&xC(A.slice(0,-1)),XQ=(A)=>ob0.test(A),oG=(A)=>fH2.test(A),OH2=new Set(["length","size","percentage"]),RH2=(A)=>vC(A,OH2,sb0),bH2=(A)=>vC(A,"position",sb0),PH2=new Set(["image","url"]),kH2=(A)=>vC(A,PH2,vH2),jH2=(A)=>vC(A,"",xH2),Gj=()=>!0,vC=(A,Q,B)=>{let w=ob0.exec(A);if(w){if(w[1])return typeof Q==="string"?w[1]===Q:Q.has(w[1]);return B(w[2])}return!1},_H2=(A)=>LH2.test(A)&&!CH2.test(A),sb0=()=>!1,xH2=(A)=>EH2.test(A),vH2=(A)=>MH2.test(A);var ib0=()=>{let A=Vw("colors"),Q=Vw("spacing"),B=Vw("blur"),w=Vw("brightness"),$=Vw("borderColor"),D=Vw("borderRadius"),I=Vw("borderSpacing"),Y=Vw("borderWidth"),X=Vw("contrast"),H=Vw("grayscale"),U=Vw("hueRotate"),F=Vw("invert"),Z=Vw("gap"),z=Vw("gradientColorStops"),f=Vw("gradientColorStopPositions"),E=Vw("inset"),C=Vw("margin"),P=Vw("opacity"),x=Vw("padding"),k=Vw("saturate"),o=Vw("scale"),r=Vw("sepia"),u=Vw("skew"),v=Vw("space"),S=Vw("translate"),h=()=>["auto","contain","none"],t=()=>["auto","hidden","clip","visible","scroll"],l=()=>["auto",XQ,Q],UA=()=>[XQ,Q],YA=()=>["",pK,nG],b=()=>["auto",xC,XQ],R=()=>["bottom","center","left","left-bottom","left-top","right","right-bottom","right-top","top"],j=()=>["solid","dashed","dotted","double","none"],s=()=>["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"],e=()=>["","0",XQ],i=()=>["auto","avoid","all","avoid-page","page","left","right","column"],WA=()=>[xC,XQ];return{cacheSize:500,separator:":",theme:{colors:[Gj],spacing:[pK,nG],blur:["none","",oG,XQ],brightness:WA(),borderColor:[A],borderRadius:["none","","full",oG,XQ],borderSpacing:UA(),borderWidth:YA(),contrast:WA(),grayscale:e(),hueRotate:WA(),invert:e(),gap:UA(),gradientColorStops:[A],gradientColorStopPositions:[VH2,nG],inset:l(),margin:l(),opacity:WA(),padding:UA(),saturate:WA(),scale:WA(),sepia:e(),skew:WA(),space:UA(),translate:UA()},classGroups:{aspect:[{aspect:["auto","square","video",XQ]}],container:["container"],columns:[{columns:[oG]}],"break-after":[{"break-after":i()}],"break-before":[{"break-before":i()}],"break-inside":[{"break-inside":["auto","avoid","avoid-page","avoid-column"]}],"box-decoration":[{"box-decoration":["slice","clone"]}],box:[{box:["border","content"]}],display:["block","inline-block","inline","flex","inline-flex","table","inline-table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row-group","table-row","flow-root","grid","inline-grid","contents","list-item","hidden"],float:[{float:["right","left","none","start","end"]}],clear:[{clear:["left","right","both","none","start","end"]}],isolation:["isolate","isolation-auto"],"object-fit":[{object:["contain","cover","fill","none","scale-down"]}],"object-position":[{object:[...R(),XQ]}],overflow:[{overflow:t()}],"overflow-x":[{"overflow-x":t()}],"overflow-y":[{"overflow-y":t()}],overscroll:[{overscroll:h()}],"overscroll-x":[{"overscroll-x":h()}],"overscroll-y":[{"overscroll-y":h()}],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",Uj,XQ]}],basis:[{basis:l()}],"flex-direction":[{flex:["row","row-reverse","col","col-reverse"]}],"flex-wrap":[{flex:["wrap","wrap-reverse","nowrap"]}],flex:[{flex:["1","auto","initial","none",XQ]}],grow:[{grow:e()}],shrink:[{shrink:e()}],order:[{order:["first","last","none",Uj,XQ]}],"grid-cols":[{"grid-cols":[Gj]}],"col-start-end":[{col:["auto",{span:["full",Uj,XQ]},XQ]}],"col-start":[{"col-start":b()}],"col-end":[{"col-end":b()}],"grid-rows":[{"grid-rows":[Gj]}],"row-start-end":[{row:["auto",{span:[Uj,XQ]},XQ]}],"row-start":[{"row-start":b()}],"row-end":[{"row-end":b()}],"grid-flow":[{"grid-flow":["row","col","dense","row-dense","col-dense"]}],"auto-cols":[{"auto-cols":["auto","min","max","fr",XQ]}],"auto-rows":[{"auto-rows":["auto","min","max","fr",XQ]}],gap:[{gap:[Z]}],"gap-x":[{"gap-x":[Z]}],"gap-y":[{"gap-y":[Z]}],"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:[x]}],px:[{px:[x]}],py:[{py:[x]}],ps:[{ps:[x]}],pe:[{pe:[x]}],pt:[{pt:[x]}],pr:[{pr:[x]}],pb:[{pb:[x]}],pl:[{pl:[x]}],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":[v]}],"space-x-reverse":["space-x-reverse"],"space-y":[{"space-y":[v]}],"space-y-reverse":["space-y-reverse"],w:[{w:["auto","min","max","fit","svw","lvw","dvw",XQ,Q]}],"min-w":[{"min-w":[XQ,Q,"min","max","fit"]}],"max-w":[{"max-w":[XQ,Q,"none","full","min","max","fit","prose",{screen:[oG]},oG]}],h:[{h:[XQ,Q,"auto","min","max","fit","svh","lvh","dvh"]}],"min-h":[{"min-h":[XQ,Q,"min","max","fit","svh","lvh","dvh"]}],"max-h":[{"max-h":[XQ,Q,"min","max","fit","svh","lvh","dvh"]}],size:[{size:[XQ,Q,"auto","min","max","fit"]}],"font-size":[{text:["base",oG,nG]}],"font-smoothing":["antialiased","subpixel-antialiased"],"font-style":["italic","not-italic"],"font-weight":[{font:["thin","extralight","light","normal","medium","semibold","bold","extrabold","black",FUA]}],"font-family":[{font:[Gj]}],"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",XQ]}],"line-clamp":[{"line-clamp":["none",xC,FUA]}],leading:[{leading:["none","tight","snug","normal","relaxed","loose",pK,XQ]}],"list-image":[{"list-image":["none",XQ]}],"list-style-type":[{list:["none","disc","decimal",XQ]}],"list-style-position":[{list:["inside","outside"]}],"placeholder-color":[{placeholder:[A]}],"placeholder-opacity":[{"placeholder-opacity":[P]}],"text-alignment":[{text:["left","center","right","justify","start","end"]}],"text-color":[{text:[A]}],"text-opacity":[{"text-opacity":[P]}],"text-decoration":["underline","overline","line-through","no-underline"],"text-decoration-style":[{decoration:[...j(),"wavy"]}],"text-decoration-thickness":[{decoration:["auto","from-font",pK,nG]}],"underline-offset":[{"underline-offset":["auto",pK,XQ]}],"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:UA()}],"vertical-align":[{align:["baseline","top","middle","bottom","text-top","text-bottom","sub","super",XQ]}],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",XQ]}],"bg-attachment":[{bg:["fixed","local","scroll"]}],"bg-clip":[{"bg-clip":["border","padding","content","text"]}],"bg-opacity":[{"bg-opacity":[P]}],"bg-origin":[{"bg-origin":["border","padding","content"]}],"bg-position":[{bg:[...R(),bH2]}],"bg-repeat":[{bg:["no-repeat",{repeat:["","x","y","round","space"]}]}],"bg-size":[{bg:["auto","cover","contain",RH2]}],"bg-image":[{bg:["none",{"gradient-to":["t","tr","r","br","b","bl","l","tl"]},kH2]}],"bg-color":[{bg:[A]}],"gradient-from-pos":[{from:[f]}],"gradient-via-pos":[{via:[f]}],"gradient-to-pos":[{to:[f]}],"gradient-from":[{from:[z]}],"gradient-via":[{via:[z]}],"gradient-to":[{to:[z]}],rounded:[{rounded:[D]}],"rounded-s":[{"rounded-s":[D]}],"rounded-e":[{"rounded-e":[D]}],"rounded-t":[{"rounded-t":[D]}],"rounded-r":[{"rounded-r":[D]}],"rounded-b":[{"rounded-b":[D]}],"rounded-l":[{"rounded-l":[D]}],"rounded-ss":[{"rounded-ss":[D]}],"rounded-se":[{"rounded-se":[D]}],"rounded-ee":[{"rounded-ee":[D]}],"rounded-es":[{"rounded-es":[D]}],"rounded-tl":[{"rounded-tl":[D]}],"rounded-tr":[{"rounded-tr":[D]}],"rounded-br":[{"rounded-br":[D]}],"rounded-bl":[{"rounded-bl":[D]}],"border-w":[{border:[Y]}],"border-w-x":[{"border-x":[Y]}],"border-w-y":[{"border-y":[Y]}],"border-w-s":[{"border-s":[Y]}],"border-w-e":[{"border-e":[Y]}],"border-w-t":[{"border-t":[Y]}],"border-w-r":[{"border-r":[Y]}],"border-w-b":[{"border-b":[Y]}],"border-w-l":[{"border-l":[Y]}],"border-opacity":[{"border-opacity":[P]}],"border-style":[{border:[...j(),"hidden"]}],"divide-x":[{"divide-x":[Y]}],"divide-x-reverse":["divide-x-reverse"],"divide-y":[{"divide-y":[Y]}],"divide-y-reverse":["divide-y-reverse"],"divide-opacity":[{"divide-opacity":[P]}],"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":[pK,XQ]}],"outline-w":[{outline:[pK,nG]}],"outline-color":[{outline:[A]}],"ring-w":[{ring:YA()}],"ring-w-inset":["ring-inset"],"ring-color":[{ring:[A]}],"ring-opacity":[{"ring-opacity":[P]}],"ring-offset-w":[{"ring-offset":[pK,nG]}],"ring-offset-color":[{"ring-offset":[A]}],shadow:[{shadow:["","inner","none",oG,jH2]}],"shadow-color":[{shadow:[Gj]}],opacity:[{opacity:[P]}],"mix-blend":[{"mix-blend":[...s(),"plus-lighter","plus-darker"]}],"bg-blend":[{"bg-blend":s()}],filter:[{filter:["","none"]}],blur:[{blur:[B]}],brightness:[{brightness:[w]}],contrast:[{contrast:[X]}],"drop-shadow":[{"drop-shadow":["","none",oG,XQ]}],grayscale:[{grayscale:[H]}],"hue-rotate":[{"hue-rotate":[U]}],invert:[{invert:[F]}],saturate:[{saturate:[k]}],sepia:[{sepia:[r]}],"backdrop-filter":[{"backdrop-filter":["","none"]}],"backdrop-blur":[{"backdrop-blur":[B]}],"backdrop-brightness":[{"backdrop-brightness":[w]}],"backdrop-contrast":[{"backdrop-contrast":[X]}],"backdrop-grayscale":[{"backdrop-grayscale":[H]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[U]}],"backdrop-invert":[{"backdrop-invert":[F]}],"backdrop-opacity":[{"backdrop-opacity":[P]}],"backdrop-saturate":[{"backdrop-saturate":[k]}],"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",XQ]}],duration:[{duration:WA()}],ease:[{ease:["linear","in","out","in-out",XQ]}],delay:[{delay:WA()}],animate:[{animate:["none","spin","ping","pulse","bounce",XQ]}],transform:[{transform:["","gpu","none"]}],scale:[{scale:[o]}],"scale-x":[{"scale-x":[o]}],"scale-y":[{"scale-y":[o]}],rotate:[{rotate:[Uj,XQ]}],"translate-x":[{"translate-x":[S]}],"translate-y":[{"translate-y":[S]}],"skew-x":[{"skew-x":[u]}],"skew-y":[{"skew-y":[u]}],"transform-origin":[{origin:["center","top","top-right","right","bottom-right","bottom","bottom-left","left","top-left",XQ]}],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",XQ]}],"caret-color":[{caret:[A]}],"pointer-events":[{"pointer-events":["none","auto"]}],resize:[{resize:["none","y","x",""]}],"scroll-behavior":[{scroll:["auto","smooth"]}],"scroll-m":[{"scroll-m":UA()}],"scroll-mx":[{"scroll-mx":UA()}],"scroll-my":[{"scroll-my":UA()}],"scroll-ms":[{"scroll-ms":UA()}],"scroll-me":[{"scroll-me":UA()}],"scroll-mt":[{"scroll-mt":UA()}],"scroll-mr":[{"scroll-mr":UA()}],"scroll-mb":[{"scroll-mb":UA()}],"scroll-ml":[{"scroll-ml":UA()}],"scroll-p":[{"scroll-p":UA()}],"scroll-px":[{"scroll-px":UA()}],"scroll-py":[{"scroll-py":UA()}],"scroll-ps":[{"scroll-ps":UA()}],"scroll-pe":[{"scroll-pe":UA()}],"scroll-pt":[{"scroll-pt":UA()}],"scroll-pr":[{"scroll-pr":UA()}],"scroll-pb":[{"scroll-pb":UA()}],"scroll-pl":[{"scroll-pl":UA()}],"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",XQ]}],fill:[{fill:[A,"none"]}],"stroke-w":[{stroke:[pK,nG,FUA]}],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"]}}},TH2=(A,{cacheSize:Q,prefix:B,separator:w,experimentalParseClassName:$,extend:D={},override:I={}})=>{Jj(A,"cacheSize",Q),Jj(A,"prefix",B),Jj(A,"separator",w),Jj(A,"experimentalParseClassName",$);for(let Y in I)SH2(A[Y],I[Y]);for(let Y in D)gH2(A[Y],D[Y]);return A},Jj=(A,Q,B)=>{if(B!==void 0)A[Q]=B},SH2=(A,Q)=>{if(Q)for(let B in Q)Jj(A,B,Q[B])},gH2=(A,Q)=>{if(Q)for(let B in Q){let w=Q[B];if(w!==void 0)A[B]=(A[B]||[]).concat(w)}},Wd=(A,...Q)=>typeof A==="function"?db0(ib0,A,...Q):db0(()=>TH2(ib0(),A),...Q);var hH2=Wd({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 m1(...A){return hH2(_C(A))}var ab0=(A)=>typeof A==="boolean"?`${A}`:A===0?"0":A,tb0=_C,cB=(A,Q)=>(B)=>{var w;if((Q===null||Q===void 0?void 0:Q.variants)==null)return tb0(A,B===null||B===void 0?void 0:B.class,B===null||B===void 0?void 0:B.className);let{variants:$,defaultVariants:D}=Q,I=Object.keys($).map((H)=>{let U=B===null||B===void 0?void 0:B[H],F=D===null||D===void 0?void 0:D[H];if(U===null)return null;let Z=ab0(U)||ab0(F);return $[H][Z]}),Y=B&&Object.entries(B).reduce((H,U)=>{let[F,Z]=U;if(Z===void 0)return H;return H[F]=Z,H},{}),X=Q===null||Q===void 0?void 0:(w=Q.compoundVariants)===null||w===void 0?void 0:w.reduce((H,U)=>{let{class:F,className:Z,...z}=U;return Object.entries(z).every((f)=>{let[E,C]=f;return Array.isArray(C)?C.includes({...D,...Y}[E]):{...D,...Y}[E]===C})?[...H,F,Z]:H},[]);return tb0(A,I,X,B===null||B===void 0?void 0:B.class,B===null||B===void 0?void 0:B.className)};import{jsxDEV as zUA}from"preact/jsx-dev-runtime";var eb0=cB("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 qUA({variant:A,title:Q,children:B,className:w}){return zUA("div",{className:m1(eb0({variant:A}),w),role:"alert",children:[Q&&zUA("p",{className:"font-medium text-current opacity-90",children:Q},void 0,!1,void 0,this),zUA("div",{className:m1(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 yH2}from"preact/jsx-dev-runtime";var AP0=cB("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 y3({variant:A,size:Q,className:B,children:w,ssrOnClick:$,type:D="button",...I}){return yH2("button",{type:D,className:m1(AP0({variant:A,size:Q}),B),...I,...$&&{onclick:$},children:w},void 0,!1,void 0,this)}import{jsxDEV as mH2}from"preact/jsx-dev-runtime";var QP0=cB("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 h6({href:A,children:Q,variant:B,size:w,external:$=!1,className:D,"aria-label":I}){let Y=$?{target:"_blank",rel:"noopener noreferrer"}:{};return mH2("a",{href:A,className:m1(QP0({variant:B,size:w}),D),"aria-label":I,...Y,children:Q},void 0,!1,void 0,this)}import{jsxDEV as Ud}from"preact/jsx-dev-runtime";var BP0=cB("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"}}),uH2={sm:"w-4 h-4",md:"w-5 h-5",lg:"w-6 h-6"};function TC({variant:A,size:Q,className:B}){let w=uH2[Q??"md"];return Ud("button",{onclick:"toggleTheme()",type:"button",className:m1(BP0({variant:A,size:Q}),B),"aria-label":"Toggle dark mode",children:Ud("svg",{className:m1(w,"transition-colors"),fill:"none",stroke:"currentColor",strokeWidth:1.6,viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:[Ud("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),Ud("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 NUA}from"preact/jsx-dev-runtime";var wP0=cB("flex flex-wrap",{variants:{orientation:{horizontal:"justify-center gap-6 items-center",vertical:"flex-col gap-2.5"}},defaultVariants:{orientation:"horizontal"}});function Gd({items:A,className:Q,linkClassName:B="hover:text-accent transition-colors",orientation:w,children:$}){if(A.length===0&&!$)return null;let D=[...A].sort((I,Y)=>I.priority-Y.priority);return NUA("ul",{className:m1(wP0({orientation:w}),Q),children:[D.map((I)=>NUA("li",{children:NUA("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 L2B}from"preact/jsx-dev-runtime";import{jsxDEV as M2B}from"preact/jsx-dev-runtime";KA();KA();import{createContext as cH2,h as lH2}from"preact";import{useContext as pH2}from"preact/hooks";var $P0=cH2(null);function Jd({imageRenderer:A,children:Q}){return lH2($P0.Provider,{value:A??null},Q)}function DP0(){return pH2($P0)}function m3(){let A=DP0();return(Q)=>rT(Q,A?{imageRenderer:A}:void 0)}import{jsxDEV as dK}from"preact/jsx-dev-runtime";var fUA=({markdown:A})=>{let Q=m3(),w=A.split(/^---$/gm).map((I)=>I.trim()).map((I)=>{let{attributes:Y,markdown:X}=FS(I),H=ZS(X),U;if(H)U=`<div class="slide-columns">${H.map((Z)=>`<div class="slide-column">${sV(Q(Z.trim()))}</div>`).join("")}</div>`;else U=sV(Q(X));return{attributes:Y,htmlContent:U}}),$=w.some((I)=>I.htmlContent.includes('class="mermaid"')),D=w.map(({attributes:I,htmlContent:Y},X)=>dK("section",{...I,dangerouslySetInnerHTML:{__html:Y}},X,!1,void 0,this));return dK("section",{className:"presentation-section",children:[dK("link",{rel:"stylesheet",href:"https://cdn.jsdelivr.net/npm/reveal.js@5.1.0/dist/reveal.min.css"},void 0,!1,void 0,this),dK("div",{className:"reveal",children:dK("div",{className:"slides",children:D},void 0,!1,void 0,this)},void 0,!1,void 0,this),dK("script",{src:"https://cdn.jsdelivr.net/npm/reveal.js@5.1.0/dist/reveal.min.js",defer:!0},void 0,!1,void 0,this),$&&dK("script",{src:"https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js",defer:!0},void 0,!1,void 0,this),dK("script",{dangerouslySetInnerHTML:{__html:`
|
|
1816
1816
|
window.addEventListener('DOMContentLoaded', () => {
|
|
1817
1817
|
if (window.Reveal) {
|
|
1818
1818
|
window.Reveal.initialize({
|
|
@@ -2653,13 +2653,13 @@ ${A.map((D)=>({url:`${Q}${D.path}`,lastmod:B,changefreq:D.path==="/"?"daily":"we
|
|
|
2653
2653
|
`+$:B,I=iX(this.outputDir,"styles","main.css");await this.cssProcessor.process(D,I,this.workingDir,this.outputDir,this.logger);let Y=await d5.readFile(I,"utf-8"),X=w.length>0?w:Q;if(X.length>0){let H=X.join(`
|
|
2654
2654
|
`)+`
|
|
2655
2655
|
|
|
2656
|
-
`+Y;await d5.writeFile(I,H,"utf-8")}this.logger.debug("CSS processed successfully with font imports")}async copyStaticAssets(){this.logger.debug("Copying static assets from public/ directory");let A=iX(process.cwd(),"public");try{await d5.access(A)}catch{this.logger.debug("No public/ directory found, skipping static assets");return}let Q=await d5.readdir(A,{withFileTypes:!0});for(let B of Q){let w=iX(A,B.name),$=iX(this.outputDir,B.name);if(B.isDirectory())await this.copyDirectory(w,$);else await d5.copyFile(w,$),this.logger.debug(`Copied static asset: ${B.name}`)}this.logger.debug("Static assets copied successfully")}async writeInlineStaticAssets(A){if(!A)return;let Q=Object.entries(A);if(Q.length===0)return;this.logger.debug(`Writing ${Q.length} inline static asset(s) from SitePackage`),await Promise.all(Q.map(async([B,w])=>{let $=B.startsWith("/")?B.slice(1):B,D=iX(this.outputDir,$);await d5.mkdir(vO2(D),{recursive:!0}),await d5.writeFile(D,w,"utf-8"),this.logger.debug(`Wrote inline static asset: ${$}`)}))}async copyDirectory(A,Q){await d5.mkdir(Q,{recursive:!0});let B=await d5.readdir(A,{withFileTypes:!0});for(let w of B){let $=iX(A,w.name),D=iX(Q,w.name);if(w.isDirectory())await this.copyDirectory($,D);else await d5.copyFile($,D)}}}function _FA(A){return new vm0(A)}KA();KA();KA();r$();var Tm0=J.object({environment:J.enum(["preview","production"]),outputDir:J.string(),workingDir:J.string().optional(),sharedImagesDir:J.string().default("./dist/images"),enableContentGeneration:J.boolean().default(!1),cleanBeforeBuild:J.boolean().default(!0),siteConfig:t7,layouts:J.record(J.any()),themeCSS:J.string().optional()}),$IB=J.object({success:J.boolean(),outputDir:J.string(),filesGenerated:J.number(),routesBuilt:J.number(),errors:J.array(J.string()).optional(),warnings:J.array(J.string()).optional()});function Sm0(A){let Q=A.list(),B=Q.length===0?["No routes registered for site build"]:[];return{routes:Q,warnings:B}}function gm0(A,Q,B){let w=Q.getProfile(),$=B.getNavigationItems("primary"),D=B.getNavigationItems("secondary");return{...A,...w.socialLinks!==void 0&&{socialLinks:w.socialLinks},navigation:{primary:$,secondary:D},copyright:A.copyright??"Powered by Rizom"}}KA();KA();var TO2=J.object({id:J.string(),entityType:J.string(),content:J.string(),metadata:J.object({slug:J.string()}).passthrough()}).passthrough(),SO2=J.object({content:J.string(),metadata:J.object({width:J.number().optional(),height:J.number().optional()}).passthrough()});async function br(A,Q){let B=Q.urlGenerator??P5.getInstance();if(A===null||A===void 0)return A;if(Array.isArray(A))return Promise.all(A.map((k)=>br(k,{...Q,urlGenerator:B})));if(typeof A!=="object")return A;let w={},$=Object.entries(A),D=await Promise.all($.map(([,k])=>br(k,{...Q,urlGenerator:B})));for(let k=0;k<$.length;k++){let o=$[k];if(o)w[o[0]]=D[k]}let I=TO2.safeParse(A);if(!I.success)return w;let Y=I.data,X=Y.entityType,H=Y.metadata.slug,U=Q.pipelineContext.entityDisplay?.[X],F=U?U.label:X.charAt(0).toUpperCase()+X.slice(1),Z=U?U.pluralName??U.label.toLowerCase()+"s":S7(X),z=`/${Z}`,f=Z.charAt(0).toUpperCase()+Z.slice(1),E=SV(Y)??void 0,C=E?Q.imageBuildService?.get(E):void 0,P={};if(C)P={coverImageUrl:C.src,coverImageWidth:C.width,coverImageHeight:C.height,...C.srcset&&{coverImageSrcset:C.srcset,coverImageSizes:C.sizes}};else{let k=await gO2(E,Q.pipelineContext.services.entityService);if(k)P={coverImageUrl:k.url,...k.width&&{coverImageWidth:k.width},...k.height&&{coverImageHeight:k.height}}}return{...w,...Y,url:B.generateUrl(X,H),typeLabel:F,listUrl:z,listLabel:f,...P}}async function gO2(A,Q){if(!A)return;let B=await Q.getEntity({entityType:"image",id:A}),w=SO2.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 hm0(A,Q){let B=new Set;try{let w=A.getEntityTypes();for(let $ of w){if($==="image")continue;let D=await A.listEntities({entityType:$});for(let I of D){let Y=SV(I);if(Y)B.add(Y)}}}catch(w){Q.warn("Failed to collect image IDs for pre-resolution",{error:L0(w)})}return[...B]}async function ym0(A,Q,B,w){if(!A.template)return A.content??null;let $=A.template,D=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($,D);if(!I)return null;return br(I,{pipelineContext:w.pipelineContext,imageBuildService:w.imageBuildService,urlGenerator:P5.getInstance()})}function mm0(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 ym0(B,Q,w,{pipelineContext:A.pipelineContext,imageBuildService:A.imageBuildService})},getViewTemplate:(Q)=>{return A.pipelineContext.services.getViewTemplate(Q)},layouts:A.parsedOptions.layouts,getSiteLayoutInfo:async()=>{return gm0(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 hO2}from"path";async function um0(A){let Q=A.parsedOptions.workingDir??hO2(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 cm0(A){await new Or({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 lm0(A){let Q=new Vr(A.pipelineContext.services.entityService,A.pipelineContext.logger,A.sharedImagesDir),B=await hm0(A.pipelineContext.services.entityService,A.pipelineContext.logger);if(B.length>0)await Q.resolveAll(B);return Q}async function pm0(A){let Q=A.reporter?.createSub({scale:{start:85,end:95}});await A.staticSiteBuilder.build(A.buildContext,(B)=>{Q?.report(B).catch(()=>{})})}function dm0(A){return{success:!0,outputDir:A.outputDir,filesGenerated:A.routesBuilt+1,routesBuilt:A.routesBuilt,...A.warnings.length>0&&{warnings:A.warnings}}}function im0(A){return{success:!1,outputDir:A.outputDir,filesGenerated:0,routesBuilt:0,errors:[A.errorMessage]}}async function rm0(A){let Q=Tm0.parse(A.buildOptions),B=T8.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 cm0({pipelineContext:A.pipelineContext});let $=await um0({logger:A.pipelineContext.logger,parsedOptions:Q,staticSiteBuilderFactory:A.staticSiteBuilderFactory}),D=Sm0(A.pipelineContext.routeRegistry);w.push(...D.warnings);let{routes:I}=D;await B?.report({message:`Building ${I.length} routes`,progress:20,total:100}),await B?.report({message:"Resolving images",progress:25,total:100});let Y=await lm0({pipelineContext:A.pipelineContext,sharedImagesDir:Q.sharedImagesDir}),X=mm0({routes:I,parsedOptions:Q,buildOptions:A.buildOptions,pipelineContext:A.pipelineContext,imageBuildService:Y,siteMetadata:Q.siteConfig});return await pm0({staticSiteBuilder:$,buildContext:X,reporter:B}),await B?.report({message:"Site build complete",progress:100,total:100}),dm0({outputDir:Q.outputDir,routesBuilt:I.length,warnings:w})}catch($){let D=Error("Site build process failed");return A.pipelineContext.logger.error("Site build failed",{error:D,originalError:$}),im0({outputDir:Q.outputDir,errorMessage:D.message})}}class ZD{static instance=null;static defaultStaticSiteBuilderFactory=_FA;pipelineContext;staticSiteBuilderFactory;static setDefaultStaticSiteBuilderFactory(A){ZD.defaultStaticSiteBuilderFactory=A}static getInstance(A,Q,B,w,$=void 0){return ZD.instance??=new ZD(A,ZD.defaultStaticSiteBuilderFactory,Q,B,w,$),ZD.instance}static resetInstance(){ZD.instance=null}static createFresh(A,Q,B,w,$,D=void 0){return new ZD(A,$??ZD.defaultStaticSiteBuilderFactory,Q,B,w,D)}constructor(A,Q,B,w,$,D){this.pipelineContext={logger:A,services:B,routeRegistry:w,profileService:$,entityDisplay:D},this.staticSiteBuilderFactory=Q,P5.getInstance().configure(D)}async build(A,Q){return rm0({buildOptions:A,progress:Q,pipelineContext:this.pipelineContext,staticSiteBuilderFactory:this.staticSiteBuilderFactory})}}KA();class xFA{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 uF(()=>{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})}}}r$();function yO2(A,Q){return A.map((B)=>({...B,template:B.template.includes(":")?B.template:`${Q}:${B.template}`}))}function Pr(A,Q,B){for(let w of A)B.register({...w,pluginId:Q,sections:w.sections?yO2(w.sections,Q):[]})}function nm0(A,Q,B){A.messaging.subscribe("plugin:site-builder:route:register",async(w)=>{try{let $=v$A.parse(w.payload),{routes:D,pluginId:I}=$;return Pr(D,I,Q),{success:!0}}catch($){return B.error("Failed to register routes",{error:$}),{success:!1,error:"Failed to register routes"}}}),A.messaging.subscribe("plugin:site-builder:route:unregister",async(w)=>{try{let $=T$A.parse(w.payload),{paths:D,pluginId:I}=$;if(D)for(let Y of D)Q.unregister(Y);else if(I)Q.unregisterByPlugin(I);return{success:!0}}catch($){return B.error("Failed to unregister routes",{error:$}),{success:!1,error:"Failed to unregister routes"}}}),A.messaging.subscribe("plugin:site-builder:route:list",async(w)=>{try{let $=S$A.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 $=g$A.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 om0}from"fs";import{join as sm0}from"path";async function mO2(A,Q,B){let w=A.siteConfig.url??"https://example.com",$=Q.list(),D=kFA(w,A.environment);await om0.writeFile(sm0(A.outputDir,"robots.txt"),D,"utf-8"),B.info(`Generated robots.txt for ${A.environment} environment`);let I=jFA($,w);await om0.writeFile(sm0(A.outputDir,"sitemap.xml"),I,"utf-8"),B.info(`Generated sitemap.xml with ${$.length} URLs`)}function am0(A){let{context:Q,routeRegistry:B,logger:w}=A;Q.messaging.subscribe("site:build:completed",async($)=>{try{let D=$.payload;return w.info(`Received site:build:completed event for ${D.environment} environment - generating SEO files`),await mO2(D,B,w),{success:!0}}catch(D){return w.error("Failed to generate SEO files",D),{success:!1}}})}tA();KA();r$();var tm0=J.object({environment:J.enum(["preview","production"]).optional(),outputDir:J.string(),workingDir:J.string().optional(),enableContentGeneration:J.boolean().optional(),siteConfig:t7.optional()});KA();r$();async function P_(A,Q){try{let B=await A({type:db,payload:void 0});if("success"in B&&B.success&&B.data){let w=t7.safeParse(B.data);if(w.success)return t7.parse({...Q,...w.data})}}catch{}return Q}class vFA extends VB{sendMessage;cfg;constructor(A,Q,B){super(A,{schema:tm0,jobTypeName:"site-build"});this.sendMessage=Q;this.cfg=B}async process(A,Q,B){let w=A.environment??"preview",$=A.enableContentGeneration??!1;try{this.logger.debug("Starting site build job",{jobId:Q,environment:w,outputDir:A.outputDir}),await B.report({progress:0,total:100,message:`Starting site build for ${w} environment`});let D=B.createSub({scale:{start:10,end:90}}),I=await P_(this.sendMessage,A.siteConfig??this.cfg.defaultSiteConfig),Y=await this.cfg.siteBuilder.build({outputDir:A.outputDir,workingDir:A.workingDir,sharedImagesDir:this.cfg.sharedImagesDir,enableContentGeneration:$,environment:w,cleanBeforeBuild:!0,siteConfig:I,layouts:this.cfg.layouts,themeCSS:this.cfg.themeCSS,slots:this.cfg.slots,headScripts:this.cfg.getHeadScripts?.(),...this.cfg.staticAssets&&{staticAssets:this.cfg.staticAssets}},D.toCallback());if(await B.report({progress:100,total:100,message:`Site build completed: ${Y.routesBuilt} routes built`}),this.logger.debug("Site build job completed",{jobId:Q,environment:w,routesBuilt:Y.routesBuilt,success:Y.success}),Y.success){this.logger.info(`Emitting site:build:completed event for ${w} environment`);let X=w==="preview"?this.cfg.previewUrl??this.cfg.siteUrl:this.cfg.siteUrl;await this.sendMessage({type:"site:build:completed",payload:{outputDir:A.outputDir,environment:w,routesBuilt:Y.routesBuilt,siteConfig:{...I,url:X},generateEntityUrl:(H,U)=>P5.getInstance().generateUrl(H,U)},broadcast:!0})}return{success:Y.success,routesBuilt:Y.routesBuilt,outputDir:A.outputDir,environment:w,...Y.errors&&{errors:Y.errors},...Y.warnings&&{warnings:Y.warnings}}}catch(D){throw this.logger.error("Site build job failed",D),D}}summarizeDataForLog(A){return{environment:A.environment,outputDir:A.outputDir}}}KA();r$();var uO2=J.object({slot:J.enum(KL).optional().default("primary"),limit:J.number().optional()});class TFA{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=uO2.parse(A??{});this.logger.debug("NavigationDataSource fetch called",{params:w});let $=this.routeRegistry.getNavigationItems(w.slot),D=w.limit?$.slice(0,w.limit):$,I=D.map((X)=>({label:X.label,href:X.href}));this.logger.debug("NavigationDataSource returning",{slot:w.slot,itemCount:D.length,items:I});let Y={navigation:I};return Q.parse(Y)}}r$();tA();KA();var cO2=J.object({environment:J.enum(["preview","production"]).optional().describe("Build environment (defaults to production, or preview if configured)")});function em0(A,Q){return[MQ(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'.",cO2,async(B)=>{return Q(B.environment),{success:!0,message:`Site build requested${B.environment?` for ${B.environment}`:""} (debounced)`,data:{}}},{cli:{name:"build"}})]}KA();r$();var Au0=J.object({previewOutputDir:J.string().describe("Output directory for preview builds").default("./dist/site-preview"),productionOutputDir:J.string().describe("Output directory for production builds").default("./dist/site-production"),sharedImagesDir:J.string().describe("Shared directory for optimized images (used by both preview and production)").default("./dist/images"),workingDir:J.string().optional().describe("Working directory for builds").default("./.preact-work"),siteInfo:t7.default({title:"Brain",description:"A knowledge management system"}),themeCSS:J.string().describe("Custom CSS theme overrides to inject into builds").optional(),analyticsScript:J.string().describe("Analytics tracking script to inject into page head (e.g., Cloudflare Web Analytics)").optional(),templates:J.any().optional().describe("Template definitions to register"),routes:J.array(WL).optional().describe("Routes to register"),layouts:J.record(J.any()).optional().describe("Layout components (at least 'default' required)"),autoRebuild:J.boolean().default(!0).describe("Automatically rebuild site when content changes"),rebuildDebounce:J.number().min(100).describe("Debounce time in ms before triggering site rebuild after content changes").default(5000),entityDisplay:J.record(J.object({label:J.string().describe("Display label for entity type (e.g., 'Essay')"),pluralName:J.string().optional().describe("URL path segment (defaults to label.toLowerCase() + 's')"),layout:J.string().optional().describe("Layout name for this entity type's generated routes (defaults to 'default')"),paginate:J.boolean().optional().describe("Enable pagination for list pages"),pageSize:J.number().optional().describe("Items per page (default: 10)"),navigation:J.object({show:J.boolean().optional().describe("Show in navigation"),slot:J.enum(KL).optional().describe("Navigation slot (primary or secondary)"),priority:J.number().min(0).max(100).optional().describe("Navigation priority (0-100)")}).optional().describe("Navigation settings for this entity type")})).optional().describe("Display metadata per entity type \u2014 label, plural name, layout, pagination, navigation slot. Consulted when auto-generating routes for active entity plugins."),staticAssets:J.record(J.string()).optional().describe("Static files to write to the output directory at build time. Keys are output paths (e.g. '/canvases/tree.js'), values are file contents as strings. Typically supplied by a SitePackage via text imports.")});var Qu0={name:"@brains/site-builder-plugin",private:!0,version:"0.2.0-alpha.53",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/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 SFA extends Bw{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",Qu0,{...A,layouts:Q},Au0);this.layouts=Q}async onRegister(A){if(this.pluginContext=A,this._routeRegistry=new Rr(A.logger),this._slotRegistry=new Dr,A.messaging.subscribe("plugin:site-builder:slot:register",async(B)=>{let{slotName:w,pluginId:$,render:D,priority:I}=B.payload;return this._slotRegistry?.register(w,{pluginId:$,render:D,...I!==void 0&&{priority:I}}),{success:!0}}),A.messaging.subscribe("plugin:site-builder:head-script:register",async(B)=>{let{pluginId:w,script:$}=B.payload;return this.headScripts.set(w,$),{success:!0}}),A.entities.registerDataSource(new TFA(this._routeRegistry,A.logger.child("NavigationDataSource"))),this.profileService=A$.getInstance(A.entityService,A.logger),nm0(A,this._routeRegistry,this.logger),this.config.templates)A.templates.register(this.config.templates);if(this.config.routes)Pr(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=ZD.getInstance(A.logger.child("SiteBuilder"),Q,this.routeRegistry,this.profileService,this.config.entityDisplay),A.jobs.registerHandler("site-build",new vFA(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 xFA(this.config,A,this.id,this.logger),this.config.autoRebuild)this.logger.debug("Auto-rebuild enabled"),this.rebuildManager.setupAutoRebuild();A.messaging.subscribe(ib,async()=>{let B=await this.getInstructions();if(B)A.registerInstructions(B);return{success:!0}}),am0({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 em0(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 P_(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 P_(A.messaging.send,this.config.siteInfo);return`## Your Site
|
|
2656
|
+
`+Y;await d5.writeFile(I,H,"utf-8")}this.logger.debug("CSS processed successfully with font imports")}async copyStaticAssets(){this.logger.debug("Copying static assets from public/ directory");let A=iX(process.cwd(),"public");try{await d5.access(A)}catch{this.logger.debug("No public/ directory found, skipping static assets");return}let Q=await d5.readdir(A,{withFileTypes:!0});for(let B of Q){let w=iX(A,B.name),$=iX(this.outputDir,B.name);if(B.isDirectory())await this.copyDirectory(w,$);else await d5.copyFile(w,$),this.logger.debug(`Copied static asset: ${B.name}`)}this.logger.debug("Static assets copied successfully")}async writeInlineStaticAssets(A){if(!A)return;let Q=Object.entries(A);if(Q.length===0)return;this.logger.debug(`Writing ${Q.length} inline static asset(s) from SitePackage`),await Promise.all(Q.map(async([B,w])=>{let $=B.startsWith("/")?B.slice(1):B,D=iX(this.outputDir,$);await d5.mkdir(vO2(D),{recursive:!0}),await d5.writeFile(D,w,"utf-8"),this.logger.debug(`Wrote inline static asset: ${$}`)}))}async copyDirectory(A,Q){await d5.mkdir(Q,{recursive:!0});let B=await d5.readdir(A,{withFileTypes:!0});for(let w of B){let $=iX(A,w.name),D=iX(Q,w.name);if(w.isDirectory())await this.copyDirectory($,D);else await d5.copyFile($,D)}}}function _FA(A){return new vm0(A)}KA();KA();KA();r$();var Tm0=J.object({environment:J.enum(["preview","production"]),outputDir:J.string(),workingDir:J.string().optional(),sharedImagesDir:J.string().default("./dist/images"),enableContentGeneration:J.boolean().default(!1),cleanBeforeBuild:J.boolean().default(!0),siteConfig:t7,layouts:J.record(J.any()),themeCSS:J.string().optional()}),$IB=J.object({success:J.boolean(),outputDir:J.string(),filesGenerated:J.number(),routesBuilt:J.number(),errors:J.array(J.string()).optional(),warnings:J.array(J.string()).optional()});function Sm0(A){let Q=A.list(),B=Q.length===0?["No routes registered for site build"]:[];return{routes:Q,warnings:B}}function gm0(A,Q,B){let w=Q.getProfile(),$=B.getNavigationItems("primary"),D=B.getNavigationItems("secondary");return{...A,...w.socialLinks!==void 0&&{socialLinks:w.socialLinks},navigation:{primary:$,secondary:D},copyright:A.copyright??"Powered by Rizom"}}KA();KA();var TO2=J.object({id:J.string(),entityType:J.string(),content:J.string(),metadata:J.object({slug:J.string()}).passthrough()}).passthrough(),SO2=J.object({content:J.string(),metadata:J.object({width:J.number().optional(),height:J.number().optional()}).passthrough()});async function br(A,Q){let B=Q.urlGenerator??P5.getInstance();if(A===null||A===void 0)return A;if(Array.isArray(A))return Promise.all(A.map((k)=>br(k,{...Q,urlGenerator:B})));if(typeof A!=="object")return A;let w={},$=Object.entries(A),D=await Promise.all($.map(([,k])=>br(k,{...Q,urlGenerator:B})));for(let k=0;k<$.length;k++){let o=$[k];if(o)w[o[0]]=D[k]}let I=TO2.safeParse(A);if(!I.success)return w;let Y=I.data,X=Y.entityType,H=Y.metadata.slug,U=Q.pipelineContext.entityDisplay?.[X],F=U?U.label:X.charAt(0).toUpperCase()+X.slice(1),Z=U?U.pluralName??U.label.toLowerCase()+"s":S7(X),z=`/${Z}`,f=Z.charAt(0).toUpperCase()+Z.slice(1),E=SV(Y)??void 0,C=E?Q.imageBuildService?.get(E):void 0,P={};if(C)P={coverImageUrl:C.src,coverImageWidth:C.width,coverImageHeight:C.height,...C.srcset&&{coverImageSrcset:C.srcset,coverImageSizes:C.sizes}};else{let k=await gO2(E,Q.pipelineContext.services.entityService);if(k)P={coverImageUrl:k.url,...k.width&&{coverImageWidth:k.width},...k.height&&{coverImageHeight:k.height}}}return{...w,...Y,url:B.generateUrl(X,H),typeLabel:F,listUrl:z,listLabel:f,...P}}async function gO2(A,Q){if(!A)return;let B=await Q.getEntity({entityType:"image",id:A}),w=SO2.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 hm0(A,Q){let B=new Set;try{let w=A.getEntityTypes();for(let $ of w){if($==="image")continue;let D=await A.listEntities({entityType:$});for(let I of D){let Y=SV(I);if(Y)B.add(Y)}}}catch(w){Q.warn("Failed to collect image IDs for pre-resolution",{error:L0(w)})}return[...B]}async function ym0(A,Q,B,w){if(!A.template)return A.content??null;let $=A.template,D=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($,D);if(!I)return null;return br(I,{pipelineContext:w.pipelineContext,imageBuildService:w.imageBuildService,urlGenerator:P5.getInstance()})}function mm0(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 ym0(B,Q,w,{pipelineContext:A.pipelineContext,imageBuildService:A.imageBuildService})},getViewTemplate:(Q)=>{return A.pipelineContext.services.getViewTemplate(Q)},layouts:A.parsedOptions.layouts,getSiteLayoutInfo:async()=>{return gm0(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 hO2}from"path";async function um0(A){let Q=A.parsedOptions.workingDir??hO2(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 cm0(A){await new Or({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 lm0(A){let Q=new Vr(A.pipelineContext.services.entityService,A.pipelineContext.logger,A.sharedImagesDir),B=await hm0(A.pipelineContext.services.entityService,A.pipelineContext.logger);if(B.length>0)await Q.resolveAll(B);return Q}async function pm0(A){let Q=A.reporter?.createSub({scale:{start:85,end:95}});await A.staticSiteBuilder.build(A.buildContext,(B)=>{Q?.report(B).catch(()=>{})})}function dm0(A){return{success:!0,outputDir:A.outputDir,filesGenerated:A.routesBuilt+1,routesBuilt:A.routesBuilt,...A.warnings.length>0&&{warnings:A.warnings}}}function im0(A){return{success:!1,outputDir:A.outputDir,filesGenerated:0,routesBuilt:0,errors:[A.errorMessage]}}async function rm0(A){let Q=Tm0.parse(A.buildOptions),B=T8.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 cm0({pipelineContext:A.pipelineContext});let $=await um0({logger:A.pipelineContext.logger,parsedOptions:Q,staticSiteBuilderFactory:A.staticSiteBuilderFactory}),D=Sm0(A.pipelineContext.routeRegistry);w.push(...D.warnings);let{routes:I}=D;await B?.report({message:`Building ${I.length} routes`,progress:20,total:100}),await B?.report({message:"Resolving images",progress:25,total:100});let Y=await lm0({pipelineContext:A.pipelineContext,sharedImagesDir:Q.sharedImagesDir}),X=mm0({routes:I,parsedOptions:Q,buildOptions:A.buildOptions,pipelineContext:A.pipelineContext,imageBuildService:Y,siteMetadata:Q.siteConfig});return await pm0({staticSiteBuilder:$,buildContext:X,reporter:B}),await B?.report({message:"Site build complete",progress:100,total:100}),dm0({outputDir:Q.outputDir,routesBuilt:I.length,warnings:w})}catch($){let D=Error("Site build process failed");return A.pipelineContext.logger.error("Site build failed",{error:D,originalError:$}),im0({outputDir:Q.outputDir,errorMessage:D.message})}}class ZD{static instance=null;static defaultStaticSiteBuilderFactory=_FA;pipelineContext;staticSiteBuilderFactory;static setDefaultStaticSiteBuilderFactory(A){ZD.defaultStaticSiteBuilderFactory=A}static getInstance(A,Q,B,w,$=void 0){return ZD.instance??=new ZD(A,ZD.defaultStaticSiteBuilderFactory,Q,B,w,$),ZD.instance}static resetInstance(){ZD.instance=null}static createFresh(A,Q,B,w,$,D=void 0){return new ZD(A,$??ZD.defaultStaticSiteBuilderFactory,Q,B,w,D)}constructor(A,Q,B,w,$,D){this.pipelineContext={logger:A,services:B,routeRegistry:w,profileService:$,entityDisplay:D},this.staticSiteBuilderFactory=Q,P5.getInstance().configure(D)}async build(A,Q){return rm0({buildOptions:A,progress:Q,pipelineContext:this.pipelineContext,staticSiteBuilderFactory:this.staticSiteBuilderFactory})}}KA();class xFA{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 uF(()=>{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})}}}r$();function yO2(A,Q){return A.map((B)=>({...B,template:B.template.includes(":")?B.template:`${Q}:${B.template}`}))}function Pr(A,Q,B){for(let w of A)B.register({...w,pluginId:Q,sections:w.sections?yO2(w.sections,Q):[]})}function nm0(A,Q,B){A.messaging.subscribe("plugin:site-builder:route:register",async(w)=>{try{let $=v$A.parse(w.payload),{routes:D,pluginId:I}=$;return Pr(D,I,Q),{success:!0}}catch($){return B.error("Failed to register routes",{error:$}),{success:!1,error:"Failed to register routes"}}}),A.messaging.subscribe("plugin:site-builder:route:unregister",async(w)=>{try{let $=T$A.parse(w.payload),{paths:D,pluginId:I}=$;if(D)for(let Y of D)Q.unregister(Y);else if(I)Q.unregisterByPlugin(I);return{success:!0}}catch($){return B.error("Failed to unregister routes",{error:$}),{success:!1,error:"Failed to unregister routes"}}}),A.messaging.subscribe("plugin:site-builder:route:list",async(w)=>{try{let $=S$A.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 $=g$A.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 om0}from"fs";import{join as sm0}from"path";async function mO2(A,Q,B){let w=A.siteConfig.url??"https://example.com",$=Q.list(),D=kFA(w,A.environment);await om0.writeFile(sm0(A.outputDir,"robots.txt"),D,"utf-8"),B.info(`Generated robots.txt for ${A.environment} environment`);let I=jFA($,w);await om0.writeFile(sm0(A.outputDir,"sitemap.xml"),I,"utf-8"),B.info(`Generated sitemap.xml with ${$.length} URLs`)}function am0(A){let{context:Q,routeRegistry:B,logger:w}=A;Q.messaging.subscribe("site:build:completed",async($)=>{try{let D=$.payload;return w.info(`Received site:build:completed event for ${D.environment} environment - generating SEO files`),await mO2(D,B,w),{success:!0}}catch(D){return w.error("Failed to generate SEO files",D),{success:!1}}})}tA();KA();r$();var tm0=J.object({environment:J.enum(["preview","production"]).optional(),outputDir:J.string(),workingDir:J.string().optional(),enableContentGeneration:J.boolean().optional(),siteConfig:t7.optional()});KA();r$();async function P_(A,Q){try{let B=await A({type:db,payload:void 0});if("success"in B&&B.success&&B.data){let w=t7.safeParse(B.data);if(w.success)return t7.parse({...Q,...w.data})}}catch{}return Q}class vFA extends VB{sendMessage;cfg;constructor(A,Q,B){super(A,{schema:tm0,jobTypeName:"site-build"});this.sendMessage=Q;this.cfg=B}async process(A,Q,B){let w=A.environment??"preview",$=A.enableContentGeneration??!1;try{this.logger.debug("Starting site build job",{jobId:Q,environment:w,outputDir:A.outputDir}),await B.report({progress:0,total:100,message:`Starting site build for ${w} environment`});let D=B.createSub({scale:{start:10,end:90}}),I=await P_(this.sendMessage,A.siteConfig??this.cfg.defaultSiteConfig),Y=await this.cfg.siteBuilder.build({outputDir:A.outputDir,workingDir:A.workingDir,sharedImagesDir:this.cfg.sharedImagesDir,enableContentGeneration:$,environment:w,cleanBeforeBuild:!0,siteConfig:I,layouts:this.cfg.layouts,themeCSS:this.cfg.themeCSS,slots:this.cfg.slots,headScripts:this.cfg.getHeadScripts?.(),...this.cfg.staticAssets&&{staticAssets:this.cfg.staticAssets}},D.toCallback());if(await B.report({progress:100,total:100,message:`Site build completed: ${Y.routesBuilt} routes built`}),this.logger.debug("Site build job completed",{jobId:Q,environment:w,routesBuilt:Y.routesBuilt,success:Y.success}),Y.success){this.logger.info(`Emitting site:build:completed event for ${w} environment`);let X=w==="preview"?this.cfg.previewUrl??this.cfg.siteUrl:this.cfg.siteUrl;await this.sendMessage({type:"site:build:completed",payload:{outputDir:A.outputDir,environment:w,routesBuilt:Y.routesBuilt,siteConfig:{...I,url:X},generateEntityUrl:(H,U)=>P5.getInstance().generateUrl(H,U)},broadcast:!0})}return{success:Y.success,routesBuilt:Y.routesBuilt,outputDir:A.outputDir,environment:w,...Y.errors&&{errors:Y.errors},...Y.warnings&&{warnings:Y.warnings}}}catch(D){throw this.logger.error("Site build job failed",D),D}}summarizeDataForLog(A){return{environment:A.environment,outputDir:A.outputDir}}}KA();r$();var uO2=J.object({slot:J.enum(KL).optional().default("primary"),limit:J.number().optional()});class TFA{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=uO2.parse(A??{});this.logger.debug("NavigationDataSource fetch called",{params:w});let $=this.routeRegistry.getNavigationItems(w.slot),D=w.limit?$.slice(0,w.limit):$,I=D.map((X)=>({label:X.label,href:X.href}));this.logger.debug("NavigationDataSource returning",{slot:w.slot,itemCount:D.length,items:I});let Y={navigation:I};return Q.parse(Y)}}r$();tA();KA();var cO2=J.object({environment:J.enum(["preview","production"]).optional().describe("Build environment (defaults to production, or preview if configured)")});function em0(A,Q){return[MQ(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'.",cO2,async(B)=>{return Q(B.environment),{success:!0,message:`Site build requested${B.environment?` for ${B.environment}`:""} (debounced)`,data:{}}},{cli:{name:"build"}})]}KA();r$();var Au0=J.object({previewOutputDir:J.string().describe("Output directory for preview builds").default("./dist/site-preview"),productionOutputDir:J.string().describe("Output directory for production builds").default("./dist/site-production"),sharedImagesDir:J.string().describe("Shared directory for optimized images (used by both preview and production)").default("./dist/images"),workingDir:J.string().optional().describe("Working directory for builds").default("./.preact-work"),siteInfo:t7.default({title:"Brain",description:"A knowledge management system"}),themeCSS:J.string().describe("Custom CSS theme overrides to inject into builds").optional(),analyticsScript:J.string().describe("Analytics tracking script to inject into page head (e.g., Cloudflare Web Analytics)").optional(),templates:J.any().optional().describe("Template definitions to register"),routes:J.array(WL).optional().describe("Routes to register"),layouts:J.record(J.any()).optional().describe("Layout components (at least 'default' required)"),autoRebuild:J.boolean().default(!0).describe("Automatically rebuild site when content changes"),rebuildDebounce:J.number().min(100).describe("Debounce time in ms before triggering site rebuild after content changes").default(5000),entityDisplay:J.record(J.object({label:J.string().describe("Display label for entity type (e.g., 'Essay')"),pluralName:J.string().optional().describe("URL path segment (defaults to label.toLowerCase() + 's')"),layout:J.string().optional().describe("Layout name for this entity type's generated routes (defaults to 'default')"),paginate:J.boolean().optional().describe("Enable pagination for list pages"),pageSize:J.number().optional().describe("Items per page (default: 10)"),navigation:J.object({show:J.boolean().optional().describe("Show in navigation"),slot:J.enum(KL).optional().describe("Navigation slot (primary or secondary)"),priority:J.number().min(0).max(100).optional().describe("Navigation priority (0-100)")}).optional().describe("Navigation settings for this entity type")})).optional().describe("Display metadata per entity type \u2014 label, plural name, layout, pagination, navigation slot. Consulted when auto-generating routes for active entity plugins."),staticAssets:J.record(J.string()).optional().describe("Static files to write to the output directory at build time. Keys are output paths (e.g. '/canvases/tree.js'), values are file contents as strings. Typically supplied by a SitePackage via text imports.")});var Qu0={name:"@brains/site-builder-plugin",private:!0,version:"0.2.0-alpha.54",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/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 SFA extends Bw{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",Qu0,{...A,layouts:Q},Au0);this.layouts=Q}async onRegister(A){if(this.pluginContext=A,this._routeRegistry=new Rr(A.logger),this._slotRegistry=new Dr,A.messaging.subscribe("plugin:site-builder:slot:register",async(B)=>{let{slotName:w,pluginId:$,render:D,priority:I}=B.payload;return this._slotRegistry?.register(w,{pluginId:$,render:D,...I!==void 0&&{priority:I}}),{success:!0}}),A.messaging.subscribe("plugin:site-builder:head-script:register",async(B)=>{let{pluginId:w,script:$}=B.payload;return this.headScripts.set(w,$),{success:!0}}),A.entities.registerDataSource(new TFA(this._routeRegistry,A.logger.child("NavigationDataSource"))),this.profileService=A$.getInstance(A.entityService,A.logger),nm0(A,this._routeRegistry,this.logger),this.config.templates)A.templates.register(this.config.templates);if(this.config.routes)Pr(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=ZD.getInstance(A.logger.child("SiteBuilder"),Q,this.routeRegistry,this.profileService,this.config.entityDisplay),A.jobs.registerHandler("site-build",new vFA(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 xFA(this.config,A,this.id,this.logger),this.config.autoRebuild)this.logger.debug("Auto-rebuild enabled"),this.rebuildManager.setupAutoRebuild();A.messaging.subscribe(ib,async()=>{let B=await this.getInstructions();if(B)A.registerInstructions(B);return{success:!0}}),am0({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 em0(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 P_(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 P_(A.messaging.send,this.config.siteInfo);return`## Your Site
|
|
2657
2657
|
${[`**Title:** ${B.title}`,`**Description:** ${B.description}`,A.domain&&`**Domain:** ${A.domain}`,A.siteUrl&&`**URL:** ${A.siteUrl}`].filter(Boolean).join(`
|
|
2658
2658
|
`)}
|
|
2659
2659
|
|
|
2660
2660
|
## Site Builder Actions
|
|
2661
2661
|
- When the user asks to build, rebuild, publish, or build the website/site again, call \`site-builder_build-site\` immediately.
|
|
2662
|
-
- 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(),ZD.resetInstance(),this.logger.debug("Cleaned up all event subscriptions")}}function zz(A={}){return new SFA(A)}tA();r$();KA();tA();r$();var Bu0=J.object({}),k_=r1.extend({id:J.literal("site-info"),entityType:J.literal("site-info"),metadata:Bu0}),gFA=Sm,zE=t7.omit({url:!0,analyticsScript:!0});tA();class rX extends Q2{constructor(){super({entityType:"site-info",schema:k_,frontmatterSchema:zE,isSingleton:!0,hasBody:!1})}createSiteInfoContent(A){let Q=zE.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 nX{static instance=null;logger;entityService;adapter;defaultSiteInfo;static getDefaultSiteInfo(){return{title:"Brain",description:"A knowledge management system"}}static getInstance(A,Q,B){return nX.instance??=new nX(A,Q,B),nX.instance}static resetInstance(){nX.instance=null}static createFresh(A,Q,B){return new nX(A,Q,B)}constructor(A,Q,B){this.entityService=A,this.logger=Q.child("SiteInfoService"),this.adapter=new rX;let w=nX.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 pO2=new rX;class kr{logger;id="site-info:entities";name="Site Info DataSource";description="Provides site metadata (title, description, CTA) and profile social links";constructor(A){this.logger=A}async fetch(A,Q,B){let{entityService:w}=B,$;try{let Y=await w.getEntity({entityType:"site-info",id:"site-info"});$=Y?pO2.parseSiteInfoBody(Y.content):{title:"Brain",description:"A knowledge management system"}}catch{$={title:"Brain",description:"A knowledge management system"}}let D;try{let Y=await w.getEntity({entityType:"anchor-profile",id:"anchor-profile"});if(Y)D=Y.metadata.socialLinks}catch{}let I={...$,socialLinks:D,copyright:$.copyright??"Powered by Rizom"};return this.logger.debug("SiteInfoDataSource returning",{title:I.title,hasSocialLinks:!!I.socialLinks}),Q.parse(I)}}var wu0={name:"@brains/site-info",private:!0,version:"0.2.0-alpha.
|
|
2662
|
+
- 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(),ZD.resetInstance(),this.logger.debug("Cleaned up all event subscriptions")}}function zz(A={}){return new SFA(A)}tA();r$();KA();tA();r$();var Bu0=J.object({}),k_=r1.extend({id:J.literal("site-info"),entityType:J.literal("site-info"),metadata:Bu0}),gFA=Sm,zE=t7.omit({url:!0,analyticsScript:!0});tA();class rX extends Q2{constructor(){super({entityType:"site-info",schema:k_,frontmatterSchema:zE,isSingleton:!0,hasBody:!1})}createSiteInfoContent(A){let Q=zE.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 nX{static instance=null;logger;entityService;adapter;defaultSiteInfo;static getDefaultSiteInfo(){return{title:"Brain",description:"A knowledge management system"}}static getInstance(A,Q,B){return nX.instance??=new nX(A,Q,B),nX.instance}static resetInstance(){nX.instance=null}static createFresh(A,Q,B){return new nX(A,Q,B)}constructor(A,Q,B){this.entityService=A,this.logger=Q.child("SiteInfoService"),this.adapter=new rX;let w=nX.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 pO2=new rX;class kr{logger;id="site-info:entities";name="Site Info DataSource";description="Provides site metadata (title, description, CTA) and profile social links";constructor(A){this.logger=A}async fetch(A,Q,B){let{entityService:w}=B,$;try{let Y=await w.getEntity({entityType:"site-info",id:"site-info"});$=Y?pO2.parseSiteInfoBody(Y.content):{title:"Brain",description:"A knowledge management system"}}catch{$={title:"Brain",description:"A knowledge management system"}}let D;try{let Y=await w.getEntity({entityType:"anchor-profile",id:"anchor-profile"});if(Y)D=Y.metadata.socialLinks}catch{}let I={...$,socialLinks:D,copyright:$.copyright??"Powered by Rizom"};return this.logger.debug("SiteInfoDataSource returning",{title:I.title,hasSocialLinks:!!I.socialLinks}),Q.parse(I)}}var wu0={name:"@brains/site-info",private:!0,version:"0.2.0-alpha.54",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 iO2=new rX;class hFA extends n2{entityType="site-info";schema=k_;adapter=iO2;defaultSiteInfo;constructor(A){super("site-info",wu0);this.defaultSiteInfo=A?.siteInfo??{}}getEntityTypeConfig(){return{embeddable:!1}}getDataSources(){return[new kr(this.logger.child("SiteInfoDataSource"))]}async onRegister(A){let Q=nX.createFresh(A.entityService,this.logger,this.defaultSiteInfo);A.messaging.subscribe(db,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:ib,payload:$,broadcast:!0})}return{success:!0}}),A.messaging.subscribe("sync:initial:completed",async()=>{return await Q.initialize(),{success:!0}})}}function qz(A){return new hFA(A)}var rO2=new rX;async function yFA(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 rO2.parseSiteInfoBody(B.content)}KA();var nO2=zE.extend({navigation:J.object({primary:J.array(J.object({label:J.string(),href:J.string(),priority:J.number()})),secondary:J.array(J.object({label:J.string(),href:J.string(),priority:J.number()}))}),copyright:J.string(),socialLinks:J.array(J.object({platform:J.enum(["github","instagram","linkedin","email","website"]).describe("Social media platform"),url:J.string().describe("Profile or contact URL"),label:J.string().optional().describe("Optional display label")})).optional().describe("Social media links from profile entity")});tA();oX();x_();KA();var mFA=J.object({defaultPrompt:J.string().default("Write a blog post about my recent work and insights"),paginate:J.boolean().default(!0),pageSize:J.number().default(10)});tA();KA();var aO2=J.object({prompt:J.string().optional(),title:J.string().optional(),content:J.string().optional(),excerpt:J.string().optional(),coverImageId:J.string().optional(),seriesName:J.string().optional(),seriesIndex:J.number().optional(),skipAi:J.boolean().optional()}),EYB=h$.extend({title:J.string().optional(),slug:J.string().optional()});class uFA extends W9{constructor(A,Q){super(A,Q,{schema:aO2,jobTypeName:"blog-generation",entityType:"post"})}async generate(A,Q){let{prompt:B,coverImageId:w,seriesName:$,seriesIndex:D,skipAi:I}=A,{title:Y,content:X,excerpt:H}=A;if(I){if(!Y)this.failEarly("Title is required when skipAi is true");X=X??`## Introduction
|
|
2663
2663
|
|
|
2664
2664
|
Add your introduction here.
|
|
2665
2665
|
|
|
@@ -2704,7 +2704,7 @@ The excerpt should be clear, concise, and compelling.`});KA();Q8();oX();import{j
|
|
|
2704
2704
|
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=UR2.parse(Q);return A.ai.generate({prompt:`Title: ${B.title}
|
|
2705
2705
|
|
|
2706
2706
|
Content:
|
|
2707
|
-
${B.content}`,templateName:"blog:excerpt"})})}var qu0={name:"@brains/blog",private:!0,version:"0.2.0-alpha.
|
|
2707
|
+
${B.content}`,templateName:"blog:excerpt"})})}var qu0={name:"@brains/blog",private:!0,version:"0.2.0-alpha.54",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/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 dFA extends n2{entityType=Nz.entityType;schema=qE;adapter=Nz;constructor(A={}){super("blog",qu0,A,mFA)}getEntityTypeConfig(){return{weight:2}}createGenerationHandler(A){return new uFA(this.logger.child("BlogGenerationJobHandler"),A)}getTemplates(){return Uu0()}getDataSources(){return[new lFA(this.logger.child("BlogDataSource"))]}async onRegister(A){let{RSSDataSource:Q}=await Promise.resolve().then(() => (Lu0(),fu0));A.entities.registerDataSource(new Q(this.logger.child("RSSDataSource"))),await Gu0(A,this.logger),Ju0(A,this.logger),Zu0(A,this.logger),zu0(A),this.logger.info("Blog plugin registered (routes auto-generated at /posts/)")}}function iFA(A={}){return new dFA(A)}oX();x_();tA();KA();KA();Qw();var VI=J.object({title:J.string(),slug:J.string(),coverImageId:J.string().optional()}),Cu0=VI.pick({title:!0,slug:!0}),LE=r1.extend({metadata:Cu0}),vr=LE.extend({frontmatter:VI}),Tr=vr.extend({description:J.string().optional(),postCount:J.number(),coverImageUrl:J.string().optional(),coverImageWidth:J.number().optional(),coverImageHeight:J.number().optional()}),Eu0=J.object({description:J.string().optional()});function fz(A){return new IB(Eu0,{title:A,mappings:[{key:"description",label:"Description",type:"string"}]})}Qw();class rFA extends Q2{constructor(){super({entityType:"series",schema:LE,frontmatterSchema:VI,supportsCoverImage:!0,bodyFormatter:fz("")})}toMarkdown(A){let Q,B={};try{Q=this.parseFrontMatter(A.content,VI).coverImageId,B=fz(A.metadata.title).parse(this.extractBody(A.content))}catch{}let w={title:A.metadata.title,slug:A.metadata.slug,...Q&&{coverImageId:Q}},D=fz(A.metadata.title).format(B);return this.buildMarkdown(D,w)}fromMarkdown(A){let Q=this.parseFrontMatter(A,VI);return{content:A,entityType:"series",metadata:{title:Q.title,slug:Q.slug}}}parseBody(A){try{let Q=this.parseFrontMatter(A,VI);return fz(Q.title).parse(this.extractBody(A))}catch{return{}}}generateFrontMatter(){return""}}var CE=new rFA;tA();KA();N4();class nFA{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 D=t1($);w.add(D);let I=B.get(D),Y=I?.content??this.createSeriesContent($),X=Aw(Y);if(I?.contentHash===X)continue;let H={id:D,entityType:"series",content:Y,contentHash:X,created:I?.created??new Date().toISOString(),updated:new Date().toISOString(),metadata:{title:$,slug:t1($)}};await this.entityService.upsertEntity({entity:H}),this.logger.debug(`Upserted series: ${$}`)}for(let $ of Q)if(!w.has($.id))await this.entityService.deleteEntity({entityType:"series",id:$.id}),this.logger.debug(`Deleted orphaned series: ${$.id}`)}async handleEntityChange(A,Q){let B=this.getSeriesName(A);if(B)await this.ensureSeriesExists(B);if(Q&&Q!==B)await this.cleanupOrphanedSeries(Q)}async handleEntityDeleted(){await this.syncAllSeries()}getSeriesName(A){let B=A.metadata.seriesName;return typeof B==="string"?B:void 0}async ensureSeriesExists(A){let Q=t1(A);if(await this.entityService.getEntity({entityType:"series",id:Q}))return;let w=this.createSeriesContent(A),$={id:Q,entityType:"series",content:w,contentHash:Aw(w),created:new Date().toISOString(),updated:new Date().toISOString(),metadata:{title:A,slug:t1(A)}};await this.entityService.upsertEntity({entity:$}),this.logger.debug(`Created series: ${A}`)}async cleanupOrphanedSeries(A){let Q=t1(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 D=this.getSeriesName($);if(D)A.add(D)}}return A}createSeriesContent(A){let Q={title:A,slug:t1(A)};return H9("",Q)}}tA();KA();var FR2=J.object({entityType:J.literal("series"),query:J.object({id:J.string().optional(),limit:J.number().optional(),page:J.number().optional(),pageSize:J.number().optional()}).passthrough()}),ZR2=J.object({type:J.enum(["list","detail"]),seriesName:J.string().optional()});function zR2(A){let Q=ZR2.safeParse(A);if(Q.success)return{type:Q.data.type,seriesName:Q.data.seriesName};let B=FR2.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 Mu0(A){let Q=M2(A.content,VI);return vr.parse({...A,frontmatter:Q.metadata})}class oFA{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=zR2(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((D)=>{let I=Mu0(D),Y=CE.parseBody(D.content);return{...I,description:Y.description,postCount:w.get(D.metadata.title)??0}});return this.logger.debug(`Found ${$.length} series entities`),A.parse({series:$})}async fetchSeriesDetail(A,Q,B,w){if(!w)w=(await B.listEntities({entityType:"series",options:{filter:{metadata:{title:A}}}}))[0];if(!w)throw Error(`Series not found: ${A}`);let $=Mu0(w),D=CE.parseBody(w.content),I=await this.getSeriesMembers(A,B);return this.logger.debug(`Found ${I.length} entities in series "${A}"`),Q.parse({seriesName:A,posts:I,series:{...$,description:D.description,postCount:I.length},description:D.description})}async fetchSeriesDetailBySlug(A,Q,B){let $=(await B.listEntities({entityType:"series",options:{filter:{metadata:{slug:A}}}}))[0];if(!$)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 D of $){let I=this.getSeriesName(D);if(I)Q.set(I,(Q.get(I)??0)+1)}}return Q}async getSeriesMembers(A,Q){let B=[],w=Q.getEntityTypes();for(let $ of w){if($==="series")continue;let D=await Q.listEntities({entityType:$,options:{filter:{metadata:{seriesName:A}}}});B.push(...D)}return B.sort(($,D)=>{let I=$.metadata.seriesIndex,Y=D.metadata.seriesIndex;return(typeof I==="number"?I:999)-(typeof Y==="number"?Y:999)}),B}getSeriesName(A){let B=A.metadata.seriesName;return typeof B==="string"?B:void 0}}tA();KA();N4();var qR2=J.object({prompt:J.string().optional(),title:J.string().optional(),seriesId:J.string().optional()});class Sr{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}
|
|
2708
2708
|
|
|
2709
2709
|
Content in this series:
|
|
2710
2710
|
${w.join(`
|
|
@@ -2716,7 +2716,7 @@ Your task is to write a series description (2-3 sentences) that:
|
|
|
2716
2716
|
3. Is engaging and makes readers want to explore the content
|
|
2717
2717
|
4. Works well as a series overview on a website
|
|
2718
2718
|
|
|
2719
|
-
Be concise and focus on what makes this series unique and valuable.`});var ju0={name:"@brains/series",private:!0,version:"0.2.0-alpha.
|
|
2719
|
+
Be concise and focus on what makes this series unique and valuable.`});var ju0={name:"@brains/series",private:!0,version:"0.2.0-alpha.54",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/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 _u0=J.discriminatedUnion("mode",[J.object({mode:J.literal("derive"),reason:J.string().optional()}),J.object({mode:J.literal("source"),entityId:J.string(),entityType:J.string(),seriesName:J.string()})]);class sFA extends n2{entityType="series";schema=LE;adapter=CE;manager;constructor(){super("series",ju0)}getEntityTypeConfig(){return{weight:0.5}}createGenerationHandler(A){return new Sr(this.logger.child("SeriesGenerationHandler"),A)}getTemplates(){return{...Pu0(),description:ku0}}getDataSources(){return[new oFA(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 nFA(A.entityService,this.logger.child("SeriesManager"))}createSeriesProjectionHandler(A){return{process:async(Q)=>{let B=_u0.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=_u0.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 Sr(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 aFA(){return new sFA}tA();KA();tA();KA();KA();tA();var ER2=J.enum(["draft","queued","published"]),FJ=J.object({title:J.string(),slug:J.string().optional(),description:J.string().optional(),author:J.string().optional(),status:ER2,publishedAt:J.string().datetime().optional(),event:J.string().optional(),coverImageId:J.string().optional()}),MR2=FJ.pick({title:!0,description:!0,status:!0,publishedAt:!0,coverImageId:!0}).extend({slug:J.string()}),gr=r1.extend({entityType:J.literal("deck"),metadata:MR2}),hr=gr.extend({frontmatter:FJ,body:J.string()}),S_=hr.extend({url:J.string().optional(),typeLabel:J.string().optional(),listUrl:J.string().optional(),listLabel:J.string().optional(),coverImageUrl:J.string().optional(),coverImageWidth:J.number().optional(),coverImageHeight:J.number().optional()});class tFA extends Q2{constructor(){super({entityType:"deck",schema:gr,frontmatterSchema:FJ,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);try{let B=this.parseFrontMatter(A.content,FJ),w={...B,slug:B.slug??A.metadata.slug};return this.buildMarkdown(Q,w)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontmatter(A),B=this.extractBody(A);this.validateSlideStructure(B);let w=Q.slug??t1(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 g_=new tFA;KA();Q8();var VR2=J.object({markdown:J.string().describe("Markdown content with slide separators (---)")}),eFA=G1({name:"deck-detail",description:"Render a presentation deck as Reveal.js slides",schema:VR2,dataSourceId:"decks:entities",requiredPermission:"public",layout:{component:fUA,fullscreen:!0}});Q8();KA();var AZA=J.object({decks:J.array(hr)}),QZA=J.object({decks:J.array(S_),pageTitle:J.string().optional()});import{jsxDEV as BZA}from"preact/jsx-dev-runtime";var wZA=({decks:A,pageTitle:Q})=>{let B=A.map((w)=>({id:w.id,url:w.url,title:w.frontmatter.title,date:w.frontmatter.publishedAt??w.created,description:w.frontmatter.description}));return BZA("div",{className:"deck-list bg-theme",children:BZA("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:BZA(zj,{title:Q??"Presentations",items:B},void 0,!1,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)};KA();class yr extends IB{constructor(){super(AZA,{title:"Deck List",mappings:[{key:"decks",label:"Decks",type:"array",itemType:"object"}]})}}var $ZA=G1({name:"deck-list",description:"List view of all presentation decks",schema:QZA,dataSourceId:"decks:entities",requiredPermission:"public",formatter:new yr,layout:{component:wZA}});KA();tA();var OR2=J.object({title:J.string().max(80).describe("A short, punchy title (2-5 words) that's memorable and evocative"),content:J.string().describe("Full slide deck content in markdown format with slide separators (---). Each slide should have a header and focused content."),description:J.string().describe("A concise 1-2 sentence summary that captures the essence of the talk")}),xu0=G1({name:"decks:generation",description:"Template for AI to generate complete slide decks from prompts",schema:OR2,dataSourceId:"shell:ai-content",requiredPermission:"public",useKnowledgeContext:!0,basePrompt:`You are creating slide decks in a distinctive voice that blends philosophy, technology, and culture.
|
|
2720
2720
|
|
|
2721
2721
|
Your task is to generate a complete slide deck based on the user's prompt.
|
|
2722
2722
|
|
|
@@ -2785,7 +2785,7 @@ Add your conclusion here`,X=X??`Presentation: ${I}`,await this.reportProgress(Q,
|
|
|
2785
2785
|
Note: This presentation is for "${$}".`:""}`,P=await this.context.ai.generate({prompt:C,templateName:"decks:generation"});I=I??P.title,Y=Y??P.content,X=X??P.description,await this.reportProgress(Q,{progress:50,message:`Generated deck: "${I}"`})}else if(!X)await this.reportProgress(Q,{progress:30,message:"Generating description with AI"}),X=(await this.context.ai.generate({prompt:`Title: ${I}
|
|
2786
2786
|
|
|
2787
2787
|
Content:
|
|
2788
|
-
${Y}`,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||!Y)this.failEarly("Title and content are required");let U={slug:t1(I),title:I,status:"draft"},F=await DK({entityType:"deck",title:I,deriveId:(f)=>f,regeneratePrompt:"Generate a different presentation deck title on the same topic.",context:this.context});if(F!==I)U.title=F,U.slug=t1(F);let Z={title:U.title,status:U.status,slug:U.slug,description:X,author:w,event:$},z=H9(Y,Z);return{id:F,content:z,metadata:U,title:F,resultExtras:{title:F,slug:U.slug},createOptions:{deduplicateId:!0}}}summarizeDataForLog(A){return{prompt:A.prompt,title:A.title}}}var Tu0={name:"@brains/decks",private:!0,version:"0.2.0-alpha.
|
|
2788
|
+
${Y}`,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||!Y)this.failEarly("Title and content are required");let U={slug:t1(I),title:I,status:"draft"},F=await DK({entityType:"deck",title:I,deriveId:(f)=>f,regeneratePrompt:"Generate a different presentation deck title on the same topic.",context:this.context});if(F!==I)U.title=F,U.slug=t1(F);let Z={title:U.title,status:U.status,slug:U.slug,description:X,author:w,event:$},z=H9(Y,Z);return{id:F,content:z,metadata:U,title:F,resultExtras:{title:F,slug:U.slug},createOptions:{deduplicateId:!0}}}summarizeDataForLog(A){return{prompt:A.prompt,title:A.title}}}var Tu0={name:"@brains/decks",private:!0,version:"0.2.0-alpha.54",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/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 YZA extends n2{entityType=g_.entityType;schema=g_.schema;adapter=g_;constructor(){super("decks",Tu0)}createGenerationHandler(A){return new IZA(this.logger.child("DeckGenerationJobHandler"),A)}getTemplates(){return{"deck-detail":eFA,"deck-list":$ZA,generation:xu0,description:vu0}}getDataSources(){return[new DZA(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 D=new Date().toISOString(),I={...$,metadata:{...$.metadata,status:"published",publishedAt:D}};await A.entityService.updateEntity({entity:{...I,content:this.adapter.toMarkdown(I)}}),await A.messaging.send({type:"publish:report:success",payload:{entityType:B,entityId:w,result:{id:w}}})}catch($){await A.messaging.send({type:"publish:report:failure",payload:{entityType:B,entityId:w,error:L0($)}})}return{success:!0}})}registerEvalHandlers(A){A.eval.registerHandler("generateDeck",async(Q)=>{let B=J.object({prompt:J.string(),event:J.string().optional()}).parse(Q);return A.ai.generate({prompt:`${B.prompt}${B.event?`
|
|
2789
2789
|
|
|
2790
2790
|
Note: This presentation is for "${B.event}".`:""}`,templateName:"decks:generation"})}),A.eval.registerHandler("generateDescription",async(Q)=>{let B=J.object({title:J.string(),content:J.string()}).parse(Q);return A.ai.generate({prompt:`Title: ${B.title}
|
|
2791
2791
|
|
|
@@ -2800,7 +2800,7 @@ Guidelines:
|
|
|
2800
2800
|
3. Depth: Provide enough detail to be useful as a reference, but stay focused on the topic.
|
|
2801
2801
|
4. Style: Informative and educational. Write as if explaining to yourself for future reference.
|
|
2802
2802
|
5. Length: Adjust based on topic complexity - concise for simple topics, more detailed for complex ones.
|
|
2803
|
-
6. No meta-commentary: Just provide the content directly without phrases like "Here is..." or "This note covers..."`});tA();KA();var hu0=J.object({prompt:J.string(),title:J.string().optional()}),jR2=h$.extend({title:J.string().optional()});class mr extends W9{constructor(A,Q){super(A,Q,{schema:hu0,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:ME.createNoteContent(w,B.body),metadata:{title:w},title:w,resultExtras:{title:w}}}summarizeDataForLog(A){return{prompt:A.prompt,title:A.title}}}var yu0={name:"@brains/note",private:!0,version:"0.2.0-alpha.
|
|
2803
|
+
6. No meta-commentary: Just provide the content directly without phrases like "Here is..." or "This note covers..."`});tA();KA();var hu0=J.object({prompt:J.string(),title:J.string().optional()}),jR2=h$.extend({title:J.string().optional()});class mr extends W9{constructor(A,Q){super(A,Q,{schema:hu0,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:ME.createNoteContent(w,B.body),metadata:{title:w},title:w,resultExtras:{title:w}}}summarizeDataForLog(A){return{prompt:A.prompt,title:A.title}}}var yu0={name:"@brains/note",private:!0,version:"0.2.0-alpha.54",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/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 WZA extends n2{entityType=ME.entityType;schema=EE;adapter=ME;constructor(A={}){super("note",yu0,A,HZA)}createGenerationHandler(A){return new mr(this.logger.child("NoteGenerationJobHandler"),A)}getTemplates(){return{generation:KZA}}async onRegister(A){A.eval.registerHandler("generateNote",async(Q)=>{let B=J.object({prompt:J.string()}).parse(Q);return A.ai.generate({prompt:B.prompt,templateName:"note:generation"})})}}function Lz(A={}){return new WZA(A)}tA();KA();KA();tA();var mu0=J.object({ref:J.string(),label:J.string()}),uu0=J.enum(["pending","draft","published"]),UW=J.object({status:uu0,title:J.string(),url:J.string().url(),description:J.string().optional(),domain:J.string(),capturedAt:J.string().datetime(),source:mu0}),cu0=UW.pick({title:!0,status:!0}),m_=r1.extend({entityType:J.literal("link"),metadata:cu0}),UZA=J.object({enableSummarization:J.boolean().default(!0).describe("Generate AI summaries for captured links"),jinaApiKey:J.string().optional().describe("Jina Reader API key for higher rate limits (500 RPM vs 20 RPM without key)")});tA();class zJ extends Q2{constructor(){super({entityType:"link",schema:m_,frontmatterSchema:UW})}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,UW),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 GZA=new zJ;tA();KA();var xR2=J.object({success:J.boolean().describe("Set to true if you can extract meaningful content. Set to false only if the provided content is empty, just an error message, or otherwise unusable."),error:J.string().describe("If success is false, explain why content could not be extracted. Use an empty string when success is true."),title:J.string().max(80).describe("The page title - extract from the content or create a descriptive one. Leave empty string if success is false."),description:J.string().describe("A one-sentence description of what the page is about. Leave empty string if success is false."),summary:J.string().describe("A 1-2 paragraph summary of the main content. Leave empty string if success is false.")}),lu0=G1({name:"link:extraction",description:"Extract structured content from webpage markdown",dataSourceId:"shell:ai-content",schema:xR2,basePrompt:`You are an expert at extracting key information from webpage content.
|
|
2804
2804
|
|
|
2805
2805
|
You will receive webpage content in markdown format. Your job is to extract structured information from it.
|
|
2806
2806
|
|
|
@@ -2822,7 +2822,7 @@ Accuracy rules:
|
|
|
2822
2822
|
|
|
2823
2823
|
`))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 gR2}from"crypto";class Cz{static URL_PATTERN=/https?:\/\/[^\s<>"{}|\\^`[\]]+?(?=[,;:\s]|$)/gi;static extractUrls(A){let Q=A.match(Cz.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=gR2("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}}}tA();KA();var hR2=J.object({url:J.string().url(),metadata:J.object({interfaceId:J.string().optional(),userId:J.string().optional(),channelId:J.string().optional(),channelName:J.string().optional(),timestamp:J.string().optional()}).optional()}),cUB=J.object({success:J.boolean(),entityId:J.string().optional(),title:J.string().optional(),url:J.string().optional(),status:J.enum(["pending","draft","published"]).optional(),error:J.string().optional()});class cr extends VB{context;linkAdapter;urlFetcher;constructor(A,Q,B){super(A,{schema:hR2,jobTypeName:"link-capture"});this.context=Q,this.linkAdapter=new zJ,this.urlFetcher=new VE(B?.jinaApiKey?{jinaApiKey:B.jinaApiKey}:void 0)}async process(A,Q,B){let{url:w,metadata:$}=A;try{await B.report({progress:Z2.START,total:100,message:"Starting link capture"});let D=Cz.generateEntityId(w);await B.report({progress:Z2.INIT,total:100,message:"Checking for existing link"});let I=await this.context.entityService.getEntity({entityType:"link",id:D});if(I){this.logger.info("Link already captured, returning existing",{url:w,entityId:D});let{frontmatter:z}=this.linkAdapter.parseLinkContent(I.content);return{success:!0,entityId:I.id,title:z.title,url:w,status:I.metadata.status}}await B.report({progress:Z2.FETCH,total:100,message:"Fetching webpage content"});let Y=await this.urlFetcher.fetch(w);if(!Y.success){if(Y.errorType==="url_not_found"||Y.errorType==="url_unreachable")return this.logger.warn("Link URL not accessible",{url:w,errorType:Y.errorType,error:Y.error}),{success:!1,error:`Could not capture link: ${Y.error}`}}await B.report({progress:Z2.PROCESS,total:100,message:"Extracting content with AI"});let X=await this.context.ai.generate({templateName:"link:extraction",prompt:Y.success?`Extract structured information from this webpage content:
|
|
2824
2824
|
|
|
2825
|
-
${Y.content}`:`The URL ${w} could not be fetched. Return success: false with error: "${Y.error}"`,data:{url:w,hasContent:Y.success},interfacePermissionGrant:"public"});this.logger.debug("AI extraction result",{result:X}),await B.report({progress:Z2.EXTRACT,total:100,message:"Processing extraction results"});let H=this.resolveSource($),U=new Date().toISOString();if(X.success===!1||!X.title||!X.description||!X.summary){let z=X.title||new URL(w).hostname;this.logger.info("Incomplete extraction, saving as pending",{url:w}),await B.report({progress:Z2.SAVE,total:100,message:"Saving link as pending"});let f=this.linkAdapter.createLinkContent({status:"pending",title:z,url:w,description:X.description,summary:X.summary,domain:new URL(w).hostname,capturedAt:U,source:H}),E=await this.context.entityService.createEntity({entity:{id:D,entityType:"link",content:f,metadata:{status:"pending",title:z}}});return await B.report({progress:Z2.COMPLETE,total:100,message:"Link saved (pending)"}),{success:!0,entityId:E.entityId,title:z,url:w,status:"pending"}}await B.report({progress:Z2.SAVE,total:100,message:`Saving link: "${X.title}"`});let F=this.linkAdapter.createLinkContent({status:"draft",title:X.title,url:w,description:X.description,summary:X.summary,domain:new URL(w).hostname,capturedAt:U,source:H}),Z=await this.context.entityService.createEntity({entity:{id:D,entityType:"link",content:F,metadata:{status:"draft",title:X.title}}});return await B.report({progress:Z2.COMPLETE,total:100,message:`Link captured: "${X.title}"`}),{success:!0,entityId:Z.entityId,title:X.title,url:w,status:"draft"}}catch(D){return this.logger.error("Link capture job failed",{error:D,jobId:Q,data:A}),F8.failure(D)}}resolveSource(A){let Q=A?.channelId,B=A?.channelName;if(Q)return{ref:`matrix:${Q}`,label:B??Q};let w=A?.interfaceId??"cli";return{ref:`${w}:local`,label:w.toUpperCase()}}summarizeDataForLog(A){return{url:A.url,interfaceId:A.metadata?.interfaceId}}}var iu0={name:"@brains/link",private:!0,version:"0.2.0-alpha.
|
|
2825
|
+
${Y.content}`:`The URL ${w} could not be fetched. Return success: false with error: "${Y.error}"`,data:{url:w,hasContent:Y.success},interfacePermissionGrant:"public"});this.logger.debug("AI extraction result",{result:X}),await B.report({progress:Z2.EXTRACT,total:100,message:"Processing extraction results"});let H=this.resolveSource($),U=new Date().toISOString();if(X.success===!1||!X.title||!X.description||!X.summary){let z=X.title||new URL(w).hostname;this.logger.info("Incomplete extraction, saving as pending",{url:w}),await B.report({progress:Z2.SAVE,total:100,message:"Saving link as pending"});let f=this.linkAdapter.createLinkContent({status:"pending",title:z,url:w,description:X.description,summary:X.summary,domain:new URL(w).hostname,capturedAt:U,source:H}),E=await this.context.entityService.createEntity({entity:{id:D,entityType:"link",content:f,metadata:{status:"pending",title:z}}});return await B.report({progress:Z2.COMPLETE,total:100,message:"Link saved (pending)"}),{success:!0,entityId:E.entityId,title:z,url:w,status:"pending"}}await B.report({progress:Z2.SAVE,total:100,message:`Saving link: "${X.title}"`});let F=this.linkAdapter.createLinkContent({status:"draft",title:X.title,url:w,description:X.description,summary:X.summary,domain:new URL(w).hostname,capturedAt:U,source:H}),Z=await this.context.entityService.createEntity({entity:{id:D,entityType:"link",content:F,metadata:{status:"draft",title:X.title}}});return await B.report({progress:Z2.COMPLETE,total:100,message:`Link captured: "${X.title}"`}),{success:!0,entityId:Z.entityId,title:X.title,url:w,status:"draft"}}catch(D){return this.logger.error("Link capture job failed",{error:D,jobId:Q,data:A}),F8.failure(D)}}resolveSource(A){let Q=A?.channelId,B=A?.channelName;if(Q)return{ref:`matrix:${Q}`,label:B??Q};let w=A?.interfaceId??"cli";return{ref:`${w}:local`,label:w.toUpperCase()}}summarizeDataForLog(A){return{url:A.url,interfaceId:A.metadata?.interfaceId}}}var iu0={name:"@brains/link",private:!0,version:"0.2.0-alpha.54",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/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 NZA extends n2{entityType=GZA.entityType;schema=m_;adapter=GZA;shell;constructor(A={}){super("link",iu0,A,UZA)}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 cr(this.logger.child("LinkCaptureJobHandler"),this.context,this.config.jinaApiKey?{jinaApiKey:this.config.jinaApiKey}:void 0),this.id),Q}async interceptCreate(A,Q,B){if(A.content)try{let D=this.adapter.fromMarkdown(A.content).metadata,I=typeof D?.title==="string"?D.title:void 0,Y=typeof D?.status==="string"?D.status:void 0,X=this.extractFirstUrl(A.content);if(I&&Y&&X){let H=t1(X)||t1(I)||`${A.entityType}-${Date.now()}`,U=new Date().toISOString();return{kind:"handled",result:{success:!0,data:{entityId:(await B.entityService.createEntity({entity:{id:H,entityType:A.entityType,content:A.content,metadata:{title:I,status:Y},created:U,updated:U}})).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 cr(this.logger.child("LinkCaptureJobHandler"),A,this.config.jinaApiKey?{jinaApiKey:this.config.jinaApiKey}:void 0)}getTemplates(){return{extraction:lu0,"link-list":pu0,"link-detail":du0}}getDataSources(){return[new qZA(this.logger.child("LinksDataSource"))]}async onRegister(A){A.eval.registerHandler("extractContent",async(Q)=>{let{url:B}=J.object({url:J.string().url()}).parse(Q),$=await new VE(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:
|
|
2826
2826
|
|
|
2827
2827
|
${$.content}`,data:{url:B,hasContent:!0},interfacePermissionGrant:"public"})})}extractFirstUrl(...A){for(let Q of A){if(!Q)continue;let[B]=Cz.extractUrls(Q);if(B)return B}return}}function ru0(A={}){return new NZA(A)}var Ez=ru0;KA();var XGB=J.object({id:J.string().optional(),metadata:J.object({conversationId:J.string().optional(),interfaceId:J.string().optional(),userId:J.string().optional(),messageId:J.string().optional(),timestamp:J.string().optional()}).optional()});tA();KA();Q8();KA();tA();var nu0=J.enum(["draft","published"]),OI=J.object({title:J.string(),slug:J.string().optional(),status:nu0,publishedAt:J.string().datetime().optional(),description:J.string(),year:J.number(),coverImageId:J.string().optional(),url:J.string().url().optional()}),ou0=OI.pick({title:!0,status:!0,publishedAt:!0,year:!0}).extend({slug:J.string()}),OE=r1.extend({entityType:J.literal("project"),metadata:ou0}),lr=J.object({context:J.string(),problem:J.string(),solution:J.string(),outcome:J.string()}),c_=OE.extend({frontmatter:OI,body:J.string(),structuredContent:lr.optional(),coverImageUrl:J.string().optional()}),RE=c_.extend({url:J.string().optional(),typeLabel:J.string().optional(),coverImageUrl:J.string().optional(),coverImageWidth:J.number().optional(),coverImageHeight:J.number().optional()}),mR2=c_.extend({url:J.string(),typeLabel:J.string(),coverImageUrl:J.string().optional(),coverImageWidth:J.number().optional(),coverImageHeight:J.number().optional()});tA();KA();KA();class fZA extends IB{constructor(){super(lr,{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 LZA=new fZA;class CZA extends Q2{constructor(){super({entityType:"project",schema:OE,frontmatterSchema:OI,supportsCoverImage:!0,bodyFormatter:LZA})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,OI),w={...B,slug:B.slug??A.metadata.slug};return this.buildMarkdown(Q,w)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,OI),B=Q.slug??t1(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,OI)}parseStructuredContent(A){return LZA.parse(this.extractBody(A.content))}createProjectContent(A,Q){let B=LZA.format(Q);return this.buildMarkdown(B,A)}}var qJ=new CZA;KA();var EZA=J.object({});import{jsxDEV as qD,Fragment as cR2}from"preact/jsx-dev-runtime";var uR2=({project:A})=>{let{frontmatter:Q,url:B,coverImageUrl:w}=A;return qD(WQ,{href:B,children:[w&&qD("img",{src:w,alt:Q.title,className:"w-full h-56 object-cover rounded-md mb-4"},void 0,!1,void 0,this),qD(U5,{children:Q.title},void 0,!1,void 0,this),qD("p",{className:"text-theme leading-relaxed",children:Q.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},MZA=({projects:A,pageTitle:Q,pagination:B,baseUrl:w="/projects"})=>{let $=Q??"Projects",D=B?.totalItems??A.length,I=`Browse all ${D} ${D===1?"project":"projects"}`;return qD(cR2,{children:[qD(u2,{title:$,description:I},void 0,!1,void 0,this),qD("div",{className:"project-list bg-theme",children:qD("div",{className:"container mx-auto px-6 md:px-12 max-w-5xl py-16 md:py-24",children:[qD("h1",{className:"text-4xl font-bold text-heading mb-12",children:$},void 0,!1,void 0,this),qD("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-8",children:A.map((Y)=>qD(uR2,{project:Y},Y.id,!1,void 0,this))},void 0,!1,void 0,this),B&&B.totalPages>1&&qD("div",{className:"mt-12",children:qD(a4,{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 UB,Fragment as su0}from"preact/jsx-dev-runtime";var lR2=({prevProject:A,nextProject:Q})=>{if(!A&&!Q)return null;return UB("nav",{className:"pt-12 mt-12 border-t border-theme-muted",children:UB("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[A?UB(WQ,{href:A.url,variant:"compact",children:[UB("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Previous"},void 0,!1,void 0,this),UB("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):UB("div",{},void 0,!1,void 0,this),Q&&UB(WQ,{href:Q.url,variant:"compact",className:"md:text-right",children:[UB("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Next"},void 0,!1,void 0,this),UB("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)},pr=({title:A,content:Q})=>{if(!Q)return null;return UB("section",{className:"mb-12",children:[UB("h2",{className:"text-2xl font-bold text-heading mb-4",children:A},void 0,!1,void 0,this),UB(GD,{markdown:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},VZA=({project:A,prevProject:Q,nextProject:B})=>{let{frontmatter:w,structuredContent:$,metadata:D,coverImageUrl:I}=A;return UB(su0,{children:[UB(u2,{title:w.title,description:w.description,...I&&{ogImage:I},ogType:"article"},void 0,!1,void 0,this),UB("article",{className:"project-detail",children:UB("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:UB("div",{className:"max-w-3xl mx-auto",children:[I&&A.coverImageWidth&&A.coverImageHeight&&UB(iK,{src:I,alt:w.title,width:A.coverImageWidth,height:A.coverImageHeight,className:"mb-8 shadow-lg"},void 0,!1,void 0,this),UB("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),UB("div",{className:"flex flex-wrap items-center gap-4 text-theme-muted mb-8",children:[UB("span",{className:"text-sm",children:D.year},void 0,!1,void 0,this),w.url&&UB(su0,{children:[UB("span",{className:"text-theme-muted",children:"|"},void 0,!1,void 0,this),UB("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),UB("p",{className:"text-lg text-theme mb-12 leading-relaxed",children:w.description},void 0,!1,void 0,this),$&&UB("div",{className:"case-study",children:[UB(pr,{title:"Context",content:$.context},void 0,!1,void 0,this),UB(pr,{title:"Problem",content:$.problem},void 0,!1,void 0,this),UB(pr,{title:"Solution",content:$.solution},void 0,!1,void 0,this),UB(pr,{title:"Outcome",content:$.outcome},void 0,!1,void 0,this)]},void 0,!0,void 0,this),UB(lR2,{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)};KA();tA();var pR2=J.object({title:J.string().max(80).describe("A clear, compelling project title (3-8 words). Should capture the essence of the project."),description:J.string().describe("A 1-2 sentence summary of the project for portfolio cards. Focus on the core value delivered."),context:J.string().describe("Background information: Who was the client/user? What was the situation? What constraints existed? (2-4 paragraphs)"),problem:J.string().describe("The challenge: What specific problem needed solving? What were the pain points? (2-3 paragraphs)"),solution:J.string().describe("The approach: What was built? What technologies/methods were used? How did it work? (3-5 paragraphs)"),outcome:J.string().describe("The results: What impact did this have? What metrics improved? What was learned? (2-3 paragraphs)")}),OZA=G1({name:"portfolio:generation",description:"Template for AI to generate portfolio project case studies",schema:pR2,dataSourceId:"shell:ai-content",requiredPermission:"public",useKnowledgeContext:!0,basePrompt:`You are helping to create a professional portfolio case study based on REAL project information.
|
|
2828
2828
|
|
|
@@ -2846,7 +2846,7 @@ ${A.prompt}
|
|
|
2846
2846
|
|
|
2847
2847
|
Project year: ${A.year}
|
|
2848
2848
|
|
|
2849
|
-
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 dr extends W9{constructor(A,Q){super(A,Q,{schema:dR2,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:RZA(A),templateName:"portfolio:generation"}),$=A.title??w.title,D=t1($);await this.reportProgress(Q,{progress:50,message:`Generated project: "${$}"`});let I={title:$,slug:D,status:"draft",description:w.description,year:B},Y={context:w.context,problem:w.problem,solution:w.solution,outcome:w.outcome};return{id:D,content:qJ.createProjectContent(I,Y),metadata:{title:$,slug:D,status:"draft",year:B},title:$,resultExtras:{title:$}}}summarizeDataForLog(A){return{prompt:A.prompt.substring(0,100),year:A.year,title:A.title}}}tA();tA();function iR2(A){let Q=M2(A.content,OI),B=qJ.parseStructuredContent(A);return c_.parse({...A,frontmatter:Q.metadata,body:Q.content,structuredContent:B})}class ir extends U6{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 iR2(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 au0={name:"@brains/portfolio",private:!0,version:"0.2.0-alpha.
|
|
2849
|
+
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 dr extends W9{constructor(A,Q){super(A,Q,{schema:dR2,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:RZA(A),templateName:"portfolio:generation"}),$=A.title??w.title,D=t1($);await this.reportProgress(Q,{progress:50,message:`Generated project: "${$}"`});let I={title:$,slug:D,status:"draft",description:w.description,year:B},Y={context:w.context,problem:w.problem,solution:w.solution,outcome:w.outcome};return{id:D,content:qJ.createProjectContent(I,Y),metadata:{title:$,slug:D,status:"draft",year:B},title:$,resultExtras:{title:$}}}summarizeDataForLog(A){return{prompt:A.prompt.substring(0,100),year:A.year,title:A.title}}}tA();tA();function iR2(A){let Q=M2(A.content,OI),B=qJ.parseStructuredContent(A);return c_.parse({...A,frontmatter:Q.metadata,body:Q.content,structuredContent:B})}class ir extends U6{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 iR2(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 au0={name:"@brains/portfolio",private:!0,version:"0.2.0-alpha.54",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/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 nR2=J.object({projects:J.array(RE),pageTitle:J.string().optional(),pagination:K9.nullable(),baseUrl:J.string().optional()});function oR2(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 bZA extends n2{entityType=qJ.entityType;schema=OE;adapter=qJ;constructor(A={}){super("portfolio",au0,A,EZA)}async interceptCreate(A,Q,B){if(!A.prompt||A.content)return{kind:"continue",input:A};let w=oR2(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 dr(this.logger.child("ProjectGenerationJobHandler"),A)}getTemplates(){return{"project-list":G1({name:"project-list",description:"Portfolio project list page template",schema:nR2,dataSourceId:"portfolio:entities",requiredPermission:"public",layout:{component:MZA}}),"project-detail":G1({name:"project-detail",description:"Individual project case study template",schema:J.object({project:RE,prevProject:RE.nullable(),nextProject:RE.nullable()}),dataSourceId:"portfolio:entities",requiredPermission:"public",layout:{component:VZA}}),generation:OZA}}getDataSources(){return[new ir(this.logger.child("ProjectDataSource"))]}async onRegister(A){this.registerEvalHandlers(A),await this.registerWithPublishPipeline(A),this.subscribeToPublishExecute(A)}registerEvalHandlers(A){A.eval.registerHandler("generateProject",async(Q)=>{let B=J.object({prompt:J.string(),year:J.number()}).parse(Q);return A.ai.generate({prompt:RZA(B),templateName:"portfolio:generation"})})}async registerWithPublishPipeline(A){let Q={name:"internal",publish:async()=>({id:"internal"})};await A.messaging.send({type:"publish:register",payload:{entityType:"project",provider:Q}})}subscribeToPublishExecute(A){A.messaging.subscribe("publish:execute",async(Q)=>{let{entityType:B,entityId:w}=Q.payload;if(B!=="project")return{success:!0};try{let $=await A.entityService.getEntity({entityType:"project",id:w});if(!$)return await A.messaging.send({type:"publish:report:failure",payload:{entityType:B,entityId:w,error:`Project not found: ${w}`}}),{success:!0};if($.metadata.status==="published")return{success:!0};let D=M2($.content,OI),I=new Date().toISOString(),Y=H9(D.content,{...D.metadata,status:"published",publishedAt:I});await A.entityService.updateEntity({entity:{...$,content:Y,metadata:{...$.metadata,status:"published",publishedAt:I}}}),await A.messaging.send({type:"publish:report:success",payload:{entityType:B,entityId:w,publishedAt:I}})}catch($){await A.messaging.send({type:"publish:report:failure",payload:{entityType:B,entityId:w,error:L0($)}})}return{success:!0}})}}function PZA(A={}){return new bZA(A)}tA();KA();var tu0=J.object({includeEntityTypes:J.array(J.string()).default([]),minRelevanceScore:J.number().min(0).max(1).default(0.5),mergeSimilarityThreshold:J.number().min(0).max(1).default(0.85),autoMerge:J.boolean().default(!0),extractableStatuses:J.array(J.string()).default(["published"]),enableAutoExtraction:J.boolean().default(!0)});tA();KA();tA();var sR2=J.object({aliases:J.array(J.string()).optional()}),rr=r1.extend({entityType:J.literal("topic"),metadata:sR2}),CJB=J.object({content:J.string()}),eu0=J.object({title:J.string().describe("Topic title")});var GW="topics",GB="topic",kZA="topics-projection",Ac0="topic:project",bE="topics-plugin";class JW extends Q2{constructor(){super({entityType:GB,schema:rr,frontmatterSchema:eu0})}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:GB}}extractMetadata(A){return{aliases:A.metadata.aliases??[]}}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))}}tA();KA();var aR2=new JW;class jZA{context;logger;constructor(A,Q){this.context=A;this.logger=Q}async synthesize(A){let Q=aR2.parseTopicBody(A.existingTopic.content);return this.logger.debug("Synthesizing merged topic",{existingTitle:Q.title,incomingTitle:A.incomingTopic.title}),this.context.ai.generate({templateName:"topics:merge-synthesis",prompt:`Canonical topic candidate:
|
|
2850
2850
|
Title: ${Q.title}
|
|
2851
2851
|
Content:
|
|
2852
2852
|
${Q.content}
|
|
@@ -2949,13 +2949,13 @@ ${A.content}`}class r_{context;logger;constructor(A,Q){this.context=A;this.logge
|
|
|
2949
2949
|
|
|
2950
2950
|
${Q.content}`}).join(`
|
|
2951
2951
|
|
|
2952
|
-
`)}async function n_(A,Q,B){if(A.length===0)return{created:0,skipped:0,batches:0};let w=qc0(A),$=new ND(Q.entityService,B),D=0,I=0;for(let Y of w){B.info(`Processing batch of ${Y.length} entities`);let X=Wb2(Y),H=await tr(Q.entityService),U=er({entityTitle:`Batch of ${Y.length} entities`,entityType:"batch",content:X,existingTopicTitles:H});try{let F=await Q.ai.generate({prompt:U,templateName:"topics:extraction"});for(let Z of F.topics){let z=sH(Z.title);if(await $.getTopic(z)){I++;continue}await $.createTopic({title:Z.title,content:Z.content}),D++}}catch(F){B.error("Batch topic extraction failed",{batchSize:Y.length,promptChars:U.length,error:L0(F)})}}return{created:D,skipped:I,batches:w.length}}KA();tA();KA();var Ub2=J.object({entityId:J.string(),entityType:J.string(),contentHash:J.string(),minRelevanceScore:J.number().min(0).max(1),autoMerge:J.boolean(),mergeSimilarityThreshold:J.number().min(0).max(1)});class SZA extends VB{topicExtractor;context;constructor(A,Q){super(Q,{schema:Ub2,jobTypeName:"topic-extraction"});this.context=A,this.topicExtractor=new r_(A,Q)}async process(A,Q,B){let{entityId:w,entityType:$,contentHash:D,minRelevanceScore:I,autoMerge:Y,mergeSimilarityThreshold:X}=A;this.logger.debug("Starting topic extraction job",{jobId:Q,entityId:w,entityType:$,contentHash:D});try{await B.report({progress:Z2.INIT,message:`Extracting topics from ${$}: ${w}`});let H=await this.context.entityService.getEntity({entityType:$,id:w});if(!H)return this.logger.warn("Entity no longer exists, skipping topic extraction",{jobId:Q,entityId:w,entityType:$}),{success:!0,topicsExtracted:0};if(H.contentHash!==D)return this.logger.info("Entity content changed since job created, skipping stale extraction",{jobId:Q,entityId:w,entityType:$,jobContentHash:D,currentContentHash:H.contentHash}),{success:!0,topicsExtracted:0};let U=await this.topicExtractor.extractFromEntity(H,I);if(await B.report({progress:Z2.EXTRACT,message:`Extracted ${U.length} topics`}),U.length===0)return this.logger.debug("No topics found in entity",{entityId:w,entityType:$}),await B.report({progress:Z2.COMPLETE,message:"No topics found"}),{success:!0,topicsExtracted:0};let F=U.map((f)=>({type:"topics:process-single",data:{topic:f,sourceEntityId:w,sourceEntityType:$,autoMerge:Y,mergeSimilarityThreshold:X},metadata:{operationType:"data_processing",operationTarget:f.title}})),Z=S8(),z=await this.context.jobs.enqueueBatch(F,{priority:5,source:bE,rootJobId:Z,metadata:{operationType:"batch_processing",operationTarget:`process topics for ${$}:${w}`,pluginId:GW}});return await B.report({progress:Z2.COMPLETE,message:`Queued ${U.length} topics for processing`}),this.logger.debug("Queued topic processing batch",{batchId:z,entityId:w,entityType:$,topicsExtracted:U.length}),{success:!0,topicsExtracted:U.length,batchId:z}}catch(H){return this.logger.error("Topic extraction job failed",{jobId:Q,entityId:w,entityType:$,error:L0(H)}),{...F8.failure(H),topicsExtracted:0}}}summarizeDataForLog(A){return{entityId:A.entityId,entityType:A.entityType,contentHash:A.contentHash}}}var Gb2=J.discriminatedUnion("mode",[J.object({mode:J.literal("derive"),reason:J.string().optional()}),J.object({mode:J.literal("rebuild"),reason:J.string().optional()}),J.object({mode:J.literal("source"),entityId:J.string(),entityType:J.string(),contentHash:J.string().optional(),minRelevanceScore:J.number().min(0).max(1).optional(),autoMerge:J.boolean().optional(),mergeSimilarityThreshold:J.number().min(0).max(1).optional()})]);function Nc0(A){let{context:Q,logger:B,config:w}=A,$=new SZA(Q,B),D=T8.from(async()=>{});if(!D)throw Error("Failed to create progress reporter");return{process:async(I)=>{if(I.mode==="derive")return await A.extractAllTopics(),{success:!0};if(I.mode==="rebuild")return await A.rebuildAllTopics(),{success:!0};let Y=await Q.entityService.getEntity({entityType:I.entityType,id:I.entityId});if(!Y)return{success:!1,topicsExtracted:0};return $.process({entityId:I.entityId,entityType:I.entityType,contentHash:I.contentHash??Y.contentHash,minRelevanceScore:I.minRelevanceScore??w.minRelevanceScore,autoMerge:I.autoMerge??w.autoMerge,mergeSimilarityThreshold:I.mergeSimilarityThreshold??w.mergeSimilarityThreshold},`topic-projection:${I.entityType}:${I.entityId}`,D)},validateAndParse:(I)=>{let Y=Gb2.safeParse(I??{});return Y.success?Y.data:null}}}function fc0(){return{priority:5,source:bE,deduplication:"coalesce",deduplicationKey:"topics-initial-derivation",metadata:{operationType:"data_processing",operationTarget:"topics-initial-derivation",pluginId:GW}}}async function Lc0(A){let Q=await Ec0(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 n_(Q,A.context,A.logger);A.logger.info("Batch topic extraction complete",B)}async function Cc0(A){let Q=await Ec0(A),B=await gZA(Q,A.context,A.logger);A.logger.info("Topic rebuild complete",B)}async function gZA(A,Q,B){let w=new ND(Q.entityService,B),$=await w.listTopics();for(let I of $)await w.deleteTopic(I.id);if(A.length===0)return{deleted:$.length,created:0,skipped:0,batches:0};let D=await n_(A,Q,B);return{deleted:$.length,...D}}async function Ec0(A){let Q=Jb2(A),B=[];for(let w of Q){let $=await A.context.entityService.listEntities({entityType:w});for(let D of $){if(!A.isEntityPublished(D))continue;B.push(D)}}return B}function Jb2(A){return A.context.entityService.getEntityTypes().filter((B)=>A.shouldProcessEntityType(B))}var kE=J.object({entityType:J.string(),content:J.string(),metadata:J.record(J.unknown()).optional()}),Fb2=kE.extend({minRelevanceScore:J.number().optional()}),Zb2=J.object({contentA:kE,contentB:kE,minRelevanceScore:J.number().optional()}),s_=J.object({title:J.string(),content:J.string()}),zb2=J.object({existingTopics:J.array(s_),incomingTopic:s_,threshold:J.number().optional()}),qb2=J.object({existingAliases:J.array(J.string()).optional(),canonicalTitle:J.string(),candidateAliases:J.array(J.string())}),Nb2=J.object({existingTopics:J.array(s_.extend({aliases:J.array(J.string()).optional()})).default([]),incomingTopic:s_.extend({relevanceScore:J.number().min(0).max(1).optional()}),threshold:J.number().optional()}),fb2=J.object({entities:J.array(kE).min(1),minRelevanceScore:J.number().optional()}),Lb2=J.object({existingTopics:J.array(s_).optional(),entities:J.array(kE)}),Cb2=J.object({entities:J.array(kE)});function o_(A,Q=""){return{id:`eval${Q}-${Date.now()}`,entityType:A.entityType,content:A.content,contentHash:Aw(A.content),metadata:A.metadata??{},created:new Date().toISOString(),updated:new Date().toISOString()}}function Mc0(A){return{title:A.title,relevanceScore:A.relevanceScore}}function Eb2(A){let Q=A.metadata.title;return typeof Q==="string"?Q:A.id}function Mb2(A,Q){return{...A,sources:[{id:Q.id,type:Q.entityType,title:Eb2(Q)}]}}async function Mz(A){let Q=await A.entityService.listEntities({entityType:GB});await Promise.all(Q.map((B)=>A.entityService.deleteEntity({entityType:GB,id:B.id})))}function Vc0(A){let{context:Q,logger:B,config:w}=A,$=new r_(Q,B),D=async(I,Y,X="")=>{let H=o_(I,X);return $.extractFromEntity(H,Y)};Q.eval.registerHandler("extractFromEntity",async(I)=>{await Mz(Q);let Y=Fb2.parse(I),X=Y.minRelevanceScore??w.minRelevanceScore,H=o_(Y);return(await $.extractFromEntity(H,X)).map((F)=>Mb2(F,H))}),Q.eval.registerHandler("checkMergeSimilarity",async(I)=>{await Mz(Q);let Y=Zb2.parse(I),X=Y.minRelevanceScore??w.minRelevanceScore,[H,U]=await Promise.all([D(Y.contentA,X,"-a"),D(Y.contentB,X,"-b")]),F=H.map((f)=>f.title.toLowerCase()),Z=U.map((f)=>f.title.toLowerCase()),z=F.filter((f)=>Z.includes(f));return{topicsA:H.map(Mc0),topicsB:U.map(Mc0),matchingTitles:z,wouldMerge:z.length>0}}),Q.eval.registerHandler("detectMergeCandidate",async(I)=>{await Mz(Q);let Y=zb2.parse(I),X=Y.threshold??w.mergeSimilarityThreshold,H=new ND(Q.entityService,B);for(let F of Y.existingTopics)await H.createTopic(F);let U=await H.findMergeCandidate({title:Y.incomingTopic.title},X);return{found:U!==null,candidateTitle:U?.title,candidateScore:U?.score}}),Q.eval.registerHandler("mergeAliases",async(I)=>{let Y=qb2.parse(I);return{aliases:new ND(Q.entityService,B).mergeAliases(Y.existingAliases,Y.canonicalTitle,Y.candidateAliases)}}),Q.eval.registerHandler("processTopicWithAutoMerge",async(I)=>{await Mz(Q);let Y=Nb2.parse(I),X=new ND(Q.entityService,B);for(let z of Y.existingTopics)await X.createTopic({title:z.title,content:z.content,metadata:{aliases:z.aliases??[]}});let H=new l_(Q,B),U=T8.from(async()=>{});if(!U)throw Error("Failed to create progress reporter");let F=await H.process({topic:{title:Y.incomingTopic.title,content:Y.incomingTopic.content,relevanceScore:Y.incomingTopic.relevanceScore??0.9},sourceEntityId:"eval-source",sourceEntityType:"post",autoMerge:!0,mergeSimilarityThreshold:Y.threshold??w.mergeSimilarityThreshold},`eval-job-${Date.now()}`,U),Z=await Q.entityService.listEntities({entityType:GB});return{...F,topicCount:Z.length,topics:Z.map(vZA)}}),Q.eval.registerHandler("rebuildTopics",async(I)=>{await Mz(Q);let Y=Lb2.parse(I),X=new ND(Q.entityService,B);for(let Z of Y.existingTopics??[])await X.createTopic(Z);let H=Y.entities.map((Z,z)=>o_(Z,`-rebuild-${z}`)),U=await gZA(H,Q,B),F=await Q.entityService.listEntities({entityType:GB});return{...U,topicCount:F.length,topics:F.map(vZA)}}),Q.eval.registerHandler("extractSequentially",async(I)=>{await Mz(Q);let Y=fb2.parse(I),X=Y.minRelevanceScore??w.minRelevanceScore,H=new ND(Q.entityService,B),U=[];for(let[Z,z]of Y.entities.entries()){let f=o_(z,`-sequential-${Z}`),E=await $.extractFromEntity(f,X);for(let C of E)await H.createTopic({title:C.title,content:C.content});U.push({extractedTitles:E.map((C)=>C.title)})}let F=await Q.entityService.listEntities({entityType:GB});return{totalTopics:F.length,perEntity:U,topics:F.map(PE)}}),Q.eval.registerHandler("batchExtract",async(I)=>{await Mz(Q);let X=Cb2.parse(I).entities.map((F,Z)=>o_(F,`-batch-${Z}`)),H=await n_(X,Q,B),U=await Q.entityService.listEntities({entityType:GB});return{...H,topics:U.map(PE)}})}var Oc0={name:"@brains/topics",private:!0,version:"0.2.0-alpha.53",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/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 Ob2=new JW;class Rc0 extends n2{entityType=GB;schema=rr;adapter=Ob2;constructor(A={}){super(GW,Oc0,A,tu0)}getEntityTypeConfig(){return{weight:0.5}}getTemplates(){return{extraction:Yc0,"merge-synthesis":Xc0,"topic-list":Hc0,"topic-detail":Kc0}}getDataSources(){return[new TZA(this.logger.child("TopicsDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableAutoExtraction)return[];return[{id:kZA,targetType:GB,job:{type:Ac0,handler:Nc0({context:A,logger:this.logger,config:this.config,extractAllTopics:()=>this.extractAllTopics(A),rebuildAllTopics:()=>this.rebuildAllTopics(A)})},initialSync:{shouldEnqueue:async()=>!await oF(A,GB),jobData:{mode:"derive",reason:"initial-sync"},jobOptions:fc0()},sourceChange:{sourceTypes:this.config.includeEntityTypes,requireInitialSync:!0,jobData:(Q)=>{let B=Q.entity;if(!B)return null;if(!this.shouldProcessEntityType(B.entityType))return null;if(!this.isEntityPublished(B))return null;return{mode:"source",entityId:B.id,entityType:B.entityType,contentHash:B.contentHash,minRelevanceScore:this.config.minRelevanceScore,autoMerge:this.config.autoMerge,mergeSimilarityThreshold:this.config.mergeSimilarityThreshold}},jobOptions:(Q)=>({priority:5,source:bE,deduplication:"coalesce",deduplicationKey:`topics-source:${Q.entityType}:${Q.entityId}:${Q.entity?.contentHash??"unknown"}`,metadata:{operationType:"data_processing",operationTarget:`topic-projection:${Q.entityType}:${Q.entityId}`,pluginId:GW}})}}]}async onRegister(A){let Q=new l_(A,this.logger);A.jobs.registerHandler("process-single",Q),A.insights.register("topic-distribution",Gc0()),Jc0({context:A,pluginId:this.id}),Vc0({context:A,logger:this.logger,config:this.config})}hasRunInitialDerivation(){return this.getDerivedEntityProjectionController(kZA)?.hasQueuedInitialSync()??!1}shouldProcessEntityType(A){if(A===GB)return!1;return this.config.includeEntityTypes.includes(A)}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 Lc0({context:A,logger:this.logger,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}async rebuildAllTopics(A){await Cc0({context:A,logger:this.logger,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}}function An(A){return new Rc0(A)}tA();KA();tA();var bc0=J.enum(["linkedin"]),Pc0=J.enum(["draft","queued","published","failed"]),kc0=J.enum(["post","deck"]),RI=J.object({title:J.string().describe("Short descriptive title (3-6 words) for file naming"),platform:bc0.describe("Target platform"),status:Pc0,coverImageId:J.string().optional().describe("Image entity ID for post image"),publishedAt:J.string().datetime().optional(),platformPostId:J.string().optional().describe("ID from platform after publishing"),sourceEntityId:J.string().optional().describe("Source entity ID if auto-generated"),sourceEntityType:kc0.optional().describe("Source entity type (post, deck)")}),jc0=RI.pick({title:!0,platform:!0,status:!0,publishedAt:!0,platformPostId:!0}).extend({slug:J.string().describe("URL-friendly identifier: {platform}-{title}")}),jE=r1.extend({entityType:J.literal("social-post"),metadata:jc0}),Qn=jE.extend({frontmatter:RI,body:J.string()}),Bn=Qn.extend({url:J.string().optional(),listUrl:J.string().optional(),listLabel:J.string().optional(),typeLabel:J.string().optional(),coverImageUrl:J.string().optional(),coverImageWidth:J.number().optional(),coverImageHeight:J.number().optional()});tA();KA();class hZA extends Q2{constructor(){super({entityType:"social-post",schema:jE,frontmatterSchema:RI,supportsCoverImage:!0})}toMarkdown(A){let Q="",B={};try{B=this.parseFrontMatter(A.content,RI),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,RI),B=`${Q.platform}-${t1(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,RI)}getPostContent(A){return this.extractBody(A.content)}createPostContent(A,Q){return this.buildMarkdown(Q,A)}}var H7=new hZA;tA();tA();KA();var Rb2=BX.extend({platform:J.enum(["linkedin"]).optional(),status:J.enum(["draft","queued","published","failed"]).optional(),sortByQueue:J.boolean().optional(),nextInQueue:J.boolean().optional()}),bb2=wX.extend({query:Rb2.optional()});function _c0(A){let Q=M2(A.content,RI);return Qn.parse({...A,frontmatter:Q.metadata,body:Q.content})}class wn extends U6{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=bb2.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}transformEntity(A){return _c0(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:U}=await this.fetchDetail(w.id,$);return Q.parse(this.buildDetailResult(U,null))}let D={};if(w.platform)D.platform=w.platform;if(w.status)D.status=w.status;let I=Object.keys(D).length>0,Y=w.sortByQueue?[{field:"queueOrder",direction:"asc"}]:this.config.defaultSort,{items:X,pagination:H}=await this.fetchList(w,$,{...I&&{filter:{metadata:D}},sortFields:Y});return Q.parse(this.buildListResult(X,H,w))}async fetchNextInQueue(A,Q){let w=(await Q.listEntities({entityType:this.config.entityType,options:{filter:{metadata:{status:"queued"}},sortFields:[{field:"queueOrder",direction:"asc"}],limit:1}}))[0],$=w?_c0(w):null;return A.parse({post:$})}}KA();var xc0=J.object({accessToken:J.string().optional(),refreshToken:J.string().optional(),organizationId:J.string().optional()}),yZA=J.object({linkedin:xc0.optional(),publishInterval:J.number().default(3600000),enabled:J.boolean().default(!0),defaultPrompt:J.string().default("Create an engaging social media post that drives engagement"),maxRetries:J.number().default(3),autoGenerateOnBlogPublish:J.boolean().default(!1)});tA();KA();uZA();import{jsxDEV as i8,Fragment as jb2}from"preact/jsx-dev-runtime";function Pb2(A,Q){if(A.length<=Q)return A;return A.slice(0,Q).trim()+"..."}function kb2(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"})}var Dn=({posts:A,pageTitle:Q,pagination:B,baseUrl:w="/social-posts"})=>{let $=Q??"Social Posts",D=B?.totalItems??A.length,I=`Browse all ${D} social ${D===1?"post":"posts"}`;return i8(jb2,{children:[i8(u2,{title:$,description:I},void 0,!1,void 0,this),i8("div",{className:"social-post-list bg-theme",children:i8("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[i8("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:$},void 0,!1,void 0,this),A.length===0?i8("p",{className:"text-theme-muted italic",children:"No social posts yet."},void 0,!1,void 0,this):i8("ul",{className:"space-y-6",children:A.map((Y)=>i8("li",{children:i8(WQ,{href:Y.url,variant:"horizontal",children:i8("div",{className:"flex flex-col sm:flex-row gap-4",children:[Y.coverImageUrl&&i8("img",{src:Y.coverImageUrl,alt:Y.frontmatter.title,className:"w-full sm:w-24 h-48 sm:h-24 object-cover rounded-lg shrink-0"},void 0,!1,void 0,this),i8("div",{className:"flex-1 min-w-0",children:[i8("div",{className:"flex items-start justify-between gap-4 mb-2",children:[i8("h2",{className:"text-lg font-semibold text-heading",children:Y.frontmatter.title},void 0,!1,void 0,this),i8("time",{className:"text-sm text-theme-muted shrink-0",children:kb2(Y.frontmatter.publishedAt??Y.created)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),i8("div",{className:"flex items-center gap-2 mb-3",children:[i8(D7,{status:Y.frontmatter.status},void 0,!1,void 0,this),i8("span",{className:"text-xs text-theme-muted uppercase",children:Y.frontmatter.platform},void 0,!1,void 0,this),i8("span",{className:"text-xs text-theme-muted font-mono",children:Y.id},void 0,!1,void 0,this)]},void 0,!0,void 0,this),i8("p",{className:"text-theme leading-relaxed",children:Pb2(Y.body,200)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},Y.id,!1,void 0,this))},void 0,!1,void 0,this),B&&B.totalPages>1&&i8(a4,{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 r8,Fragment as _b2}from"preact/jsx-dev-runtime";function vc0(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric",hour:"numeric",minute:"2-digit"})}var In=({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 r8(_b2,{children:[r8(u2,{title:Q,description:B},void 0,!1,void 0,this),r8("section",{className:"social-post-detail",children:r8("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:r8("div",{className:"max-w-3xl mx-auto",children:[r8(LI,{items:w},void 0,!1,void 0,this),r8("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-4",children:A.frontmatter.title},void 0,!1,void 0,this),r8("div",{className:"flex flex-wrap items-center gap-3 mb-6",children:[r8(D7,{status:A.frontmatter.status},void 0,!1,void 0,this),r8("span",{className:"text-sm text-theme-muted uppercase",children:A.frontmatter.platform},void 0,!1,void 0,this),r8("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&&r8(iK,{src:A.coverImageUrl,alt:A.frontmatter.title,width:A.coverImageWidth,height:A.coverImageHeight,className:"mb-8"},void 0,!1,void 0,this),r8(WQ,{className:"p-8 mb-8",children:r8("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),r8("div",{className:"space-y-4 text-sm text-theme-muted",children:[r8("div",{children:[r8("span",{className:"font-medium",children:"Created:"},void 0,!1,void 0,this)," ",vc0(A.created)]},void 0,!0,void 0,this),A.frontmatter.publishedAt&&r8("div",{children:[r8("span",{className:"font-medium",children:"Published:"},void 0,!1,void 0,this)," ",vc0(A.frontmatter.publishedAt)]},void 0,!0,void 0,this),A.frontmatter.platformPostId&&r8("div",{children:r8("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 a_(A){return`social-media:${A}`}var cZA=J.object({prompt:J.string().optional(),platform:J.enum(["linkedin"]).optional(),sourceEntityType:J.enum(["post","deck"]).optional(),sourceEntityId:J.string().optional(),title:J.string().optional().describe("Required when content is provided directly"),content:J.string().optional(),addToQueue:J.boolean().optional(),generateImage:J.boolean().optional().describe("Auto-generate cover image for post")}),xb2=h$.extend({slug:J.string().optional()});class Vz extends W9{constructor(A,Q){super(A,Q,{schema:cZA,jobTypeName:"social-post-generation",entityType:"social-post"})}async generate(A,Q){let B=A.platform??"linkedin",w=A.addToQueue??!1,{prompt:$,sourceEntityType:D,sourceEntityId:I}=A,{content:Y,title:X}=A;if(Y&&X)await this.reportProgress(Q,{progress:50,message:"Using provided content"});else if(Y&&!X){await this.reportProgress(Q,{progress:10,message:"Shaping content with AI"});let C=await this.context.ai.generate({prompt:Y,templateName:a_(B)});X=C.title,Y=C.content,await this.reportProgress(Q,{progress:50,message:"Social post shaped from content"})}else if(I&&D){await this.reportProgress(Q,{progress:10,message:`Fetching source ${D}`});let C=await this.context.entityService.getEntity({entityType:D,id:I});if(!C)this.failEarly(`Source entity not found: ${D}/${I}`);await this.reportProgress(Q,{progress:30,message:"Generating social post from source content"});let x=J.object({slug:J.string()}).safeParse(C.metadata),k=x.success?x.data.slug:I,o=await this.context.ai.generate({prompt:`Create an engaging ${B} post to promote this ${D}:
|
|
2952
|
+
`)}async function n_(A,Q,B){if(A.length===0)return{created:0,skipped:0,batches:0};let w=qc0(A),$=new ND(Q.entityService,B),D=0,I=0;for(let Y of w){B.info(`Processing batch of ${Y.length} entities`);let X=Wb2(Y),H=await tr(Q.entityService),U=er({entityTitle:`Batch of ${Y.length} entities`,entityType:"batch",content:X,existingTopicTitles:H});try{let F=await Q.ai.generate({prompt:U,templateName:"topics:extraction"});for(let Z of F.topics){let z=sH(Z.title);if(await $.getTopic(z)){I++;continue}await $.createTopic({title:Z.title,content:Z.content}),D++}}catch(F){B.error("Batch topic extraction failed",{batchSize:Y.length,promptChars:U.length,error:L0(F)})}}return{created:D,skipped:I,batches:w.length}}KA();tA();KA();var Ub2=J.object({entityId:J.string(),entityType:J.string(),contentHash:J.string(),minRelevanceScore:J.number().min(0).max(1),autoMerge:J.boolean(),mergeSimilarityThreshold:J.number().min(0).max(1)});class SZA extends VB{topicExtractor;context;constructor(A,Q){super(Q,{schema:Ub2,jobTypeName:"topic-extraction"});this.context=A,this.topicExtractor=new r_(A,Q)}async process(A,Q,B){let{entityId:w,entityType:$,contentHash:D,minRelevanceScore:I,autoMerge:Y,mergeSimilarityThreshold:X}=A;this.logger.debug("Starting topic extraction job",{jobId:Q,entityId:w,entityType:$,contentHash:D});try{await B.report({progress:Z2.INIT,message:`Extracting topics from ${$}: ${w}`});let H=await this.context.entityService.getEntity({entityType:$,id:w});if(!H)return this.logger.warn("Entity no longer exists, skipping topic extraction",{jobId:Q,entityId:w,entityType:$}),{success:!0,topicsExtracted:0};if(H.contentHash!==D)return this.logger.info("Entity content changed since job created, skipping stale extraction",{jobId:Q,entityId:w,entityType:$,jobContentHash:D,currentContentHash:H.contentHash}),{success:!0,topicsExtracted:0};let U=await this.topicExtractor.extractFromEntity(H,I);if(await B.report({progress:Z2.EXTRACT,message:`Extracted ${U.length} topics`}),U.length===0)return this.logger.debug("No topics found in entity",{entityId:w,entityType:$}),await B.report({progress:Z2.COMPLETE,message:"No topics found"}),{success:!0,topicsExtracted:0};let F=U.map((f)=>({type:"topics:process-single",data:{topic:f,sourceEntityId:w,sourceEntityType:$,autoMerge:Y,mergeSimilarityThreshold:X},metadata:{operationType:"data_processing",operationTarget:f.title}})),Z=S8(),z=await this.context.jobs.enqueueBatch(F,{priority:5,source:bE,rootJobId:Z,metadata:{operationType:"batch_processing",operationTarget:`process topics for ${$}:${w}`,pluginId:GW}});return await B.report({progress:Z2.COMPLETE,message:`Queued ${U.length} topics for processing`}),this.logger.debug("Queued topic processing batch",{batchId:z,entityId:w,entityType:$,topicsExtracted:U.length}),{success:!0,topicsExtracted:U.length,batchId:z}}catch(H){return this.logger.error("Topic extraction job failed",{jobId:Q,entityId:w,entityType:$,error:L0(H)}),{...F8.failure(H),topicsExtracted:0}}}summarizeDataForLog(A){return{entityId:A.entityId,entityType:A.entityType,contentHash:A.contentHash}}}var Gb2=J.discriminatedUnion("mode",[J.object({mode:J.literal("derive"),reason:J.string().optional()}),J.object({mode:J.literal("rebuild"),reason:J.string().optional()}),J.object({mode:J.literal("source"),entityId:J.string(),entityType:J.string(),contentHash:J.string().optional(),minRelevanceScore:J.number().min(0).max(1).optional(),autoMerge:J.boolean().optional(),mergeSimilarityThreshold:J.number().min(0).max(1).optional()})]);function Nc0(A){let{context:Q,logger:B,config:w}=A,$=new SZA(Q,B),D=T8.from(async()=>{});if(!D)throw Error("Failed to create progress reporter");return{process:async(I)=>{if(I.mode==="derive")return await A.extractAllTopics(),{success:!0};if(I.mode==="rebuild")return await A.rebuildAllTopics(),{success:!0};let Y=await Q.entityService.getEntity({entityType:I.entityType,id:I.entityId});if(!Y)return{success:!1,topicsExtracted:0};return $.process({entityId:I.entityId,entityType:I.entityType,contentHash:I.contentHash??Y.contentHash,minRelevanceScore:I.minRelevanceScore??w.minRelevanceScore,autoMerge:I.autoMerge??w.autoMerge,mergeSimilarityThreshold:I.mergeSimilarityThreshold??w.mergeSimilarityThreshold},`topic-projection:${I.entityType}:${I.entityId}`,D)},validateAndParse:(I)=>{let Y=Gb2.safeParse(I??{});return Y.success?Y.data:null}}}function fc0(){return{priority:5,source:bE,deduplication:"coalesce",deduplicationKey:"topics-initial-derivation",metadata:{operationType:"data_processing",operationTarget:"topics-initial-derivation",pluginId:GW}}}async function Lc0(A){let Q=await Ec0(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 n_(Q,A.context,A.logger);A.logger.info("Batch topic extraction complete",B)}async function Cc0(A){let Q=await Ec0(A),B=await gZA(Q,A.context,A.logger);A.logger.info("Topic rebuild complete",B)}async function gZA(A,Q,B){let w=new ND(Q.entityService,B),$=await w.listTopics();for(let I of $)await w.deleteTopic(I.id);if(A.length===0)return{deleted:$.length,created:0,skipped:0,batches:0};let D=await n_(A,Q,B);return{deleted:$.length,...D}}async function Ec0(A){let Q=Jb2(A),B=[];for(let w of Q){let $=await A.context.entityService.listEntities({entityType:w});for(let D of $){if(!A.isEntityPublished(D))continue;B.push(D)}}return B}function Jb2(A){return A.context.entityService.getEntityTypes().filter((B)=>A.shouldProcessEntityType(B))}var kE=J.object({entityType:J.string(),content:J.string(),metadata:J.record(J.unknown()).optional()}),Fb2=kE.extend({minRelevanceScore:J.number().optional()}),Zb2=J.object({contentA:kE,contentB:kE,minRelevanceScore:J.number().optional()}),s_=J.object({title:J.string(),content:J.string()}),zb2=J.object({existingTopics:J.array(s_),incomingTopic:s_,threshold:J.number().optional()}),qb2=J.object({existingAliases:J.array(J.string()).optional(),canonicalTitle:J.string(),candidateAliases:J.array(J.string())}),Nb2=J.object({existingTopics:J.array(s_.extend({aliases:J.array(J.string()).optional()})).default([]),incomingTopic:s_.extend({relevanceScore:J.number().min(0).max(1).optional()}),threshold:J.number().optional()}),fb2=J.object({entities:J.array(kE).min(1),minRelevanceScore:J.number().optional()}),Lb2=J.object({existingTopics:J.array(s_).optional(),entities:J.array(kE)}),Cb2=J.object({entities:J.array(kE)});function o_(A,Q=""){return{id:`eval${Q}-${Date.now()}`,entityType:A.entityType,content:A.content,contentHash:Aw(A.content),metadata:A.metadata??{},created:new Date().toISOString(),updated:new Date().toISOString()}}function Mc0(A){return{title:A.title,relevanceScore:A.relevanceScore}}function Eb2(A){let Q=A.metadata.title;return typeof Q==="string"?Q:A.id}function Mb2(A,Q){return{...A,sources:[{id:Q.id,type:Q.entityType,title:Eb2(Q)}]}}async function Mz(A){let Q=await A.entityService.listEntities({entityType:GB});await Promise.all(Q.map((B)=>A.entityService.deleteEntity({entityType:GB,id:B.id})))}function Vc0(A){let{context:Q,logger:B,config:w}=A,$=new r_(Q,B),D=async(I,Y,X="")=>{let H=o_(I,X);return $.extractFromEntity(H,Y)};Q.eval.registerHandler("extractFromEntity",async(I)=>{await Mz(Q);let Y=Fb2.parse(I),X=Y.minRelevanceScore??w.minRelevanceScore,H=o_(Y);return(await $.extractFromEntity(H,X)).map((F)=>Mb2(F,H))}),Q.eval.registerHandler("checkMergeSimilarity",async(I)=>{await Mz(Q);let Y=Zb2.parse(I),X=Y.minRelevanceScore??w.minRelevanceScore,[H,U]=await Promise.all([D(Y.contentA,X,"-a"),D(Y.contentB,X,"-b")]),F=H.map((f)=>f.title.toLowerCase()),Z=U.map((f)=>f.title.toLowerCase()),z=F.filter((f)=>Z.includes(f));return{topicsA:H.map(Mc0),topicsB:U.map(Mc0),matchingTitles:z,wouldMerge:z.length>0}}),Q.eval.registerHandler("detectMergeCandidate",async(I)=>{await Mz(Q);let Y=zb2.parse(I),X=Y.threshold??w.mergeSimilarityThreshold,H=new ND(Q.entityService,B);for(let F of Y.existingTopics)await H.createTopic(F);let U=await H.findMergeCandidate({title:Y.incomingTopic.title},X);return{found:U!==null,candidateTitle:U?.title,candidateScore:U?.score}}),Q.eval.registerHandler("mergeAliases",async(I)=>{let Y=qb2.parse(I);return{aliases:new ND(Q.entityService,B).mergeAliases(Y.existingAliases,Y.canonicalTitle,Y.candidateAliases)}}),Q.eval.registerHandler("processTopicWithAutoMerge",async(I)=>{await Mz(Q);let Y=Nb2.parse(I),X=new ND(Q.entityService,B);for(let z of Y.existingTopics)await X.createTopic({title:z.title,content:z.content,metadata:{aliases:z.aliases??[]}});let H=new l_(Q,B),U=T8.from(async()=>{});if(!U)throw Error("Failed to create progress reporter");let F=await H.process({topic:{title:Y.incomingTopic.title,content:Y.incomingTopic.content,relevanceScore:Y.incomingTopic.relevanceScore??0.9},sourceEntityId:"eval-source",sourceEntityType:"post",autoMerge:!0,mergeSimilarityThreshold:Y.threshold??w.mergeSimilarityThreshold},`eval-job-${Date.now()}`,U),Z=await Q.entityService.listEntities({entityType:GB});return{...F,topicCount:Z.length,topics:Z.map(vZA)}}),Q.eval.registerHandler("rebuildTopics",async(I)=>{await Mz(Q);let Y=Lb2.parse(I),X=new ND(Q.entityService,B);for(let Z of Y.existingTopics??[])await X.createTopic(Z);let H=Y.entities.map((Z,z)=>o_(Z,`-rebuild-${z}`)),U=await gZA(H,Q,B),F=await Q.entityService.listEntities({entityType:GB});return{...U,topicCount:F.length,topics:F.map(vZA)}}),Q.eval.registerHandler("extractSequentially",async(I)=>{await Mz(Q);let Y=fb2.parse(I),X=Y.minRelevanceScore??w.minRelevanceScore,H=new ND(Q.entityService,B),U=[];for(let[Z,z]of Y.entities.entries()){let f=o_(z,`-sequential-${Z}`),E=await $.extractFromEntity(f,X);for(let C of E)await H.createTopic({title:C.title,content:C.content});U.push({extractedTitles:E.map((C)=>C.title)})}let F=await Q.entityService.listEntities({entityType:GB});return{totalTopics:F.length,perEntity:U,topics:F.map(PE)}}),Q.eval.registerHandler("batchExtract",async(I)=>{await Mz(Q);let X=Cb2.parse(I).entities.map((F,Z)=>o_(F,`-batch-${Z}`)),H=await n_(X,Q,B),U=await Q.entityService.listEntities({entityType:GB});return{...H,topics:U.map(PE)}})}var Oc0={name:"@brains/topics",private:!0,version:"0.2.0-alpha.54",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/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 Ob2=new JW;class Rc0 extends n2{entityType=GB;schema=rr;adapter=Ob2;constructor(A={}){super(GW,Oc0,A,tu0)}getEntityTypeConfig(){return{weight:0.5}}getTemplates(){return{extraction:Yc0,"merge-synthesis":Xc0,"topic-list":Hc0,"topic-detail":Kc0}}getDataSources(){return[new TZA(this.logger.child("TopicsDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableAutoExtraction)return[];return[{id:kZA,targetType:GB,job:{type:Ac0,handler:Nc0({context:A,logger:this.logger,config:this.config,extractAllTopics:()=>this.extractAllTopics(A),rebuildAllTopics:()=>this.rebuildAllTopics(A)})},initialSync:{shouldEnqueue:async()=>!await oF(A,GB),jobData:{mode:"derive",reason:"initial-sync"},jobOptions:fc0()},sourceChange:{sourceTypes:this.config.includeEntityTypes,requireInitialSync:!0,jobData:(Q)=>{let B=Q.entity;if(!B)return null;if(!this.shouldProcessEntityType(B.entityType))return null;if(!this.isEntityPublished(B))return null;return{mode:"source",entityId:B.id,entityType:B.entityType,contentHash:B.contentHash,minRelevanceScore:this.config.minRelevanceScore,autoMerge:this.config.autoMerge,mergeSimilarityThreshold:this.config.mergeSimilarityThreshold}},jobOptions:(Q)=>({priority:5,source:bE,deduplication:"coalesce",deduplicationKey:`topics-source:${Q.entityType}:${Q.entityId}:${Q.entity?.contentHash??"unknown"}`,metadata:{operationType:"data_processing",operationTarget:`topic-projection:${Q.entityType}:${Q.entityId}`,pluginId:GW}})}}]}async onRegister(A){let Q=new l_(A,this.logger);A.jobs.registerHandler("process-single",Q),A.insights.register("topic-distribution",Gc0()),Jc0({context:A,pluginId:this.id}),Vc0({context:A,logger:this.logger,config:this.config})}hasRunInitialDerivation(){return this.getDerivedEntityProjectionController(kZA)?.hasQueuedInitialSync()??!1}shouldProcessEntityType(A){if(A===GB)return!1;return this.config.includeEntityTypes.includes(A)}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 Lc0({context:A,logger:this.logger,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}async rebuildAllTopics(A){await Cc0({context:A,logger:this.logger,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}}function An(A){return new Rc0(A)}tA();KA();tA();var bc0=J.enum(["linkedin"]),Pc0=J.enum(["draft","queued","published","failed"]),kc0=J.enum(["post","deck"]),RI=J.object({title:J.string().describe("Short descriptive title (3-6 words) for file naming"),platform:bc0.describe("Target platform"),status:Pc0,coverImageId:J.string().optional().describe("Image entity ID for post image"),publishedAt:J.string().datetime().optional(),platformPostId:J.string().optional().describe("ID from platform after publishing"),sourceEntityId:J.string().optional().describe("Source entity ID if auto-generated"),sourceEntityType:kc0.optional().describe("Source entity type (post, deck)")}),jc0=RI.pick({title:!0,platform:!0,status:!0,publishedAt:!0,platformPostId:!0}).extend({slug:J.string().describe("URL-friendly identifier: {platform}-{title}")}),jE=r1.extend({entityType:J.literal("social-post"),metadata:jc0}),Qn=jE.extend({frontmatter:RI,body:J.string()}),Bn=Qn.extend({url:J.string().optional(),listUrl:J.string().optional(),listLabel:J.string().optional(),typeLabel:J.string().optional(),coverImageUrl:J.string().optional(),coverImageWidth:J.number().optional(),coverImageHeight:J.number().optional()});tA();KA();class hZA extends Q2{constructor(){super({entityType:"social-post",schema:jE,frontmatterSchema:RI,supportsCoverImage:!0})}toMarkdown(A){let Q="",B={};try{B=this.parseFrontMatter(A.content,RI),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,RI),B=`${Q.platform}-${t1(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,RI)}getPostContent(A){return this.extractBody(A.content)}createPostContent(A,Q){return this.buildMarkdown(Q,A)}}var H7=new hZA;tA();tA();KA();var Rb2=BX.extend({platform:J.enum(["linkedin"]).optional(),status:J.enum(["draft","queued","published","failed"]).optional(),sortByQueue:J.boolean().optional(),nextInQueue:J.boolean().optional()}),bb2=wX.extend({query:Rb2.optional()});function _c0(A){let Q=M2(A.content,RI);return Qn.parse({...A,frontmatter:Q.metadata,body:Q.content})}class wn extends U6{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=bb2.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}transformEntity(A){return _c0(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:U}=await this.fetchDetail(w.id,$);return Q.parse(this.buildDetailResult(U,null))}let D={};if(w.platform)D.platform=w.platform;if(w.status)D.status=w.status;let I=Object.keys(D).length>0,Y=w.sortByQueue?[{field:"queueOrder",direction:"asc"}]:this.config.defaultSort,{items:X,pagination:H}=await this.fetchList(w,$,{...I&&{filter:{metadata:D}},sortFields:Y});return Q.parse(this.buildListResult(X,H,w))}async fetchNextInQueue(A,Q){let w=(await Q.listEntities({entityType:this.config.entityType,options:{filter:{metadata:{status:"queued"}},sortFields:[{field:"queueOrder",direction:"asc"}],limit:1}}))[0],$=w?_c0(w):null;return A.parse({post:$})}}KA();var xc0=J.object({accessToken:J.string().optional(),refreshToken:J.string().optional(),organizationId:J.string().optional()}),yZA=J.object({linkedin:xc0.optional(),publishInterval:J.number().default(3600000),enabled:J.boolean().default(!0),defaultPrompt:J.string().default("Create an engaging social media post that drives engagement"),maxRetries:J.number().default(3),autoGenerateOnBlogPublish:J.boolean().default(!1)});tA();KA();uZA();import{jsxDEV as i8,Fragment as jb2}from"preact/jsx-dev-runtime";function Pb2(A,Q){if(A.length<=Q)return A;return A.slice(0,Q).trim()+"..."}function kb2(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"})}var Dn=({posts:A,pageTitle:Q,pagination:B,baseUrl:w="/social-posts"})=>{let $=Q??"Social Posts",D=B?.totalItems??A.length,I=`Browse all ${D} social ${D===1?"post":"posts"}`;return i8(jb2,{children:[i8(u2,{title:$,description:I},void 0,!1,void 0,this),i8("div",{className:"social-post-list bg-theme",children:i8("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[i8("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:$},void 0,!1,void 0,this),A.length===0?i8("p",{className:"text-theme-muted italic",children:"No social posts yet."},void 0,!1,void 0,this):i8("ul",{className:"space-y-6",children:A.map((Y)=>i8("li",{children:i8(WQ,{href:Y.url,variant:"horizontal",children:i8("div",{className:"flex flex-col sm:flex-row gap-4",children:[Y.coverImageUrl&&i8("img",{src:Y.coverImageUrl,alt:Y.frontmatter.title,className:"w-full sm:w-24 h-48 sm:h-24 object-cover rounded-lg shrink-0"},void 0,!1,void 0,this),i8("div",{className:"flex-1 min-w-0",children:[i8("div",{className:"flex items-start justify-between gap-4 mb-2",children:[i8("h2",{className:"text-lg font-semibold text-heading",children:Y.frontmatter.title},void 0,!1,void 0,this),i8("time",{className:"text-sm text-theme-muted shrink-0",children:kb2(Y.frontmatter.publishedAt??Y.created)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),i8("div",{className:"flex items-center gap-2 mb-3",children:[i8(D7,{status:Y.frontmatter.status},void 0,!1,void 0,this),i8("span",{className:"text-xs text-theme-muted uppercase",children:Y.frontmatter.platform},void 0,!1,void 0,this),i8("span",{className:"text-xs text-theme-muted font-mono",children:Y.id},void 0,!1,void 0,this)]},void 0,!0,void 0,this),i8("p",{className:"text-theme leading-relaxed",children:Pb2(Y.body,200)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},Y.id,!1,void 0,this))},void 0,!1,void 0,this),B&&B.totalPages>1&&i8(a4,{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 r8,Fragment as _b2}from"preact/jsx-dev-runtime";function vc0(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric",hour:"numeric",minute:"2-digit"})}var In=({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 r8(_b2,{children:[r8(u2,{title:Q,description:B},void 0,!1,void 0,this),r8("section",{className:"social-post-detail",children:r8("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:r8("div",{className:"max-w-3xl mx-auto",children:[r8(LI,{items:w},void 0,!1,void 0,this),r8("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-4",children:A.frontmatter.title},void 0,!1,void 0,this),r8("div",{className:"flex flex-wrap items-center gap-3 mb-6",children:[r8(D7,{status:A.frontmatter.status},void 0,!1,void 0,this),r8("span",{className:"text-sm text-theme-muted uppercase",children:A.frontmatter.platform},void 0,!1,void 0,this),r8("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&&r8(iK,{src:A.coverImageUrl,alt:A.frontmatter.title,width:A.coverImageWidth,height:A.coverImageHeight,className:"mb-8"},void 0,!1,void 0,this),r8(WQ,{className:"p-8 mb-8",children:r8("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),r8("div",{className:"space-y-4 text-sm text-theme-muted",children:[r8("div",{children:[r8("span",{className:"font-medium",children:"Created:"},void 0,!1,void 0,this)," ",vc0(A.created)]},void 0,!0,void 0,this),A.frontmatter.publishedAt&&r8("div",{children:[r8("span",{className:"font-medium",children:"Published:"},void 0,!1,void 0,this)," ",vc0(A.frontmatter.publishedAt)]},void 0,!0,void 0,this),A.frontmatter.platformPostId&&r8("div",{children:r8("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 a_(A){return`social-media:${A}`}var cZA=J.object({prompt:J.string().optional(),platform:J.enum(["linkedin"]).optional(),sourceEntityType:J.enum(["post","deck"]).optional(),sourceEntityId:J.string().optional(),title:J.string().optional().describe("Required when content is provided directly"),content:J.string().optional(),addToQueue:J.boolean().optional(),generateImage:J.boolean().optional().describe("Auto-generate cover image for post")}),xb2=h$.extend({slug:J.string().optional()});class Vz extends W9{constructor(A,Q){super(A,Q,{schema:cZA,jobTypeName:"social-post-generation",entityType:"social-post"})}async generate(A,Q){let B=A.platform??"linkedin",w=A.addToQueue??!1,{prompt:$,sourceEntityType:D,sourceEntityId:I}=A,{content:Y,title:X}=A;if(Y&&X)await this.reportProgress(Q,{progress:50,message:"Using provided content"});else if(Y&&!X){await this.reportProgress(Q,{progress:10,message:"Shaping content with AI"});let C=await this.context.ai.generate({prompt:Y,templateName:a_(B)});X=C.title,Y=C.content,await this.reportProgress(Q,{progress:50,message:"Social post shaped from content"})}else if(I&&D){await this.reportProgress(Q,{progress:10,message:`Fetching source ${D}`});let C=await this.context.entityService.getEntity({entityType:D,id:I});if(!C)this.failEarly(`Source entity not found: ${D}/${I}`);await this.reportProgress(Q,{progress:30,message:"Generating social post from source content"});let x=J.object({slug:J.string()}).safeParse(C.metadata),k=x.success?x.data.slug:I,o=await this.context.ai.generate({prompt:`Create an engaging ${B} post to promote this ${D}:
|
|
2953
2953
|
|
|
2954
2954
|
Source: ${D}/${k}
|
|
2955
2955
|
|
|
2956
2956
|
${C.content}`,templateName:a_(B)});X=o.title,Y=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:a_(B)});X=C.title,Y=C.content,await this.reportProgress(Q,{progress:50,message:"Social post generated"})}else this.failEarly("No content source provided (prompt, sourceEntityId, or content)");if(!Y||!X)this.failEarly("Content or title was not generated");let U={title:X,platform:B,status:w?"queued":"draft",...I&&{sourceEntityId:I},...D&&{sourceEntityType:D}},F=H7.createPostContent(U,Y),z=H7.fromMarkdown(F).metadata;if(!z)this.failEarly("Failed to parse social post metadata");let f=await DK({entityType:"social-post",title:X,deriveId:(C)=>`${B}-${t1(C)}`,regeneratePrompt:"Generate a different social media post title on the same topic.",context:this.context}),E=F;if(f!==X){z.title=f,z.slug=`${B}-${t1(f)}`;let C={...U,title:f};E=H7.createPostContent(C,Y)}return{id:z.slug,content:E,metadata:z,title:f,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}}}class lZA{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 D={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":D},visibility:{"com.linkedin.ugc.MemberNetworkVisibility":"PUBLIC"}})});if(!I.ok){let H=await I.text();throw this.logger.error("LinkedIn API error",{status:I.status,error:H}),Error(`LinkedIn API error: ${I.status} - ${H}`)}let Y=I.headers.get("X-RestLi-Id")??"";this.logger.info("LinkedIn post created",{postId:Y,hasImage:!!$});let X={id:Y};if(Y)X.url=`https://www.linkedin.com/feed/update/${Y}`;return X}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 Y=await B.text();return this.logger.warn("LinkedIn image upload registration failed",{status:B.status,error:Y}),null}let w=await B.json(),$=w.value.uploadMechanism["com.linkedin.digitalmedia.uploading.MediaUploadHttpRequest"].uploadUrl,D=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:D}),D}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 pZA(A,Q){return new lZA(A,Q)}tA();KA();Q8();uZA();var vb2=J.object({posts:J.array(Bn),totalCount:J.number().optional(),pagination:K9.nullable(),baseUrl:J.string().optional()}),Tb2=J.object({post:Bn});function Tc0(){return{linkedin:$n,"social-post-list":G1({name:"social-post-list",description:"Social post list page template",schema:vb2,dataSourceId:"social-media:posts",requiredPermission:"public",layout:{component:Dn}}),"social-post-detail":G1({name:"social-post-detail",description:"Individual social post template",schema:Tb2,dataSourceId:"social-media:posts",requiredPermission:"public",layout:{component:In}})}}KA();var Sb2=J.object({prompt:J.string().optional(),content:J.string().optional(),platform:J.enum(["linkedin"]).default("linkedin")}),gb2=J.object({prompt:J.string().optional(),content:J.string().optional(),title:J.string().optional(),platform:J.enum(["linkedin"]).optional()});function Sc0(A){A.eval.registerHandler("generation",async(Q)=>{let B=Sb2.parse(Q),w=B.content?`Create an engaging LinkedIn post to share this content:
|
|
2957
2957
|
|
|
2958
|
-
${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=gb2.parse(Q),w=[],$=T8.from(async(H)=>{let U={progress:H.progress};if(H.message!==void 0)U.message=H.message;w.push(U)});if(!$)throw Error("Failed to create progress reporter");let I=await new Vz(A.logger,A).process(B,`eval-${Date.now()}`,$),Y=!1,X;if(I.success&&I.entityId){let H=await A.entityService.getEntity({entityType:"social-post",id:I.entityId});Y=!!H,X=H?.content.slice(0,300)}return{...I,entityExists:Y,entityPreview:X,progressSteps:w}})}KA();tA();class t_{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,D=this.providers.get($);if(!D){await this.reportFailure(Q,B,`No provider configured for platform: ${$}`);return}let I=M2(w.content,RI),Y;if(I.metadata.coverImageId)Y=await this.fetchImageData(I.metadata.coverImageId);try{let X=await D.publish(I.content,w.metadata,Y),H=new Date().toISOString(),U=X.id||void 0,F={...I.metadata,status:"published",publishedAt:H,...U&&{platformPostId:U}},Z=H7.createPostContent(F,I.content);await this.entityService.updateEntity({entity:{...w,content:Z,metadata:{...w.metadata,status:"published",publishedAt:H,platformPostId:U}}}),await this.reportSuccess(Q,B,X.id),this.logger.info(`Post published successfully: ${B}`,{platform:$,platformPostId:U})}catch(X){let H=X instanceof Error?X.message:String(X),U={...I.metadata,status:"failed"},F=H7.createPostContent(U,I.content);await this.entityService.updateEntity({entity:{...w,content:F,metadata:{...w.metadata,status:"failed"}}}),await this.reportFailure(Q,B,H),this.logger.error(`Post publish failed: ${B}`,{platform:$,error:H})}}catch(w){let $=L0(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],D=w[2];return{data:Buffer.from(D,"base64"),mimeType:$}}catch(Q){this.logger.warn("Failed to fetch cover image",{imageId:A,error:Q});return}}}function gc0(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 hc0(A,Q,B){let w=new t_({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")}KA();function yc0(A,Q){A.messaging.subscribe("entity:updated",async(B)=>{let{entityType:w,entityId:$,entity:D}=B.payload;if(w!=="post")return{success:!0};if(D.metadata?.status!=="queued")return{success:!0};try{if((await A.entityService.listEntities({entityType:"social-post",options:{filter:{metadata:{sourceEntityType:"post",sourceEntityId:$}},limit:1}})).length>0)return Q.debug(`Social post already exists for ${$}, skipping auto-generate`),{success:!0};return await A.messaging.send({type:"social:auto-generate",payload:{sourceEntityType:w,sourceEntityId:$,platform:"linkedin"}}),Q.info(`Auto-generate social post triggered for queued post ${$}`),{success:!0}}catch(Y){let X=L0(Y);return Q.error(`Failed to trigger auto-generate for ${$}:`,{error:X}),{success:!0}}}),Q.debug("Subscribed to entity:updated for auto-generation")}function mc0(A,Q){A.messaging.subscribe("social:auto-generate",async(B)=>{let{sourceEntityType:w,sourceEntityId:$,platform:D}=B.payload;try{let I=await A.jobs.enqueue({type:`${H7.entityType}:generation`,data:{sourceEntityType:w,sourceEntityId:$,platform:D,addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}});return Q.info(`Social post generation job enqueued for ${w}/${$}`,{jobId:I}),{success:!0,jobId:I}}catch(I){let Y=L0(I);return Q.error(`Failed to enqueue social post generation for ${$}:`,{error:Y}),{success:!1}}}),Q.debug("Subscribed to social:auto-generate messages")}function uc0(A,Q){A.messaging.subscribe("generate:execute",async(B)=>{let{entityType:w}=B.payload;if(w!=="social-post")return{success:!0};Q.info("Received generate:execute for social-post");try{let $=await A.entityService.listEntities({entityType:"post",options:{filter:{metadata:{status:"published"}},limit:5}});if($.length===0)return Q.info("No published posts found for social post generation"),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:"No published posts available for social post generation"}}),{success:!0};let D=null;for(let Y of $)if((await A.entityService.listEntities({entityType:"social-post",options:{filter:{metadata:{sourceEntityType:"post",sourceEntityId:Y.id}},limit:1}})).length===0){D=Y;break}if(!D)return Q.info("All recent posts already have social posts"),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:"All recent posts already have social posts generated"}}),{success:!0};let I=await A.jobs.enqueue({type:`${H7.entityType}:generation`,data:{sourceEntityType:"post",sourceEntityId:D.id,platform:"linkedin",addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}});return Q.info("Social post generation job queued",{jobId:I,sourcePostId:D.id}),{success:!0}}catch($){let D=L0($);return Q.error("Failed to handle generate:execute:",{error:D}),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:D}}),{success:!0}}}),Q.debug("Subscribed to generate:execute messages")}var cc0={name:"@brains/social-media",private:!0,version:"0.2.0-alpha.53",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/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 dZA extends n2{entityType=H7.entityType;schema=jE;adapter=H7;providers=new Map;constructor(A){super("social-media",cc0,A,yZA)}createGenerationHandler(A){return new Vz(this.logger.child("GenerationJobHandler"),A)}getTemplates(){return Tc0()}getDataSources(){return[new wn(this.logger.child("SocialPostDataSource"))]}async onRegister(A){if(this.initializeProviders(),gc0(A,this.providers,this.logger),hc0(A,this.providers,this.logger),this.config.autoGenerateOnBlogPublish)yc0(A,this.logger),mc0(A,this.logger),this.logger.info("Auto-generate on blog publish enabled");uc0(A,this.logger),Sc0(A),this.logger.info("Social media plugin registered successfully")}initializeProviders(){if(this.config.linkedin?.accessToken){let A=pZA(this.config.linkedin,this.logger.child("LinkedInClient"));this.providers.set("linkedin",A),this.logger.info("LinkedIn provider initialized")}}}function e_(A){return new dZA(A)}KA();var yb2=J.enum(["draft","queued","published","failed"]),JzB=J.object({status:yb2.default("draft"),queueOrder:J.number().optional().describe("Position in publish queue (lower = sooner)"),publishedAt:J.string().datetime().optional()});class iZA{name="internal";async publish(A,Q){return{id:"internal"}}}var R9={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"},NJ={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"};KA();var mb2=J.object({skipIfDraftExists:J.boolean().optional(),minSourceEntities:J.number().optional(),maxUnpublishedDrafts:J.number().optional(),sourceEntityType:J.string().optional()}),lc0=J.object({entitySchedules:J.record(J.string(),J.string()).optional(),generationSchedules:J.record(J.string(),J.string()).optional(),generationConditions:J.record(J.string(),mb2).optional(),maxRetries:J.number().optional().default(3),retryBaseDelayMs:J.number().optional().default(5000)});class aX{static instance=null;queues=new Map;static getInstance(){return aX.instance??=new aX,aX.instance}static resetInstance(){aX.instance=null}static createFresh(){return new aX}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,D={entityId:Q,entityType:A,position:$,queuedAt:new Date().toISOString()};return B.push(D),{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((Y)=>Y.entityId===Q);if($===-1)return;let[D]=w.splice($,1);if(!D)return;let I=Math.max(0,Math.min(B-1,w.length));w.splice(I,0,D),this.recalculatePositions(w)}async list(A){let Q=this.queues.get(A);if(!Q)return[];return[...Q]}async getNext(A){let Q=this.queues.get(A);if(!Q||Q.length===0)return null;return Q[0]??null}async getNextAcrossTypes(){let A=null;for(let Q of this.queues.values()){let B=Q[0];if(!B)continue;if(!A||B.queuedAt<A.queuedAt)A=B}return A}async popNext(A){let Q=this.queues.get(A);if(!Q||Q.length===0)return null;let B=Q.shift()??null;if(B)this.recalculatePositions(Q);return B}getRegisteredTypes(){return Array.from(this.queues.keys())}async getQueuedEntityTypes(){let A=[];for(let[Q,B]of this.queues.entries())if(B.length>0)A.push(Q);return A}getOrCreateQueue(A){let Q=this.queues.get(A);if(!Q)Q=[],this.queues.set(A,Q);return Q}recalculatePositions(A){A.forEach((Q,B)=>{Q.position=B+1})}}class tX{static instance=null;providers=new Map;defaultProvider=new iZA;static getInstance(){return tX.instance??=new tX,tX.instance}static resetInstance(){tX.instance=null}static createFresh(){return new tX}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())}}KA();KA();async function pc0(A,Q){let B={entityType:A.entityType,entityId:A.entityId};if(Q.messageBus)await Q.messageBus.send({type:R9.EXECUTE,payload:B,sender:"publish-service"});Q.onExecute?.(B)}async function dc0(A,Q){let B=Q.providerRegistry.get(A.entityType);if(!Q.entityService){Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:"EntityService not available for provider mode",retryCount:0,willRetry:!1});return}let w=await Q.entityService.getEntity({entityType:A.entityType,id:A.entityId});if(!w){Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:`Entity not found: ${A.entityType}/${A.entityId}`,retryCount:0,willRetry:!1});return}try{let $=await B.publish(w.content,w.metadata);Q.retryTracker.clearRetries(A.entityId),Q.onPublish?.({entityType:A.entityType,entityId:A.entityId,result:$})}catch($){let D=L0($);Q.retryTracker.recordFailure(A.entityId,D);let I=Q.retryTracker.getRetryInfo(A.entityId);Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:D,retryCount:I?.retryCount??1,willRetry:I?.willRetry??!1})}}function ic0(A,Q,B,w){if(w.retryTracker.clearRetries(Q),w.messageBus)w.messageBus.send({type:R9.COMPLETED,payload:{entityType:A,entityId:Q,result:B},sender:"publish-service"});w.onPublish?.({entityType:A,entityId:Q,result:B})}function rc0(A,Q,B,w){w.retryTracker.recordFailure(Q,B);let $=w.retryTracker.getRetryInfo(Q),D={entityType:A,entityId:Q,error:B,retryCount:$?.retryCount??1,willRetry:$?.willRetry??!1};if(w.messageBus)w.messageBus.send({type:R9.FAILED,payload:D,sender:"publish-service"});w.onFailed?.(D)}async function nc0(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:NJ.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:NJ.EXECUTE,payload:w,sender:"content-pipeline"});Q.onGenerate?.(w)}function oc0(A,Q,B){if(B)B.send({type:NJ.COMPLETED,payload:{entityType:A,entityId:Q},sender:"content-pipeline"})}function sc0(A,Q,B){if(B)B.send({type:NJ.FAILED,payload:{entityType:A,error:Q},sender:"content-pipeline"})}var ub2=1000;class rZA{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(ub2,()=>this.processUnscheduledTypes())}stop(){if(cb2(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 pc0(A,this.deps.getPublishDeps());else await dc0(A,this.deps.getPublishDeps())}get entitySchedules(){return this.deps.config.entitySchedules}}function cb2(A){for(let Q of A.values())Q.stop();A.clear()}class nZA{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(){lb2(this.generationJobs)}async handleTriggerGeneration(A){if(!this.deps.isRunning())return;try{await nc0(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 lb2(A){for(let Q of A.values())Q.stop();A.clear()}class WY{static instance=null;config;publishRunner;generationRunner;running=!1;static getInstance(A){return WY.instance??=new WY(A),WY.instance}static resetInstance(){if(WY.instance)WY.instance.stop();WY.instance=null}static createFresh(A){return new WY(A)}constructor(A){this.config={...A,entitySchedules:A.entitySchedules??{},generationSchedules:A.generationSchedules??{},generationConditions:A.generationConditions??{}},this.validateCronExpressions(),this.publishRunner=new rZA({config:this.config,getPublishDeps:()=>this.publishDeps,isRunning:()=>this.running}),this.generationRunner=new nZA({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){ic0(A,Q,B,this.publishDeps)}failPublish(A,Q,B){rc0(A,Q,B,this.publishDeps)}async publishDirect(A,Q,B,w){return this.config.providerRegistry.get(A).publish(B,w)}completeGeneration(A,Q){oc0(A,Q,this.config.messageBus)}failGeneration(A,Q){sc0(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}" - ${L0(w)}`)}}}var ac0={maxRetries:3,baseDelayMs:5000};class eX{static instance=null;retries=new Map;config;static getInstance(A){return eX.instance??=new eX(A??ac0),eX.instance}static resetInstance(){eX.instance=null}static createFresh(A){return new eX(A??ac0)}constructor(A){this.config=A}recordFailure(A,Q){let w=(this.retries.get(A)?.retryCount??0)+1,$=this.config.baseDelayMs*Math.pow(2,w-1),D=Date.now()+$;this.retries.set(A,{entityId:A,retryCount:w,lastError:Q,nextRetryAt:D})}shouldRetry(A){let Q=this.retries.get(A);if(!Q)return!1;return Q.retryCount<this.config.maxRetries}isReadyForRetry(A){let Q=this.retries.get(A);if(!Q)return!1;return Date.now()>=Q.nextRetryAt}clearRetries(A){this.retries.delete(A)}getRetryInfo(A){let Q=this.retries.get(A);if(!Q)return null;return{entityId:Q.entityId,retryCount:Q.retryCount,lastError:Q.lastError,nextRetryAt:Q.nextRetryAt,willRetry:Q.retryCount<this.config.maxRetries}}}function b9(A,Q,B,w,$,D,I,Y){return b9.fromTZ(b9.tp(A,Q,B,w,$,D,I),Y)}b9.fromTZISO=(A,Q,B)=>b9.fromTZ(pb2(A,Q),B);b9.fromTZ=function(A,Q){let B=new Date(Date.UTC(A.y,A.m-1,A.d,A.h,A.i,A.s)),w=oZA(A.tz,B),$=new Date(B.getTime()-w),D=oZA(A.tz,$);if(D-w===0)return $;{let I=new Date(B.getTime()-D),Y=oZA(A.tz,I);if(Y-D===0)return I;if(!Q&&Y-D>0)return I;if(Q)throw Error("Invalid date passed to fromTZ()");return $}};b9.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}};b9.tp=(A,Q,B,w,$,D,I)=>({y:A,m:Q,d:B,h:w,i:$,s:D,tz:I});function oZA(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 pb2(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("+")?b9.tp(B.getUTCFullYear(),B.getUTCMonth()+1,B.getUTCDate(),B.getUTCHours(),B.getUTCMinutes(),B.getUTCSeconds(),"Etc/UTC"):b9.tp(B.getFullYear(),B.getMonth()+1,B.getDate(),B.getHours(),B.getMinutes(),B.getSeconds(),Q)}b9.minitz=b9;var sZA=32,Qx=31|sZA,Ql0=[1,2,4,8,16],tc0=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 bI(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,Qx),this.dayOfWeek[7]&&(this.dayOfWeek[0]=this.dayOfWeek[7])}partToArray(A,Q,B,w){let $=this[A],D=A==="day"&&this.lastDayOfMonth;if(Q===""&&!D)throw TypeError("CronPattern: configuration entry "+A+" ("+Q+") is empty, check for trailing spaces.");if(Q==="*")return $.fill(w);let I=Q.split(",");if(I.length>1)for(let Y=0;Y<I.length;Y++)this.partToArray(A,I[Y],B,w);else Q.indexOf("-")!==-1&&Q.indexOf("/")!==-1?this.handleRangeWithStepping(Q,A,B,w):Q.indexOf("-")!==-1?this.handleRange(Q,A,B,w):Q.indexOf("/")!==-1?this.handleStepping(Q,A,B,w):Q!==""&&this.handleNumber(Q,A,B,w)}throwAtIllegalCharacters(A){for(let Q=0;Q<A.length;Q++)if((Q===5?/[^/*0-9,\-#L]+/:/[^/*0-9,-]+/).test(A[Q]))throw TypeError("CronPattern: configuration entry "+Q+" ("+A[Q]+") contains illegal characters.")}handleNumber(A,Q,B,w){let $=this.extractNth(A,Q),D=parseInt($[0],10)+B;if(isNaN(D))throw TypeError("CronPattern: "+Q+" is not a number: '"+A+"'");this.setPart(Q,D,$[1]||w)}setPart(A,Q,B){if(!Object.prototype.hasOwnProperty.call(this,A))throw TypeError("CronPattern: Invalid part specified: "+A);if(A==="dayOfWeek"){if(Q===7&&(Q=0),Q<0||Q>6)throw RangeError("CronPattern: Invalid value for dayOfWeek: "+Q);this.setNthWeekdayOfMonth(Q,B);return}if(A==="second"||A==="minute"){if(Q<0||Q>=60)throw RangeError("CronPattern: Invalid value for "+A+": "+Q)}else if(A==="hour"){if(Q<0||Q>=24)throw RangeError("CronPattern: Invalid value for "+A+": "+Q)}else if(A==="day"){if(Q<0||Q>=31)throw RangeError("CronPattern: Invalid value for "+A+": "+Q)}else if(A==="month"&&(Q<0||Q>=12))throw RangeError("CronPattern: Invalid value for "+A+": "+Q);this[A][Q]=B}handleRangeWithStepping(A,Q,B,w){let $=this.extractNth(A,Q),D=$[0].match(/^(\d+)-(\d+)\/(\d+)$/);if(D===null)throw TypeError("CronPattern: Syntax error, illegal range with stepping: '"+A+"'");let[,I,Y,X]=D,H=parseInt(I,10)+B,U=parseInt(Y,10)+B,F=parseInt(X,10);if(isNaN(H))throw TypeError("CronPattern: Syntax error, illegal lower range (NaN)");if(isNaN(U))throw TypeError("CronPattern: Syntax error, illegal upper range (NaN)");if(isNaN(F))throw TypeError("CronPattern: Syntax error, illegal stepping: (NaN)");if(F===0)throw TypeError("CronPattern: Syntax error, illegal stepping: 0");if(F>this[Q].length)throw TypeError("CronPattern: Syntax error, steps cannot be greater than maximum value of part ("+this[Q].length+")");if(H>U)throw TypeError("CronPattern: From value is larger than to value: '"+A+"'");for(let Z=H;Z<=U;Z+=F)this.setPart(Q,Z,$[1]||w)}extractNth(A,Q){let B=A,w;if(B.includes("#")){if(Q!=="dayOfWeek")throw Error("CronPattern: nth (#) only allowed in day-of-week field");w=B.split("#")[1],B=B.split("#")[0]}return[B,w]}handleRange(A,Q,B,w){let $=this.extractNth(A,Q),D=$[0].split("-");if(D.length!==2)throw TypeError("CronPattern: Syntax error, illegal range: '"+A+"'");let I=parseInt(D[0],10)+B,Y=parseInt(D[1],10)+B;if(isNaN(I))throw TypeError("CronPattern: Syntax error, illegal lower range (NaN)");if(isNaN(Y))throw TypeError("CronPattern: Syntax error, illegal upper range (NaN)");if(I>Y)throw TypeError("CronPattern: From value is larger than to value: '"+A+"'");for(let X=I;X<=Y;X++)this.setPart(Q,X,$[1]||w)}handleStepping(A,Q,B,w){let $=this.extractNth(A,Q),D=$[0].split("/");if(D.length!==2)throw TypeError("CronPattern: Syntax error, illegal stepping: '"+A+"'");D[0]===""&&(D[0]="*");let I=0;D[0]!=="*"&&(I=parseInt(D[0],10)+B);let Y=parseInt(D[1],10);if(isNaN(Y))throw TypeError("CronPattern: Syntax error, illegal stepping: (NaN)");if(Y===0)throw TypeError("CronPattern: Syntax error, illegal stepping: 0");if(Y>this[Q].length)throw TypeError("CronPattern: Syntax error, max steps for part is ("+this[Q].length+")");for(let X=I;X<this[Q].length;X+=Y)this.setPart(Q,X,$[1]||w)}replaceAlphaDays(A){return A.replace(/-sun/gi,"-7").replace(/sun/gi,"0").replace(/mon/gi,"1").replace(/tue/gi,"2").replace(/wed/gi,"3").replace(/thu/gi,"4").replace(/fri/gi,"5").replace(/sat/gi,"6")}replaceAlphaMonths(A){return A.replace(/jan/gi,"1").replace(/feb/gi,"2").replace(/mar/gi,"3").replace(/apr/gi,"4").replace(/may/gi,"5").replace(/jun/gi,"6").replace(/jul/gi,"7").replace(/aug/gi,"8").replace(/sep/gi,"9").replace(/oct/gi,"10").replace(/nov/gi,"11").replace(/dec/gi,"12")}handleNicknames(A){let Q=A.trim().toLowerCase();return Q==="@yearly"||Q==="@annually"?"0 0 1 1 *":Q==="@monthly"?"0 0 1 * *":Q==="@weekly"?"0 0 * * 0":Q==="@daily"?"0 0 * * *":Q==="@hourly"?"0 * * * *":A}setNthWeekdayOfMonth(A,Q){if(typeof Q!="number"&&Q==="L")this.dayOfWeek[A]=this.dayOfWeek[A]|sZA;else if(Q===Qx)this.dayOfWeek[A]=Qx;else if(Q<6&&Q>0)this.dayOfWeek[A]=this.dayOfWeek[A]|Ql0[Q-1];else throw TypeError(`CronPattern: nth weekday out of range, should be 1-5 or L. Value: ${Q}, Type: ${typeof Q}`)}},ec0=[31,28,31,30,31,30,31,31,30,31,30,31],FW=[["month","year",0],["day","month",-1],["hour","day",0],["minute","hour",0],["second","minute",0]],bI=class A{tz;ms;second;minute;hour;day;month;year;constructor(Q,B){if(this.tz=B,Q&&Q instanceof Date)if(!isNaN(Q))this.fromDate(Q);else throw TypeError("CronDate: Invalid date passed to CronDate constructor");else if(Q===void 0)this.fromDate(new Date);else if(Q&&typeof Q=="string")this.fromString(Q);else if(Q instanceof A)this.fromCronDate(Q);else throw TypeError("CronDate: Invalid type ("+typeof Q+") passed to CronDate constructor")}isNthWeekdayOfMonth(Q,B,w,$){let D=new Date(Date.UTC(Q,B,w)).getUTCDay(),I=0;for(let Y=1;Y<=w;Y++)new Date(Date.UTC(Q,B,Y)).getUTCDay()===D&&I++;if($&Qx&&Ql0[I-1]&$)return!0;if($&sZA){let Y=new Date(Date.UTC(Q,B+1,0)).getUTCDate();for(let X=w+1;X<=Y;X++)if(new Date(Date.UTC(Q,B,X)).getUTCDay()===D)return!1;return!0}return!1}fromDate(Q){if(this.tz!==void 0)if(typeof this.tz=="number")this.ms=Q.getUTCMilliseconds(),this.second=Q.getUTCSeconds(),this.minute=Q.getUTCMinutes()+this.tz,this.hour=Q.getUTCHours(),this.day=Q.getUTCDate(),this.month=Q.getUTCMonth(),this.year=Q.getUTCFullYear(),this.apply();else{let B=b9.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>ec0[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=b9.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(b9.fromTZISO(Q,this.tz))}findNext(Q,B,w,$){let D=this[B],I;w.lastDayOfMonth&&(this.month!==1?I=ec0[this.month]:I=new Date(Date.UTC(this.year,this.month+1,0,0,0,0,0)).getUTCDate());let Y=!w.starDOW&&B=="day"?new Date(Date.UTC(this.year,this.month,1,0,0,0,0)).getUTCDay():void 0;for(let X=this[B]+$;X<w[B].length;X++){let H=w[B][X];if(B==="day"&&w.lastDayOfMonth&&X-$==I&&(H=1),B==="day"&&!w.starDOW){let U=w.dayOfWeek[(Y+(X-$-1))%7];if(U&&U&Qx)U=this.isNthWeekdayOfMonth(this.year,this.month,X-$,U)?1:0;else if(U)throw Error(`CronDate: Invalid value for dayOfWeek encountered. ${U}`);Q.legacyMode&&!w.starDOM?H=H||U:H=H&&U}if(H)return this[B]=X-$,D!==this[B]?2:1}return 3}recurse(Q,B,w){let $=this.findNext(B,FW[w][0],Q,FW[w][2]);if($>1){let D=w+1;for(;D<FW.length;)this[FW[D][0]]=-FW[D][2],D++;if($===3)return this[FW[w][1]]++,this[FW[w][0]]=-FW[w][2],this.apply(),this.recurse(Q,B,0);if(this.apply())return this.recurse(Q,B,w-1)}return w+=1,w>=FW.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)):b9.fromTZ(b9.tp(this.year,this.month+1,this.day,this.hour,this.minute,this.second,this.tz),!1)}getTime(){return this.getDate(!1).getTime()}};function db2(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 bI(A.startAt,A.timezone)),A.stopAt&&(A.stopAt=new bI(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 Ax(A){return Object.prototype.toString.call(A)==="[object Function]"||typeof A=="function"||A instanceof Function}function ib2(A){return Ax(A)}function rb2(A){typeof Deno<"u"&&typeof Deno.unrefTimer<"u"?Deno.unrefTimer(A):A&&typeof A.unref<"u"&&A.unref()}var Al0=30000,Yn=[],aZA=class{name;options;_states;fn;constructor(A,Q,B){let w,$;if(Ax(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(Ax(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=db2(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 tc0("* * * * *")},A&&(A instanceof Date||typeof A=="string"&&A.indexOf(":")>0)?this._states.once=new bI(A,this.options.timezone||this.options.utcOffset):this._states.pattern=new tc0(A,this.options.timezone),this.name){if(Yn.find((D)=>D.name===this.name))throw Error("Cron: Tried to initialize new named job '"+this.name+"', but name already taken.");Yn.push(this)}return $!==void 0&&ib2($)&&(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 bI||A instanceof Date?Q.getTime()-A.getTime():Q.getTime()-new bI(A).getTime():null}stop(){this._states.kill=!0,this._states.currentTimeout&&clearTimeout(this._states.currentTimeout);let A=Yn.indexOf(this);A>=0&&Yn.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>Al0&&(Q=Al0),this._states.currentTimeout=setTimeout(()=>this._checkTrigger(B),Q),this._states.currentTimeout&&this.options.unref&&rb2(this._states.currentTimeout),this)}async _trigger(A){if(this._states.blocking=!0,this._states.currentRun=new bI(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){Ax(this.options.catch)&&this.options.catch(Q,this)}else this.fn!==void 0&&await this.fn(this,this.options.context);this._states.previousRun=new bI(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&&Ax(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 bI(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 bI(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 bI(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 bI(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 Xn{scheduleCron(A,Q){let B=new aZA(A,()=>{Q()});return{stop:()=>B.stop()}}scheduleInterval(A,Q){let B=setInterval(()=>{Q()},A);return{stop:()=>clearInterval(B)}}validateCron(A){new aZA(A).stop()}}tA();KA();var tZA=J.object({action:J.enum(["list","add","remove","reorder"]).describe("Queue action to perform"),entityType:J.string().optional().describe("Entity type (required for add/remove/reorder, optional for list)"),entityId:J.string().optional().describe("Entity ID (required for add/remove/reorder)"),position:J.number().optional().describe("New position for reorder action (1-based)")}),eZA=J.object({position:J.number(),entityType:J.string(),entityId:J.string(),queuedAt:J.string()}),nb2=J.object({success:J.literal(!0),message:J.string().optional(),data:J.object({queue:J.array(eZA).optional(),entityType:J.string().optional(),entityId:J.string().optional(),position:J.number().optional()}).optional()}),ob2=J.object({success:J.literal(!1),error:J.string(),code:J.string().optional()}),A3A=J.union([nb2,ob2]);function Hn(A,Q,B){return{...MQ(Q,"queue","Manage the publish queue for all entity types (list, add, remove, reorder)",tZA,async($)=>{let{action:D,entityType:I,entityId:Y,position:X}=$;switch(D){case"list":return sb2(B,I);case"add":return ab2(B,I,Y);case"remove":return tb2(B,I,Y);case"reorder":return eb2(B,I,Y,X);default:return{success:!1,error:`Unknown action: ${D}`}}}),outputSchema:A3A}}async function sb2(A,Q){let B=[];if(Q)B=await A.list(Q);else{let $=A.getRegisteredTypes();for(let D of $){let I=await A.list(D);B.push(...I)}B.sort((D,I)=>new Date(D.queuedAt).getTime()-new Date(I.queuedAt).getTime())}if(B.length===0)return{success:!0,data:{queue:[]},message:"No items in queue"};return{success:!0,data:{queue:B.map(($,D)=>({position:D+1,entityType:$.entityType,entityId:$.entityId,queuedAt:$.queuedAt}))},message:`${B.length} items in queue`}}async function ab2(A,Q,B){let w=Q3A("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 tb2(A,Q,B){let w=Q3A("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 eb2(A,Q,B,w){let $=Q3A("reorder",Q,B);if(!$.success)return $.error;let D=AP2(w);if(!D.success)return D.error;return await A.reorder($.entityType,$.entityId,D.position),{success:!0,data:{entityType:$.entityType,entityId:$.entityId,position:D.position},message:`Moved to position ${D.position}`}}function Q3A(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 AP2(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}}tA();KA();tA();KA();async function Bl0(A,Q){let{bodyContent:B,coverImageId:w}=QP2(Q.content),$=w?await BP2(A,w):void 0,D={bodyContent:B};if($)D.imageData=$;return D}function QP2(A){try{let Q=M2(A,J.record(J.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 BP2(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 B3A=J.object({entityType:J.string().describe("Entity type to publish (e.g., social-post, post, deck)"),id:J.string().optional().describe("Entity ID to publish"),slug:J.string().optional().describe("Entity slug to publish")}),wP2=J.object({success:J.literal(!0),message:J.string().optional(),data:J.object({entityType:J.string().optional(),entityId:J.string().optional(),platformId:J.string().optional(),url:J.string().optional()}).optional()}),$P2=J.object({success:J.literal(!1),error:J.string(),code:J.string().optional()}),w3A=J.union([wP2,$P2]);function Kn(A,Q,B){return{...MQ(Q,"publish","Publish an entity directly to its platform. Works with any registered entity type (social-post, post, deck, etc.)",B3A,async($)=>{let{entityType:D,id:I,slug:Y}=$;if(!I&&!Y)return{success:!1,error:"Either 'id' or 'slug' must be provided"};let X=await DP2(A,D,I,Y);if(!X)return{success:!1,error:`Entity not found: ${D}:${I??Y}`};if(X.metadata.status==="published")return{success:!1,error:"Entity is already published"};if(!B.has(D))return{success:!1,error:`No publish provider registered for ${D}. Check that the required credentials are configured.`};let H=B.get(D),{bodyContent:U,imageData:F}=await Bl0(A,X),Z=await H.publish(U,X.metadata,F);return await A.entityService.updateEntity({entity:{...X,metadata:{...X.metadata,status:"published",publishedAt:new Date().toISOString(),platformId:Z.id}}}),{success:!0,data:{entityType:D,entityId:X.id,platformId:Z.id,url:Z.url},message:`Published ${D}:${X.id}`}}),outputSchema:w3A}}async function DP2(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}tA();KA();function wl0(A,Q){IP2(A,Q),YP2(A,Q)}function IP2(A,Q){A.messaging.subscribe(R9.REGISTER,async(B)=>XP2(Q,B.payload)),A.messaging.subscribe(R9.QUEUE,async(B)=>HP2(A,Q,B.payload)),A.messaging.subscribe(R9.DIRECT,async(B)=>KP2(A,Q,B.payload)),A.messaging.subscribe(R9.REMOVE,async(B)=>WP2(Q,B.payload)),A.messaging.subscribe(R9.REORDER,async(B)=>UP2(Q,B.payload)),A.messaging.subscribe(R9.LIST,async(B)=>GP2(A,Q,B.payload)),A.messaging.subscribe(R9.REPORT_SUCCESS,async(B)=>JP2(Q,B.payload)),A.messaging.subscribe(R9.REPORT_FAILURE,async(B)=>FP2(Q,B.payload)),Q.logger.debug("Subscribed to publish messages")}function YP2(A,Q){A.messaging.subscribe(NJ.REPORT_SUCCESS,async(B)=>ZP2(Q,B.payload)),A.messaging.subscribe(NJ.REPORT_FAILURE,async(B)=>zP2(Q,B.payload)),Q.logger.debug("Subscribed to generation messages")}async function XP2(A,Q){let{entityType:B,provider:w}=Q;try{if(w)A.providerRegistry.register(B,w),A.logger.info(`Registered provider for entity type: ${B}`,{providerName:w.name});return{success:!0}}catch($){let D=L0($);return A.logger.error(`Failed to register provider: ${D}`),{success:!1}}}async function HP2(A,Q,B){let{entityType:w,entityId:$}=B;try{let D=await Q.queueManager.add(w,$);return await A.messaging.send({type:R9.QUEUED,payload:{entityType:w,entityId:$,position:D.position}}),Q.logger.debug(`Entity queued: ${$}`,{entityType:w,position:D.position}),{success:!0}}catch(D){let I=L0(D);return Q.logger.error(`Failed to queue entity: ${I}`),{success:!1}}}async function KP2(A,Q,B){let{entityType:w,entityId:$}=B;return await A.messaging.send({type:R9.EXECUTE,payload:{entityType:w,entityId:$}}),Q.logger.debug(`Direct publish requested: ${$}`,{entityType:w}),{success:!0}}async function WP2(A,Q){let{entityType:B,entityId:w}=Q;try{return await A.queueManager.remove(B,w),A.logger.debug(`Entity removed from queue: ${w}`,{entityType:B}),{success:!0}}catch($){let D=L0($);return A.logger.error(`Failed to remove entity: ${D}`),{success:!1}}}async function UP2(A,Q){let{entityType:B,entityId:w,position:$}=Q;try{return await A.queueManager.reorder(B,w,$),A.logger.debug(`Entity reordered: ${w}`,{entityType:B,newPosition:$}),{success:!0}}catch(D){let I=L0(D);return A.logger.error(`Failed to reorder entity: ${I}`),{success:!1}}}async function GP2(A,Q,B){let{entityType:w}=B;try{let $=await Q.queueManager.list(w);return await A.messaging.send({type:R9.LIST_RESPONSE,payload:{entityType:w,queue:$.map((D)=>({entityId:D.entityId,position:D.position,queuedAt:D.queuedAt}))}}),{success:!0}}catch($){let D=L0($);return Q.logger.error(`Failed to list queue: ${D}`),{success:!1}}}async function JP2(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 FP2(A,Q){let{entityType:B,entityId:w,error:$}=Q;A.scheduler.failPublish(B,w,$);let D=A.retryTracker.getRetryInfo(w);return A.logger.info(`Publish reported failure: ${w}`,{entityType:B,error:$,retryCount:D?.retryCount,willRetry:D?.willRetry}),{success:!0}}async function ZP2(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 zP2(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}}KA();async function $l0(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:L0($)}),{shouldGenerate:!1,reason:`Condition check failed: ${L0($)}`}}}function Dl0(A){let{context:Q,config:B,queueManager:w,providerRegistry:$,retryTracker:D,logger:I}=A,Y=qP2(Q);return WY.createFresh({queueManager:w,providerRegistry:$,retryTracker:D,logger:I,backend:new Xn,...B.entitySchedules&&{entitySchedules:B.entitySchedules},...B.generationSchedules&&{generationSchedules:B.generationSchedules},...B.generationConditions&&{generationConditions:B.generationConditions},messageBus:Y,entityService:Q.entityService,onCheckGenerationConditions:(X,H)=>$l0(Q.entityService,I,X,H)})}function qP2(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 Il0(A,Q,B){let w=A.getEntityTypes();for(let D of w){let I=await A.listEntities({entityType:D,options:{filter:{metadata:{status:"queued"}}}});for(let Y of I)await Q.add(Y.entityType,Y.id)}let $=0;for(let D of w){let I=await Q.list(D);$+=I.length}if($>0)B.info(`Rebuilt queue with ${$} queued entities`)}var NP2=["draft","queued","published","failed"];async function Yl0(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",dataProvider:()=>fP2(A)}})}async function fP2(A){let Q=A.entityService.getEntityTypes(),B=[],w={draft:0,queued:0,published:0,failed:0};for(let $ of Q){let D=await A.entityService.listEntities({entityType:$});for(let I of D){let Y=LP2(I.metadata.status);if(!Y)continue;w[Y]++,B.push({id:I.id,title:CP2(I.id,I.metadata.title),type:$,status:Y})}}return{summary:w,items:B}}function LP2(A){return NP2.find((Q)=>Q===A)}function CP2(A,Q){return typeof Q==="string"?Q:A}var Xl0={name:"@brains/content-pipeline",private:!0,version:"0.2.0-alpha.53",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/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 $3A extends Bw{pluginContext;queueManager;providerRegistry;retryTracker;scheduler;constructor(A){super("content-pipeline",Xl0,A??{},lc0)}async onRegister(A){this.pluginContext=A,this.queueManager=aX.createFresh(),this.providerRegistry=tX.createFresh(),this.retryTracker=eX.createFresh({maxRetries:this.config.maxRetries,baseDelayMs:this.config.retryBaseDelayMs}),this.scheduler=Dl0({context:A,config:this.config,queueManager:this.queueManager,providerRegistry:this.providerRegistry,retryTracker:this.retryTracker,logger:this.logger}),wl0(A,{queueManager:this.queueManager,providerRegistry:this.providerRegistry,retryTracker:this.retryTracker,scheduler:this.scheduler,logger:this.logger})}async onReady(A){await Il0(A.entityService,this.queueManager,this.logger),await Yl0(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[Hn(this.pluginContext,this.id,this.queueManager),Kn(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(),aX.resetInstance(),tX.resetInstance(),eX.resetInstance()}}function D3A(A){return new $3A(A)}tA();KA();var Hl0=J.object({accountId:J.string().describe("Cloudflare account ID"),apiToken:J.string().describe("Cloudflare API token with Analytics:Read permission"),siteTag:J.string().describe("Cloudflare Web Analytics site tag")}),I3A=J.object({cloudflare:Hl0.optional()});tA();KA();var MP2=J.object({date:J.string().describe("Single date in YYYY-MM-DD format").optional(),days:J.number().min(1).max(365).describe("Number of days back from yesterday (e.g., 7 for last week)").optional(),startDate:J.string().describe("Start date in YYYY-MM-DD format (use with endDate)").optional(),endDate:J.string().describe("End date in YYYY-MM-DD format (use with startDate)").optional(),limit:J.number().min(1).max(100).default(20).describe("Maximum items for breakdowns (pages, referrers, countries)")});function VP2(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 Kl0(A,Q,B){let w=[];if(!B)return w;return w.push(MQ(A,"query",`Query website analytics from Cloudflare.
|
|
2958
|
+
${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=gb2.parse(Q),w=[],$=T8.from(async(H)=>{let U={progress:H.progress};if(H.message!==void 0)U.message=H.message;w.push(U)});if(!$)throw Error("Failed to create progress reporter");let I=await new Vz(A.logger,A).process(B,`eval-${Date.now()}`,$),Y=!1,X;if(I.success&&I.entityId){let H=await A.entityService.getEntity({entityType:"social-post",id:I.entityId});Y=!!H,X=H?.content.slice(0,300)}return{...I,entityExists:Y,entityPreview:X,progressSteps:w}})}KA();tA();class t_{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,D=this.providers.get($);if(!D){await this.reportFailure(Q,B,`No provider configured for platform: ${$}`);return}let I=M2(w.content,RI),Y;if(I.metadata.coverImageId)Y=await this.fetchImageData(I.metadata.coverImageId);try{let X=await D.publish(I.content,w.metadata,Y),H=new Date().toISOString(),U=X.id||void 0,F={...I.metadata,status:"published",publishedAt:H,...U&&{platformPostId:U}},Z=H7.createPostContent(F,I.content);await this.entityService.updateEntity({entity:{...w,content:Z,metadata:{...w.metadata,status:"published",publishedAt:H,platformPostId:U}}}),await this.reportSuccess(Q,B,X.id),this.logger.info(`Post published successfully: ${B}`,{platform:$,platformPostId:U})}catch(X){let H=X instanceof Error?X.message:String(X),U={...I.metadata,status:"failed"},F=H7.createPostContent(U,I.content);await this.entityService.updateEntity({entity:{...w,content:F,metadata:{...w.metadata,status:"failed"}}}),await this.reportFailure(Q,B,H),this.logger.error(`Post publish failed: ${B}`,{platform:$,error:H})}}catch(w){let $=L0(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],D=w[2];return{data:Buffer.from(D,"base64"),mimeType:$}}catch(Q){this.logger.warn("Failed to fetch cover image",{imageId:A,error:Q});return}}}function gc0(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 hc0(A,Q,B){let w=new t_({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")}KA();function yc0(A,Q){A.messaging.subscribe("entity:updated",async(B)=>{let{entityType:w,entityId:$,entity:D}=B.payload;if(w!=="post")return{success:!0};if(D.metadata?.status!=="queued")return{success:!0};try{if((await A.entityService.listEntities({entityType:"social-post",options:{filter:{metadata:{sourceEntityType:"post",sourceEntityId:$}},limit:1}})).length>0)return Q.debug(`Social post already exists for ${$}, skipping auto-generate`),{success:!0};return await A.messaging.send({type:"social:auto-generate",payload:{sourceEntityType:w,sourceEntityId:$,platform:"linkedin"}}),Q.info(`Auto-generate social post triggered for queued post ${$}`),{success:!0}}catch(Y){let X=L0(Y);return Q.error(`Failed to trigger auto-generate for ${$}:`,{error:X}),{success:!0}}}),Q.debug("Subscribed to entity:updated for auto-generation")}function mc0(A,Q){A.messaging.subscribe("social:auto-generate",async(B)=>{let{sourceEntityType:w,sourceEntityId:$,platform:D}=B.payload;try{let I=await A.jobs.enqueue({type:`${H7.entityType}:generation`,data:{sourceEntityType:w,sourceEntityId:$,platform:D,addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}});return Q.info(`Social post generation job enqueued for ${w}/${$}`,{jobId:I}),{success:!0,jobId:I}}catch(I){let Y=L0(I);return Q.error(`Failed to enqueue social post generation for ${$}:`,{error:Y}),{success:!1}}}),Q.debug("Subscribed to social:auto-generate messages")}function uc0(A,Q){A.messaging.subscribe("generate:execute",async(B)=>{let{entityType:w}=B.payload;if(w!=="social-post")return{success:!0};Q.info("Received generate:execute for social-post");try{let $=await A.entityService.listEntities({entityType:"post",options:{filter:{metadata:{status:"published"}},limit:5}});if($.length===0)return Q.info("No published posts found for social post generation"),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:"No published posts available for social post generation"}}),{success:!0};let D=null;for(let Y of $)if((await A.entityService.listEntities({entityType:"social-post",options:{filter:{metadata:{sourceEntityType:"post",sourceEntityId:Y.id}},limit:1}})).length===0){D=Y;break}if(!D)return Q.info("All recent posts already have social posts"),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:"All recent posts already have social posts generated"}}),{success:!0};let I=await A.jobs.enqueue({type:`${H7.entityType}:generation`,data:{sourceEntityType:"post",sourceEntityId:D.id,platform:"linkedin",addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}});return Q.info("Social post generation job queued",{jobId:I,sourcePostId:D.id}),{success:!0}}catch($){let D=L0($);return Q.error("Failed to handle generate:execute:",{error:D}),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:D}}),{success:!0}}}),Q.debug("Subscribed to generate:execute messages")}var cc0={name:"@brains/social-media",private:!0,version:"0.2.0-alpha.54",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/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 dZA extends n2{entityType=H7.entityType;schema=jE;adapter=H7;providers=new Map;constructor(A){super("social-media",cc0,A,yZA)}createGenerationHandler(A){return new Vz(this.logger.child("GenerationJobHandler"),A)}getTemplates(){return Tc0()}getDataSources(){return[new wn(this.logger.child("SocialPostDataSource"))]}async onRegister(A){if(this.initializeProviders(),gc0(A,this.providers,this.logger),hc0(A,this.providers,this.logger),this.config.autoGenerateOnBlogPublish)yc0(A,this.logger),mc0(A,this.logger),this.logger.info("Auto-generate on blog publish enabled");uc0(A,this.logger),Sc0(A),this.logger.info("Social media plugin registered successfully")}initializeProviders(){if(this.config.linkedin?.accessToken){let A=pZA(this.config.linkedin,this.logger.child("LinkedInClient"));this.providers.set("linkedin",A),this.logger.info("LinkedIn provider initialized")}}}function e_(A){return new dZA(A)}KA();var yb2=J.enum(["draft","queued","published","failed"]),JzB=J.object({status:yb2.default("draft"),queueOrder:J.number().optional().describe("Position in publish queue (lower = sooner)"),publishedAt:J.string().datetime().optional()});class iZA{name="internal";async publish(A,Q){return{id:"internal"}}}var R9={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"},NJ={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"};KA();var mb2=J.object({skipIfDraftExists:J.boolean().optional(),minSourceEntities:J.number().optional(),maxUnpublishedDrafts:J.number().optional(),sourceEntityType:J.string().optional()}),lc0=J.object({entitySchedules:J.record(J.string(),J.string()).optional(),generationSchedules:J.record(J.string(),J.string()).optional(),generationConditions:J.record(J.string(),mb2).optional(),maxRetries:J.number().optional().default(3),retryBaseDelayMs:J.number().optional().default(5000)});class aX{static instance=null;queues=new Map;static getInstance(){return aX.instance??=new aX,aX.instance}static resetInstance(){aX.instance=null}static createFresh(){return new aX}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,D={entityId:Q,entityType:A,position:$,queuedAt:new Date().toISOString()};return B.push(D),{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((Y)=>Y.entityId===Q);if($===-1)return;let[D]=w.splice($,1);if(!D)return;let I=Math.max(0,Math.min(B-1,w.length));w.splice(I,0,D),this.recalculatePositions(w)}async list(A){let Q=this.queues.get(A);if(!Q)return[];return[...Q]}async getNext(A){let Q=this.queues.get(A);if(!Q||Q.length===0)return null;return Q[0]??null}async getNextAcrossTypes(){let A=null;for(let Q of this.queues.values()){let B=Q[0];if(!B)continue;if(!A||B.queuedAt<A.queuedAt)A=B}return A}async popNext(A){let Q=this.queues.get(A);if(!Q||Q.length===0)return null;let B=Q.shift()??null;if(B)this.recalculatePositions(Q);return B}getRegisteredTypes(){return Array.from(this.queues.keys())}async getQueuedEntityTypes(){let A=[];for(let[Q,B]of this.queues.entries())if(B.length>0)A.push(Q);return A}getOrCreateQueue(A){let Q=this.queues.get(A);if(!Q)Q=[],this.queues.set(A,Q);return Q}recalculatePositions(A){A.forEach((Q,B)=>{Q.position=B+1})}}class tX{static instance=null;providers=new Map;defaultProvider=new iZA;static getInstance(){return tX.instance??=new tX,tX.instance}static resetInstance(){tX.instance=null}static createFresh(){return new tX}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())}}KA();KA();async function pc0(A,Q){let B={entityType:A.entityType,entityId:A.entityId};if(Q.messageBus)await Q.messageBus.send({type:R9.EXECUTE,payload:B,sender:"publish-service"});Q.onExecute?.(B)}async function dc0(A,Q){let B=Q.providerRegistry.get(A.entityType);if(!Q.entityService){Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:"EntityService not available for provider mode",retryCount:0,willRetry:!1});return}let w=await Q.entityService.getEntity({entityType:A.entityType,id:A.entityId});if(!w){Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:`Entity not found: ${A.entityType}/${A.entityId}`,retryCount:0,willRetry:!1});return}try{let $=await B.publish(w.content,w.metadata);Q.retryTracker.clearRetries(A.entityId),Q.onPublish?.({entityType:A.entityType,entityId:A.entityId,result:$})}catch($){let D=L0($);Q.retryTracker.recordFailure(A.entityId,D);let I=Q.retryTracker.getRetryInfo(A.entityId);Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:D,retryCount:I?.retryCount??1,willRetry:I?.willRetry??!1})}}function ic0(A,Q,B,w){if(w.retryTracker.clearRetries(Q),w.messageBus)w.messageBus.send({type:R9.COMPLETED,payload:{entityType:A,entityId:Q,result:B},sender:"publish-service"});w.onPublish?.({entityType:A,entityId:Q,result:B})}function rc0(A,Q,B,w){w.retryTracker.recordFailure(Q,B);let $=w.retryTracker.getRetryInfo(Q),D={entityType:A,entityId:Q,error:B,retryCount:$?.retryCount??1,willRetry:$?.willRetry??!1};if(w.messageBus)w.messageBus.send({type:R9.FAILED,payload:D,sender:"publish-service"});w.onFailed?.(D)}async function nc0(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:NJ.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:NJ.EXECUTE,payload:w,sender:"content-pipeline"});Q.onGenerate?.(w)}function oc0(A,Q,B){if(B)B.send({type:NJ.COMPLETED,payload:{entityType:A,entityId:Q},sender:"content-pipeline"})}function sc0(A,Q,B){if(B)B.send({type:NJ.FAILED,payload:{entityType:A,error:Q},sender:"content-pipeline"})}var ub2=1000;class rZA{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(ub2,()=>this.processUnscheduledTypes())}stop(){if(cb2(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 pc0(A,this.deps.getPublishDeps());else await dc0(A,this.deps.getPublishDeps())}get entitySchedules(){return this.deps.config.entitySchedules}}function cb2(A){for(let Q of A.values())Q.stop();A.clear()}class nZA{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(){lb2(this.generationJobs)}async handleTriggerGeneration(A){if(!this.deps.isRunning())return;try{await nc0(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 lb2(A){for(let Q of A.values())Q.stop();A.clear()}class WY{static instance=null;config;publishRunner;generationRunner;running=!1;static getInstance(A){return WY.instance??=new WY(A),WY.instance}static resetInstance(){if(WY.instance)WY.instance.stop();WY.instance=null}static createFresh(A){return new WY(A)}constructor(A){this.config={...A,entitySchedules:A.entitySchedules??{},generationSchedules:A.generationSchedules??{},generationConditions:A.generationConditions??{}},this.validateCronExpressions(),this.publishRunner=new rZA({config:this.config,getPublishDeps:()=>this.publishDeps,isRunning:()=>this.running}),this.generationRunner=new nZA({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){ic0(A,Q,B,this.publishDeps)}failPublish(A,Q,B){rc0(A,Q,B,this.publishDeps)}async publishDirect(A,Q,B,w){return this.config.providerRegistry.get(A).publish(B,w)}completeGeneration(A,Q){oc0(A,Q,this.config.messageBus)}failGeneration(A,Q){sc0(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}" - ${L0(w)}`)}}}var ac0={maxRetries:3,baseDelayMs:5000};class eX{static instance=null;retries=new Map;config;static getInstance(A){return eX.instance??=new eX(A??ac0),eX.instance}static resetInstance(){eX.instance=null}static createFresh(A){return new eX(A??ac0)}constructor(A){this.config=A}recordFailure(A,Q){let w=(this.retries.get(A)?.retryCount??0)+1,$=this.config.baseDelayMs*Math.pow(2,w-1),D=Date.now()+$;this.retries.set(A,{entityId:A,retryCount:w,lastError:Q,nextRetryAt:D})}shouldRetry(A){let Q=this.retries.get(A);if(!Q)return!1;return Q.retryCount<this.config.maxRetries}isReadyForRetry(A){let Q=this.retries.get(A);if(!Q)return!1;return Date.now()>=Q.nextRetryAt}clearRetries(A){this.retries.delete(A)}getRetryInfo(A){let Q=this.retries.get(A);if(!Q)return null;return{entityId:Q.entityId,retryCount:Q.retryCount,lastError:Q.lastError,nextRetryAt:Q.nextRetryAt,willRetry:Q.retryCount<this.config.maxRetries}}}function b9(A,Q,B,w,$,D,I,Y){return b9.fromTZ(b9.tp(A,Q,B,w,$,D,I),Y)}b9.fromTZISO=(A,Q,B)=>b9.fromTZ(pb2(A,Q),B);b9.fromTZ=function(A,Q){let B=new Date(Date.UTC(A.y,A.m-1,A.d,A.h,A.i,A.s)),w=oZA(A.tz,B),$=new Date(B.getTime()-w),D=oZA(A.tz,$);if(D-w===0)return $;{let I=new Date(B.getTime()-D),Y=oZA(A.tz,I);if(Y-D===0)return I;if(!Q&&Y-D>0)return I;if(Q)throw Error("Invalid date passed to fromTZ()");return $}};b9.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}};b9.tp=(A,Q,B,w,$,D,I)=>({y:A,m:Q,d:B,h:w,i:$,s:D,tz:I});function oZA(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 pb2(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("+")?b9.tp(B.getUTCFullYear(),B.getUTCMonth()+1,B.getUTCDate(),B.getUTCHours(),B.getUTCMinutes(),B.getUTCSeconds(),"Etc/UTC"):b9.tp(B.getFullYear(),B.getMonth()+1,B.getDate(),B.getHours(),B.getMinutes(),B.getSeconds(),Q)}b9.minitz=b9;var sZA=32,Qx=31|sZA,Ql0=[1,2,4,8,16],tc0=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 bI(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,Qx),this.dayOfWeek[7]&&(this.dayOfWeek[0]=this.dayOfWeek[7])}partToArray(A,Q,B,w){let $=this[A],D=A==="day"&&this.lastDayOfMonth;if(Q===""&&!D)throw TypeError("CronPattern: configuration entry "+A+" ("+Q+") is empty, check for trailing spaces.");if(Q==="*")return $.fill(w);let I=Q.split(",");if(I.length>1)for(let Y=0;Y<I.length;Y++)this.partToArray(A,I[Y],B,w);else Q.indexOf("-")!==-1&&Q.indexOf("/")!==-1?this.handleRangeWithStepping(Q,A,B,w):Q.indexOf("-")!==-1?this.handleRange(Q,A,B,w):Q.indexOf("/")!==-1?this.handleStepping(Q,A,B,w):Q!==""&&this.handleNumber(Q,A,B,w)}throwAtIllegalCharacters(A){for(let Q=0;Q<A.length;Q++)if((Q===5?/[^/*0-9,\-#L]+/:/[^/*0-9,-]+/).test(A[Q]))throw TypeError("CronPattern: configuration entry "+Q+" ("+A[Q]+") contains illegal characters.")}handleNumber(A,Q,B,w){let $=this.extractNth(A,Q),D=parseInt($[0],10)+B;if(isNaN(D))throw TypeError("CronPattern: "+Q+" is not a number: '"+A+"'");this.setPart(Q,D,$[1]||w)}setPart(A,Q,B){if(!Object.prototype.hasOwnProperty.call(this,A))throw TypeError("CronPattern: Invalid part specified: "+A);if(A==="dayOfWeek"){if(Q===7&&(Q=0),Q<0||Q>6)throw RangeError("CronPattern: Invalid value for dayOfWeek: "+Q);this.setNthWeekdayOfMonth(Q,B);return}if(A==="second"||A==="minute"){if(Q<0||Q>=60)throw RangeError("CronPattern: Invalid value for "+A+": "+Q)}else if(A==="hour"){if(Q<0||Q>=24)throw RangeError("CronPattern: Invalid value for "+A+": "+Q)}else if(A==="day"){if(Q<0||Q>=31)throw RangeError("CronPattern: Invalid value for "+A+": "+Q)}else if(A==="month"&&(Q<0||Q>=12))throw RangeError("CronPattern: Invalid value for "+A+": "+Q);this[A][Q]=B}handleRangeWithStepping(A,Q,B,w){let $=this.extractNth(A,Q),D=$[0].match(/^(\d+)-(\d+)\/(\d+)$/);if(D===null)throw TypeError("CronPattern: Syntax error, illegal range with stepping: '"+A+"'");let[,I,Y,X]=D,H=parseInt(I,10)+B,U=parseInt(Y,10)+B,F=parseInt(X,10);if(isNaN(H))throw TypeError("CronPattern: Syntax error, illegal lower range (NaN)");if(isNaN(U))throw TypeError("CronPattern: Syntax error, illegal upper range (NaN)");if(isNaN(F))throw TypeError("CronPattern: Syntax error, illegal stepping: (NaN)");if(F===0)throw TypeError("CronPattern: Syntax error, illegal stepping: 0");if(F>this[Q].length)throw TypeError("CronPattern: Syntax error, steps cannot be greater than maximum value of part ("+this[Q].length+")");if(H>U)throw TypeError("CronPattern: From value is larger than to value: '"+A+"'");for(let Z=H;Z<=U;Z+=F)this.setPart(Q,Z,$[1]||w)}extractNth(A,Q){let B=A,w;if(B.includes("#")){if(Q!=="dayOfWeek")throw Error("CronPattern: nth (#) only allowed in day-of-week field");w=B.split("#")[1],B=B.split("#")[0]}return[B,w]}handleRange(A,Q,B,w){let $=this.extractNth(A,Q),D=$[0].split("-");if(D.length!==2)throw TypeError("CronPattern: Syntax error, illegal range: '"+A+"'");let I=parseInt(D[0],10)+B,Y=parseInt(D[1],10)+B;if(isNaN(I))throw TypeError("CronPattern: Syntax error, illegal lower range (NaN)");if(isNaN(Y))throw TypeError("CronPattern: Syntax error, illegal upper range (NaN)");if(I>Y)throw TypeError("CronPattern: From value is larger than to value: '"+A+"'");for(let X=I;X<=Y;X++)this.setPart(Q,X,$[1]||w)}handleStepping(A,Q,B,w){let $=this.extractNth(A,Q),D=$[0].split("/");if(D.length!==2)throw TypeError("CronPattern: Syntax error, illegal stepping: '"+A+"'");D[0]===""&&(D[0]="*");let I=0;D[0]!=="*"&&(I=parseInt(D[0],10)+B);let Y=parseInt(D[1],10);if(isNaN(Y))throw TypeError("CronPattern: Syntax error, illegal stepping: (NaN)");if(Y===0)throw TypeError("CronPattern: Syntax error, illegal stepping: 0");if(Y>this[Q].length)throw TypeError("CronPattern: Syntax error, max steps for part is ("+this[Q].length+")");for(let X=I;X<this[Q].length;X+=Y)this.setPart(Q,X,$[1]||w)}replaceAlphaDays(A){return A.replace(/-sun/gi,"-7").replace(/sun/gi,"0").replace(/mon/gi,"1").replace(/tue/gi,"2").replace(/wed/gi,"3").replace(/thu/gi,"4").replace(/fri/gi,"5").replace(/sat/gi,"6")}replaceAlphaMonths(A){return A.replace(/jan/gi,"1").replace(/feb/gi,"2").replace(/mar/gi,"3").replace(/apr/gi,"4").replace(/may/gi,"5").replace(/jun/gi,"6").replace(/jul/gi,"7").replace(/aug/gi,"8").replace(/sep/gi,"9").replace(/oct/gi,"10").replace(/nov/gi,"11").replace(/dec/gi,"12")}handleNicknames(A){let Q=A.trim().toLowerCase();return Q==="@yearly"||Q==="@annually"?"0 0 1 1 *":Q==="@monthly"?"0 0 1 * *":Q==="@weekly"?"0 0 * * 0":Q==="@daily"?"0 0 * * *":Q==="@hourly"?"0 * * * *":A}setNthWeekdayOfMonth(A,Q){if(typeof Q!="number"&&Q==="L")this.dayOfWeek[A]=this.dayOfWeek[A]|sZA;else if(Q===Qx)this.dayOfWeek[A]=Qx;else if(Q<6&&Q>0)this.dayOfWeek[A]=this.dayOfWeek[A]|Ql0[Q-1];else throw TypeError(`CronPattern: nth weekday out of range, should be 1-5 or L. Value: ${Q}, Type: ${typeof Q}`)}},ec0=[31,28,31,30,31,30,31,31,30,31,30,31],FW=[["month","year",0],["day","month",-1],["hour","day",0],["minute","hour",0],["second","minute",0]],bI=class A{tz;ms;second;minute;hour;day;month;year;constructor(Q,B){if(this.tz=B,Q&&Q instanceof Date)if(!isNaN(Q))this.fromDate(Q);else throw TypeError("CronDate: Invalid date passed to CronDate constructor");else if(Q===void 0)this.fromDate(new Date);else if(Q&&typeof Q=="string")this.fromString(Q);else if(Q instanceof A)this.fromCronDate(Q);else throw TypeError("CronDate: Invalid type ("+typeof Q+") passed to CronDate constructor")}isNthWeekdayOfMonth(Q,B,w,$){let D=new Date(Date.UTC(Q,B,w)).getUTCDay(),I=0;for(let Y=1;Y<=w;Y++)new Date(Date.UTC(Q,B,Y)).getUTCDay()===D&&I++;if($&Qx&&Ql0[I-1]&$)return!0;if($&sZA){let Y=new Date(Date.UTC(Q,B+1,0)).getUTCDate();for(let X=w+1;X<=Y;X++)if(new Date(Date.UTC(Q,B,X)).getUTCDay()===D)return!1;return!0}return!1}fromDate(Q){if(this.tz!==void 0)if(typeof this.tz=="number")this.ms=Q.getUTCMilliseconds(),this.second=Q.getUTCSeconds(),this.minute=Q.getUTCMinutes()+this.tz,this.hour=Q.getUTCHours(),this.day=Q.getUTCDate(),this.month=Q.getUTCMonth(),this.year=Q.getUTCFullYear(),this.apply();else{let B=b9.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>ec0[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=b9.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(b9.fromTZISO(Q,this.tz))}findNext(Q,B,w,$){let D=this[B],I;w.lastDayOfMonth&&(this.month!==1?I=ec0[this.month]:I=new Date(Date.UTC(this.year,this.month+1,0,0,0,0,0)).getUTCDate());let Y=!w.starDOW&&B=="day"?new Date(Date.UTC(this.year,this.month,1,0,0,0,0)).getUTCDay():void 0;for(let X=this[B]+$;X<w[B].length;X++){let H=w[B][X];if(B==="day"&&w.lastDayOfMonth&&X-$==I&&(H=1),B==="day"&&!w.starDOW){let U=w.dayOfWeek[(Y+(X-$-1))%7];if(U&&U&Qx)U=this.isNthWeekdayOfMonth(this.year,this.month,X-$,U)?1:0;else if(U)throw Error(`CronDate: Invalid value for dayOfWeek encountered. ${U}`);Q.legacyMode&&!w.starDOM?H=H||U:H=H&&U}if(H)return this[B]=X-$,D!==this[B]?2:1}return 3}recurse(Q,B,w){let $=this.findNext(B,FW[w][0],Q,FW[w][2]);if($>1){let D=w+1;for(;D<FW.length;)this[FW[D][0]]=-FW[D][2],D++;if($===3)return this[FW[w][1]]++,this[FW[w][0]]=-FW[w][2],this.apply(),this.recurse(Q,B,0);if(this.apply())return this.recurse(Q,B,w-1)}return w+=1,w>=FW.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)):b9.fromTZ(b9.tp(this.year,this.month+1,this.day,this.hour,this.minute,this.second,this.tz),!1)}getTime(){return this.getDate(!1).getTime()}};function db2(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 bI(A.startAt,A.timezone)),A.stopAt&&(A.stopAt=new bI(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 Ax(A){return Object.prototype.toString.call(A)==="[object Function]"||typeof A=="function"||A instanceof Function}function ib2(A){return Ax(A)}function rb2(A){typeof Deno<"u"&&typeof Deno.unrefTimer<"u"?Deno.unrefTimer(A):A&&typeof A.unref<"u"&&A.unref()}var Al0=30000,Yn=[],aZA=class{name;options;_states;fn;constructor(A,Q,B){let w,$;if(Ax(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(Ax(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=db2(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 tc0("* * * * *")},A&&(A instanceof Date||typeof A=="string"&&A.indexOf(":")>0)?this._states.once=new bI(A,this.options.timezone||this.options.utcOffset):this._states.pattern=new tc0(A,this.options.timezone),this.name){if(Yn.find((D)=>D.name===this.name))throw Error("Cron: Tried to initialize new named job '"+this.name+"', but name already taken.");Yn.push(this)}return $!==void 0&&ib2($)&&(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 bI||A instanceof Date?Q.getTime()-A.getTime():Q.getTime()-new bI(A).getTime():null}stop(){this._states.kill=!0,this._states.currentTimeout&&clearTimeout(this._states.currentTimeout);let A=Yn.indexOf(this);A>=0&&Yn.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>Al0&&(Q=Al0),this._states.currentTimeout=setTimeout(()=>this._checkTrigger(B),Q),this._states.currentTimeout&&this.options.unref&&rb2(this._states.currentTimeout),this)}async _trigger(A){if(this._states.blocking=!0,this._states.currentRun=new bI(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){Ax(this.options.catch)&&this.options.catch(Q,this)}else this.fn!==void 0&&await this.fn(this,this.options.context);this._states.previousRun=new bI(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&&Ax(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 bI(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 bI(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 bI(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 bI(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 Xn{scheduleCron(A,Q){let B=new aZA(A,()=>{Q()});return{stop:()=>B.stop()}}scheduleInterval(A,Q){let B=setInterval(()=>{Q()},A);return{stop:()=>clearInterval(B)}}validateCron(A){new aZA(A).stop()}}tA();KA();var tZA=J.object({action:J.enum(["list","add","remove","reorder"]).describe("Queue action to perform"),entityType:J.string().optional().describe("Entity type (required for add/remove/reorder, optional for list)"),entityId:J.string().optional().describe("Entity ID (required for add/remove/reorder)"),position:J.number().optional().describe("New position for reorder action (1-based)")}),eZA=J.object({position:J.number(),entityType:J.string(),entityId:J.string(),queuedAt:J.string()}),nb2=J.object({success:J.literal(!0),message:J.string().optional(),data:J.object({queue:J.array(eZA).optional(),entityType:J.string().optional(),entityId:J.string().optional(),position:J.number().optional()}).optional()}),ob2=J.object({success:J.literal(!1),error:J.string(),code:J.string().optional()}),A3A=J.union([nb2,ob2]);function Hn(A,Q,B){return{...MQ(Q,"queue","Manage the publish queue for all entity types (list, add, remove, reorder)",tZA,async($)=>{let{action:D,entityType:I,entityId:Y,position:X}=$;switch(D){case"list":return sb2(B,I);case"add":return ab2(B,I,Y);case"remove":return tb2(B,I,Y);case"reorder":return eb2(B,I,Y,X);default:return{success:!1,error:`Unknown action: ${D}`}}}),outputSchema:A3A}}async function sb2(A,Q){let B=[];if(Q)B=await A.list(Q);else{let $=A.getRegisteredTypes();for(let D of $){let I=await A.list(D);B.push(...I)}B.sort((D,I)=>new Date(D.queuedAt).getTime()-new Date(I.queuedAt).getTime())}if(B.length===0)return{success:!0,data:{queue:[]},message:"No items in queue"};return{success:!0,data:{queue:B.map(($,D)=>({position:D+1,entityType:$.entityType,entityId:$.entityId,queuedAt:$.queuedAt}))},message:`${B.length} items in queue`}}async function ab2(A,Q,B){let w=Q3A("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 tb2(A,Q,B){let w=Q3A("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 eb2(A,Q,B,w){let $=Q3A("reorder",Q,B);if(!$.success)return $.error;let D=AP2(w);if(!D.success)return D.error;return await A.reorder($.entityType,$.entityId,D.position),{success:!0,data:{entityType:$.entityType,entityId:$.entityId,position:D.position},message:`Moved to position ${D.position}`}}function Q3A(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 AP2(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}}tA();KA();tA();KA();async function Bl0(A,Q){let{bodyContent:B,coverImageId:w}=QP2(Q.content),$=w?await BP2(A,w):void 0,D={bodyContent:B};if($)D.imageData=$;return D}function QP2(A){try{let Q=M2(A,J.record(J.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 BP2(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 B3A=J.object({entityType:J.string().describe("Entity type to publish (e.g., social-post, post, deck)"),id:J.string().optional().describe("Entity ID to publish"),slug:J.string().optional().describe("Entity slug to publish")}),wP2=J.object({success:J.literal(!0),message:J.string().optional(),data:J.object({entityType:J.string().optional(),entityId:J.string().optional(),platformId:J.string().optional(),url:J.string().optional()}).optional()}),$P2=J.object({success:J.literal(!1),error:J.string(),code:J.string().optional()}),w3A=J.union([wP2,$P2]);function Kn(A,Q,B){return{...MQ(Q,"publish","Publish an entity directly to its platform. Works with any registered entity type (social-post, post, deck, etc.)",B3A,async($)=>{let{entityType:D,id:I,slug:Y}=$;if(!I&&!Y)return{success:!1,error:"Either 'id' or 'slug' must be provided"};let X=await DP2(A,D,I,Y);if(!X)return{success:!1,error:`Entity not found: ${D}:${I??Y}`};if(X.metadata.status==="published")return{success:!1,error:"Entity is already published"};if(!B.has(D))return{success:!1,error:`No publish provider registered for ${D}. Check that the required credentials are configured.`};let H=B.get(D),{bodyContent:U,imageData:F}=await Bl0(A,X),Z=await H.publish(U,X.metadata,F);return await A.entityService.updateEntity({entity:{...X,metadata:{...X.metadata,status:"published",publishedAt:new Date().toISOString(),platformId:Z.id}}}),{success:!0,data:{entityType:D,entityId:X.id,platformId:Z.id,url:Z.url},message:`Published ${D}:${X.id}`}}),outputSchema:w3A}}async function DP2(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}tA();KA();function wl0(A,Q){IP2(A,Q),YP2(A,Q)}function IP2(A,Q){A.messaging.subscribe(R9.REGISTER,async(B)=>XP2(Q,B.payload)),A.messaging.subscribe(R9.QUEUE,async(B)=>HP2(A,Q,B.payload)),A.messaging.subscribe(R9.DIRECT,async(B)=>KP2(A,Q,B.payload)),A.messaging.subscribe(R9.REMOVE,async(B)=>WP2(Q,B.payload)),A.messaging.subscribe(R9.REORDER,async(B)=>UP2(Q,B.payload)),A.messaging.subscribe(R9.LIST,async(B)=>GP2(A,Q,B.payload)),A.messaging.subscribe(R9.REPORT_SUCCESS,async(B)=>JP2(Q,B.payload)),A.messaging.subscribe(R9.REPORT_FAILURE,async(B)=>FP2(Q,B.payload)),Q.logger.debug("Subscribed to publish messages")}function YP2(A,Q){A.messaging.subscribe(NJ.REPORT_SUCCESS,async(B)=>ZP2(Q,B.payload)),A.messaging.subscribe(NJ.REPORT_FAILURE,async(B)=>zP2(Q,B.payload)),Q.logger.debug("Subscribed to generation messages")}async function XP2(A,Q){let{entityType:B,provider:w}=Q;try{if(w)A.providerRegistry.register(B,w),A.logger.info(`Registered provider for entity type: ${B}`,{providerName:w.name});return{success:!0}}catch($){let D=L0($);return A.logger.error(`Failed to register provider: ${D}`),{success:!1}}}async function HP2(A,Q,B){let{entityType:w,entityId:$}=B;try{let D=await Q.queueManager.add(w,$);return await A.messaging.send({type:R9.QUEUED,payload:{entityType:w,entityId:$,position:D.position}}),Q.logger.debug(`Entity queued: ${$}`,{entityType:w,position:D.position}),{success:!0}}catch(D){let I=L0(D);return Q.logger.error(`Failed to queue entity: ${I}`),{success:!1}}}async function KP2(A,Q,B){let{entityType:w,entityId:$}=B;return await A.messaging.send({type:R9.EXECUTE,payload:{entityType:w,entityId:$}}),Q.logger.debug(`Direct publish requested: ${$}`,{entityType:w}),{success:!0}}async function WP2(A,Q){let{entityType:B,entityId:w}=Q;try{return await A.queueManager.remove(B,w),A.logger.debug(`Entity removed from queue: ${w}`,{entityType:B}),{success:!0}}catch($){let D=L0($);return A.logger.error(`Failed to remove entity: ${D}`),{success:!1}}}async function UP2(A,Q){let{entityType:B,entityId:w,position:$}=Q;try{return await A.queueManager.reorder(B,w,$),A.logger.debug(`Entity reordered: ${w}`,{entityType:B,newPosition:$}),{success:!0}}catch(D){let I=L0(D);return A.logger.error(`Failed to reorder entity: ${I}`),{success:!1}}}async function GP2(A,Q,B){let{entityType:w}=B;try{let $=await Q.queueManager.list(w);return await A.messaging.send({type:R9.LIST_RESPONSE,payload:{entityType:w,queue:$.map((D)=>({entityId:D.entityId,position:D.position,queuedAt:D.queuedAt}))}}),{success:!0}}catch($){let D=L0($);return Q.logger.error(`Failed to list queue: ${D}`),{success:!1}}}async function JP2(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 FP2(A,Q){let{entityType:B,entityId:w,error:$}=Q;A.scheduler.failPublish(B,w,$);let D=A.retryTracker.getRetryInfo(w);return A.logger.info(`Publish reported failure: ${w}`,{entityType:B,error:$,retryCount:D?.retryCount,willRetry:D?.willRetry}),{success:!0}}async function ZP2(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 zP2(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}}KA();async function $l0(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:L0($)}),{shouldGenerate:!1,reason:`Condition check failed: ${L0($)}`}}}function Dl0(A){let{context:Q,config:B,queueManager:w,providerRegistry:$,retryTracker:D,logger:I}=A,Y=qP2(Q);return WY.createFresh({queueManager:w,providerRegistry:$,retryTracker:D,logger:I,backend:new Xn,...B.entitySchedules&&{entitySchedules:B.entitySchedules},...B.generationSchedules&&{generationSchedules:B.generationSchedules},...B.generationConditions&&{generationConditions:B.generationConditions},messageBus:Y,entityService:Q.entityService,onCheckGenerationConditions:(X,H)=>$l0(Q.entityService,I,X,H)})}function qP2(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 Il0(A,Q,B){let w=A.getEntityTypes();for(let D of w){let I=await A.listEntities({entityType:D,options:{filter:{metadata:{status:"queued"}}}});for(let Y of I)await Q.add(Y.entityType,Y.id)}let $=0;for(let D of w){let I=await Q.list(D);$+=I.length}if($>0)B.info(`Rebuilt queue with ${$} queued entities`)}var NP2=["draft","queued","published","failed"];async function Yl0(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",dataProvider:()=>fP2(A)}})}async function fP2(A){let Q=A.entityService.getEntityTypes(),B=[],w={draft:0,queued:0,published:0,failed:0};for(let $ of Q){let D=await A.entityService.listEntities({entityType:$});for(let I of D){let Y=LP2(I.metadata.status);if(!Y)continue;w[Y]++,B.push({id:I.id,title:CP2(I.id,I.metadata.title),type:$,status:Y})}}return{summary:w,items:B}}function LP2(A){return NP2.find((Q)=>Q===A)}function CP2(A,Q){return typeof Q==="string"?Q:A}var Xl0={name:"@brains/content-pipeline",private:!0,version:"0.2.0-alpha.54",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/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 $3A extends Bw{pluginContext;queueManager;providerRegistry;retryTracker;scheduler;constructor(A){super("content-pipeline",Xl0,A??{},lc0)}async onRegister(A){this.pluginContext=A,this.queueManager=aX.createFresh(),this.providerRegistry=tX.createFresh(),this.retryTracker=eX.createFresh({maxRetries:this.config.maxRetries,baseDelayMs:this.config.retryBaseDelayMs}),this.scheduler=Dl0({context:A,config:this.config,queueManager:this.queueManager,providerRegistry:this.providerRegistry,retryTracker:this.retryTracker,logger:this.logger}),wl0(A,{queueManager:this.queueManager,providerRegistry:this.providerRegistry,retryTracker:this.retryTracker,scheduler:this.scheduler,logger:this.logger})}async onReady(A){await Il0(A.entityService,this.queueManager,this.logger),await Yl0(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[Hn(this.pluginContext,this.id,this.queueManager),Kn(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(),aX.resetInstance(),tX.resetInstance(),eX.resetInstance()}}function D3A(A){return new $3A(A)}tA();KA();var Hl0=J.object({accountId:J.string().describe("Cloudflare account ID"),apiToken:J.string().describe("Cloudflare API token with Analytics:Read permission"),siteTag:J.string().describe("Cloudflare Web Analytics site tag")}),I3A=J.object({cloudflare:Hl0.optional()});tA();KA();var MP2=J.object({date:J.string().describe("Single date in YYYY-MM-DD format").optional(),days:J.number().min(1).max(365).describe("Number of days back from yesterday (e.g., 7 for last week)").optional(),startDate:J.string().describe("Start date in YYYY-MM-DD format (use with endDate)").optional(),endDate:J.string().describe("End date in YYYY-MM-DD format (use with startDate)").optional(),limit:J.number().min(1).max(100).default(20).describe("Maximum items for breakdowns (pages, referrers, countries)")});function VP2(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 Kl0(A,Q,B){let w=[];if(!B)return w;return w.push(MQ(A,"query",`Query website analytics from Cloudflare.
|
|
2959
2959
|
|
|
2960
2960
|
Date range options (use only one):
|
|
2961
2961
|
- No params: yesterday only
|
|
@@ -3093,7 +3093,7 @@ Returns pageviews, visitors, top pages, referrers, devices, and countries.`,MP2,
|
|
|
3093
3093
|
}
|
|
3094
3094
|
}
|
|
3095
3095
|
}
|
|
3096
|
-
`,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}))}}KA();var X3A=7,OP2=10;function Ul0(A){return async()=>{if(!A)return{unavailable:!0,reason:"Cloudflare analytics not configured"};let Q=NN(),B=US(X3A),w=PU(B),$=PU(Q);try{let[D,I]=await Promise.all([A.getWebsiteStats({startDate:w,endDate:$}),A.getTopPages({startDate:w,endDate:$,limit:OP2})]);return{days:X3A,startDate:w,endDate:$,pageviews:D.pageviews,visitors:D.visitors,topPages:I}}catch(D){return{error:D instanceof Error?D.message:"Failed to fetch analytics",days:X3A}}}}var Gl0={name:"@brains/analytics",private:!0,version:"0.2.0-alpha.
|
|
3096
|
+
`,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}))}}KA();var X3A=7,OP2=10;function Ul0(A){return async()=>{if(!A)return{unavailable:!0,reason:"Cloudflare analytics not configured"};let Q=NN(),B=US(X3A),w=PU(B),$=PU(Q);try{let[D,I]=await Promise.all([A.getWebsiteStats({startDate:w,endDate:$}),A.getTopPages({startDate:w,endDate:$,limit:OP2})]);return{days:X3A,startDate:w,endDate:$,pageviews:D.pageviews,visitors:D.visitors,topPages:I}}catch(D){return{error:D instanceof Error?D.message:"Failed to fetch analytics",days:X3A}}}}var Gl0={name:"@brains/analytics",private:!0,version:"0.2.0-alpha.54",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 Jl0 extends Bw{cloudflareClient;constructor(A={}){super("analytics",Gl0,A,I3A)}async onRegister(A){this.cloudflareClient=this.config.cloudflare?new Y3A(this.config.cloudflare):void 0,A.insights.register("traffic-overview",Ul0(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:Wl0(Q)}})}async getTools(){return Kl0(this.id,this.getContext(),this.cloudflareClient)}}function bP2(A={}){return new Jl0(A)}var Wn=bP2;tA();KA();Qw();var PP2=new Set(["description","excerpt","summary","tagline","story"]);function kP2(A){if(A.endsWith("s"))return A;return S7(A)}function H3A(A,Q=!1,B){let w=A._def.typeName;if(w==="ZodOptional"||w==="ZodNullable")return H3A(A._def.innerType,!0,B);if(w==="ZodDefault")return H3A(A._def.innerType,Q,A._def.defaultValue());return{inner:A,isOptional:Q,defaultValue:B}}function K3A(A,Q){let{inner:B,isOptional:w,defaultValue:$}=H3A(Q),D=B._def.typeName,I={name:A,label:nY(A),widget:"string",...w&&{required:!1},...$!==void 0&&{default:$}};switch(D){case"ZodString":{if((B._def.checks??[]).some((X)=>X.kind==="datetime"))return{...I,widget:"datetime"};if(PP2.has(A))return{...I,widget:"text"};return{...I,widget:"string"}}case"ZodNumber":return{...I,widget:"number"};case"ZodBoolean":return{...I,widget:"boolean"};case"ZodEnum":{let Y=B._def.values;return{...I,widget:"select",options:Y}}case"ZodArray":{let Y=B._def.type,X=K3A("item",Y);if(X.widget==="object"&&X.fields)return{...I,widget:"list",fields:X.fields};return{...I,widget:"list",field:{name:A,label:nY(A),widget:X.widget}}}case"ZodObject":{let Y=B.shape,X=Object.entries(Y).map(([H,U])=>K3A(H,U));return{...I,widget:"object",fields:X}}default:return{...I,widget:"string"}}}function Fl0(A,Q){let B=Object.entries(A.shape).map(([w,$])=>K3A(w,$));if(Q)B.push({name:"body",label:"Body",widget:"markdown"});return B}function Zl0(A){let Q=[],B=[];for(let w of A.entityTypes){let $=A.getFrontmatterSchema(w);if(!$)continue;let D=A.getAdapter(w),I=D?.hasBody!==!1,Y=A.entityDisplay?.[w],X=w===Qg?"Note":nY(w),H=Y?.label??X,U=Y?.pluralName??kP2(H);if(D?.isSingleton){B.push({name:w,label:H,file:`${w}/${w}.md`,fields:Fl0($,I)});continue}if(w===Qg){Q.push({name:w,label:U,folder:".",create:!0,extension:"md",format:"frontmatter",fields:[{name:"body",label:"Body",widget:"markdown"}]});continue}Q.push({name:w,label:U,folder:w,create:!0,extension:"md",format:"frontmatter",fields:Fl0($,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 W3A(A){return`<!doctype html>
|
|
3097
3097
|
<html>
|
|
3098
3098
|
<head>
|
|
3099
3099
|
<meta charset="utf-8" />
|
|
@@ -3104,7 +3104,7 @@ Returns pageviews, visitors, top pages, referrers, devices, and countries.`,MP2,
|
|
|
3104
3104
|
</head>
|
|
3105
3105
|
<body></body>
|
|
3106
3106
|
</html>
|
|
3107
|
-
`}KA();var zl0={name:"@brains/cms",private:!0,version:"0.2.0-alpha.
|
|
3107
|
+
`}KA();var zl0={name:"@brains/cms",private:!0,version:"0.2.0-alpha.54",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 _P2=J.object({label:J.string().optional(),pluralName:J.string().optional()}).passthrough(),xP2=J.object({entityDisplay:J.record(_P2).optional(),routePath:J.string().default("/cms")});function vP2(A){return`${A.endsWith("/")?A:`${A}/`}config.yml`}function TP2(A,Q){let B=A.entityDisplay??Q?.entityDisplay;return B?{entityDisplay:B}:{}}async function SP2(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 gP2(A,Q={}){let{repo:B,branch:w}=await SP2(A);return Zl0({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 ql0(A,Q={}){return rY(await gP2(A,Q))}class U3A extends Bw{constructor(A={}){super("cms",zl0,A,xP2)}async onRegister(A){await super.onRegister(A),A.endpoints.register({label:"CMS",url:this.config.routePath,priority:40})}getWebRoutes(){let A=vP2(this.config.routePath);return[{path:this.config.routePath,method:"GET",public:!0,handler:async()=>{return new Response(W3A({cmsConfigPath:A}),{headers:{"Content-Type":"text/html; charset=utf-8"}})}},{path:A,method:"GET",public:!0,handler:async()=>{try{let Q=await ql0(this.getContext(),TP2(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 Oz(A){return new U3A(A)}tA();KA();KA();var Un=["StatsWidget","ListWidget","CustomWidget","PipelineWidget","IdentityWidget","ProfileWidget","SystemWidget"],hP2=new Set(Un);function G3A(A){return hP2.has(A)}var yP2=J.object({id:J.string(),pluginId:J.string(),title:J.string(),description:J.string().optional(),priority:J.number().default(50),section:J.enum(["primary","secondary","sidebar"]).default("primary"),rendererName:J.string()});class Gn{widgets=new Map;logger;constructor(A){this.logger=A.child("DashboardWidgetRegistry")}register(A){let Q=`${A.pluginId}:${A.id}`;this.widgets.set(Q,A),this.logger.debug("Dashboard widget registered",{key:Q,title:A.title,rendererName:A.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){return Array.from(this.widgets.values()).filter((Q)=>!A||Q.section===A).sort((Q,B)=>Q.priority-B.priority)}get size(){return this.widgets.size}}KA();class Jn{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(){let A={},Q=this.registry.list(),B=await Promise.allSettled(Q.map(async(w)=>{let $=await w.dataProvider(),{dataProvider:D,component:I,...Y}=w;return{key:`${w.pluginId}:${w.id}`,widget:Y,data:$}}));for(let w=0;w<B.length;w++){let $=B[w],D=Q[w];if(!$||!D)continue;if($.status==="fulfilled")A[$.value.key]={widget:$.value.widget,data:$.value.data};else this.logger.error("Widget data provider failed",{widgetId:D.id,pluginId:D.pluginId,error:L0($.reason)})}return{widgets:A}}async fetch(A,Q,B){return await this.getDashboardData()}}import{render as Wk2}from"preact-render-to-string";var Nl0=`
|
|
3108
3108
|
:root {
|
|
3109
3109
|
--ink: #0a0819;
|
|
3110
3110
|
--ink-raised: #14112b;
|
|
@@ -4038,7 +4038,7 @@ body::after {
|
|
|
4038
4038
|
}
|
|
4039
4039
|
});
|
|
4040
4040
|
})();`;function Zk2({input:A}){let Q=A.entityCounts.reduce((D,{count:I})=>D+I,0),B=Gk2(A.widgets),w=Boolean(A.character.role)||Boolean(A.character.purpose)||A.character.values.length>0,$=A.appInfo.endpoints.length>0;return sB("html",{lang:"en","data-theme":"dark",children:[sB("head",{children:[sB("meta",{charSet:"utf-8"},void 0,!1,void 0,this),sB("meta",{name:"viewport",content:"width=device-width, initial-scale=1.0"},void 0,!1,void 0,this),sB("title",{children:A.title},void 0,!1,void 0,this),sB("link",{rel:"preconnect",href:"https://fonts.googleapis.com"},void 0,!1,void 0,this),sB("link",{rel:"preconnect",href:"https://fonts.gstatic.com",crossOrigin:"anonymous"},void 0,!1,void 0,this),sB("link",{href:Uk2,rel:"stylesheet"},void 0,!1,void 0,this),sB("style",{dangerouslySetInnerHTML:{__html:Nl0}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),sB("body",{children:[sB("main",{class:"console","data-component":"dashboard:dashboard",children:[sB(Ll0,{title:A.title,tagline:A.profile.description,appInfo:A.appInfo,now:new Date},void 0,!1,void 0,this),sB("section",{class:"layout",children:[sB("div",{class:"main-column",children:[sB(Cl0,{total:Q,entityCounts:A.entityCounts},void 0,!1,void 0,this),B.primary.map((D)=>sB(Fn,{widget:D},`${D.widget.pluginId}:${D.widget.id}`,!1,void 0,this)),B.secondary.map((D)=>sB(Fn,{widget:D},`${D.widget.pluginId}:${D.widget.id}`,!1,void 0,this))]},void 0,!0,void 0,this),(w||B.sidebar.length>0||$)&&sB("div",{class:"sidebar-column",children:[sB(El0,{character:A.character},void 0,!1,void 0,this),B.sidebar.map((D)=>sB(Fn,{widget:D},`${D.widget.pluginId}:${D.widget.id}`,!1,void 0,this)),sB(Ml0,{endpoints:A.appInfo.endpoints,baseUrl:A.baseUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),sB(bl0,{title:A.title,appInfo:A.appInfo},void 0,!1,void 0,this)]},void 0,!0,void 0,this),sB("button",{class:"theme-toggle",id:"themeToggle","aria-label":"Toggle theme",children:"Light mode"},void 0,!1,void 0,this),sB("script",{dangerouslySetInnerHTML:{__html:Jk2}},void 0,!1,void 0,this),sB("script",{dangerouslySetInnerHTML:{__html:Fk2}},void 0,!1,void 0,this),A.widgetScripts.map((D,I)=>sB("script",{dangerouslySetInnerHTML:{__html:D}},`widget-script:${I}`,!1,void 0,this))]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}function Pl0(A){return`<!doctype html>
|
|
4041
|
-
${Wk2(sB(Zk2,{input:A},void 0,!1,void 0,this))}`}function kl0(A,Q){let B={},w=new Set;for(let[$,D]of Object.entries(A)){let I=Q?.get(D.widget.pluginId,D.widget.id);if(B[$]={...D,...I?.component?{component:I.component}:{}},I?.clientScript)w.add(I.clientScript)}return{widgets:B,widgetScripts:Array.from(w)}}var jl0={name:"@brains/dashboard",private:!0,version:"0.2.0-alpha.
|
|
4041
|
+
${Wk2(sB(Zk2,{input:A},void 0,!1,void 0,this))}`}function kl0(A,Q){let B={},w=new Set;for(let[$,D]of Object.entries(A)){let I=Q?.get(D.widget.pluginId,D.widget.id);if(B[$]={...D,...I?.component?{component:I.component}:{}},I?.clientScript)w.add(I.clientScript)}return{widgets:B,widgetScripts:Array.from(w)}}var jl0={name:"@brains/dashboard",private:!0,version:"0.2.0-alpha.54",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/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 qk2=J.object({version:J.string().default("1.0.0"),routePath:J.string().default("/dashboard")}),Nk2=J.object({id:J.string(),pluginId:J.string(),title:J.string(),description:J.string().optional(),priority:J.number().default(50),section:J.enum(["primary","secondary","sidebar"]).default("primary"),rendererName:J.string(),component:J.custom().optional(),clientScript:J.string().optional(),dataProvider:J.function().returns(J.promise(J.unknown()))}).superRefine((A,Q)=>{if(!G3A(A.rendererName)&&!A.component)Q.addIssue({code:J.ZodIssueCode.custom,message:"Custom dashboard widgets must register a Preact component.",path:["component"]})}),fk2=J.object({pluginId:J.string(),widgetId:J.string().optional()});function Lk2(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,...A.component?{component:A.component}:{},...A.clientScript?{clientScript:A.clientScript}:{},dataProvider:A.dataProvider}}class Z3A extends Bw{widgetRegistry=null;datasource=null;siteUrl;ctx;constructor(A){super("dashboard",jl0,A??{},qk2)}async onRegister(A){this.siteUrl=A.siteUrl,this.ctx=A,this.widgetRegistry=new Gn(this.logger),this.datasource=new Jn(this.widgetRegistry,this.logger),A.entities.registerDataSource(this.datasource),A.messaging.subscribe("dashboard:register-widget",async(Q)=>{try{let B=Nk2.parse(Q.payload),w=Lk2(B);return this.widgetRegistry?.register(w),this.logger.debug("Widget registered via messaging",{widgetId:B.id,pluginId:B.pluginId,rendererName:B.rendererName,builtIn:Un.includes(B.rendererName)}),{success:!0}}catch(B){return this.logger.error("Failed to register widget",{error:L0(B),payload:Q.payload}),{success:!1,error:"Widget registration failed"}}}),A.messaging.subscribe("dashboard:unregister-widget",async(Q)=>{let B=fk2.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,w,$]=await Promise.all([this.datasource.getDashboardData(),Q.appInfo(),Q.entityService.getEntityCounts()]),D=Q.identity.get(),I=Q.identity.getProfile(),Y=this.siteUrl??(()=>{try{return new URL(A.url).origin}catch{return}})(),X=I.name||w.model||"Brain Dashboard",H=kl0(B.widgets,this.widgetRegistry),U={title:X,baseUrl:Y,widgets:H.widgets,widgetScripts:H.widgetScripts,character:D,profile:I,appInfo:w,entityCounts:$};return new Response(Pl0(U),{headers:{"Content-Type":"text/html; charset=utf-8"}})}}]}async getTools(){return[]}getWidgetRegistry(){return this.widgetRegistry}}function LJ(A){return new Z3A(A)}KA();var Ck2=J.object({id:J.string(),pluginId:J.string(),title:J.string(),description:J.string().optional(),priority:J.number(),section:J.enum(["primary","secondary","sidebar"]),rendererName:J.string(),component:J.custom().optional()}),Ek2=J.object({widget:Ck2,data:J.unknown()}),Mk2=J.object({widgets:J.record(Ek2)});KA();tA();KA();import{h as hk2}from"preact";KA();N4();tA();var _E=J.enum(["draft","queued","published","failed"]),Bx=J.object({subject:J.string(),status:_E,entityIds:J.array(J.string()).optional(),scheduledFor:J.string().datetime().optional(),sentAt:J.string().datetime().optional(),buttondownId:J.string().optional(),sourceEntityType:J.string().optional()}),_l0=Bx.pick({subject:!0,status:!0,entityIds:!0,scheduledFor:!0,sentAt:!0,buttondownId:!0,sourceEntityType:!0}),wx=r1.extend({entityType:J.literal("newsletter"),metadata:_l0});tA();class xl0 extends Q2{constructor(){super({entityType:"newsletter",schema:wx,frontmatterSchema:Bx})}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 vl0=new xl0;tA();tA();KA();var Vk2=BX.extend({status:J.enum(["draft","queued","published","failed"]).optional()}),Ok2=wX.extend({query:Vk2.optional()});function Tl0(A){try{let{content:Q}=M2(A.content,Bx);return Q}catch{return A.content}}class z3A extends U6{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=Ok2.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}transformEntity(A){let Q=Tl0(A),B={id:A.id,subject:A.metadata.subject,status:A.metadata.status,excerpt:bU(Q,150),created:A.created,url:`/newsletters/${A.id}`};if(A.metadata.sentAt)B.sentAt=A.metadata.sentAt;return B}buildListResult(A,Q,B){return{newsletters:A,totalCount:Q?.totalItems??A.length,pagination:Q}}async fetch(A,Q,B){let{query:w}=this.parseQuery(A),$=B.entityService;if(w.id)return this.fetchSingleNewsletter(w.id,Q,$);let D=w.status,I=D?{filter:{metadata:{status:D}}}:void 0,{items:Y,pagination:X}=await this.fetchList(w,$,I);return Q.parse(this.buildListResult(Y,X,w))}async fetchSingleNewsletter(A,Q,B){let w=await B.getEntity({entityType:this.config.entityType,id:A});if(!w)throw Error(`Newsletter not found: ${A}`);let $=await this.resolveNavigation(w,B),D=[];if(w.metadata.entityIds?.length){let X=w.metadata.sourceEntityType??"post";D=(await Promise.all(w.metadata.entityIds.map(async(U)=>{let F=await B.getEntity({entityType:X,id:U});if(F){let Z=F.metadata;return{id:U,title:Z.title??U,url:`/${X}s/${Z.slug??U}`}}return null}))).filter((U)=>U!==null)}let I=Tl0(w),Y={id:w.id,subject:w.metadata.subject,status:w.metadata.status,content:I,created:w.created,updated:w.updated,sentAt:w.metadata.sentAt,scheduledFor:w.metadata.scheduledFor,newsletter:w,prevNewsletter:$.prev?{id:$.prev.id,subject:$.prev.subject,url:$.prev.url}:null,nextNewsletter:$.next?{id:$.next.id,subject:$.next.subject,url:$.next.url}:null,sourceEntities:D.length>0?D:void 0};return Q.parse(Y)}}tA();KA();var Rk2=J.object({prompt:J.string().optional().describe("AI generation prompt"),sourceEntityIds:J.array(J.string()).optional().describe("Entity IDs to include in newsletter (e.g., blog posts)"),sourceEntityType:J.enum(["post"]).optional().describe("Type of source entities"),content:J.string().optional().describe("Direct content (skip AI)"),subject:J.string().optional().describe("Newsletter subject (AI-generated if not provided)"),addToQueue:J.boolean().optional().describe("Create as queued (true) or draft (false)")});class q3A extends W9{constructor(A,Q){super(A,Q,{schema:Rk2,jobTypeName:"newsletter:generation",entityType:"newsletter"})}async generate(A,Q){let B=A.addToQueue??!1,{prompt:w,sourceEntityIds:$,sourceEntityType:D}=A,{content:I,subject:Y}=A;if(I){if(!Y)this.failEarly("Subject is required when providing content directly");await this.reportProgress(Q,{progress:50,message:"Using provided content"})}else if($&&$.length>0){let Z=D??"post";await this.reportProgress(Q,{progress:10,message:`Fetching ${$.length} source entities`});let f=(await Promise.all($.map((k)=>this.context.entityService.getEntity({entityType:Z,id:k})))).filter((k)=>k!=null);if(f.length===0)this.failEarly(`No source entities found for IDs: ${$.join(", ")}`);await this.reportProgress(Q,{progress:30,message:`Generating newsletter from ${f.length} posts`});let C=`Create an engaging newsletter that highlights these blog posts:
|
|
4042
4042
|
|
|
4043
4043
|
${f.map((k)=>`## ${k.metadata.title}
|
|
4044
4044
|
|
|
@@ -4107,14 +4107,14 @@ Newsletter-specific guidelines:
|
|
|
4107
4107
|
- "Reply and let me know..."
|
|
4108
4108
|
- "Until next time..."
|
|
4109
4109
|
|
|
4110
|
-
The goal is to build a relationship with readers through valuable, authentic content.`});KA();tA();import{jsxDEV as L$,Fragment as _k2}from"preact/jsx-dev-runtime";var Pk2=J.object({id:J.string(),subject:J.string(),status:_E,excerpt:J.string(),created:J.string(),sentAt:J.string().optional(),url:J.string()}),kk2=J.object({newsletters:J.array(Pk2),totalCount:J.number(),pagination:K9.nullable()}),jk2=({newsletters:A,totalCount:Q,pageTitle:B,pagination:w,baseUrl:$="/newsletters"})=>{let D=B??"Newsletters",I=`Browse all ${Q} ${Q===1?"newsletter":"newsletters"}`;return L$(_k2,{children:[L$(u2,{title:D,description:I},void 0,!1,void 0,this),L$("div",{className:"newsletter-list bg-theme",children:L$("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[L$("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:D},void 0,!1,void 0,this),A.length===0?L$("p",{className:"text-theme-muted italic",children:"No newsletters yet."},void 0,!1,void 0,this):L$("div",{className:"space-y-4",children:A.map((Y)=>L$(WQ,{href:Y.url,children:[L$(U5,{className:"text-lg",children:Y.subject},void 0,!1,void 0,this),L$(y5,{children:L$("div",{className:"flex items-center gap-3",children:[L$(D7,{status:Y.status},void 0,!1,void 0,this),L$("span",{className:"text-sm text-theme-muted",children:lw(Y.sentAt??Y.created,{style:"long"})},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Y.excerpt&&L$("p",{className:"text-theme-muted line-clamp-2",children:Y.excerpt},void 0,!1,void 0,this)]},Y.id,!0,void 0,this))},void 0,!1,void 0,this),w&&w.totalPages>1&&L$(a4,{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)},gl0=G1({name:"newsletter-list",description:"Newsletter list page template",schema:kk2,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:jk2}});KA();tA();import{jsxDEV as Hw,Fragment as Sk2}from"preact/jsx-dev-runtime";var xk2=J.object({id:J.string(),title:J.string(),url:J.string()}),hl0=J.object({id:J.string(),subject:J.string(),url:J.string()}),vk2=J.object({id:J.string(),subject:J.string(),status:_E,content:J.string(),created:J.string(),updated:J.string(),sentAt:J.string().optional(),scheduledFor:J.string().optional(),sourceEntities:J.array(xk2).optional(),prevNewsletter:hl0.nullable().optional(),nextNewsletter:hl0.nullable().optional()}),Tk2=({subject:A,status:Q,content:B,created:w,sentAt:$,scheduledFor:D,sourceEntities:I,prevNewsletter:Y,nextNewsletter:X})=>{let H=[{label:"Home",href:"/"},{label:"Newsletters",href:"/newsletters"},{label:A}],U=$??w,F=$?"Sent":"Created";return Hw(Sk2,{children:[Hw(u2,{title:A,description:`Newsletter: ${A}`},void 0,!1,void 0,this),Hw("section",{className:"newsletter-detail-section",children:Hw("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:Hw("div",{className:"max-w-3xl mx-auto",children:[Hw(LI,{items:H},void 0,!1,void 0,this),Hw("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),Hw("div",{className:"flex flex-wrap items-center gap-3 mb-8 text-sm text-theme-muted",children:[Hw(D7,{status:Q},void 0,!1,void 0,this),Hw("span",{children:[F,": ",lw(U,{style:"long"})]},void 0,!0,void 0,this),D&&Q==="queued"&&Hw("span",{children:["Scheduled for: ",lw(D,{style:"long"})]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),I&&I.length>0&&Hw(WQ,{variant:"compact",className:"mb-8",children:[Hw("h3",{className:"text-sm font-medium text-heading mb-2",children:"Related Content"},void 0,!1,void 0,this),Hw("ul",{className:"space-y-1",children:I.map((Z)=>Hw("li",{children:Hw("a",{href:Z.url,className:"text-sm text-brand hover:text-brand-dark transition-colors",children:Z.title},void 0,!1,void 0,this)},Z.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Hw(GD,{markdown:B},void 0,!1,void 0,this),(Y??X)&&Hw("nav",{className:"mt-12 pt-8 border-t border-theme",children:Hw("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[Y?Hw(WQ,{href:Y.url,variant:"compact",children:[Hw("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Newer"},void 0,!1,void 0,this),Hw("span",{className:"block mt-1 font-medium text-heading group-hover:text-brand transition-colors truncate",children:Y.subject},void 0,!1,void 0,this)]},void 0,!0,void 0,this):Hw("div",{},void 0,!1,void 0,this),X&&Hw(WQ,{href:X.url,variant:"compact",className:"md:text-right",children:[Hw("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Older"},void 0,!1,void 0,this),Hw("span",{className:"block mt-1 font-medium text-heading group-hover:text-brand transition-colors truncate",children:X.subject},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},yl0=G1({name:"newsletter-detail",description:"Individual newsletter detail template",schema:vk2,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:Tk2}});var ml0={name:"@brains/newsletter-entity",private:!0,version:"0.2.0-alpha.
|
|
4110
|
+
The goal is to build a relationship with readers through valuable, authentic content.`});KA();tA();import{jsxDEV as L$,Fragment as _k2}from"preact/jsx-dev-runtime";var Pk2=J.object({id:J.string(),subject:J.string(),status:_E,excerpt:J.string(),created:J.string(),sentAt:J.string().optional(),url:J.string()}),kk2=J.object({newsletters:J.array(Pk2),totalCount:J.number(),pagination:K9.nullable()}),jk2=({newsletters:A,totalCount:Q,pageTitle:B,pagination:w,baseUrl:$="/newsletters"})=>{let D=B??"Newsletters",I=`Browse all ${Q} ${Q===1?"newsletter":"newsletters"}`;return L$(_k2,{children:[L$(u2,{title:D,description:I},void 0,!1,void 0,this),L$("div",{className:"newsletter-list bg-theme",children:L$("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[L$("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:D},void 0,!1,void 0,this),A.length===0?L$("p",{className:"text-theme-muted italic",children:"No newsletters yet."},void 0,!1,void 0,this):L$("div",{className:"space-y-4",children:A.map((Y)=>L$(WQ,{href:Y.url,children:[L$(U5,{className:"text-lg",children:Y.subject},void 0,!1,void 0,this),L$(y5,{children:L$("div",{className:"flex items-center gap-3",children:[L$(D7,{status:Y.status},void 0,!1,void 0,this),L$("span",{className:"text-sm text-theme-muted",children:lw(Y.sentAt??Y.created,{style:"long"})},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Y.excerpt&&L$("p",{className:"text-theme-muted line-clamp-2",children:Y.excerpt},void 0,!1,void 0,this)]},Y.id,!0,void 0,this))},void 0,!1,void 0,this),w&&w.totalPages>1&&L$(a4,{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)},gl0=G1({name:"newsletter-list",description:"Newsletter list page template",schema:kk2,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:jk2}});KA();tA();import{jsxDEV as Hw,Fragment as Sk2}from"preact/jsx-dev-runtime";var xk2=J.object({id:J.string(),title:J.string(),url:J.string()}),hl0=J.object({id:J.string(),subject:J.string(),url:J.string()}),vk2=J.object({id:J.string(),subject:J.string(),status:_E,content:J.string(),created:J.string(),updated:J.string(),sentAt:J.string().optional(),scheduledFor:J.string().optional(),sourceEntities:J.array(xk2).optional(),prevNewsletter:hl0.nullable().optional(),nextNewsletter:hl0.nullable().optional()}),Tk2=({subject:A,status:Q,content:B,created:w,sentAt:$,scheduledFor:D,sourceEntities:I,prevNewsletter:Y,nextNewsletter:X})=>{let H=[{label:"Home",href:"/"},{label:"Newsletters",href:"/newsletters"},{label:A}],U=$??w,F=$?"Sent":"Created";return Hw(Sk2,{children:[Hw(u2,{title:A,description:`Newsletter: ${A}`},void 0,!1,void 0,this),Hw("section",{className:"newsletter-detail-section",children:Hw("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:Hw("div",{className:"max-w-3xl mx-auto",children:[Hw(LI,{items:H},void 0,!1,void 0,this),Hw("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),Hw("div",{className:"flex flex-wrap items-center gap-3 mb-8 text-sm text-theme-muted",children:[Hw(D7,{status:Q},void 0,!1,void 0,this),Hw("span",{children:[F,": ",lw(U,{style:"long"})]},void 0,!0,void 0,this),D&&Q==="queued"&&Hw("span",{children:["Scheduled for: ",lw(D,{style:"long"})]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),I&&I.length>0&&Hw(WQ,{variant:"compact",className:"mb-8",children:[Hw("h3",{className:"text-sm font-medium text-heading mb-2",children:"Related Content"},void 0,!1,void 0,this),Hw("ul",{className:"space-y-1",children:I.map((Z)=>Hw("li",{children:Hw("a",{href:Z.url,className:"text-sm text-brand hover:text-brand-dark transition-colors",children:Z.title},void 0,!1,void 0,this)},Z.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Hw(GD,{markdown:B},void 0,!1,void 0,this),(Y??X)&&Hw("nav",{className:"mt-12 pt-8 border-t border-theme",children:Hw("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[Y?Hw(WQ,{href:Y.url,variant:"compact",children:[Hw("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Newer"},void 0,!1,void 0,this),Hw("span",{className:"block mt-1 font-medium text-heading group-hover:text-brand transition-colors truncate",children:Y.subject},void 0,!1,void 0,this)]},void 0,!0,void 0,this):Hw("div",{},void 0,!1,void 0,this),X&&Hw(WQ,{href:X.url,variant:"compact",className:"md:text-right",children:[Hw("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Older"},void 0,!1,void 0,this),Hw("span",{className:"block mt-1 font-medium text-heading group-hover:text-brand transition-colors truncate",children:X.subject},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},yl0=G1({name:"newsletter-detail",description:"Individual newsletter detail template",schema:vk2,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:Tk2}});var ml0={name:"@brains/newsletter-entity",private:!0,version:"0.2.0-alpha.54",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/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 yk2=J.object({});class N3A extends n2{entityType="newsletter";schema=wx;adapter=vl0;constructor(A={}){super("newsletter",ml0,A,yk2)}createGenerationHandler(A){return new q3A(this.logger,A)}getTemplates(){return{generation:Sl0,"newsletter-list":gl0,"newsletter-detail":yl0}}getDataSources(){return[new z3A(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:()=>hk2(mUA,{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 D=await A.messaging.send({type:"buttondown:send",payload:{entityId:w,subject:$.metadata.subject,content:$.content}}),I=new Date().toISOString(),Y=!("noop"in D)&&D.data?D.data.emailId:void 0;return await A.entityService.updateEntity({entity:{...$,metadata:{...$.metadata,status:"published",sentAt:I,buttondownId:Y}}}),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 D=L0($);return await A.messaging.send({type:"publish:report:failure",payload:{entityType:B,entityId:w,error:D}}),{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:L0(B)}}),{success:!0}}})}registerEvalHandlers(A){let Q=J.object({prompt:J.string().optional(),content:J.string().optional()});A.eval.registerHandler("generation",async(B)=>{let w=Q.parse(B),$=w.content?`Create an engaging newsletter based on this content:
|
|
4111
4111
|
|
|
4112
|
-
${w.content}`:w.prompt??"Write an engaging newsletter";return A.ai.generate({prompt:$,templateName:"newsletter:generation"})})}}function f3A(A={}){return new N3A(A)}tA();KA();class xE{config;logger;constructor(A,Q){this.config=A;this.logger=Q}async request(A,Q={}){let B=`https://api.buttondown.email/v1${A}`;this.logger.debug("Buttondown API request",{endpoint:A,method:Q.method??"GET"});let w=await fetch(B,{...Q,headers:{Authorization:`Token ${this.config.apiKey}`,"Content-Type":"application/json",...Q.headers}});if(!w.ok){let $=await w.json().catch(()=>({})),D=$.detail??$.message??`HTTP ${w.status}`;throw this.logger.error("Buttondown API error",{endpoint:A,status:w.status,error:D}),Error(`Buttondown API error: ${D}`)}return w.json()}async createSubscriber(A){let Q={email_address:A.email,type:this.config.doubleOptIn?"unactivated":"regular"};if(A.name)Q.metadata={name:A.name};if(A.tags&&A.tags.length>0)Q.tags=A.tags;this.logger.info("Creating subscriber",{email:A.email});try{return await this.request("/subscribers",{method:"POST",body:JSON.stringify(Q)})}catch(B){if(B instanceof Error&&B.message.includes("already subscribed")){let w=B.message.match(/id=([a-f0-9-]+)/);return this.logger.info("Subscriber already exists",{email:A.email}),{id:w?.[1]??"existing",email:A.email,subscriber_type:"already_subscribed"}}throw B}}async unsubscribe(A){this.logger.info("Unsubscribing",{email:A}),await this.request(`/subscribers/${encodeURIComponent(A)}`,{method:"DELETE"})}async listSubscribers(A){let Q=new URLSearchParams;if(A?.type)Q.set("type",A.type);if(A?.limit)Q.set("page_size",String(A.limit));let B=Q.toString(),w=B?`/subscribers?${B}`:"/subscribers";return this.request(w)}async createEmail(A){let Q={subject:A.subject,body:A.body,status:A.status??"draft"};if(A.publish_date)Q.publish_date=A.publish_date;return this.logger.info("Creating email",{subject:A.subject,status:A.status??"draft"}),this.request("/emails",{method:"POST",body:JSON.stringify(Q)})}async getEmail(A){return this.request(`/emails/${A}`)}async validateCredentials(){try{return await this.request("/subscribers?page_size=1"),!0}catch{return!1}}}tA();KA();var mk2=J.object({email:J.string().email().describe("Email address to subscribe"),name:J.string().optional().describe("Subscriber name (optional)"),tags:J.array(J.string()).optional().describe("Tags to apply to subscriber (optional)")}),uk2=J.object({email:J.string().email().describe("Email address to unsubscribe")}),ck2=J.object({type:J.enum(["unactivated","regular","unsubscribed"]).optional().describe("Filter by subscriber status"),limit:J.number().optional().describe("Maximum number of results")});function ul0(A,Q,B){let w=new xE(Q,B);return[MQ(A,"subscribe","Subscribe an email address to the newsletter. Uses double opt-in by default.",mk2,async($)=>{try{let D=await w.createSubscriber({email:$.email,...$.name&&{name:$.name},...$.tags&&{tags:$.tags}}),I=D.subscriber_type==="already_subscribed";return _6({subscriberId:D.id,email:D.email,status:D.subscriber_type,message:I?"already_subscribed":"subscribed"},I?`${$.email} is already subscribed`:`Subscribed ${$.email} successfully`)}catch(D){return k5(L0(D))}}),MQ(A,"unsubscribe","Unsubscribe an email address from the newsletter.",uk2,async($)=>{try{return await w.unsubscribe($.email),_6({email:$.email},`Unsubscribed ${$.email} successfully`)}catch(D){return k5(L0(D))}}),MQ(A,"list_subscribers","List newsletter subscribers with optional filtering by status.",ck2,async($)=>{try{let D=await w.listSubscribers({...$.type&&{type:$.type},...$.limit&&{limit:$.limit}});return _6({subscribers:D.results.map((I)=>({id:I.id,email:I.email,status:I.subscriber_type})),count:D.count},`Found ${D.count} subscribers`)}catch(D){return k5(L0(D))}})]}KA();async function cl0(A,Q,B,w){if(A.entityType!=="post")return{success:!0,skipped:!0,reason:"Only post entity types trigger auto-send"};let $=await B.getEntity({entityType:"post",id:A.entityId});if(!$)return{success:!1,error:`Post ${A.entityId} not found`};w.info("Auto-sending newsletter for published post",{postId:$.id,title:$.metadata.title});try{let D=await Q.createEmail({subject:$.metadata.title,body:$.content,status:"about_to_send"});return w.info("Newsletter sent for post",{postId:$.id,emailId:D.id}),{success:!0,emailId:D.id}}catch(D){let I=L0(D);return w.error("Failed to send newsletter for post",{postId:$.id,error:I}),{success:!1,error:I}}}var ll0={name:"@brains/buttondown",private:!0,version:"0.2.0-alpha.
|
|
4112
|
+
${w.content}`:w.prompt??"Write an engaging newsletter";return A.ai.generate({prompt:$,templateName:"newsletter:generation"})})}}function f3A(A={}){return new N3A(A)}tA();KA();class xE{config;logger;constructor(A,Q){this.config=A;this.logger=Q}async request(A,Q={}){let B=`https://api.buttondown.email/v1${A}`;this.logger.debug("Buttondown API request",{endpoint:A,method:Q.method??"GET"});let w=await fetch(B,{...Q,headers:{Authorization:`Token ${this.config.apiKey}`,"Content-Type":"application/json",...Q.headers}});if(!w.ok){let $=await w.json().catch(()=>({})),D=$.detail??$.message??`HTTP ${w.status}`;throw this.logger.error("Buttondown API error",{endpoint:A,status:w.status,error:D}),Error(`Buttondown API error: ${D}`)}return w.json()}async createSubscriber(A){let Q={email_address:A.email,type:this.config.doubleOptIn?"unactivated":"regular"};if(A.name)Q.metadata={name:A.name};if(A.tags&&A.tags.length>0)Q.tags=A.tags;this.logger.info("Creating subscriber",{email:A.email});try{return await this.request("/subscribers",{method:"POST",body:JSON.stringify(Q)})}catch(B){if(B instanceof Error&&B.message.includes("already subscribed")){let w=B.message.match(/id=([a-f0-9-]+)/);return this.logger.info("Subscriber already exists",{email:A.email}),{id:w?.[1]??"existing",email:A.email,subscriber_type:"already_subscribed"}}throw B}}async unsubscribe(A){this.logger.info("Unsubscribing",{email:A}),await this.request(`/subscribers/${encodeURIComponent(A)}`,{method:"DELETE"})}async listSubscribers(A){let Q=new URLSearchParams;if(A?.type)Q.set("type",A.type);if(A?.limit)Q.set("page_size",String(A.limit));let B=Q.toString(),w=B?`/subscribers?${B}`:"/subscribers";return this.request(w)}async createEmail(A){let Q={subject:A.subject,body:A.body,status:A.status??"draft"};if(A.publish_date)Q.publish_date=A.publish_date;return this.logger.info("Creating email",{subject:A.subject,status:A.status??"draft"}),this.request("/emails",{method:"POST",body:JSON.stringify(Q)})}async getEmail(A){return this.request(`/emails/${A}`)}async validateCredentials(){try{return await this.request("/subscribers?page_size=1"),!0}catch{return!1}}}tA();KA();var mk2=J.object({email:J.string().email().describe("Email address to subscribe"),name:J.string().optional().describe("Subscriber name (optional)"),tags:J.array(J.string()).optional().describe("Tags to apply to subscriber (optional)")}),uk2=J.object({email:J.string().email().describe("Email address to unsubscribe")}),ck2=J.object({type:J.enum(["unactivated","regular","unsubscribed"]).optional().describe("Filter by subscriber status"),limit:J.number().optional().describe("Maximum number of results")});function ul0(A,Q,B){let w=new xE(Q,B);return[MQ(A,"subscribe","Subscribe an email address to the newsletter. Uses double opt-in by default.",mk2,async($)=>{try{let D=await w.createSubscriber({email:$.email,...$.name&&{name:$.name},...$.tags&&{tags:$.tags}}),I=D.subscriber_type==="already_subscribed";return _6({subscriberId:D.id,email:D.email,status:D.subscriber_type,message:I?"already_subscribed":"subscribed"},I?`${$.email} is already subscribed`:`Subscribed ${$.email} successfully`)}catch(D){return k5(L0(D))}}),MQ(A,"unsubscribe","Unsubscribe an email address from the newsletter.",uk2,async($)=>{try{return await w.unsubscribe($.email),_6({email:$.email},`Unsubscribed ${$.email} successfully`)}catch(D){return k5(L0(D))}}),MQ(A,"list_subscribers","List newsletter subscribers with optional filtering by status.",ck2,async($)=>{try{let D=await w.listSubscribers({...$.type&&{type:$.type},...$.limit&&{limit:$.limit}});return _6({subscribers:D.results.map((I)=>({id:I.id,email:I.email,status:I.subscriber_type})),count:D.count},`Found ${D.count} subscribers`)}catch(D){return k5(L0(D))}})]}KA();async function cl0(A,Q,B,w){if(A.entityType!=="post")return{success:!0,skipped:!0,reason:"Only post entity types trigger auto-send"};let $=await B.getEntity({entityType:"post",id:A.entityId});if(!$)return{success:!1,error:`Post ${A.entityId} not found`};w.info("Auto-sending newsletter for published post",{postId:$.id,title:$.metadata.title});try{let D=await Q.createEmail({subject:$.metadata.title,body:$.content,status:"about_to_send"});return w.info("Newsletter sent for post",{postId:$.id,emailId:D.id}),{success:!0,emailId:D.id}}catch(D){let I=L0(D);return w.error("Failed to send newsletter for post",{postId:$.id,error:I}),{success:!1,error:I}}}var ll0={name:"@brains/buttondown",private:!0,version:"0.2.0-alpha.54",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 pk2=J.object({apiKey:J.string().optional().describe("Buttondown API key"),doubleOptIn:J.boolean().default(!0).describe("Require email confirmation for new subscribers"),autoSendOnPublish:J.boolean().default(!1).describe("Automatically send newsletter when a blog post is published")});class L3A extends Bw{constructor(A={}){super("buttondown",ll0,A,pk2)}async onRegister(A){if(A.messaging.subscribe("buttondown:is-configured",async()=>{return{success:!!this.config.apiKey}}),this.config.apiKey){let Q=new xE({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:L0(w)}),{success:!1}}}),this.config.autoSendOnPublish)A.messaging.subscribe("publish:completed",async(B)=>{return await cl0(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 ul0(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 C3A(A={}){return new L3A(A)}var dk2=J.object({apiKey:J.string().optional().describe("Buttondown API key"),doubleOptIn:J.boolean().optional().describe("Require email confirmation for new subscribers"),autoSendOnPublish:J.boolean().optional().describe("Automatically send newsletter when a blog post is published")});function pl0(A={}){let Q=dk2.parse(A);return[f3A({}),C3A({...Q.apiKey!==void 0&&{apiKey:Q.apiKey},...Q.doubleOptIn!==void 0&&{doubleOptIn:Q.doubleOptIn},...Q.autoSendOnPublish!==void 0&&{autoSendOnPublish:Q.autoSendOnPublish}})]}tA();KA();import{existsSync as wj2,mkdirSync as $j2,writeFileSync as Dj2}from"fs";import{join as ZW}from"path";KA();var E3A=J.object({baseFolder:J.string().default("_obsidian")});KA();function ik2(A){let Q=A,B=!0,w=void 0,$=!1,D=!0;while(D){if(D=!1,Q instanceof J.ZodOptional)B=!1,Q=Q._def.innerType,D=!0;if(Q instanceof J.ZodDefault)B=!1,$=!0,w=Q._def.defaultValue(),Q=Q._def.innerType,D=!0;if(Q instanceof J.ZodNullable)B=!1,Q=Q._def.innerType,D=!0}let I={inner:Q,required:B};if($)I.defaultValue=w;return I}function rk2(A){if(A instanceof J.ZodEnum)return{type:"enum",enumValues:A._def.values};if(A instanceof J.ZodLiteral)return{type:"string",defaultValue:A._def.value};if(A instanceof J.ZodString)return{type:"string"};if(A instanceof J.ZodNumber)return{type:"number"};if(A instanceof J.ZodBoolean)return{type:"boolean"};if(A instanceof J.ZodArray)return{type:"array"};if(A instanceof J.ZodDate)return{type:"date"};if(A instanceof J.ZodPipeline){if(A._def.out instanceof J.ZodDate)return{type:"date"}}return{type:"unknown"}}function dl0(A){let Q=A.shape,B=[];for(let[w,$]of Object.entries(Q)){let{inner:D,required:I,defaultValue:Y}=ik2($),X=rk2(D),H={name:w,type:X.type,required:I},U=Y!==void 0?Y:X.defaultValue;if(U!==void 0)H.defaultValue=U;if(X.enumValues)H.enumValues=X.enumValues;B.push(H)}return B}function nk2(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 il0(A,Q,B=""){let w=["---"];for(let $ of Q){let D=nk2($,A);if(D==="")w.push(`${$.name}:`);else w.push(`${$.name}: ${D}`)}if(w.push("---"),w.push(""),B)w.push(B);else w.push("<!-- Write your content here -->"),w.push("");return w.join(`
|
|
4113
4113
|
`)}KA();var ok2={string:"Input",number:"Number",boolean:"Boolean",date:"Date",enum:"Select",array:"Multi",unknown:"Input"};function sk2(A){let Q={name:A.name,id:A.name,type:ok2[A.type]};if(A.type==="enum"&&A.enumValues){let B={};A.enumValues.forEach((w,$)=>{B[String($)]=w}),Q.options=B}return Q}function rl0(A,Q){let B={filesPaths:A,fields:Q.map(sk2)};return`---
|
|
4114
4114
|
${rY(B)}---
|
|
4115
|
-
`}KA();var ak2=new Set(["entityType"]),tk2={base:"Notes"},ek2=new Set(["base"]);function Aj2(A){let Q=["file.name"];for(let B of A)if(!ak2.has(B.name))Q.push(B.name);return Q}function Qj2(A){return A.some((Q)=>Q.name==="status"&&Q.type==="enum")}function nl0(A,Q){let B=tk2[A]??XS(A),w=Qj2(Q),$=Aj2(Q),D=[{type:"table",name:`All ${B}`,order:$}];if(w)D.push({type:"table",name:"By Status",groupBy:{property:"status",direction:"ASC"},order:$});let Y={filters:{and:[ek2.has(A)?'file.folder == "/"':`file.inFolder("${A}")`]},views:D};return{filename:`${B}.base`,content:rY(Y),hasStatus:w}}function ol0(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 rY(B)}function sl0(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 rY(B)}var al0={name:"@brains/obsidian-vault",private:!0,version:"0.2.0-alpha.53",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 Ij2={mkdir:$j2,writeFile:Dj2,existsFile:wj2},Yj2=J.object({entityTypes:J.array(J.string()).optional().describe("Entity types to generate templates for (default: all)")});class M3A extends Bw{deps;constructor(A={},Q={}){super("obsidian-vault",al0,A,E3A);this.deps={...Ij2,...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[MQ(this.id,"sync-templates","Generate Obsidian templates, Metadata Menu fileClass definitions, and Bases views for all registered entity types.",Yj2,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,$=ZW(A.dataDir,this.config.baseFolder),D=ZW($,"templates"),I=ZW($,"fileClasses"),Y=ZW($,"bases");this.deps.mkdir(D,{recursive:!0}),this.deps.mkdir(I,{recursive:!0}),this.deps.mkdir(Y,{recursive:!0});let X=[],H=[],U=[],F=[],Z=[],z=[];for(let C of w){let P=A.entities.getEffectiveFrontmatterSchema(C);if(!P){this.logger.debug(`Skipping ${C}: no frontmatter schema`),H.push(C);continue}let x=dl0(P),k=A.entities.getAdapter(C),o=k?.isSingleton===!0,r=rl0(C,x);if(this.deps.writeFile(ZW(I,`${C}.md`),r),U.push(C),o){Z.push(C),this.logger.debug(`Generated fileClass (singleton): ${C}`);continue}let u=k?.getBodyTemplate()??"",v=il0(C,x,u);this.deps.writeFile(ZW(D,`${C}.md`),v),X.push(C);let S=nl0(C,x),h=ZW(Y,S.filename);if(!this.deps.existsFile(h))this.deps.writeFile(h,S.content),F.push(C),this.logger.debug(`Generated base: ${S.filename}`);if(S.hasStatus)z.push({entityType:C,fields:x});this.logger.debug(`Generated template + fileClass: ${C}`)}let f=ol0(Z);if(f){let C=ZW(Y,"Settings.base");if(!this.deps.existsFile(C))this.deps.writeFile(C,f),F.push("Settings"),this.logger.debug("Generated Settings.base")}let E=sl0(z);if(E){let C=ZW(Y,"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 ${X.length} templates, ${U.length} fileClasses, ${F.length} bases (${H.length} skipped)`),_6({generated:X,skipped:H,fileClasses:U,bases:F})}catch(B){return this.logger.error("Failed to sync",{error:B}),k5(B instanceof Error?B.message:"Unknown error")}}}function V3A(A,Q){return new M3A(A,Q)}tA();KA();tA();var O3A=J.enum(["new","planned","in-progress","done","declined"]),R3A=J.enum(["low","medium","high","critical"]),$x=J.object({title:J.string(),status:O3A,priority:R3A.default("medium"),requested:J.number().int().default(1),declinedReason:J.string().optional()}),tl0=J.object({title:J.string(),status:O3A,priority:R3A,requested:J.number().int(),slug:J.string()}),Dx=r1.extend({entityType:J.literal("wish"),metadata:tl0}),b3A=J.object({});tA();KA();class Ix extends Q2{constructor(){super({entityType:"wish",schema:Dx,frontmatterSchema:$x})}createWishContent(A,Q){return this.buildMarkdown(Q,A)}parseWishContent(A){let Q=this.parseFrontMatter(A,$x);return{frontmatter:$x.parse(Q),description:this.extractBody(A).trim()}}fromMarkdown(A){let{frontmatter:Q}=this.parseWishContent(A),B=t1(Q.title);return{content:A,entityType:"wish",metadata:{title:Q.title,status:Q.status,priority:Q.priority,requested:Q.requested,slug:B}}}}var P3A=new Ix;KA();KA();async function el0(A,Q){let B=`${Q.title}: ${Q.description}`,$=(await A.search({query:B,options:{types:["wish"],limit:1}}))[0];if($&&$.score>=A.similarityThreshold)return $.entity;let D=t1(Q.title);return A.getEntity({entityType:"wish",id:D})}class Zn{logger;context;adapter=new Ix;constructor(A,Q){this.logger=A;this.context=Q}async process(A,Q,B){let w=A.title??A.prompt??"Untitled wish",$=A.content??A.prompt??"",D=await el0({search:(H)=>this.context.entityService.search(H),getEntity:(H)=>this.context.entityService.getEntity(H),similarityThreshold:0.85},{title:w,description:$});if(D){let{frontmatter:H,description:U}=this.adapter.parseWishContent(D.content),F=H.requested+1,Z=this.adapter.createWishContent({...H,requested:F},U);return await this.context.entityService.updateEntity({entity:{...D,content:Z,metadata:{...D.metadata,requested:F}}}),this.logger.info("Incremented wish request count",{id:D.id,requested:F}),{success:!0,entityId:D.id,existed:!0,requested:F}}let I=t1(w),Y=A.options?.priority??"medium",X=this.adapter.createWishContent({title:w,status:"new",priority:Y,requested:1},$);return await this.context.entityService.createEntity({entity:{id:I,entityType:"wish",content:X,metadata:{title:w,status:"new",priority:Y,requested:1,slug:I}}}),this.logger.info("Created new wish",{id:I,title:w}),{success:!0,entityId:I,existed:!1,requested:1}}}var Ap0={critical:0,high:1,medium:2,low:3};function Qp0(A){A.sort((Q,B)=>{let w=B.metadata.requested-Q.metadata.requested;if(w!==0)return w;return Ap0[Q.metadata.priority]-Ap0[B.metadata.priority]})}var Bp0={name:"@brains/wishlist",private:!0,version:"0.2.0-alpha.53",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 wp0 extends n2{entityType=P3A.entityType;schema=Dx;adapter=P3A;constructor(A={}){super("wishlist",Bp0,A,b3A)}async interceptCreate(A,Q,B){let w=await new Zn(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 Qp0(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 Zn(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 Hj2(A={}){return new wp0(A)}var zn=Hj2;tA();KA();tA();var Yx=J.object({title:J.string(),target:J.string()}),$p0=J.object({title:J.string(),target:J.string(),slug:J.string().optional()}),Xx=r1.extend({entityType:J.literal("prompt"),metadata:$p0});tA();KA();class k3A extends Q2{constructor(){super({entityType:"prompt",schema:Xx,frontmatterSchema:Yx})}toMarkdown(A){let Q=this.extractBody(A.content),B=this.parseFrontMatter(A.content,Yx);return this.buildMarkdown(Q,B)}fromMarkdown(A){let Q=this.parseFrontMatter(A,Yx),B=t1(Q.target.replace(/:/g,"-"));return{content:A,entityType:"prompt",metadata:{title:Q.title,target:Q.target,slug:B}}}}var qn=new k3A;var Dp0={name:"@brains/prompt",private:!0,version:"0.2.0-alpha.53",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 j3A extends n2{entityType=qn.entityType;schema=Xx;adapter=qn;constructor(){super("prompt",Dp0,{},void 0)}getEntityTypeConfig(){return{embeddable:!1}}}function bz(){return new j3A}tA();KA();class Nn{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(Wj2),total:$.total,totalPages:$.total_pages,page:Q.page}}async triggerDownload(A){try{await this.fetchFn(A,{headers:{Authorization:`Client-ID ${this.apiKey}`}})}catch{}}}function Wj2(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}}KA();var Ip0={query:J.string().describe("Search terms for stock photos"),perPage:J.number().min(1).max(30).default(10).describe("Results per page (1-30)"),page:J.number().min(1).default(1).describe("Page number")},Yp0={photoId:J.string().describe("Photo ID from search results"),downloadLocation:J.string().url().describe("Download tracking URL (required by provider ToS)"),photographerName:J.string().describe("Photographer name for attribution"),photographerUrl:J.string().url().describe("Photographer profile URL for attribution"),sourceUrl:J.string().url().describe("Photo page URL on provider"),imageUrl:J.string().url().describe("Image URL to download"),title:J.string().optional().describe("Image entity title"),alt:J.string().optional().describe("Alt text for the image"),targetEntityType:J.string().optional().describe("Entity type to set cover image on"),targetEntityId:J.string().optional().describe("Entity ID to set cover image on")};function Hp0(A,Q){return[Uj2(A,Q),Gj2(A,Q)]}function Uj2(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:Ip0,handler:async(B)=>{let w=J.object(Ip0).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 Gj2(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:Yp0,handler:async(B)=>{let w=J.object(Yp0).safeParse(B);if(!w.success)return{success:!1,error:`Invalid input: ${w.error.message}`};let{photoId:$,downloadLocation:D,photographerName:I,photographerUrl:Y,sourceUrl:X,imageUrl:H,title:U,alt:F,targetEntityType:Z,targetEntityId:z}=w.data,f={photographerName:I,photographerUrl:Y,sourceUrl:X},E=await Q.entityService.listEntities({entityType:"image",options:{limit:1,filter:{metadata:{sourceUrl:H}}}});if(E[0]){let u={imageEntityId:E[0].id,alreadyExisted:!0,attribution:f};if(Z&&z)await Xp0(Q.entityService,Z,z,E[0].id),u.coverSet=!0;return{success:!0,data:u}}Q.provider.triggerDownload(D).catch(()=>{});let C;try{C=await Q.fetchImage(H)}catch(u){return{success:!1,error:u instanceof Error?u.message:"Image download failed"}}let P=U??`Stock photo ${$}`,x=YG.createImageEntity({dataUrl:C,title:P,alt:F??P}),k={id:$,...x,metadata:{...x.metadata,sourceUrl:H}},{entityId:o}=await Q.entityService.createEntity({entity:k}),r={imageEntityId:o,alreadyExisted:!1,attribution:f};if(Z&&z)await Xp0(Q.entityService,Z,z,o),r.coverSet=!0;return{success:!0,data:r}}}}async function Xp0(A,Q,B,w){let $=await A.getEntity({entityType:Q,id:B});if(!$)return;await A.updateEntity({entity:{...$,metadata:{...$.metadata,coverImageId:w}}})}KA();var Kp0={name:"@brains/stock-photo",private:!0,version:"0.2.0-alpha.53",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 Fj2=J.object({provider:J.enum(["unsplash"]).default("unsplash"),apiKey:J.string().optional().describe("Stock photo provider API key")});class _3A extends Bw{deps;cachedTools=null;constructor(A={},Q={}){super("stock-photo",Kp0,A,Fj2);this.deps=Q}async getTools(){if(!this.config.apiKey)return[];if(this.cachedTools)return this.cachedTools;let A=this.getContext(),Q=new Nn(this.config.apiKey,this.deps.fetch??globalThis.fetch);return this.cachedTools=Hp0(this.id,{provider:Q,entityService:A.entityService,fetchImage:this.deps.fetchImage??g$}),this.cachedTools}}function x3A(A={},Q={}){return new _3A(A,Q)}tA();KA();tA();tA();KA();var Wp0=J.enum(["ai","foundation","work"]),Up0=J.object({suffix:Wp0,title:J.string(),body:J.string(),linkLabel:J.string(),linkHref:J.string()}),Hx=J.object({eyebrow:J.string(),headline:J.string(),cards:J.array(Up0).min(1)}),fn=J.object({title:J.string(),slug:J.string(),status:J.enum(["draft","published"])}),Kx=r1.extend({entityType:J.literal("ecosystem-section"),metadata:fn});class Gp0 extends Q2{constructor(){super({entityType:"ecosystem-section",schema:Kx,frontmatterSchema:fn})}fromMarkdown(A){return{content:A,entityType:"ecosystem-section",metadata:this.parseFrontmatter(A)}}}var v3A=new Gp0;KA();function Zj2(A){return A.replace(/^---\n[\s\S]*?\n---\n?/,"")}function T3A(A,Q){return new RegExp(`(?:^|\\n)## ${Q}\\s*\\n([\\s\\S]*?)(?=\\n## |$)`).exec(A)?.[1]?.trim()??""}function Wx(A,Q){return new RegExp(`(?:^|\\n)#### ${Q}\\s*\\n([\\s\\S]*?)(?=\\n#### |\\n### |$)`).exec(A)?.[1]?.trim()??""}function Ln(A){let Q=Zj2(A),w=T3A(Q,"Cards").split(/^### Card \d+\s*$/m).map(($)=>$.trim()).filter(Boolean);return Hx.parse({eyebrow:T3A(Q,"Eyebrow"),headline:T3A(Q,"Headline"),cards:w.map(($)=>({suffix:Wx($,"Suffix"),title:Wx($,"Title"),body:Wx($,"Body"),linkLabel:Wx($,"Link Label"),linkHref:Wx($,"Link Href")}))})}function Jp0(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(`
|
|
4115
|
+
`}KA();var ak2=new Set(["entityType"]),tk2={base:"Notes"},ek2=new Set(["base"]);function Aj2(A){let Q=["file.name"];for(let B of A)if(!ak2.has(B.name))Q.push(B.name);return Q}function Qj2(A){return A.some((Q)=>Q.name==="status"&&Q.type==="enum")}function nl0(A,Q){let B=tk2[A]??XS(A),w=Qj2(Q),$=Aj2(Q),D=[{type:"table",name:`All ${B}`,order:$}];if(w)D.push({type:"table",name:"By Status",groupBy:{property:"status",direction:"ASC"},order:$});let Y={filters:{and:[ek2.has(A)?'file.folder == "/"':`file.inFolder("${A}")`]},views:D};return{filename:`${B}.base`,content:rY(Y),hasStatus:w}}function ol0(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 rY(B)}function sl0(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 rY(B)}var al0={name:"@brains/obsidian-vault",private:!0,version:"0.2.0-alpha.54",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 Ij2={mkdir:$j2,writeFile:Dj2,existsFile:wj2},Yj2=J.object({entityTypes:J.array(J.string()).optional().describe("Entity types to generate templates for (default: all)")});class M3A extends Bw{deps;constructor(A={},Q={}){super("obsidian-vault",al0,A,E3A);this.deps={...Ij2,...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[MQ(this.id,"sync-templates","Generate Obsidian templates, Metadata Menu fileClass definitions, and Bases views for all registered entity types.",Yj2,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,$=ZW(A.dataDir,this.config.baseFolder),D=ZW($,"templates"),I=ZW($,"fileClasses"),Y=ZW($,"bases");this.deps.mkdir(D,{recursive:!0}),this.deps.mkdir(I,{recursive:!0}),this.deps.mkdir(Y,{recursive:!0});let X=[],H=[],U=[],F=[],Z=[],z=[];for(let C of w){let P=A.entities.getEffectiveFrontmatterSchema(C);if(!P){this.logger.debug(`Skipping ${C}: no frontmatter schema`),H.push(C);continue}let x=dl0(P),k=A.entities.getAdapter(C),o=k?.isSingleton===!0,r=rl0(C,x);if(this.deps.writeFile(ZW(I,`${C}.md`),r),U.push(C),o){Z.push(C),this.logger.debug(`Generated fileClass (singleton): ${C}`);continue}let u=k?.getBodyTemplate()??"",v=il0(C,x,u);this.deps.writeFile(ZW(D,`${C}.md`),v),X.push(C);let S=nl0(C,x),h=ZW(Y,S.filename);if(!this.deps.existsFile(h))this.deps.writeFile(h,S.content),F.push(C),this.logger.debug(`Generated base: ${S.filename}`);if(S.hasStatus)z.push({entityType:C,fields:x});this.logger.debug(`Generated template + fileClass: ${C}`)}let f=ol0(Z);if(f){let C=ZW(Y,"Settings.base");if(!this.deps.existsFile(C))this.deps.writeFile(C,f),F.push("Settings"),this.logger.debug("Generated Settings.base")}let E=sl0(z);if(E){let C=ZW(Y,"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 ${X.length} templates, ${U.length} fileClasses, ${F.length} bases (${H.length} skipped)`),_6({generated:X,skipped:H,fileClasses:U,bases:F})}catch(B){return this.logger.error("Failed to sync",{error:B}),k5(B instanceof Error?B.message:"Unknown error")}}}function V3A(A,Q){return new M3A(A,Q)}tA();KA();tA();var O3A=J.enum(["new","planned","in-progress","done","declined"]),R3A=J.enum(["low","medium","high","critical"]),$x=J.object({title:J.string(),status:O3A,priority:R3A.default("medium"),requested:J.number().int().default(1),declinedReason:J.string().optional()}),tl0=J.object({title:J.string(),status:O3A,priority:R3A,requested:J.number().int(),slug:J.string()}),Dx=r1.extend({entityType:J.literal("wish"),metadata:tl0}),b3A=J.object({});tA();KA();class Ix extends Q2{constructor(){super({entityType:"wish",schema:Dx,frontmatterSchema:$x})}createWishContent(A,Q){return this.buildMarkdown(Q,A)}parseWishContent(A){let Q=this.parseFrontMatter(A,$x);return{frontmatter:$x.parse(Q),description:this.extractBody(A).trim()}}fromMarkdown(A){let{frontmatter:Q}=this.parseWishContent(A),B=t1(Q.title);return{content:A,entityType:"wish",metadata:{title:Q.title,status:Q.status,priority:Q.priority,requested:Q.requested,slug:B}}}}var P3A=new Ix;KA();KA();async function el0(A,Q){let B=`${Q.title}: ${Q.description}`,$=(await A.search({query:B,options:{types:["wish"],limit:1}}))[0];if($&&$.score>=A.similarityThreshold)return $.entity;let D=t1(Q.title);return A.getEntity({entityType:"wish",id:D})}class Zn{logger;context;adapter=new Ix;constructor(A,Q){this.logger=A;this.context=Q}async process(A,Q,B){let w=A.title??A.prompt??"Untitled wish",$=A.content??A.prompt??"",D=await el0({search:(H)=>this.context.entityService.search(H),getEntity:(H)=>this.context.entityService.getEntity(H),similarityThreshold:0.85},{title:w,description:$});if(D){let{frontmatter:H,description:U}=this.adapter.parseWishContent(D.content),F=H.requested+1,Z=this.adapter.createWishContent({...H,requested:F},U);return await this.context.entityService.updateEntity({entity:{...D,content:Z,metadata:{...D.metadata,requested:F}}}),this.logger.info("Incremented wish request count",{id:D.id,requested:F}),{success:!0,entityId:D.id,existed:!0,requested:F}}let I=t1(w),Y=A.options?.priority??"medium",X=this.adapter.createWishContent({title:w,status:"new",priority:Y,requested:1},$);return await this.context.entityService.createEntity({entity:{id:I,entityType:"wish",content:X,metadata:{title:w,status:"new",priority:Y,requested:1,slug:I}}}),this.logger.info("Created new wish",{id:I,title:w}),{success:!0,entityId:I,existed:!1,requested:1}}}var Ap0={critical:0,high:1,medium:2,low:3};function Qp0(A){A.sort((Q,B)=>{let w=B.metadata.requested-Q.metadata.requested;if(w!==0)return w;return Ap0[Q.metadata.priority]-Ap0[B.metadata.priority]})}var Bp0={name:"@brains/wishlist",private:!0,version:"0.2.0-alpha.54",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 wp0 extends n2{entityType=P3A.entityType;schema=Dx;adapter=P3A;constructor(A={}){super("wishlist",Bp0,A,b3A)}async interceptCreate(A,Q,B){let w=await new Zn(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 Qp0(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 Zn(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 Hj2(A={}){return new wp0(A)}var zn=Hj2;tA();KA();tA();var Yx=J.object({title:J.string(),target:J.string()}),$p0=J.object({title:J.string(),target:J.string(),slug:J.string().optional()}),Xx=r1.extend({entityType:J.literal("prompt"),metadata:$p0});tA();KA();class k3A extends Q2{constructor(){super({entityType:"prompt",schema:Xx,frontmatterSchema:Yx})}toMarkdown(A){let Q=this.extractBody(A.content),B=this.parseFrontMatter(A.content,Yx);return this.buildMarkdown(Q,B)}fromMarkdown(A){let Q=this.parseFrontMatter(A,Yx),B=t1(Q.target.replace(/:/g,"-"));return{content:A,entityType:"prompt",metadata:{title:Q.title,target:Q.target,slug:B}}}}var qn=new k3A;var Dp0={name:"@brains/prompt",private:!0,version:"0.2.0-alpha.54",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 j3A extends n2{entityType=qn.entityType;schema=Xx;adapter=qn;constructor(){super("prompt",Dp0,{},void 0)}getEntityTypeConfig(){return{embeddable:!1}}}function bz(){return new j3A}tA();KA();class Nn{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(Wj2),total:$.total,totalPages:$.total_pages,page:Q.page}}async triggerDownload(A){try{await this.fetchFn(A,{headers:{Authorization:`Client-ID ${this.apiKey}`}})}catch{}}}function Wj2(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}}KA();var Ip0={query:J.string().describe("Search terms for stock photos"),perPage:J.number().min(1).max(30).default(10).describe("Results per page (1-30)"),page:J.number().min(1).default(1).describe("Page number")},Yp0={photoId:J.string().describe("Photo ID from search results"),downloadLocation:J.string().url().describe("Download tracking URL (required by provider ToS)"),photographerName:J.string().describe("Photographer name for attribution"),photographerUrl:J.string().url().describe("Photographer profile URL for attribution"),sourceUrl:J.string().url().describe("Photo page URL on provider"),imageUrl:J.string().url().describe("Image URL to download"),title:J.string().optional().describe("Image entity title"),alt:J.string().optional().describe("Alt text for the image"),targetEntityType:J.string().optional().describe("Entity type to set cover image on"),targetEntityId:J.string().optional().describe("Entity ID to set cover image on")};function Hp0(A,Q){return[Uj2(A,Q),Gj2(A,Q)]}function Uj2(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:Ip0,handler:async(B)=>{let w=J.object(Ip0).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 Gj2(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:Yp0,handler:async(B)=>{let w=J.object(Yp0).safeParse(B);if(!w.success)return{success:!1,error:`Invalid input: ${w.error.message}`};let{photoId:$,downloadLocation:D,photographerName:I,photographerUrl:Y,sourceUrl:X,imageUrl:H,title:U,alt:F,targetEntityType:Z,targetEntityId:z}=w.data,f={photographerName:I,photographerUrl:Y,sourceUrl:X},E=await Q.entityService.listEntities({entityType:"image",options:{limit:1,filter:{metadata:{sourceUrl:H}}}});if(E[0]){let u={imageEntityId:E[0].id,alreadyExisted:!0,attribution:f};if(Z&&z)await Xp0(Q.entityService,Z,z,E[0].id),u.coverSet=!0;return{success:!0,data:u}}Q.provider.triggerDownload(D).catch(()=>{});let C;try{C=await Q.fetchImage(H)}catch(u){return{success:!1,error:u instanceof Error?u.message:"Image download failed"}}let P=U??`Stock photo ${$}`,x=YG.createImageEntity({dataUrl:C,title:P,alt:F??P}),k={id:$,...x,metadata:{...x.metadata,sourceUrl:H}},{entityId:o}=await Q.entityService.createEntity({entity:k}),r={imageEntityId:o,alreadyExisted:!1,attribution:f};if(Z&&z)await Xp0(Q.entityService,Z,z,o),r.coverSet=!0;return{success:!0,data:r}}}}async function Xp0(A,Q,B,w){let $=await A.getEntity({entityType:Q,id:B});if(!$)return;await A.updateEntity({entity:{...$,metadata:{...$.metadata,coverImageId:w}}})}KA();var Kp0={name:"@brains/stock-photo",private:!0,version:"0.2.0-alpha.54",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 Fj2=J.object({provider:J.enum(["unsplash"]).default("unsplash"),apiKey:J.string().optional().describe("Stock photo provider API key")});class _3A extends Bw{deps;cachedTools=null;constructor(A={},Q={}){super("stock-photo",Kp0,A,Fj2);this.deps=Q}async getTools(){if(!this.config.apiKey)return[];if(this.cachedTools)return this.cachedTools;let A=this.getContext(),Q=new Nn(this.config.apiKey,this.deps.fetch??globalThis.fetch);return this.cachedTools=Hp0(this.id,{provider:Q,entityService:A.entityService,fetchImage:this.deps.fetchImage??g$}),this.cachedTools}}function x3A(A={},Q={}){return new _3A(A,Q)}tA();KA();tA();tA();KA();var Wp0=J.enum(["ai","foundation","work"]),Up0=J.object({suffix:Wp0,title:J.string(),body:J.string(),linkLabel:J.string(),linkHref:J.string()}),Hx=J.object({eyebrow:J.string(),headline:J.string(),cards:J.array(Up0).min(1)}),fn=J.object({title:J.string(),slug:J.string(),status:J.enum(["draft","published"])}),Kx=r1.extend({entityType:J.literal("ecosystem-section"),metadata:fn});class Gp0 extends Q2{constructor(){super({entityType:"ecosystem-section",schema:Kx,frontmatterSchema:fn})}fromMarkdown(A){return{content:A,entityType:"ecosystem-section",metadata:this.parseFrontmatter(A)}}}var v3A=new Gp0;KA();function Zj2(A){return A.replace(/^---\n[\s\S]*?\n---\n?/,"")}function T3A(A,Q){return new RegExp(`(?:^|\\n)## ${Q}\\s*\\n([\\s\\S]*?)(?=\\n## |$)`).exec(A)?.[1]?.trim()??""}function Wx(A,Q){return new RegExp(`(?:^|\\n)#### ${Q}\\s*\\n([\\s\\S]*?)(?=\\n#### |\\n### |$)`).exec(A)?.[1]?.trim()??""}function Ln(A){let Q=Zj2(A),w=T3A(Q,"Cards").split(/^### Card \d+\s*$/m).map(($)=>$.trim()).filter(Boolean);return Hx.parse({eyebrow:T3A(Q,"Eyebrow"),headline:T3A(Q,"Headline"),cards:w.map(($)=>({suffix:Wx($,"Suffix"),title:Wx($,"Title"),body:Wx($,"Body"),linkLabel:Wx($,"Link Label"),linkHref:Wx($,"Link Href")}))})}function Jp0(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(`
|
|
4116
4116
|
`)}var zj2=J.object({query:J.object({id:J.string().optional()}).optional()}).passthrough();class Cn{id="rizom-ecosystem:entities";name="Rizom Ecosystem";description="Fetches an ecosystem-section entity for rendering";async fetch(A,Q,B){let $=zj2.parse(A??{}).query?.id??"rizom-ecosystem",D=await B.entityService.getEntity({entityType:"ecosystem-section",id:$});if(!D)throw Error(`Ecosystem section not found: ${$}`);return Q.parse(Ln(D.content))}}tA();var qj2=Wd({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 AH(...A){return qj2(_C(A))}import{jsxDEV as ZEB}from"preact/jsx-dev-runtime";import{jsxDEV as fEB}from"preact/jsx-dev-runtime";import{jsxDEV as MEB}from"preact/jsx-dev-runtime";import{jsxDEV as fj2}from"preact/jsx-dev-runtime";var S3A="px-6 md:px-10 xl:px-20",Nj2=`${S3A} relative z-[1]`,g3A=({id:A,className:Q,children:B})=>fj2("section",{id:A,className:AH(Nj2,Q),children:B},void 0,!1,void 0,this);import{jsxDEV as En}from"preact/jsx-dev-runtime";var Lj2={work:"text-accent",foundation:"text-secondary",ai:"text-accent-bright"},Ux=({name:A="rizom",brandSuffix:Q,className:B,dotClassName:w,suffixClassName:$})=>{let D=Lj2[Q];return En("span",{className:AH("inline-flex items-baseline gap-0 font-display font-medium tracking-[-0.015em] [font-variation-settings:'opsz'_24]",B),children:[En("span",{className:"text-theme",children:A},void 0,!1,void 0,this),En("span",{className:AH(D??"text-accent",w),children:"."},void 0,!1,void 0,this),En("span",{className:AH("italic font-normal text-theme-muted",$),children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as SEB}from"preact/jsx-dev-runtime";import{jsxDEV as mEB}from"preact/jsx-dev-runtime";import{jsxDEV as pEB,Fragment as lEB}from"preact/jsx-dev-runtime";import{jsxDEV as rEB}from"preact/jsx-dev-runtime";import{Fragment as h3A}from"preact";import{jsxDEV as Gx}from"preact/jsx-dev-runtime";var Cj2=/(\*[^*]+\*)/;function y3A(A,Q){let B=A.split(`
|
|
4117
|
-
`);return Gx(h3A,{children:B.map((w,$)=>Gx(h3A,{children:[$>0&&Gx("br",{},void 0,!1,void 0,this),w.split(Cj2).map((D,I)=>{if(D.length>=3&&D.startsWith("*")&&D.endsWith("*"))return Gx("span",{className:Q,children:D.slice(1,-1)},I,!1,void 0,this);return Gx(h3A,{children:D},I,!1,void 0,this)})]},$,!0,void 0,this))},void 0,!1,void 0,this)}import{jsxDEV as K7,Fragment as xj2}from"preact/jsx-dev-runtime";var Ej2="italic text-accent font-normal",Mj2="You are here",Vj2={work:"text-accent",foundation:"text-secondary",ai:"text-accent-bright"},Oj2={work:"border-t-accent/60",foundation:"border-t-secondary/60",ai:"border-t-accent-bright/60"},Rj2={work:"hover:border-t-accent",foundation:"hover:border-t-secondary",ai:"hover:border-t-accent-bright"},bj2="font-label text-[10.5px] uppercase tracking-[0.26em] mt-1",Pj2="font-body text-[15px] leading-[1.6] text-theme-muted mt-2",kj2="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",jj2="font-label text-[10.5px] uppercase tracking-[0.22em] text-accent self-start mt-[18px] pb-1",_j2=({card:A})=>{let Q=A.linkLabel===Mj2,B=A.linkHref.trim().length===0,w=K7(xj2,{children:[K7(Ux,{brandSuffix:A.suffix,className:"text-[clamp(28px,3vw,40px)] [font-variation-settings:'opsz'_96]"},void 0,!1,void 0,this),K7("span",{className:`${bj2} ${Vj2[A.suffix]}`,children:A.title},void 0,!1,void 0,this),K7("p",{className:Pj2,children:A.body},void 0,!1,void 0,this),Q?K7("span",{className:jj2,children:A.linkLabel},void 0,!1,void 0,this):K7("span",{className:kj2,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?Oj2[A.suffix]:"border-white/10"}`;return Q||B?K7("div",{className:$,children:w},void 0,!1,void 0,this):K7("a",{href:A.linkHref,className:`${$} text-inherit no-underline transition-colors ${Rj2[A.suffix]}`,children:w},void 0,!1,void 0,this)},m3A=({eyebrow:A,headline:Q,cards:B})=>K7(g3A,{id:"ecosystem",className:"pt-[112px] pb-[144px] border-t border-white/5",children:[K7("div",{className:"mx-auto mb-[88px] max-w-[1180px] text-center",children:[K7("span",{className:"font-label text-[11px] font-semibold uppercase tracking-[0.24em] text-accent",children:A},void 0,!1,void 0,this),K7("h2",{className:"mt-5 font-display text-[clamp(34px,4.4vw,60px)] font-[380] leading-[1.04] tracking-[-0.02em] [font-variation-settings:'opsz'_96]",children:y3A(Q,Ej2)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),K7("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)=>K7(_j2,{card:w},w.suffix,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this);var vj2=[{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 Fp0(A){return{eyebrow:"The Ecosystem",headline:"One practice. *Three faces.*",cards:vj2.map((Q)=>Q.suffix===A?{...Q,linkLabel:"You are here",linkHref:""}:Q)}}var Tj2=Fp0();var u3A=G1({name:"ecosystem",description:"Rizom ecosystem sibling-site section",schema:Hx,formatter:{parse:Ln,format:Jp0},dataSourceId:"rizom-ecosystem:entities",requiredPermission:"public",layout:{component:m3A}});var Zp0={name:"@brains/rizom-ecosystem",private:!0,version:"0.2.0-alpha.
|
|
4117
|
+
`);return Gx(h3A,{children:B.map((w,$)=>Gx(h3A,{children:[$>0&&Gx("br",{},void 0,!1,void 0,this),w.split(Cj2).map((D,I)=>{if(D.length>=3&&D.startsWith("*")&&D.endsWith("*"))return Gx("span",{className:Q,children:D.slice(1,-1)},I,!1,void 0,this);return Gx(h3A,{children:D},I,!1,void 0,this)})]},$,!0,void 0,this))},void 0,!1,void 0,this)}import{jsxDEV as K7,Fragment as xj2}from"preact/jsx-dev-runtime";var Ej2="italic text-accent font-normal",Mj2="You are here",Vj2={work:"text-accent",foundation:"text-secondary",ai:"text-accent-bright"},Oj2={work:"border-t-accent/60",foundation:"border-t-secondary/60",ai:"border-t-accent-bright/60"},Rj2={work:"hover:border-t-accent",foundation:"hover:border-t-secondary",ai:"hover:border-t-accent-bright"},bj2="font-label text-[10.5px] uppercase tracking-[0.26em] mt-1",Pj2="font-body text-[15px] leading-[1.6] text-theme-muted mt-2",kj2="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",jj2="font-label text-[10.5px] uppercase tracking-[0.22em] text-accent self-start mt-[18px] pb-1",_j2=({card:A})=>{let Q=A.linkLabel===Mj2,B=A.linkHref.trim().length===0,w=K7(xj2,{children:[K7(Ux,{brandSuffix:A.suffix,className:"text-[clamp(28px,3vw,40px)] [font-variation-settings:'opsz'_96]"},void 0,!1,void 0,this),K7("span",{className:`${bj2} ${Vj2[A.suffix]}`,children:A.title},void 0,!1,void 0,this),K7("p",{className:Pj2,children:A.body},void 0,!1,void 0,this),Q?K7("span",{className:jj2,children:A.linkLabel},void 0,!1,void 0,this):K7("span",{className:kj2,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?Oj2[A.suffix]:"border-white/10"}`;return Q||B?K7("div",{className:$,children:w},void 0,!1,void 0,this):K7("a",{href:A.linkHref,className:`${$} text-inherit no-underline transition-colors ${Rj2[A.suffix]}`,children:w},void 0,!1,void 0,this)},m3A=({eyebrow:A,headline:Q,cards:B})=>K7(g3A,{id:"ecosystem",className:"pt-[112px] pb-[144px] border-t border-white/5",children:[K7("div",{className:"mx-auto mb-[88px] max-w-[1180px] text-center",children:[K7("span",{className:"font-label text-[11px] font-semibold uppercase tracking-[0.24em] text-accent",children:A},void 0,!1,void 0,this),K7("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:y3A(Q,Ej2)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),K7("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)=>K7(_j2,{card:w},w.suffix,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this);var vj2=[{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 Fp0(A){return{eyebrow:"The Ecosystem",headline:"One practice. *Three faces.*",cards:vj2.map((Q)=>Q.suffix===A?{...Q,linkLabel:"You are here",linkHref:""}:Q)}}var Tj2=Fp0();var u3A=G1({name:"ecosystem",description:"Rizom ecosystem sibling-site section",schema:Hx,formatter:{parse:Ln,format:Jp0},dataSourceId:"rizom-ecosystem:entities",requiredPermission:"public",layout:{component:m3A}});var Zp0={name:"@brains/rizom-ecosystem",private:!0,version:"0.2.0-alpha.54",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 c3A extends n2{entityType="ecosystem-section";schema=Kx;adapter=v3A;constructor(A={}){super("rizom-ecosystem",Zp0,A,J.object({}).default({}))}getTemplates(){return{ecosystem:u3A}}getDataSources(){return[new Cn]}}function Pz(A={}){return new c3A(A)}KA();tA();tA();KA();KA();tA();var i5="agent",zp0="agent-discovery",qp0="agent:generation",Np0="agent-network",fp0="AgentNetworkWidget",Jx="agent-discovery:entities",l3A="agent-list",p3A="agent-detail",O8="skill",Lp0="skill",Mn="skill-derivation",Cp0="skill:project",Ep0="skill-derivation",Mp0="skill:skill-derivation",Vp0="skills";var vE=J.object({name:J.string(),description:J.string(),tags:J.array(J.string())}),PI=J.enum(["discovered","approved"]).describe("Discovered for review or approved for calling"),UY=L4.pick({name:!0,kind:!0,organization:!0}).extend({brainName:J.string().describe("Name of the brain instance"),url:J.string().url().describe("Brain endpoint URL"),did:J.string().optional().describe("Decentralized identifier (public)"),status:PI,discoveredAt:J.string().datetime().describe("When this agent was first discovered")}),Op0=UY.pick({name:!0,url:!0,status:!0}).extend({discoveredAt:J.string().datetime().optional(),slug:J.string()}),TE=r1.extend({entityType:J.literal(i5),metadata:Op0}),Fx=TE.extend({frontmatter:UY,about:J.string(),skills:J.array(vE),notes:J.string()}),SE=Fx.extend({url:J.string().optional(),typeLabel:J.string().optional()}),gj2=Fx.extend({url:J.string(),typeLabel:J.string()});KA();var hj2=J.array(vE);function Rp0(A){let Q=hj2.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(`
|
|
4118
4118
|
`)}function bp0(A){if(!A.trim())return[];let Q=[];for(let B of A.split(`
|
|
4119
4119
|
`)){let w=B.match(/^- (.+?): (.+?)(?:\s+\[(.+?)\])?$/);if(!w)continue;let $=w[1]??"",D=w[2]??"",I=w[3],Y=I?I.split(",").map((X)=>X.trim()).filter(Boolean):[];Q.push({name:$,description:D,tags:Y})}return Q}var yj2=J.object({about:J.string(),skills:J.array(vE),notes:J.string()}),Pp0=new IB(yj2,{title:"Agent",mappings:[{key:"about",label:"About",type:"string"},{key:"skills",label:"Skills",type:"custom",formatter:Rp0,parser:bp0},{key:"notes",label:"Notes",type:"string"}]});class kI extends Q2{constructor(){super({entityType:i5,schema:TE,frontmatterSchema:UY})}fromMarkdown(A){let Q=this.parseFrontMatter(A,UY),B=zN(Q.url);return{content:A,entityType:i5,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:PI.parse(A.status),discoveredAt:A.discoveredAt},B=Pp0.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=Pp0.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,UY),body:this.parseAgentContent(A.content)}}}tA();var mj2=new kI,uj2=BX.extend({status:PI.optional()}),cj2=wX.extend({query:uj2.optional()});function lj2(A){let Q=M2(A.content,UY),B=mj2.parseAgentContent(A.content);return Fx.parse({...A,frontmatter:Q.metadata,about:B.about,skills:B.skills,notes:B.notes})}class Vn extends U6{id=Jx;name="Agent Directory DataSource";description="Fetches and transforms agent entities for rendering";config={entityType:i5,defaultSort:[{field:"discoveredAt",direction:"desc"}],defaultLimit:50,lookupField:"slug",enableNavigation:!0};constructor(A){super(A)}transformEntity(A){return lj2(A)}buildDetailResult(A,Q){return{agent:A,prevAgent:Q?.prev??null,nextAgent:Q?.next??null}}parseQuery(A){let Q=cj2.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}buildListResult(A,Q,B){let w=PI.safeParse(B.status);return{agents:A,pagination:Q,baseUrl:B.baseUrl,selectedStatus:w.success?w.data:"all"}}async fetch(A,Q,B){let{query:w}=this.parseQuery(A);if(w.id)return super.fetch(A,Q,B);let{items:$,pagination:D}=await this.fetchList(w,B.entityService,w.status?{filter:{metadata:{status:w.status}}}:void 0);return Q.parse(this.buildListResult($,D,w))}}tA();KA();tA();async function kp0(A,Q){let w=`${(A.startsWith("http")?A:`https://${A}`).replace(/\/$/,"")}/.well-known/agent-card.json`;try{let $=await Q(w);if(!$.ok)return null;let D=await $.json();return xO(D)}catch{return null}}function On(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""}KA();var pj2=new kI;function jp0(A){return A.trim().toLowerCase().replace(/[_\s]+/g,"-")}function CJ(A){let Q=new Set,B=[];for(let w of A){let $=jp0(w);if(!$||Q.has($))continue;Q.add($),B.push($)}return B}function dj2(A,Q){if(Q.count!==A.count)return Q.count-A.count;return A.tag.localeCompare(Q.tag)}async function _p0(A,Q={}){let B=Q.minCount??1,w=Q.topN??12,$=new Map,[D,I]=await Promise.all([A.entityService.listEntities({entityType:O8}),A.entityService.listEntities({entityType:i5})]),Y=(X)=>{for(let H of CJ(X))$.set(H,($.get(H)??0)+1)};for(let X of D)Y(X.metadata.tags);for(let X of I){let H=pj2.parseAgentContent(X.content);Y(H.skills.flatMap((U)=>U.tags))}return Array.from($.entries()).map(([X,H])=>({tag:X,count:H})).filter((X)=>X.count>=B).sort(dj2).slice(0,w)}function xp0(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(`
|
|
4120
4120
|
`)}var ij2=new kI;function vp0(A,Q={}){let B=A.anchor?.name??A.brainName,w=A.anchor?.kind??"professional",$=[];if(A.anchor?.description)$.push(A.anchor.description);if(A.description)$.push(A.description);let D=Q.status??"discovered",I=new Date().toISOString();return{content:ij2.createAgentContent({name:B,kind:w,...A.anchor?.organization&&{organization:A.anchor.organization},brainName:A.brainName,url:A.url,status:D,discoveredAt:I,about:$.join(`
|
|
@@ -4214,7 +4214,7 @@ ${rY(B)}---
|
|
|
4214
4214
|
setView("agents");
|
|
4215
4215
|
setTagFilter("all");
|
|
4216
4216
|
});
|
|
4217
|
-
})();`;import{jsxDEV as KQ}from"preact/jsx-dev-runtime";function Q_2({item:A}){return KQ("li",{class:"list-item",children:[KQ("div",{class:"list-main",children:[KQ("span",{class:"list-name",children:A.name},void 0,!1,void 0,this),KQ("span",{class:"list-desc",children:A.description},void 0,!1,void 0,this),A.tags.length>0&&KQ("div",{class:"list-tags",children:A.tags.map((Q)=>KQ("span",{class:"tag",children:Q},`${A.id}:${Q}`,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),KQ("div",{class:"list-meta",children:A.status==="discovered"&&KQ("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 B_2({item:A}){return KQ("li",{class:"list-item agent-network-skill-row","data-agent-network-skill-row":!0,"data-agent-network-tags":JSON.stringify(A.tags),children:[KQ("div",{class:"list-main",children:KQ("span",{class:"list-name",children:A.name},void 0,!1,void 0,this)},void 0,!1,void 0,this),KQ("div",{class:"list-meta",children:KQ("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 w_2({kind:A,items:Q,active:B}){return KQ("div",{class:`agent-network-panel${B?" is-active":""}`,"data-agent-network-panel":A,children:Q.length>0?KQ("ul",{class:"list agent-network-list",children:Q.map((w)=>KQ(Q_2,{item:w},w.id,!1,void 0,this))},void 0,!1,void 0,this):KQ("p",{class:"agent-network-empty",children:"Nothing to show yet."},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function $_2({skills:A,count:Q,filters:B}){return KQ("div",{class:"agent-network-panel","data-agent-network-panel":"skills",children:[KQ("div",{class:"agent-network-filter-row",role:"tablist","aria-label":"Filter skills by tag",children:[KQ("button",{class:"agent-network-filter is-active",type:"button","data-agent-network-tag-filter":"all","aria-pressed":"true",children:[KQ("span",{class:"count",children:Q},void 0,!1,void 0,this),KQ("span",{class:"label",children:"all"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),B.map((w)=>KQ("button",{class:`agent-network-filter${w.variant==="gap"?" is-gap":""}`,type:"button","data-agent-network-tag-filter":w.tag,"aria-pressed":"false",children:[KQ("span",{class:"count",children:w.count},void 0,!1,void 0,this),KQ("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?KQ("ul",{class:"list agent-network-list agent-network-skills-list",children:A.map((w)=>KQ(B_2,{item:w},w.id,!1,void 0,this))},void 0,!1,void 0,this):KQ("p",{class:"agent-network-empty",children:"Nothing to show yet."},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function r3A({data:A}){let Q=mp0.safeParse(A);if(!Q.success)return KQ("p",{class:"muted",children:"Nothing to show yet."},void 0,!1,void 0,this);let B=Q.data;return KQ("div",{"data-agent-network-widget":!0,"data-agent-network-view":"agents",children:[KQ("div",{class:"agent-network-view-tabs",role:"tablist","aria-label":"Browse the agent network",children:[KQ("button",{class:"agent-network-view-tab is-active",type:"button","data-agent-network-view-tab":"agents","aria-pressed":"true",children:["Agents",KQ("span",{class:"agent-network-view-count",children:B.counts.agents},void 0,!1,void 0,this)]},void 0,!0,void 0,this),KQ("button",{class:"agent-network-view-tab",type:"button","data-agent-network-view-tab":"skills","aria-pressed":"false",children:["Skills",KQ("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),KQ("div",{class:"agent-network-kind-tabs",role:"tablist","aria-label":"Filter agents by kind",children:i3A.map((w)=>{let $=w==="all";return KQ("button",{class:`agent-network-kind-tab${$?" is-active":""}`,type:"button","data-agent-network-kind-tab":w,"aria-pressed":$?"true":"false",children:[KQ("span",{class:"agent-network-kind-count",children:B.agents[w].length},void 0,!1,void 0,this),KQ("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),i3A.map((w)=>KQ(w_2,{kind:w,items:B.agents[w],active:w==="all"},w,!1,void 0,this)),KQ($_2,{skills:B.skills,count:B.counts.skills,filters:B.skillFilters},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function cp0(A,Q){A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"dashboard:register-widget",payload:{id:Np0,pluginId:Q,title:"Agent Network",section:"secondary",priority:15,rendererName:fp0,component:r3A,clientScript:bn,dataProvider:async()=>up0(A)}}),{success:!0}})}function lp0(){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.'}tA();Q8();KA();import{jsxDEV as pp0}from"preact/jsx-dev-runtime";function Pn(A){try{return new URL(A).hostname}catch{return A}}var kn=({name:A,className:Q=""})=>{let B=A.charAt(0).toUpperCase(),w=0;for(let D=0;D<A.length;D++)w=A.charCodeAt(D)+((w<<5)-w);let $=Math.abs(w)%360;return pp0("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)},jn=({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 pp0("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 s1,Fragment as Y_2}from"preact/jsx-dev-runtime";var D_2=({skills:A})=>{if(A.length===0)return null;return s1("div",{className:"flex gap-1.5 flex-wrap mt-2",children:A.map((Q)=>s1("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 I_2(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric"})}function dp0(A,Q,B){let w=new URLSearchParams({status:Q});if(B>1)w.set("page",String(B));return`${A}?${w.toString()}`}var n3A=({agent:A})=>{let{frontmatter:Q,about:B,skills:w,url:$}=A,D=Q.status==="approved";return s1("a",{href:$,className:`flex items-start gap-5 p-6 rounded-xl border border-theme bg-theme-subtle hover:shadow-lg transition-shadow ${D?"":"opacity-70"}`,children:[s1(kn,{name:Q.name,className:"w-12 h-12 text-lg"},void 0,!1,void 0,this),s1("div",{className:"flex-1 min-w-0",children:[s1("div",{className:"flex items-center gap-2 mb-1 flex-wrap",children:[s1("span",{className:"text-lg font-semibold text-heading",children:Q.name},void 0,!1,void 0,this),s1(jn,{kind:Q.kind,size:"sm"},void 0,!1,void 0,this),Q.organization&&s1("span",{className:"text-xs text-theme-muted",children:["\xB7 ",Q.organization]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),s1("div",{className:"text-sm text-theme-muted mb-1",children:Q.brainName},void 0,!1,void 0,this),B&&s1("p",{className:"text-sm text-theme-muted line-clamp-2 mb-0",children:B},void 0,!1,void 0,this),D&&s1(D_2,{skills:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this),s1("div",{className:"flex flex-col items-end gap-1 flex-shrink-0 text-right",children:[s1("span",{className:"text-xs text-theme-muted",children:Pn(Q.url)},void 0,!1,void 0,this),s1("span",{className:"text-[11px] text-theme-muted opacity-60",children:D?`Discovered ${I_2(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)},ip0=({agents:A,pageTitle:Q,pagination:B,baseUrl:w="/agents",selectedStatus:$})=>{let D=Q??"Agent Directory",I=B?.totalItems??A.length,Y=A.filter((Z)=>Z.frontmatter.status==="approved"),X=A.filter((Z)=>Z.frontmatter.status==="discovered"),H=Y.length,U=X.length,F=`Your network of ${I} ${I===1?"brain":"brains"} and their anchors`;return s1(Y_2,{children:[s1(u2,{title:D,description:F},void 0,!1,void 0,this),s1("div",{className:"agent-list bg-theme",children:s1("div",{className:"container mx-auto px-6 md:px-12 max-w-5xl py-16 md:py-24",children:[s1("div",{className:"mb-8 pb-6 border-b border-theme",children:[s1("h1",{className:"text-4xl font-bold text-heading mb-2",children:D},void 0,!1,void 0,this),s1("p",{className:"text-theme-muted mb-4",children:F},void 0,!1,void 0,this),s1("div",{className:"flex flex-wrap gap-2 text-sm mb-4",children:[s1("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-heading",children:[I," total"]},void 0,!0,void 0,this),s1("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-status-success",children:[H," approved"]},void 0,!0,void 0,this),s1("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-theme-muted",children:[U," discovered"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),s1("div",{className:"flex flex-wrap gap-2 text-sm",children:[s1("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),s1("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),s1("a",{href:`${w}?status=discovered`,className:`px-3 py-1 rounded-full border transition-colors ${$==="discovered"?"border-theme text-heading bg-theme-subtle":"border-theme text-theme-muted hover:text-heading"}`,children:"Discovered"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),$==="all"&&Y.length>0&&s1("section",{className:"mb-10",children:[s1("div",{className:"flex items-center justify-between mb-4",children:[s1("h2",{className:"text-lg font-semibold text-heading",children:"Approved brains"},void 0,!1,void 0,this),s1("span",{className:"text-sm text-theme-muted",children:Y.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),s1("div",{className:"flex flex-col gap-4",children:Y.map((Z)=>s1(n3A,{agent:Z},Z.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$==="all"&&X.length>0&&s1("section",{children:[s1("div",{className:"flex items-center justify-between mb-4",children:[s1("div",{children:[s1("h2",{className:"text-lg font-semibold text-heading",children:"Discovered brains"},void 0,!1,void 0,this),s1("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),s1("span",{className:"text-sm text-theme-muted",children:X.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),s1("div",{className:"flex flex-col gap-4",children:X.map((Z)=>s1(n3A,{agent:Z},Z.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$!=="all"&&A.length>0&&s1("section",{children:[s1("div",{className:"flex items-center justify-between mb-4",children:[s1("h2",{className:"text-lg font-semibold text-heading",children:$==="approved"?"Approved brains":"Discovered brains"},void 0,!1,void 0,this),s1("span",{className:"text-sm text-theme-muted",children:A.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),s1("div",{className:"flex flex-col gap-4",children:A.map((Z)=>s1(n3A,{agent:Z},Z.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.length===0&&s1("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"&&s1("div",{className:"mt-12",children:s1(a4,{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"&&s1("nav",{"aria-label":"Pagination",className:"flex items-center justify-center gap-3 mt-12",children:[B.hasPrevPage?s1("a",{href:dp0(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):s1("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),s1("span",{className:"text-sm text-theme-muted",children:["Page ",B.currentPage," of ",B.totalPages]},void 0,!0,void 0,this),B.hasNextPage?s1("a",{href:dp0(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):s1("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 c1,Fragment as W_2}from"preact/jsx-dev-runtime";function X_2(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"})}var Zx=({children:A})=>c1("h2",{className:"text-sm font-semibold text-theme-muted uppercase tracking-wide mb-3",children:A},void 0,!1,void 0,this),H_2=({skill:A})=>c1("div",{className:"flex items-start gap-3 px-4 py-3 bg-theme-subtle rounded-lg",children:[c1("div",{className:"flex-1",children:[c1("div",{className:"text-sm font-semibold text-heading",children:A.name},void 0,!1,void 0,this),c1("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&&c1("div",{className:"flex gap-1 flex-shrink-0",children:A.tags.map((Q)=>c1("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),K_2=({label:A,value:Q,valueClassName:B})=>c1("div",{className:"flex justify-between text-[13px]",children:[c1("span",{className:"text-theme-muted",children:A},void 0,!1,void 0,this),c1("span",{className:B??"text-heading",children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this),rp0=({agent:A,prevAgent:Q,nextAgent:B})=>{let{frontmatter:w,about:$,skills:D,notes:I}=A,Y=Pn(w.url),X=w.status==="approved";return c1(W_2,{children:[c1(u2,{title:w.name,description:$||`Agent profile for ${w.name}`},void 0,!1,void 0,this),c1("article",{className:"agent-detail",children:c1("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:[c1("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),c1("div",{className:"flex items-start gap-6 mb-8",children:[c1(kn,{name:w.name,className:"w-[72px] h-[72px] text-3xl"},void 0,!1,void 0,this),c1("div",{children:[c1("div",{className:"flex items-center gap-3 mb-1",children:[c1("h1",{className:"text-3xl md:text-4xl font-bold text-heading",children:w.name},void 0,!1,void 0,this),c1(jn,{kind:w.kind},void 0,!1,void 0,this)]},void 0,!0,void 0,this),c1("div",{className:"text-base text-theme-muted mb-2",children:w.brainName},void 0,!1,void 0,this),c1("div",{className:"flex items-center gap-3 text-theme-muted",children:[w.organization&&c1("span",{className:"text-[15px]",children:w.organization},void 0,!1,void 0,this),w.organization&&c1("span",{className:"text-theme-muted opacity-40",children:"\xB7"},void 0,!1,void 0,this),c1("span",{className:"text-sm",children:["Discovered ",X_2(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),c1("div",{className:"border-b border-theme mb-8"},void 0,!1,void 0,this),!X&&c1("div",{className:"mb-8 rounded-xl border border-theme bg-theme-subtle px-5 py-4",children:[c1("div",{className:"text-sm font-semibold text-heading mb-1",children:"Saved for review"},void 0,!1,void 0,this),c1("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),c1("div",{className:"flex flex-col md:flex-row gap-12",children:[c1("div",{className:"flex-[2] min-w-0",children:[$&&c1("section",{className:"mb-8",children:[c1(Zx,{children:"About"},void 0,!1,void 0,this),c1("p",{className:"text-[15px] text-theme leading-relaxed",children:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this),D.length>0&&c1("section",{className:"mb-8",children:[c1(Zx,{children:"Skills"},void 0,!1,void 0,this),c1("div",{className:"flex flex-col gap-2.5",children:D.map((H)=>c1(H_2,{skill:H},H.name,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),I&&c1("section",{className:"mb-8",children:[c1(Zx,{children:"Notes"},void 0,!1,void 0,this),c1("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),c1("aside",{className:"flex-1 md:pl-8 md:border-l border-theme-muted/20",children:[c1("section",{className:"mb-8",children:[c1(Zx,{children:"Brain"},void 0,!1,void 0,this),c1("div",{className:"p-4 bg-theme-subtle rounded-xl",children:[c1("div",{className:"text-[15px] font-semibold text-heading mb-1",children:w.brainName},void 0,!1,void 0,this),w.did&&c1("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),c1("section",{className:"mb-8",children:[c1(Zx,{children:"Connection"},void 0,!1,void 0,this),c1("div",{className:"flex flex-col gap-3",children:[c1("div",{children:[c1("div",{className:"text-[13px] text-theme-muted mb-0.5",children:"Endpoint"},void 0,!1,void 0,this),c1("div",{className:"text-xs text-heading font-mono",children:w.url},void 0,!1,void 0,this)]},void 0,!0,void 0,this),c1(K_2,{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),c1("a",{href:w.url.replace(/\/a2a\/?$/,""),target:"_blank",rel:"noopener noreferrer",className:"flex items-center justify-center px-5 py-3 bg-theme-dark text-theme-inverse rounded-lg text-sm font-medium hover:opacity-90 transition-opacity",children:["Visit ",Y," \u2197"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),(Q??B)&&c1("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:[c1("div",{className:"min-h-[1px]",children:Q&&c1("a",{href:Q.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[c1("span",{children:"\u2190 Previous"},void 0,!1,void 0,this),c1("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),c1("div",{className:"min-h-[1px] md:text-right",children:B&&c1("a",{href:B.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[c1("span",{children:"Next \u2192"},void 0,!1,void 0,this),c1("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 U_2=J.object({agents:J.array(SE),pageTitle:J.string().optional(),pagination:K9.nullable(),baseUrl:J.string().optional(),selectedStatus:J.union([J.literal("all"),PI])});function np0(){return{[l3A]:G1({name:l3A,description:"Agent directory list page template",schema:U_2,dataSourceId:Jx,requiredPermission:"public",layout:{component:ip0}}),[p3A]:G1({name:p3A,description:"Individual agent profile template",schema:J.object({agent:SE,prevAgent:SE.nullable(),nextAgent:SE.nullable()}),dataSourceId:Jx,requiredPermission:"public",layout:{component:rp0}})}}var _n={name:"@brains/agent-discovery",private:!0,version:"0.2.0-alpha.53",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/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 J_2=new kI;class o3A extends n2{entityType=i5;schema=TE;adapter=J_2;constructor(){super(zp0,_n)}interceptCreate(A,Q,B){return Tp0(A,Q,B,this.id)}createGenerationHandler(A){return new d3A(this.logger.child("AgentGenerationJobHandler"),A)}getTemplates(){return np0()}getDataSources(){return[new Vn(this.logger.child("AgentDataSource"))]}async onRegister(A){cp0(A,this.id)}async getInstructions(){return lp0()}}function s3A(){return new o3A}tA();KA();tA();var gE=l7,op0=l7,zx=r1.extend({entityType:J.literal(O8),metadata:op0});tA();class hE extends Q2{constructor(){super({entityType:O8,schema:zx,frontmatterSchema:gE})}fromMarkdown(A){let Q=this.parseFrontMatter(A,gE);return{content:A,entityType:O8,metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}tA();KA();var F_2=J.object({skills:J.array(gE)}),sp0=G1({name:"skill:skill-derivation",description:"Derive skills from topic titles and brain capabilities",dataSourceId:"shell:ai-content",schema:F_2,useKnowledgeContext:!0,basePrompt:`You are analyzing a brain's content to identify its high-level capabilities.
|
|
4217
|
+
})();`;import{jsxDEV as KQ}from"preact/jsx-dev-runtime";function Q_2({item:A}){return KQ("li",{class:"list-item",children:[KQ("div",{class:"list-main",children:[KQ("span",{class:"list-name",children:A.name},void 0,!1,void 0,this),KQ("span",{class:"list-desc",children:A.description},void 0,!1,void 0,this),A.tags.length>0&&KQ("div",{class:"list-tags",children:A.tags.map((Q)=>KQ("span",{class:"tag",children:Q},`${A.id}:${Q}`,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),KQ("div",{class:"list-meta",children:A.status==="discovered"&&KQ("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 B_2({item:A}){return KQ("li",{class:"list-item agent-network-skill-row","data-agent-network-skill-row":!0,"data-agent-network-tags":JSON.stringify(A.tags),children:[KQ("div",{class:"list-main",children:KQ("span",{class:"list-name",children:A.name},void 0,!1,void 0,this)},void 0,!1,void 0,this),KQ("div",{class:"list-meta",children:KQ("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 w_2({kind:A,items:Q,active:B}){return KQ("div",{class:`agent-network-panel${B?" is-active":""}`,"data-agent-network-panel":A,children:Q.length>0?KQ("ul",{class:"list agent-network-list",children:Q.map((w)=>KQ(Q_2,{item:w},w.id,!1,void 0,this))},void 0,!1,void 0,this):KQ("p",{class:"agent-network-empty",children:"Nothing to show yet."},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function $_2({skills:A,count:Q,filters:B}){return KQ("div",{class:"agent-network-panel","data-agent-network-panel":"skills",children:[KQ("div",{class:"agent-network-filter-row",role:"tablist","aria-label":"Filter skills by tag",children:[KQ("button",{class:"agent-network-filter is-active",type:"button","data-agent-network-tag-filter":"all","aria-pressed":"true",children:[KQ("span",{class:"count",children:Q},void 0,!1,void 0,this),KQ("span",{class:"label",children:"all"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),B.map((w)=>KQ("button",{class:`agent-network-filter${w.variant==="gap"?" is-gap":""}`,type:"button","data-agent-network-tag-filter":w.tag,"aria-pressed":"false",children:[KQ("span",{class:"count",children:w.count},void 0,!1,void 0,this),KQ("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?KQ("ul",{class:"list agent-network-list agent-network-skills-list",children:A.map((w)=>KQ(B_2,{item:w},w.id,!1,void 0,this))},void 0,!1,void 0,this):KQ("p",{class:"agent-network-empty",children:"Nothing to show yet."},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function r3A({data:A}){let Q=mp0.safeParse(A);if(!Q.success)return KQ("p",{class:"muted",children:"Nothing to show yet."},void 0,!1,void 0,this);let B=Q.data;return KQ("div",{"data-agent-network-widget":!0,"data-agent-network-view":"agents",children:[KQ("div",{class:"agent-network-view-tabs",role:"tablist","aria-label":"Browse the agent network",children:[KQ("button",{class:"agent-network-view-tab is-active",type:"button","data-agent-network-view-tab":"agents","aria-pressed":"true",children:["Agents",KQ("span",{class:"agent-network-view-count",children:B.counts.agents},void 0,!1,void 0,this)]},void 0,!0,void 0,this),KQ("button",{class:"agent-network-view-tab",type:"button","data-agent-network-view-tab":"skills","aria-pressed":"false",children:["Skills",KQ("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),KQ("div",{class:"agent-network-kind-tabs",role:"tablist","aria-label":"Filter agents by kind",children:i3A.map((w)=>{let $=w==="all";return KQ("button",{class:`agent-network-kind-tab${$?" is-active":""}`,type:"button","data-agent-network-kind-tab":w,"aria-pressed":$?"true":"false",children:[KQ("span",{class:"agent-network-kind-count",children:B.agents[w].length},void 0,!1,void 0,this),KQ("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),i3A.map((w)=>KQ(w_2,{kind:w,items:B.agents[w],active:w==="all"},w,!1,void 0,this)),KQ($_2,{skills:B.skills,count:B.counts.skills,filters:B.skillFilters},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function cp0(A,Q){A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"dashboard:register-widget",payload:{id:Np0,pluginId:Q,title:"Agent Network",section:"secondary",priority:15,rendererName:fp0,component:r3A,clientScript:bn,dataProvider:async()=>up0(A)}}),{success:!0}})}function lp0(){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.'}tA();Q8();KA();import{jsxDEV as pp0}from"preact/jsx-dev-runtime";function Pn(A){try{return new URL(A).hostname}catch{return A}}var kn=({name:A,className:Q=""})=>{let B=A.charAt(0).toUpperCase(),w=0;for(let D=0;D<A.length;D++)w=A.charCodeAt(D)+((w<<5)-w);let $=Math.abs(w)%360;return pp0("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)},jn=({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 pp0("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 s1,Fragment as Y_2}from"preact/jsx-dev-runtime";var D_2=({skills:A})=>{if(A.length===0)return null;return s1("div",{className:"flex gap-1.5 flex-wrap mt-2",children:A.map((Q)=>s1("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 I_2(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric"})}function dp0(A,Q,B){let w=new URLSearchParams({status:Q});if(B>1)w.set("page",String(B));return`${A}?${w.toString()}`}var n3A=({agent:A})=>{let{frontmatter:Q,about:B,skills:w,url:$}=A,D=Q.status==="approved";return s1("a",{href:$,className:`flex items-start gap-5 p-6 rounded-xl border border-theme bg-theme-subtle hover:shadow-lg transition-shadow ${D?"":"opacity-70"}`,children:[s1(kn,{name:Q.name,className:"w-12 h-12 text-lg"},void 0,!1,void 0,this),s1("div",{className:"flex-1 min-w-0",children:[s1("div",{className:"flex items-center gap-2 mb-1 flex-wrap",children:[s1("span",{className:"text-lg font-semibold text-heading",children:Q.name},void 0,!1,void 0,this),s1(jn,{kind:Q.kind,size:"sm"},void 0,!1,void 0,this),Q.organization&&s1("span",{className:"text-xs text-theme-muted",children:["\xB7 ",Q.organization]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),s1("div",{className:"text-sm text-theme-muted mb-1",children:Q.brainName},void 0,!1,void 0,this),B&&s1("p",{className:"text-sm text-theme-muted line-clamp-2 mb-0",children:B},void 0,!1,void 0,this),D&&s1(D_2,{skills:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this),s1("div",{className:"flex flex-col items-end gap-1 flex-shrink-0 text-right",children:[s1("span",{className:"text-xs text-theme-muted",children:Pn(Q.url)},void 0,!1,void 0,this),s1("span",{className:"text-[11px] text-theme-muted opacity-60",children:D?`Discovered ${I_2(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)},ip0=({agents:A,pageTitle:Q,pagination:B,baseUrl:w="/agents",selectedStatus:$})=>{let D=Q??"Agent Directory",I=B?.totalItems??A.length,Y=A.filter((Z)=>Z.frontmatter.status==="approved"),X=A.filter((Z)=>Z.frontmatter.status==="discovered"),H=Y.length,U=X.length,F=`Your network of ${I} ${I===1?"brain":"brains"} and their anchors`;return s1(Y_2,{children:[s1(u2,{title:D,description:F},void 0,!1,void 0,this),s1("div",{className:"agent-list bg-theme",children:s1("div",{className:"container mx-auto px-6 md:px-12 max-w-5xl py-16 md:py-24",children:[s1("div",{className:"mb-8 pb-6 border-b border-theme",children:[s1("h1",{className:"text-4xl font-bold text-heading mb-2",children:D},void 0,!1,void 0,this),s1("p",{className:"text-theme-muted mb-4",children:F},void 0,!1,void 0,this),s1("div",{className:"flex flex-wrap gap-2 text-sm mb-4",children:[s1("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-heading",children:[I," total"]},void 0,!0,void 0,this),s1("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-status-success",children:[H," approved"]},void 0,!0,void 0,this),s1("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-theme-muted",children:[U," discovered"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),s1("div",{className:"flex flex-wrap gap-2 text-sm",children:[s1("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),s1("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),s1("a",{href:`${w}?status=discovered`,className:`px-3 py-1 rounded-full border transition-colors ${$==="discovered"?"border-theme text-heading bg-theme-subtle":"border-theme text-theme-muted hover:text-heading"}`,children:"Discovered"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),$==="all"&&Y.length>0&&s1("section",{className:"mb-10",children:[s1("div",{className:"flex items-center justify-between mb-4",children:[s1("h2",{className:"text-lg font-semibold text-heading",children:"Approved brains"},void 0,!1,void 0,this),s1("span",{className:"text-sm text-theme-muted",children:Y.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),s1("div",{className:"flex flex-col gap-4",children:Y.map((Z)=>s1(n3A,{agent:Z},Z.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$==="all"&&X.length>0&&s1("section",{children:[s1("div",{className:"flex items-center justify-between mb-4",children:[s1("div",{children:[s1("h2",{className:"text-lg font-semibold text-heading",children:"Discovered brains"},void 0,!1,void 0,this),s1("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),s1("span",{className:"text-sm text-theme-muted",children:X.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),s1("div",{className:"flex flex-col gap-4",children:X.map((Z)=>s1(n3A,{agent:Z},Z.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$!=="all"&&A.length>0&&s1("section",{children:[s1("div",{className:"flex items-center justify-between mb-4",children:[s1("h2",{className:"text-lg font-semibold text-heading",children:$==="approved"?"Approved brains":"Discovered brains"},void 0,!1,void 0,this),s1("span",{className:"text-sm text-theme-muted",children:A.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),s1("div",{className:"flex flex-col gap-4",children:A.map((Z)=>s1(n3A,{agent:Z},Z.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.length===0&&s1("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"&&s1("div",{className:"mt-12",children:s1(a4,{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"&&s1("nav",{"aria-label":"Pagination",className:"flex items-center justify-center gap-3 mt-12",children:[B.hasPrevPage?s1("a",{href:dp0(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):s1("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),s1("span",{className:"text-sm text-theme-muted",children:["Page ",B.currentPage," of ",B.totalPages]},void 0,!0,void 0,this),B.hasNextPage?s1("a",{href:dp0(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):s1("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 c1,Fragment as W_2}from"preact/jsx-dev-runtime";function X_2(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"})}var Zx=({children:A})=>c1("h2",{className:"text-sm font-semibold text-theme-muted uppercase tracking-wide mb-3",children:A},void 0,!1,void 0,this),H_2=({skill:A})=>c1("div",{className:"flex items-start gap-3 px-4 py-3 bg-theme-subtle rounded-lg",children:[c1("div",{className:"flex-1",children:[c1("div",{className:"text-sm font-semibold text-heading",children:A.name},void 0,!1,void 0,this),c1("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&&c1("div",{className:"flex gap-1 flex-shrink-0",children:A.tags.map((Q)=>c1("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),K_2=({label:A,value:Q,valueClassName:B})=>c1("div",{className:"flex justify-between text-[13px]",children:[c1("span",{className:"text-theme-muted",children:A},void 0,!1,void 0,this),c1("span",{className:B??"text-heading",children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this),rp0=({agent:A,prevAgent:Q,nextAgent:B})=>{let{frontmatter:w,about:$,skills:D,notes:I}=A,Y=Pn(w.url),X=w.status==="approved";return c1(W_2,{children:[c1(u2,{title:w.name,description:$||`Agent profile for ${w.name}`},void 0,!1,void 0,this),c1("article",{className:"agent-detail",children:c1("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:[c1("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),c1("div",{className:"flex items-start gap-6 mb-8",children:[c1(kn,{name:w.name,className:"w-[72px] h-[72px] text-3xl"},void 0,!1,void 0,this),c1("div",{children:[c1("div",{className:"flex items-center gap-3 mb-1",children:[c1("h1",{className:"text-3xl md:text-4xl font-bold text-heading",children:w.name},void 0,!1,void 0,this),c1(jn,{kind:w.kind},void 0,!1,void 0,this)]},void 0,!0,void 0,this),c1("div",{className:"text-base text-theme-muted mb-2",children:w.brainName},void 0,!1,void 0,this),c1("div",{className:"flex items-center gap-3 text-theme-muted",children:[w.organization&&c1("span",{className:"text-[15px]",children:w.organization},void 0,!1,void 0,this),w.organization&&c1("span",{className:"text-theme-muted opacity-40",children:"\xB7"},void 0,!1,void 0,this),c1("span",{className:"text-sm",children:["Discovered ",X_2(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),c1("div",{className:"border-b border-theme mb-8"},void 0,!1,void 0,this),!X&&c1("div",{className:"mb-8 rounded-xl border border-theme bg-theme-subtle px-5 py-4",children:[c1("div",{className:"text-sm font-semibold text-heading mb-1",children:"Saved for review"},void 0,!1,void 0,this),c1("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),c1("div",{className:"flex flex-col md:flex-row gap-12",children:[c1("div",{className:"flex-[2] min-w-0",children:[$&&c1("section",{className:"mb-8",children:[c1(Zx,{children:"About"},void 0,!1,void 0,this),c1("p",{className:"text-[15px] text-theme leading-relaxed",children:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this),D.length>0&&c1("section",{className:"mb-8",children:[c1(Zx,{children:"Skills"},void 0,!1,void 0,this),c1("div",{className:"flex flex-col gap-2.5",children:D.map((H)=>c1(H_2,{skill:H},H.name,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),I&&c1("section",{className:"mb-8",children:[c1(Zx,{children:"Notes"},void 0,!1,void 0,this),c1("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),c1("aside",{className:"flex-1 md:pl-8 md:border-l border-theme-muted/20",children:[c1("section",{className:"mb-8",children:[c1(Zx,{children:"Brain"},void 0,!1,void 0,this),c1("div",{className:"p-4 bg-theme-subtle rounded-xl",children:[c1("div",{className:"text-[15px] font-semibold text-heading mb-1",children:w.brainName},void 0,!1,void 0,this),w.did&&c1("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),c1("section",{className:"mb-8",children:[c1(Zx,{children:"Connection"},void 0,!1,void 0,this),c1("div",{className:"flex flex-col gap-3",children:[c1("div",{children:[c1("div",{className:"text-[13px] text-theme-muted mb-0.5",children:"Endpoint"},void 0,!1,void 0,this),c1("div",{className:"text-xs text-heading font-mono",children:w.url},void 0,!1,void 0,this)]},void 0,!0,void 0,this),c1(K_2,{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),c1("a",{href:w.url.replace(/\/a2a\/?$/,""),target:"_blank",rel:"noopener noreferrer",className:"flex items-center justify-center px-5 py-3 bg-theme-dark text-theme-inverse rounded-lg text-sm font-medium hover:opacity-90 transition-opacity",children:["Visit ",Y," \u2197"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),(Q??B)&&c1("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:[c1("div",{className:"min-h-[1px]",children:Q&&c1("a",{href:Q.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[c1("span",{children:"\u2190 Previous"},void 0,!1,void 0,this),c1("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),c1("div",{className:"min-h-[1px] md:text-right",children:B&&c1("a",{href:B.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[c1("span",{children:"Next \u2192"},void 0,!1,void 0,this),c1("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 U_2=J.object({agents:J.array(SE),pageTitle:J.string().optional(),pagination:K9.nullable(),baseUrl:J.string().optional(),selectedStatus:J.union([J.literal("all"),PI])});function np0(){return{[l3A]:G1({name:l3A,description:"Agent directory list page template",schema:U_2,dataSourceId:Jx,requiredPermission:"public",layout:{component:ip0}}),[p3A]:G1({name:p3A,description:"Individual agent profile template",schema:J.object({agent:SE,prevAgent:SE.nullable(),nextAgent:SE.nullable()}),dataSourceId:Jx,requiredPermission:"public",layout:{component:rp0}})}}var _n={name:"@brains/agent-discovery",private:!0,version:"0.2.0-alpha.54",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/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 J_2=new kI;class o3A extends n2{entityType=i5;schema=TE;adapter=J_2;constructor(){super(zp0,_n)}interceptCreate(A,Q,B){return Tp0(A,Q,B,this.id)}createGenerationHandler(A){return new d3A(this.logger.child("AgentGenerationJobHandler"),A)}getTemplates(){return np0()}getDataSources(){return[new Vn(this.logger.child("AgentDataSource"))]}async onRegister(A){cp0(A,this.id)}async getInstructions(){return lp0()}}function s3A(){return new o3A}tA();KA();tA();var gE=l7,op0=l7,zx=r1.extend({entityType:J.literal(O8),metadata:op0});tA();class hE extends Q2{constructor(){super({entityType:O8,schema:zx,frontmatterSchema:gE})}fromMarkdown(A){let Q=this.parseFrontMatter(A,gE);return{content:A,entityType:O8,metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}tA();KA();var F_2=J.object({skills:J.array(gE)}),sp0=G1({name:"skill:skill-derivation",description:"Derive skills from topic titles and brain capabilities",dataSourceId:"shell:ai-content",schema:F_2,useKnowledgeContext:!0,basePrompt:`You are analyzing a brain's content to identify its high-level capabilities.
|
|
4218
4218
|
|
|
4219
4219
|
Given knowledge domains, CONSOLIDATE related topics into broader skills.
|
|
4220
4220
|
There should be FEWER skills than topics \u2014 combine related domains.
|
|
@@ -4364,9 +4364,9 @@ Context:
|
|
|
4364
4364
|
${JSON.stringify(w,null,2)}
|
|
4365
4365
|
|
|
4366
4366
|
Draft SWOT:
|
|
4367
|
-
${JSON.stringify(B,null,2)}`}function mn(A){return A.map((Q)=>Q.detail===null?{title:Q.title}:{title:Q.title,detail:Q.detail})}function g_2(A,Q){let B=["strengths","weaknesses","opportunities","threats"];for(let w of B){let $=new Set(A[w].map((D)=>D.theme.trim().toLowerCase()));for(let D of Q[w]){let I=D.sourceTheme.trim().toLowerCase();if(!$.has(I))throw Error(`SWOT refinement invented theme "${D.sourceTheme}" in ${w}`)}}}class un{logger;context;adapter=new zW;constructor(A,Q){this.logger=A;this.context=Q}validateAndParse(A){let Q=e3A.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 $zA(this.context),$;if(w.summary.brainSkillCount+w.summary.approvedAgentCount+w.summary.discoveredAgentCount===0)$={strengths:[],weaknesses:[],opportunities:[],threats:[]};else{await B.report({progress:0.6,message:"Synthesizing SWOT analysis"});let{object:H}=await this.context.ai.generateObject(await v_2(this.context,w),AzA),U=AzA.parse(H);await B.report({progress:0.75,message:"Refining SWOT language"});let F=await this.context.ai.generateObject(await S_2(this.context,w,U),gn);$=gn.parse(F.object),g_2(U,$)}let I=new Date().toISOString(),Y=this.adapter.createSwotContent({strengths:mn($.strengths),weaknesses:mn($.weaknesses),opportunities:mn($.opportunities),threats:mn($.threats),derivedAt:I});await B.report({progress:0.9,message:"Saving SWOT entity"});let X=await this.context.entityService.getEntity({entityType:"swot",id:"swot"});if(X)await this.context.entityService.updateEntity({entity:{...X,content:Y,metadata:{derivedAt:I}}});else await this.context.entityService.createEntity({entity:{id:"swot",entityType:"swot",content:Y,metadata:{derivedAt:I}}});return this.logger.info("SWOT derivation complete",{derivedAt:I,brainSkillCount:w.summary.brainSkillCount,approvedAgentCount:w.summary.approvedAgentCount,discoveredAgentCount:w.summary.discoveredAgentCount}),{entityId:"swot"}}}KA();import{jsxDEV as P9}from"preact/jsx-dev-runtime";var cn=J.object({title:J.string(),detail:J.string().optional()}),h_2=J.discriminatedUnion("status",[J.object({status:J.literal("generating")}),J.object({status:J.literal("ready"),strengths:J.array(cn).default([]),weaknesses:J.array(cn).default([]),opportunities:J.array(cn).default([]),threats:J.array(cn).default([]),derivedAt:J.string()})]);function y_2({items:A}){if(A.length===0)return P9("p",{class:"swot-empty",children:"\u2014"},void 0,!1,void 0,this);return P9("ul",{class:"swot-list",children:A.map((Q)=>P9("li",{class:"swot-item",children:[P9("b",{children:Q.title},void 0,!1,void 0,this),Q.detail?P9("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 ln({title:A,tone:Q,items:B}){return P9("section",{class:`swot-cell is-${Q}`,children:[P9("div",{class:"swot-head",children:A},void 0,!1,void 0,this),P9(y_2,{items:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function YzA({data:A}){let Q=h_2.safeParse(A);if(!Q.success||Q.data.status==="generating")return P9("div",{"data-swot-widget":!0,children:P9("p",{class:"muted",children:"generating assessment\u2026"},void 0,!1,void 0,this)},void 0,!1,void 0,this);let B=Q.data;return P9("div",{"data-swot-widget":!0,children:P9("div",{class:"swot",role:"grid","aria-label":"SWOT analysis of agent network",children:[P9(ln,{title:"Strengths",tone:"s",items:B.strengths},void 0,!1,void 0,this),P9(ln,{title:"Weaknesses",tone:"w",items:B.weaknesses},void 0,!1,void 0,this),P9(ln,{title:"Opportunities",tone:"o",items:B.opportunities},void 0,!1,void 0,this),P9(ln,{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)}KA();var XzA={name:"@brains/assessment",private:!0,version:"0.2.0-alpha.
|
|
4367
|
+
${JSON.stringify(B,null,2)}`}function mn(A){return A.map((Q)=>Q.detail===null?{title:Q.title}:{title:Q.title,detail:Q.detail})}function g_2(A,Q){let B=["strengths","weaknesses","opportunities","threats"];for(let w of B){let $=new Set(A[w].map((D)=>D.theme.trim().toLowerCase()));for(let D of Q[w]){let I=D.sourceTheme.trim().toLowerCase();if(!$.has(I))throw Error(`SWOT refinement invented theme "${D.sourceTheme}" in ${w}`)}}}class un{logger;context;adapter=new zW;constructor(A,Q){this.logger=A;this.context=Q}validateAndParse(A){let Q=e3A.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 $zA(this.context),$;if(w.summary.brainSkillCount+w.summary.approvedAgentCount+w.summary.discoveredAgentCount===0)$={strengths:[],weaknesses:[],opportunities:[],threats:[]};else{await B.report({progress:0.6,message:"Synthesizing SWOT analysis"});let{object:H}=await this.context.ai.generateObject(await v_2(this.context,w),AzA),U=AzA.parse(H);await B.report({progress:0.75,message:"Refining SWOT language"});let F=await this.context.ai.generateObject(await S_2(this.context,w,U),gn);$=gn.parse(F.object),g_2(U,$)}let I=new Date().toISOString(),Y=this.adapter.createSwotContent({strengths:mn($.strengths),weaknesses:mn($.weaknesses),opportunities:mn($.opportunities),threats:mn($.threats),derivedAt:I});await B.report({progress:0.9,message:"Saving SWOT entity"});let X=await this.context.entityService.getEntity({entityType:"swot",id:"swot"});if(X)await this.context.entityService.updateEntity({entity:{...X,content:Y,metadata:{derivedAt:I}}});else await this.context.entityService.createEntity({entity:{id:"swot",entityType:"swot",content:Y,metadata:{derivedAt:I}}});return this.logger.info("SWOT derivation complete",{derivedAt:I,brainSkillCount:w.summary.brainSkillCount,approvedAgentCount:w.summary.approvedAgentCount,discoveredAgentCount:w.summary.discoveredAgentCount}),{entityId:"swot"}}}KA();import{jsxDEV as P9}from"preact/jsx-dev-runtime";var cn=J.object({title:J.string(),detail:J.string().optional()}),h_2=J.discriminatedUnion("status",[J.object({status:J.literal("generating")}),J.object({status:J.literal("ready"),strengths:J.array(cn).default([]),weaknesses:J.array(cn).default([]),opportunities:J.array(cn).default([]),threats:J.array(cn).default([]),derivedAt:J.string()})]);function y_2({items:A}){if(A.length===0)return P9("p",{class:"swot-empty",children:"\u2014"},void 0,!1,void 0,this);return P9("ul",{class:"swot-list",children:A.map((Q)=>P9("li",{class:"swot-item",children:[P9("b",{children:Q.title},void 0,!1,void 0,this),Q.detail?P9("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 ln({title:A,tone:Q,items:B}){return P9("section",{class:`swot-cell is-${Q}`,children:[P9("div",{class:"swot-head",children:A},void 0,!1,void 0,this),P9(y_2,{items:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function YzA({data:A}){let Q=h_2.safeParse(A);if(!Q.success||Q.data.status==="generating")return P9("div",{"data-swot-widget":!0,children:P9("p",{class:"muted",children:"generating assessment\u2026"},void 0,!1,void 0,this)},void 0,!1,void 0,this);let B=Q.data;return P9("div",{"data-swot-widget":!0,children:P9("div",{class:"swot",role:"grid","aria-label":"SWOT analysis of agent network",children:[P9(ln,{title:"Strengths",tone:"s",items:B.strengths},void 0,!1,void 0,this),P9(ln,{title:"Weaknesses",tone:"w",items:B.weaknesses},void 0,!1,void 0,this),P9(ln,{title:"Opportunities",tone:"o",items:B.opportunities},void 0,!1,void 0,this),P9(ln,{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)}KA();var XzA={name:"@brains/assessment",private:!0,version:"0.2.0-alpha.54",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/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 HzA=new zW;class KzA extends n2{entityType="swot";schema=yE;adapter=HzA;initialSyncComplete=!1;constructor(){super("swot",XzA)}async onRegister(A){let Q=new un(this.logger.child("SwotDerivationHandler"),A);A.jobs.registerHandler("derive",Q),A.eval.registerHandler("deriveSwot",async()=>{let D=T8.from(async()=>{});if(!D)throw Error("Expected progress reporter to be created");await Q.process({reason:"eval"},"eval-swot-derive",D);let I=await A.entityService.getEntity({entityType:"swot",id:"swot"});if(!I)throw Error("Expected SWOT entity to be created during eval");return HzA.parseSwotContent(I.content).frontmatter});let B=async(D)=>{try{return await A.jobs.enqueue({type:"derive",data:{reason:D},options:{source:this.id,priority:10,deduplication:"coalesce",deduplicationKey:"swot",metadata:{operationType:"data_processing",operationTarget:`swot:${D}`}}})}catch(I){return this.logger.error("Failed to queue SWOT derivation",{error:I,reason:D}),null}},w=async(D)=>{if(!await A.entityService.getEntity({entityType:"swot",id:"swot"}))await B(D)};A.messaging.subscribe("sync:initial:completed",async()=>{return this.initialSyncComplete=!0,await w("initial-missing-entity"),{success:!0}}),A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"dashboard:register-widget",payload:{id:"swot",pluginId:this.id,title:"SWOT",section:"secondary",priority:14,rendererName:"SwotWidget",component:YzA,dataProvider:async()=>{let D=await A.entityService.getEntity({entityType:"swot",id:"swot"});if(!D)return{status:"generating"};let{frontmatter:I}=HzA.parseSwotContent(D.content);return{status:"ready",...I}}}}),{success:!0}});let $=async(D)=>{let{entityType:I}=D.payload;if(!this.initialSyncComplete)return{success:!0};if(I!=="agent"&&I!=="skill")return{success:!0};return await B("entity-change"),{success:!0}};A.messaging.subscribe("entity:created",$),A.messaging.subscribe("entity:updated",$),A.messaging.subscribe("entity:deleted",$)}}function WzA(){return new KzA}tA();KA();var $bB=new zW,Kd0=J.object({name:J.string(),description:J.string(),tags:J.array(J.string())}),UzA=J.enum(["discovered","approved"]),u_2=J.object({name:J.string(),kind:J.enum(["professional","team","collective"]),organization:J.string().optional(),brainName:J.string(),url:J.string().url(),did:J.string().optional(),status:UzA,discoveredAt:J.string().datetime()}),c_2=r1.extend({entityType:J.literal("agent"),metadata:J.object({name:J.string(),url:J.string().url(),status:UzA,slug:J.string()})}),l_2=r1.extend({entityType:J.literal("skill"),metadata:l7}),p_2=J.object({about:J.string(),skills:J.array(Kd0),notes:J.string()});function d_2(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(`
|
|
4368
4368
|
`)}function i_2(A){if(!A.trim())return[];return A.split(`
|
|
4369
|
-
`).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 r_2=new IB(p_2,{title:"Agent",mappings:[{key:"about",label:"About",type:"string"},{key:"skills",label:"Skills",type:"custom",formatter:d_2,parser:i_2},{key:"notes",label:"Notes",type:"string"}]});class Wd0 extends Q2{constructor(){super({entityType:"agent",schema:c_2,frontmatterSchema:u_2})}fromMarkdown(A){return{content:A,entityType:"agent"}}createAgentContent(A){let Q=r_2.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 Ud0 extends Q2{constructor(){super({entityType:"skill",schema:l_2,frontmatterSchema:l7})}fromMarkdown(A){let Q=this.parseFrontMatter(A,l7);return{content:A,entityType:"skill",metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}var DbB=new Wd0,IbB=new Ud0,YbB=J.object({skills:J.array(l7),agents:J.array(J.object({id:J.string().optional(),name:J.string(),kind:J.enum(["professional","team","collective"]),organization:J.string().optional(),brainName:J.string(),url:J.string().url(),did:J.string().optional(),status:UzA,discoveredAt:J.string().datetime().optional(),about:J.string(),skills:J.array(Kd0),notes:J.string().default("")}))});var n_2=J.object({}).strict();function pn(A={}){return n_2.parse(A),[WzA()]}tA();KA();Q8();r$();KA();tA();var dn=Hg.extend({expertise:J.array(J.string()).optional().describe("Skills, domains, areas of focus"),currentFocus:J.string().optional().describe("What you're currently working on"),availability:J.string().optional().describe("What you're open to (consulting, speaking, etc.)")}),EJ=L4.extend(dn.shape);tA();IK();KA();var o_2=new $X;class rn{postsListUrl;decksListUrl;id="professional:homepage-list";name="Homepage List DataSource";description="Fetches profile, blog posts, and presentation decks for homepage";constructor(A,Q){this.postsListUrl=A;this.decksListUrl=Q}async fetch(A,Q,B){let w=B.entityService,[$,D,I,Y]=await Promise.all([TN(w),w.listEntities({entityType:"post",options:{limit:20}}),w.listEntities({entityType:"deck",options:{limit:20}}),yFA(w)]),X=o_2.parseProfileBody($,EJ),H=D.sort(rV).slice(0,3).map(v_),U=I.sort(rV).slice(0,3).map(h_);if(!Y.cta)throw Error("CTA not configured in site-info");let F={profile:X,posts:H,decks:U,postsListUrl:this.postsListUrl,decksListUrl:this.decksListUrl,cta:Y.cta,sections:Y.sections??{}};return Q.parse(F)}}tA();IK();var s_2=new $X;class nn{id="professional:about";name="About Page DataSource";description="Fetches full profile data for the about page";async fetch(A,Q,B){let w=await TN(B.entityService),D={profile:s_2.parseProfileBody(w,EJ)};return Q.parse(D)}}import{jsxDEV as aB,Fragment as e_2}from"preact/jsx-dev-runtime";var a_2="grid md:grid-cols-[14rem_1px_1fr] gap-y-2 gap-x-0 md:gap-16 items-start",t_2="border-t md:border-t-0 md:border-l border-rule-strong md:self-stretch",GzA=({number:A,title:Q,blurb:B,children:w})=>aB("section",{className:"py-20 border-b border-rule px-6 md:px-12",children:aB("div",{className:"max-w-6xl mx-auto",children:aB("div",{className:a_2,children:[aB(vUA,{title:Q,number:A,blurb:B},void 0,!1,void 0,this),aB("div",{className:t_2,"aria-hidden":"true"},void 0,!1,void 0,this),aB("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),JzA=({profile:A,posts:Q,decks:B,postsListUrl:w,decksListUrl:$,cta:D,sections:I})=>{let Y=A.tagline||A.description,X=Q.map((z)=>({id:z.id,url:z.url,title:z.metadata.title,date:z.metadata.publishedAt||z.created,description:z.frontmatter.excerpt,series:z.frontmatter.seriesName&&z.frontmatter.seriesIndex?{name:z.frontmatter.seriesName,index:z.frontmatter.seriesIndex}:void 0})),H=B.map((z)=>({id:z.id,url:z.url,title:z.frontmatter.title||z.id,date:z.frontmatter.publishedAt??z.created,description:z.frontmatter.description})),U=A.name||"Home",F=A.intro||A.description||Y||"Professional site",Z=Boolean(A.description)||A.expertise!==void 0&&A.expertise.length>0;return aB(e_2,{children:[aB(u2,{title:U,description:F,ogType:"website"},void 0,!1,void 0,this),aB("div",{className:"homepage-list bg-theme",children:[aB("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:aB("div",{className:"relative z-10 max-w-6xl mx-auto w-full",children:[A.name&&aB("div",{className:"flex items-center gap-[0.6rem] mb-6 font-mono text-[0.7rem] font-medium uppercase tracking-[0.22em] text-accent",children:[aB("span",{className:"w-[18px] h-px bg-accent","aria-hidden":"true"},void 0,!1,void 0,this),aB("span",{children:A.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Y&&aB("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:zd(Y,"italic font-normal text-accent [font-variation-settings:'opsz'_144,'SOFT'_80]")},void 0,!1,void 0,this),A.intro&&aB("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:zd(A.intro,"italic text-accent")},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),aB(GzA,{number:"01",title:"Essays",blurb:I.essays?.blurb,children:aB(Zd,{items:X,viewAllUrl:w,viewAllLabel:"View all essays"},void 0,!1,void 0,this)},void 0,!1,void 0,this),H.length>0&&aB(GzA,{number:"02",title:"Presentations",blurb:I.presentations?.blurb,children:aB(Zd,{items:H,viewAllUrl:$,viewAllLabel:"View all presentations"},void 0,!1,void 0,this)},void 0,!1,void 0,this),Z&&aB(GzA,{number:"03",title:"About",blurb:I.about?.blurb,children:aB("div",{className:"flex flex-col gap-8",children:[A.description&&aB("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&&aB(TUA,{subjects:A.expertise},void 0,!1,void 0,this),aB("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",aB("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),aB(CUA,{cta:D,variant:"editorial",socialLinks:A.socialLinks},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as fB,Fragment as Ax2}from"preact/jsx-dev-runtime";var FzA=({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 fB(Ax2,{children:[fB(u2,{title:Q,description:B,ogType:"profile"},void 0,!1,void 0,this),fB("div",{className:"about-page bg-theme",children:[fB("header",{className:"hero-bg-pattern relative w-full py-16 md:py-24 px-6 md:px-12 bg-theme overflow-hidden",children:fB("div",{className:"relative z-10 max-w-4xl mx-auto",children:[fB("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&&fB("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),fB("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-12 md:py-16",children:[A.story&&fB("section",{className:"content-section-reveal mb-20 md:mb-28",children:fB(GD,{markdown:A.story},void 0,!1,void 0,this)},void 0,!1,void 0,this),w&&fB("div",{className:"content-section-reveal grid md:grid-cols-2 gap-x-16 gap-y-12",children:[A.expertise&&A.expertise.length>0&&fB("section",{children:[fB("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Expertise"},void 0,!1,void 0,this),fB("ul",{className:"flex flex-wrap gap-3",children:A.expertise.map(($,D)=>fB("li",{className:Fj({variant:"accent",size:"lg"}),children:$},D,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.currentFocus&&fB("section",{children:[fB("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Current Focus"},void 0,!1,void 0,this),fB("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&&fB("section",{children:[fB("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Availability"},void 0,!1,void 0,this),fB("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)&&fB("section",{children:[fB("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Contact"},void 0,!1,void 0,this),fB("div",{className:"space-y-4",children:[A.email&&fB("p",{className:"text-lg",children:fB("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&&fB("p",{className:"text-lg",children:fB("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&&fB("div",{className:"flex flex-wrap gap-4 mt-4",children:A.socialLinks.map(($,D)=>fB(h6,{href:$.url,external:!0,variant:"secondary",size:"md",children:$.label||$.platform},D,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as k9,Fragment as Gd0}from"preact/jsx-dev-runtime";var ZzA=()=>{return k9(Gd0,{children:[k9(u2,{title:"Thanks for subscribing!",description:"You've successfully subscribed to the newsletter."},void 0,!1,void 0,this),k9("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:k9("div",{className:"text-center max-w-md",children:[k9("div",{className:"text-6xl mb-6",children:"\uD83C\uDF89"},void 0,!1,void 0,this),k9("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Thanks for subscribing!"},void 0,!1,void 0,this),k9("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),k9(h6,{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)},zzA=()=>{return k9(Gd0,{children:[k9(u2,{title:"Subscription failed",description:"There was a problem with your subscription."},void 0,!1,void 0,this),k9("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:k9("div",{className:"text-center max-w-md",children:[k9("div",{className:"text-6xl mb-6",children:"\uD83D\uDE22"},void 0,!1,void 0,this),k9("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Something went wrong"},void 0,!1,void 0,this),k9("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),k9(h6,{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)};KA();var Jd0=J.object({label:J.string().describe("Display label for entity type (e.g., 'Essay')"),pluralName:J.string().optional().describe("URL path segment (defaults to label.toLowerCase() + 's')")}),Fd0=J.object({entityDisplay:J.object({post:Jd0,deck:Jd0}).describe("Display metadata for post and deck entity types (required for homepage)")});var Zd0={name:"@brains/site-professional",private:!0,version:"0.2.0-alpha.53",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 qzA extends Bw{dependencies=["blog","decks"];constructor(A){super("professional-site",Zd0,A,Fd0)}async onRegister(A){A.entities.extendFrontmatterSchema("anchor-profile",dn);let Q=this.config.entityDisplay.post,B=this.config.entityDisplay.deck,w=`/${Q.pluralName??Q.label.toLowerCase()+"s"}`,$=`/${B.pluralName??B.label.toLowerCase()+"s"}`,D=new rn(w,$);A.entities.registerDataSource(D);let I=new nn;A.entities.registerDataSource(I);let Y=J.object({profile:EJ,posts:J.array(KW),decks:J.array(S_),postsListUrl:J.string(),decksListUrl:J.string(),cta:gFA,sections:J.record(J.string(),gm)}),X=J.object({profile:EJ}),H=J.object({});A.templates.register({"homepage-list":G1({name:"homepage-list",description:"Professional homepage with essays and presentations",schema:Y,dataSourceId:"professional:homepage-list",requiredPermission:"public",layout:{component:JzA}}),about:G1({name:"about",description:"About page with full profile information",schema:X,dataSourceId:"professional:about",requiredPermission:"public",layout:{component:FzA}}),"subscribe-thanks":G1({name:"subscribe-thanks",description:"Newsletter subscription success page",schema:H,requiredPermission:"public",layout:{component:ZzA}}),"subscribe-error":G1({name:"subscribe-error",description:"Newsletter subscription error page",schema:H,requiredPermission:"public",layout:{component:zzA}})}),this.logger.info("Professional site plugin registered successfully")}async getTools(){return[]}async getResources(){return[]}}function zd0(A){return new qzA(A??{})}var qd0=[{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 on}from"preact/jsx-dev-runtime";function Nd0({sections:A,siteInfo:Q,slots:B,wordmark:w}){return on("div",{className:"flex flex-col min-h-screen bg-theme overflow-x-clip",children:[on(OUA,{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),on("main",{className:"flex-grow flex flex-col bg-theme",children:A},void 0,!1,void 0,this),on(MUA,{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 Bx2={layouts:{default:Nd0},routes:qd0,plugin:zd0,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"}}}},Nx=Bx2;var fd0=`/*
|
|
4369
|
+
`).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 r_2=new IB(p_2,{title:"Agent",mappings:[{key:"about",label:"About",type:"string"},{key:"skills",label:"Skills",type:"custom",formatter:d_2,parser:i_2},{key:"notes",label:"Notes",type:"string"}]});class Wd0 extends Q2{constructor(){super({entityType:"agent",schema:c_2,frontmatterSchema:u_2})}fromMarkdown(A){return{content:A,entityType:"agent"}}createAgentContent(A){let Q=r_2.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 Ud0 extends Q2{constructor(){super({entityType:"skill",schema:l_2,frontmatterSchema:l7})}fromMarkdown(A){let Q=this.parseFrontMatter(A,l7);return{content:A,entityType:"skill",metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}var DbB=new Wd0,IbB=new Ud0,YbB=J.object({skills:J.array(l7),agents:J.array(J.object({id:J.string().optional(),name:J.string(),kind:J.enum(["professional","team","collective"]),organization:J.string().optional(),brainName:J.string(),url:J.string().url(),did:J.string().optional(),status:UzA,discoveredAt:J.string().datetime().optional(),about:J.string(),skills:J.array(Kd0),notes:J.string().default("")}))});var n_2=J.object({}).strict();function pn(A={}){return n_2.parse(A),[WzA()]}tA();KA();Q8();r$();KA();tA();var dn=Hg.extend({expertise:J.array(J.string()).optional().describe("Skills, domains, areas of focus"),currentFocus:J.string().optional().describe("What you're currently working on"),availability:J.string().optional().describe("What you're open to (consulting, speaking, etc.)")}),EJ=L4.extend(dn.shape);tA();IK();KA();var o_2=new $X;class rn{postsListUrl;decksListUrl;id="professional:homepage-list";name="Homepage List DataSource";description="Fetches profile, blog posts, and presentation decks for homepage";constructor(A,Q){this.postsListUrl=A;this.decksListUrl=Q}async fetch(A,Q,B){let w=B.entityService,[$,D,I,Y]=await Promise.all([TN(w),w.listEntities({entityType:"post",options:{limit:20}}),w.listEntities({entityType:"deck",options:{limit:20}}),yFA(w)]),X=o_2.parseProfileBody($,EJ),H=D.sort(rV).slice(0,3).map(v_),U=I.sort(rV).slice(0,3).map(h_);if(!Y.cta)throw Error("CTA not configured in site-info");let F={profile:X,posts:H,decks:U,postsListUrl:this.postsListUrl,decksListUrl:this.decksListUrl,cta:Y.cta,sections:Y.sections??{}};return Q.parse(F)}}tA();IK();var s_2=new $X;class nn{id="professional:about";name="About Page DataSource";description="Fetches full profile data for the about page";async fetch(A,Q,B){let w=await TN(B.entityService),D={profile:s_2.parseProfileBody(w,EJ)};return Q.parse(D)}}import{jsxDEV as aB,Fragment as e_2}from"preact/jsx-dev-runtime";var a_2="grid md:grid-cols-[14rem_1px_1fr] gap-y-2 gap-x-0 md:gap-16 items-start",t_2="border-t md:border-t-0 md:border-l border-rule-strong md:self-stretch",GzA=({number:A,title:Q,blurb:B,children:w})=>aB("section",{className:"py-20 border-b border-rule px-6 md:px-12",children:aB("div",{className:"max-w-6xl mx-auto",children:aB("div",{className:a_2,children:[aB(vUA,{title:Q,number:A,blurb:B},void 0,!1,void 0,this),aB("div",{className:t_2,"aria-hidden":"true"},void 0,!1,void 0,this),aB("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),JzA=({profile:A,posts:Q,decks:B,postsListUrl:w,decksListUrl:$,cta:D,sections:I})=>{let Y=A.tagline||A.description,X=Q.map((z)=>({id:z.id,url:z.url,title:z.metadata.title,date:z.metadata.publishedAt||z.created,description:z.frontmatter.excerpt,series:z.frontmatter.seriesName&&z.frontmatter.seriesIndex?{name:z.frontmatter.seriesName,index:z.frontmatter.seriesIndex}:void 0})),H=B.map((z)=>({id:z.id,url:z.url,title:z.frontmatter.title||z.id,date:z.frontmatter.publishedAt??z.created,description:z.frontmatter.description})),U=A.name||"Home",F=A.intro||A.description||Y||"Professional site",Z=Boolean(A.description)||A.expertise!==void 0&&A.expertise.length>0;return aB(e_2,{children:[aB(u2,{title:U,description:F,ogType:"website"},void 0,!1,void 0,this),aB("div",{className:"homepage-list bg-theme",children:[aB("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:aB("div",{className:"relative z-10 max-w-6xl mx-auto w-full",children:[A.name&&aB("div",{className:"flex items-center gap-[0.6rem] mb-6 font-mono text-[0.7rem] font-medium uppercase tracking-[0.22em] text-accent",children:[aB("span",{className:"w-[18px] h-px bg-accent","aria-hidden":"true"},void 0,!1,void 0,this),aB("span",{children:A.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Y&&aB("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:zd(Y,"italic font-normal text-accent [font-variation-settings:'opsz'_144,'SOFT'_80]")},void 0,!1,void 0,this),A.intro&&aB("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:zd(A.intro,"italic text-accent")},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),aB(GzA,{number:"01",title:"Essays",blurb:I.essays?.blurb,children:aB(Zd,{items:X,viewAllUrl:w,viewAllLabel:"View all essays"},void 0,!1,void 0,this)},void 0,!1,void 0,this),H.length>0&&aB(GzA,{number:"02",title:"Presentations",blurb:I.presentations?.blurb,children:aB(Zd,{items:H,viewAllUrl:$,viewAllLabel:"View all presentations"},void 0,!1,void 0,this)},void 0,!1,void 0,this),Z&&aB(GzA,{number:"03",title:"About",blurb:I.about?.blurb,children:aB("div",{className:"flex flex-col gap-8",children:[A.description&&aB("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&&aB(TUA,{subjects:A.expertise},void 0,!1,void 0,this),aB("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",aB("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),aB(CUA,{cta:D,variant:"editorial",socialLinks:A.socialLinks},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as fB,Fragment as Ax2}from"preact/jsx-dev-runtime";var FzA=({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 fB(Ax2,{children:[fB(u2,{title:Q,description:B,ogType:"profile"},void 0,!1,void 0,this),fB("div",{className:"about-page bg-theme",children:[fB("header",{className:"hero-bg-pattern relative w-full py-16 md:py-24 px-6 md:px-12 bg-theme overflow-hidden",children:fB("div",{className:"relative z-10 max-w-4xl mx-auto",children:[fB("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&&fB("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),fB("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-12 md:py-16",children:[A.story&&fB("section",{className:"content-section-reveal mb-20 md:mb-28",children:fB(GD,{markdown:A.story},void 0,!1,void 0,this)},void 0,!1,void 0,this),w&&fB("div",{className:"content-section-reveal grid md:grid-cols-2 gap-x-16 gap-y-12",children:[A.expertise&&A.expertise.length>0&&fB("section",{children:[fB("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Expertise"},void 0,!1,void 0,this),fB("ul",{className:"flex flex-wrap gap-3",children:A.expertise.map(($,D)=>fB("li",{className:Fj({variant:"accent",size:"lg"}),children:$},D,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.currentFocus&&fB("section",{children:[fB("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Current Focus"},void 0,!1,void 0,this),fB("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&&fB("section",{children:[fB("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Availability"},void 0,!1,void 0,this),fB("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)&&fB("section",{children:[fB("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Contact"},void 0,!1,void 0,this),fB("div",{className:"space-y-4",children:[A.email&&fB("p",{className:"text-lg",children:fB("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&&fB("p",{className:"text-lg",children:fB("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&&fB("div",{className:"flex flex-wrap gap-4 mt-4",children:A.socialLinks.map(($,D)=>fB(h6,{href:$.url,external:!0,variant:"secondary",size:"md",children:$.label||$.platform},D,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as k9,Fragment as Gd0}from"preact/jsx-dev-runtime";var ZzA=()=>{return k9(Gd0,{children:[k9(u2,{title:"Thanks for subscribing!",description:"You've successfully subscribed to the newsletter."},void 0,!1,void 0,this),k9("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:k9("div",{className:"text-center max-w-md",children:[k9("div",{className:"text-6xl mb-6",children:"\uD83C\uDF89"},void 0,!1,void 0,this),k9("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Thanks for subscribing!"},void 0,!1,void 0,this),k9("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),k9(h6,{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)},zzA=()=>{return k9(Gd0,{children:[k9(u2,{title:"Subscription failed",description:"There was a problem with your subscription."},void 0,!1,void 0,this),k9("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:k9("div",{className:"text-center max-w-md",children:[k9("div",{className:"text-6xl mb-6",children:"\uD83D\uDE22"},void 0,!1,void 0,this),k9("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Something went wrong"},void 0,!1,void 0,this),k9("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),k9(h6,{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)};KA();var Jd0=J.object({label:J.string().describe("Display label for entity type (e.g., 'Essay')"),pluralName:J.string().optional().describe("URL path segment (defaults to label.toLowerCase() + 's')")}),Fd0=J.object({entityDisplay:J.object({post:Jd0,deck:Jd0}).describe("Display metadata for post and deck entity types (required for homepage)")});var Zd0={name:"@brains/site-professional",private:!0,version:"0.2.0-alpha.54",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 qzA extends Bw{dependencies=["blog","decks"];constructor(A){super("professional-site",Zd0,A,Fd0)}async onRegister(A){A.entities.extendFrontmatterSchema("anchor-profile",dn);let Q=this.config.entityDisplay.post,B=this.config.entityDisplay.deck,w=`/${Q.pluralName??Q.label.toLowerCase()+"s"}`,$=`/${B.pluralName??B.label.toLowerCase()+"s"}`,D=new rn(w,$);A.entities.registerDataSource(D);let I=new nn;A.entities.registerDataSource(I);let Y=J.object({profile:EJ,posts:J.array(KW),decks:J.array(S_),postsListUrl:J.string(),decksListUrl:J.string(),cta:gFA,sections:J.record(J.string(),gm)}),X=J.object({profile:EJ}),H=J.object({});A.templates.register({"homepage-list":G1({name:"homepage-list",description:"Professional homepage with essays and presentations",schema:Y,dataSourceId:"professional:homepage-list",requiredPermission:"public",layout:{component:JzA}}),about:G1({name:"about",description:"About page with full profile information",schema:X,dataSourceId:"professional:about",requiredPermission:"public",layout:{component:FzA}}),"subscribe-thanks":G1({name:"subscribe-thanks",description:"Newsletter subscription success page",schema:H,requiredPermission:"public",layout:{component:ZzA}}),"subscribe-error":G1({name:"subscribe-error",description:"Newsletter subscription error page",schema:H,requiredPermission:"public",layout:{component:zzA}})}),this.logger.info("Professional site plugin registered successfully")}async getTools(){return[]}async getResources(){return[]}}function zd0(A){return new qzA(A??{})}var qd0=[{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 on}from"preact/jsx-dev-runtime";function Nd0({sections:A,siteInfo:Q,slots:B,wordmark:w}){return on("div",{className:"flex flex-col min-h-screen bg-theme overflow-x-clip",children:[on(OUA,{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),on("main",{className:"flex-grow flex flex-col bg-theme",children:A},void 0,!1,void 0,this),on(MUA,{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 Bx2={layouts:{default:Nd0},routes:qd0,plugin:zd0,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"}}}},Nx=Bx2;var fd0=`/*
|
|
4370
4370
|
* Default theme \u2014 simplified editorial base inspired by the Rizom family.
|
|
4371
4371
|
*
|
|
4372
4372
|
* This theme is intentionally less branded than @brains/theme-rizom. It
|
|
@@ -4754,7 +4754,7 @@ ${JSON.stringify(B,null,2)}`}function mn(A){return A.map((Q)=>Q.detail===null?{t
|
|
|
4754
4754
|
|
|
4755
4755
|
.btn-primary:disabled { opacity: 0.5; }
|
|
4756
4756
|
}
|
|
4757
|
-
`;var uE=fd0;import{join as Dx2}from"path";var Ld0={name:"@brains/rover",version:"0.2.0-alpha.53",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/blog":"workspace:*","@brains/cms":"workspace:*","@brains/content-pipeline":"workspace:*","@brains/dashboard":"workspace:*","@brains/decks":"workspace:*","@brains/directory-sync":"workspace:*","@brains/discord":"workspace:*","@brains/image-plugin":"workspace:*","@brains/link":"workspace:*","@brains/mcp":"workspace:*","@brains/newsletter":"workspace:*","@brains/note":"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 Cd0=["prompt","note","link","wishlist","topics","directory-sync","agents","assessment","cms","dashboard-root","mcp","webserver","discord","a2a"],Ed0=[...Cd0.filter((A)=>A!=="dashboard-root"),"image","dashboard","blog","series","decks","analytics","obsidian-vault","site-info","site-builder"],Ix2=[...Ed0,"portfolio","topics","content-pipeline","social-media","newsletter","stock-photo"],Yx2=["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."],Md0=QG({name:"rover",version:Ld0.version,model:"gpt-5.4-mini",site:Nx,theme:uE,presets:{core:Cd0,default:Ed0,full:Ix2},evalDisable:["discord","webserver","mcp","analytics","dashboard","dashboard-root"],agentInstructions:Yx2,capabilities:[["prompt",bz,void 0],["image",sb,void 0],["cms",Oz,{}],["dashboard",LJ,void 0],["dashboard-root",LJ,{routePath:"/"}],["blog",iFA,{}],["series",aFA,void 0],["decks",y_,void 0],["note",Lz,{}],["link",Ez,{}],["portfolio",PZA,{}],["topics",An,{includeEntityTypes:["post","deck","project","link","anchor-profile"]}],["content-pipeline",D3A,{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",e_,{autoGenerateOnBlogPublish:!0}],["newsletter",pl0,{doubleOptIn:!0}],["obsidian-vault",V3A,{autoSync:!0}],["wishlist",zn,{}],["stock-photo",x3A,{}],["agents",vn,void 0],["assessment",pn,void 0],["directory-sync",h3,{seedContent:!0,seedContentPath:Dx2(import.meta.dir,"..","seed-content"),initialSync:!0}],["analytics",Wn,{}],["rizom-ecosystem",Pz,void 0],["site-info",qz,void 0],["site-builder",zz,{cms:{}}]],interfaces:[["mcp",XG,()=>({})],["discord",lG,()=>({})],["webserver",pG,()=>({})],["a2a",qC,()=>({})]],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"}}});$G();tA();KA();KA();tA();var sn=J.object({routeId:J.string(),sectionId:J.string()}),fx=r1.extend({entityType:J.literal("site-content"),template:J.string().optional(),content:J.string(),metadata:sn});tA();class Vd0 extends Q2{constructor(){super({entityType:"site-content",schema:fx,frontmatterSchema:sn})}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 NzA=new Vd0;KA();var an=J.object({routeId:J.string().optional().describe("Optional: specific route filter"),sectionId:J.string().optional().describe("Optional: specific section filter"),dryRun:J.boolean().optional().default(!1).describe("Optional: preview changes without executing"),force:J.boolean().optional().default(!1).describe("Force regeneration even if content exists")}),qkB=J.object({jobs:J.array(J.object({jobId:J.string(),routeId:J.string(),sectionId:J.string()})),totalSections:J.number(),queuedSections:J.number(),skippedSections:J.number().optional(),batchId:J.string().optional()});class fzA{context;constructor(A){this.context=A}createJobOptions(A,Q){if(!A)return;return{source:A.operationType??Q,rootJobId:A.rootJobId??`${Q}-${Date.now()}`,metadata:{operationType:A.operationType??"content_operations",progressToken:A.progressToken,pluginId:A.pluginId??"site-content"}}}async fetchRoutes(){let A=await this.context.messaging.send({type:"site-builder:routes:list",payload:{}});if("noop"in A)throw Error("No handler for site-builder:routes:list \u2014 is site-builder plugin loaded?");if(!A.success||!A.data)throw Error("Failed to fetch routes from site-builder");return A.data}async generate(A,Q,B){let w=this.context.logger.child("SiteContentOperations"),$=await this.fetchRoutes(),D=$;if(A.routeId){if(D=$.filter((U)=>U.id===A.routeId),D.length===0)throw Error(`Route not found: ${A.routeId}`)}let I=[];for(let U of D)for(let F of U.sections){if(A.sectionId&&F.id!==A.sectionId)continue;if(F.content){w.debug("Section has static content, skipping",{routeId:U.id,sectionId:F.id});continue}if(F.template){let Z=this.context.templates.getCapabilities(F.template);if(!Z){w.warn("Template not found, skipping section",{routeId:U.id,sectionId:F.id,templateName:F.template});continue}if(!Z.canGenerate){w.debug("Template doesn't support generation, skipping",{routeId:U.id,sectionId:F.id,templateName:F.template,capabilities:Z});continue}}else{w.debug("Section has no template, skipping",{routeId:U.id,sectionId:F.id});continue}if(!A.force&&!A.dryRun){let Z=`${U.id}:${F.id}`;if(await this.context.entityService.getEntity({entityType:"site-content",id:Z})){w.debug("Content already exists, skipping",{routeId:U.id,sectionId:F.id});continue}}I.push({route:U,section:F})}let Y=I.length;if(A.dryRun)return{jobs:[],totalSections:Y,queuedSections:Y,batchId:`dry-run-${Date.now()}`};let X=[],H=[];for(let{route:U,section:F}of I){let Z=`${U.id}:${F.id}`,z=F.template,f={routeId:U.id,sectionId:F.id,entityId:Z,entityType:"site-content",templateName:z,context:{prompt:typeof F.content==="string"?F.content:void 0,data:{routeId:U.id,sectionId:F.id,routeTitle:U.title||Q?.title||"",routeDescription:U.description||Q?.description||"",sectionContent:F.content},conversationId:"system"},siteConfig:Q};H.push({type:"shell:content-generation",data:f})}if(H.length>0){let U=this.createJobOptions(B,"site:content-generation"),F=await this.context.jobs.enqueueBatch(H,U);for(let Z=0;Z<I.length;Z++){let z=I[Z];if(z)X.push({jobId:`${F}-${Z}`,routeId:z.route.id,sectionId:z.section.id})}return{jobs:X,totalSections:Y,queuedSections:X.length,batchId:F}}return{jobs:[],totalSections:Y,queuedSections:0,batchId:`empty-${Date.now()}`}}}class LzA{siteConfig;operations;constructor(A,Q){this.siteConfig=Q;this.operations=new fzA(A)}async generateContent(A,Q){let B=an.parse(A);return this.operations.generate(B,this.siteConfig,Q)}}KA();function Lx(A,Q){return Q?A.optional():A}function EzA(A){switch(A.type){case"string":return Lx(J.string(),A.optional);case"number":return Lx(J.number(),A.optional);case"enum":{let Q=[...A.options];return Lx(J.enum(Q),A.optional)}case"object":{let Q={};for(let[B,w]of Object.entries(A.fields))Q[B]=EzA(w);return Lx(J.object(Q),A.optional)}case"array":{let Q=J.array(Xx2(A));if(A.minItems!==void 0)Q=Q.min(A.minItems);if(A.length!==void 0)Q=Q.length(A.length);return Lx(Q,A.optional)}}}function Xx2(A){let{items:Q}=A;switch(Q.type){case"string":return J.string();case"number":return J.number();case"enum":{let B=[...Q.options];return J.enum(B)}case"object":{let B={};for(let[w,$]of Object.entries(Q.fields))B[w]=EzA($);return J.object(B)}}}function CzA(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])=>CzA(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,$])=>CzA(w,$)),B}}}}function Hx2(A,Q){let B={};for(let[D,I]of Object.entries(Q.fields))B[D]=EzA(I);let w=J.object(B),$=new IB(w,{title:Q.title,mappings:Object.entries(Q.fields).map(([D,I])=>CzA(D,I))});return{name:A,description:Q.description,schema:w,formatter:$,requiredPermission:Q.requiredPermission??"public",layout:{component:Q.layout,...Q.fullscreen!==void 0?{fullscreen:Q.fullscreen}:{}},...Q.runtimeScripts?{runtimeScripts:Q.runtimeScripts}:{}}}function MzA(A){return Object.fromEntries(Object.entries(A.sections).map(([Q,B])=>[Q,Hx2(Q,B)]))}KA();var Od0=J.object({namespace:J.string(),sections:J.record(J.any())}),Rd0=J.object({definitions:J.union([Od0,J.array(Od0)]).optional()});tA();function bd0(A,Q){return[MQ(Q,"generate","Generate content for all routes, a specific route, or a specific section",an,async(B,w)=>{let $=A();if(!$)return{success:!1,error:"Site content service not initialized"};if(B.sectionId&&!B.routeId)return{success:!1,error:"sectionId requires routeId to be specified"};let D={rootJobId:`generate-${Date.now()}`,progressToken:w.progressToken,pluginId:Q,operationType:"content_operations",interfaceType:w.interfaceType,channelId:w.channelId},I=await $.generateContent(B,D);return{success:!0,message:`Generated ${I.queuedSections} of ${I.totalSections} sections. ${I.queuedSections>0?"Jobs are running in the background.":"No new content to generate."}`,data:{batchId:I.batchId,jobsQueued:I.queuedSections,totalSections:I.totalSections,jobs:I.jobs}}})]}var Pd0={name:"@brains/site-content",private:!0,version:"0.2.0-alpha.53",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/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 VzA extends Bw{siteContentService;constructor(A={}){super("site-content",Pd0,A,Rd0)}async onRegister(A){A.entities.register("site-content",fx,NzA);for(let Q of oY(this.config.definitions))A.templates.register(MzA(Q),Q.namespace);this.siteContentService=new LzA(A)}async getTools(){return bd0(()=>this.siteContentService,this.id)}}function Cx(A={}){return new VzA(A)}tA();KA();Q8();KA();tA();var kd0=J.enum(["available","early access","coming soon","planned"]),jd0=J.object({title:J.string(),description:J.string()}),qW=J.object({name:J.string(),availability:kd0,order:J.number()}),tn=J.object({tagline:J.string(),promise:J.string(),role:J.string(),purpose:J.string(),audience:J.string(),values:J.array(J.string()).min(1),features:J.array(jd0).min(1).max(6),story:J.string()}),Wx2=qW.pick({name:!0,availability:!0,order:!0}).extend({slug:J.string()}),cE=r1.extend({entityType:J.literal("product"),metadata:Wx2}),en=cE.extend({frontmatter:qW,body:tn,labels:J.record(J.string(),J.string())}),Ao=en.extend({url:J.string().optional(),typeLabel:J.string().optional(),listUrl:J.string().optional(),listLabel:J.string().optional()});tA();KA();KA();class lE extends IB{constructor(){super(tn,{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 OzA extends Q2{constructor(){super({entityType:"product",schema:cE,frontmatterSchema:qW,bodyFormatter:new lE})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,qW);return this.buildMarkdown(Q,B)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,qW),B=t1(Q.name);return{content:A,entityType:"product",metadata:{name:Q.name,slug:B,availability:Q.availability,order:Q.order}}}}var Qo=new OzA;KA();tA();var _d0=J.object({title:J.string(),description:J.string()}),xd0=J.object({title:J.string(),description:J.string()}),Ux2=J.object({title:J.string(),description:J.string()}),vd0=J.object({heading:J.string(),buttonText:J.string(),link:J.string()}),NW=J.object({headline:J.string(),tagline:J.string()}),Gx2=J.object({title:J.string(),description:J.string()}),Bo=J.object({vision:J.string(),pillars:J.array(_d0).min(1).max(6),approach:J.array(Gx2).min(1).max(6),productsIntro:J.string(),technologies:J.array(Ux2).min(1).max(6),benefits:J.array(xd0).min(1).max(6),cta:vd0}),Td0=NW.pick({headline:!0}).extend({slug:J.string()}),pE=r1.extend({entityType:J.literal("products-overview"),metadata:Td0}),Ex=pE.extend({frontmatter:NW,body:Bo,labels:J.record(J.string(),J.string())});tA();KA();KA();class dE extends IB{constructor(){super(Bo,{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 RzA extends Q2{constructor(){super({entityType:"products-overview",schema:pE,frontmatterSchema:NW,bodyFormatter:new dE})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,NW);return this.buildMarkdown(Q,B)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,NW),B=t1(Q.headline);return{content:A,entityType:"products-overview",metadata:{headline:Q.headline,slug:B}}}}var bzA=new RzA;tA();KA();var Jx2=J.object({entityType:J.string(),query:J.object({id:J.string().optional()}).optional()});function Sd0(A,Q){let B=M2(A.content,qW),w=Q.parse(B.content),$=Q.getLabels();return en.parse({...A,frontmatter:B.metadata,body:w,labels:$})}function gd0(A,Q){let B=M2(A.content,NW),w=Q.parse(B.content),$=Q.getLabels();return Ex.parse({...A,frontmatter:B.metadata,body:w,labels:$})}class wo{logger;id="products:entities";name="Products Entity DataSource";description="Fetches products and overview for the products page";overviewFormatter=new dE;productFormatter=new lE;constructor(A){this.logger=A;this.logger.debug("ProductsDataSource initialized")}async fetch(A,Q,B){let w=Jx2.parse(A),$=B.entityService;if(w.entityType==="products-overview"){let H=(await $.listEntities({entityType:"products-overview",options:{limit:1}}))[0];if(!H)throw Error("Products overview entity not found");let U=gd0(H,this.overviewFormatter);return Q.parse(U)}if(w.query?.id){let H=(await $.listEntities({entityType:"product",options:{filter:{metadata:{slug:w.query.id}},limit:1}}))[0];if(!H)throw Error(`Product not found: ${w.query.id}`);return Q.parse({product:Sd0(H,this.productFormatter)})}let[D,I]=await Promise.all([$.listEntities({entityType:"products-overview",options:{limit:1}}),$.listEntities({entityType:"product",options:{sortFields:[{field:"order",direction:"asc"}]}})]),Y=D[0];if(!Y)throw Error("Products overview entity not found");return Q.parse({overview:gd0(Y,this.overviewFormatter),products:I.map((X)=>Sd0(X,this.productFormatter))})}}import{jsxDEV as l0,Fragment as zx2}from"preact/jsx-dev-runtime";var hd0=({overview:A,products:Q})=>{let{frontmatter:B,body:w,labels:$}=A;return l0(zx2,{children:[l0(u2,{title:B.headline,description:B.tagline},void 0,!1,void 0,this),l0("header",{className:"relative w-full min-h-[80vh] flex items-end px-6 md:px-12 bg-brand-dark overflow-hidden",children:[l0("style",{children:`
|
|
4757
|
+
`;var uE=fd0;import{join as Dx2}from"path";var Ld0={name:"@brains/rover",version:"0.2.0-alpha.54",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/blog":"workspace:*","@brains/cms":"workspace:*","@brains/content-pipeline":"workspace:*","@brains/dashboard":"workspace:*","@brains/decks":"workspace:*","@brains/directory-sync":"workspace:*","@brains/discord":"workspace:*","@brains/image-plugin":"workspace:*","@brains/link":"workspace:*","@brains/mcp":"workspace:*","@brains/newsletter":"workspace:*","@brains/note":"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 Cd0=["prompt","note","link","wishlist","topics","directory-sync","agents","assessment","cms","dashboard-root","mcp","webserver","discord","a2a"],Ed0=[...Cd0.filter((A)=>A!=="dashboard-root"),"image","dashboard","blog","series","decks","analytics","obsidian-vault","site-info","site-builder"],Ix2=[...Ed0,"portfolio","topics","content-pipeline","social-media","newsletter","stock-photo"],Yx2=["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."],Md0=QG({name:"rover",version:Ld0.version,model:"gpt-5.4-mini",site:Nx,theme:uE,presets:{core:Cd0,default:Ed0,full:Ix2},evalDisable:["discord","webserver","mcp","analytics","dashboard","dashboard-root"],agentInstructions:Yx2,capabilities:[["prompt",bz,void 0],["image",sb,void 0],["cms",Oz,{}],["dashboard",LJ,void 0],["dashboard-root",LJ,{routePath:"/"}],["blog",iFA,{}],["series",aFA,void 0],["decks",y_,void 0],["note",Lz,{}],["link",Ez,{}],["portfolio",PZA,{}],["topics",An,{includeEntityTypes:["post","deck","project","link","anchor-profile"]}],["content-pipeline",D3A,{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",e_,{autoGenerateOnBlogPublish:!0}],["newsletter",pl0,{doubleOptIn:!0}],["obsidian-vault",V3A,{autoSync:!0}],["wishlist",zn,{}],["stock-photo",x3A,{}],["agents",vn,void 0],["assessment",pn,void 0],["directory-sync",h3,{seedContent:!0,seedContentPath:Dx2(import.meta.dir,"..","seed-content"),initialSync:!0}],["analytics",Wn,{}],["rizom-ecosystem",Pz,void 0],["site-info",qz,void 0],["site-builder",zz,{cms:{}}]],interfaces:[["mcp",XG,()=>({})],["discord",lG,()=>({})],["webserver",pG,()=>({})],["a2a",qC,()=>({})]],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"}}});$G();tA();KA();KA();tA();var sn=J.object({routeId:J.string(),sectionId:J.string()}),fx=r1.extend({entityType:J.literal("site-content"),template:J.string().optional(),content:J.string(),metadata:sn});tA();class Vd0 extends Q2{constructor(){super({entityType:"site-content",schema:fx,frontmatterSchema:sn})}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 NzA=new Vd0;KA();var an=J.object({routeId:J.string().optional().describe("Optional: specific route filter"),sectionId:J.string().optional().describe("Optional: specific section filter"),dryRun:J.boolean().optional().default(!1).describe("Optional: preview changes without executing"),force:J.boolean().optional().default(!1).describe("Force regeneration even if content exists")}),qkB=J.object({jobs:J.array(J.object({jobId:J.string(),routeId:J.string(),sectionId:J.string()})),totalSections:J.number(),queuedSections:J.number(),skippedSections:J.number().optional(),batchId:J.string().optional()});class fzA{context;constructor(A){this.context=A}createJobOptions(A,Q){if(!A)return;return{source:A.operationType??Q,rootJobId:A.rootJobId??`${Q}-${Date.now()}`,metadata:{operationType:A.operationType??"content_operations",progressToken:A.progressToken,pluginId:A.pluginId??"site-content"}}}async fetchRoutes(){let A=await this.context.messaging.send({type:"site-builder:routes:list",payload:{}});if("noop"in A)throw Error("No handler for site-builder:routes:list \u2014 is site-builder plugin loaded?");if(!A.success||!A.data)throw Error("Failed to fetch routes from site-builder");return A.data}async generate(A,Q,B){let w=this.context.logger.child("SiteContentOperations"),$=await this.fetchRoutes(),D=$;if(A.routeId){if(D=$.filter((U)=>U.id===A.routeId),D.length===0)throw Error(`Route not found: ${A.routeId}`)}let I=[];for(let U of D)for(let F of U.sections){if(A.sectionId&&F.id!==A.sectionId)continue;if(F.content){w.debug("Section has static content, skipping",{routeId:U.id,sectionId:F.id});continue}if(F.template){let Z=this.context.templates.getCapabilities(F.template);if(!Z){w.warn("Template not found, skipping section",{routeId:U.id,sectionId:F.id,templateName:F.template});continue}if(!Z.canGenerate){w.debug("Template doesn't support generation, skipping",{routeId:U.id,sectionId:F.id,templateName:F.template,capabilities:Z});continue}}else{w.debug("Section has no template, skipping",{routeId:U.id,sectionId:F.id});continue}if(!A.force&&!A.dryRun){let Z=`${U.id}:${F.id}`;if(await this.context.entityService.getEntity({entityType:"site-content",id:Z})){w.debug("Content already exists, skipping",{routeId:U.id,sectionId:F.id});continue}}I.push({route:U,section:F})}let Y=I.length;if(A.dryRun)return{jobs:[],totalSections:Y,queuedSections:Y,batchId:`dry-run-${Date.now()}`};let X=[],H=[];for(let{route:U,section:F}of I){let Z=`${U.id}:${F.id}`,z=F.template,f={routeId:U.id,sectionId:F.id,entityId:Z,entityType:"site-content",templateName:z,context:{prompt:typeof F.content==="string"?F.content:void 0,data:{routeId:U.id,sectionId:F.id,routeTitle:U.title||Q?.title||"",routeDescription:U.description||Q?.description||"",sectionContent:F.content},conversationId:"system"},siteConfig:Q};H.push({type:"shell:content-generation",data:f})}if(H.length>0){let U=this.createJobOptions(B,"site:content-generation"),F=await this.context.jobs.enqueueBatch(H,U);for(let Z=0;Z<I.length;Z++){let z=I[Z];if(z)X.push({jobId:`${F}-${Z}`,routeId:z.route.id,sectionId:z.section.id})}return{jobs:X,totalSections:Y,queuedSections:X.length,batchId:F}}return{jobs:[],totalSections:Y,queuedSections:0,batchId:`empty-${Date.now()}`}}}class LzA{siteConfig;operations;constructor(A,Q){this.siteConfig=Q;this.operations=new fzA(A)}async generateContent(A,Q){let B=an.parse(A);return this.operations.generate(B,this.siteConfig,Q)}}KA();function Lx(A,Q){return Q?A.optional():A}function EzA(A){switch(A.type){case"string":return Lx(J.string(),A.optional);case"number":return Lx(J.number(),A.optional);case"enum":{let Q=[...A.options];return Lx(J.enum(Q),A.optional)}case"object":{let Q={};for(let[B,w]of Object.entries(A.fields))Q[B]=EzA(w);return Lx(J.object(Q),A.optional)}case"array":{let Q=J.array(Xx2(A));if(A.minItems!==void 0)Q=Q.min(A.minItems);if(A.length!==void 0)Q=Q.length(A.length);return Lx(Q,A.optional)}}}function Xx2(A){let{items:Q}=A;switch(Q.type){case"string":return J.string();case"number":return J.number();case"enum":{let B=[...Q.options];return J.enum(B)}case"object":{let B={};for(let[w,$]of Object.entries(Q.fields))B[w]=EzA($);return J.object(B)}}}function CzA(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])=>CzA(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,$])=>CzA(w,$)),B}}}}function Hx2(A,Q){let B={};for(let[D,I]of Object.entries(Q.fields))B[D]=EzA(I);let w=J.object(B),$=new IB(w,{title:Q.title,mappings:Object.entries(Q.fields).map(([D,I])=>CzA(D,I))});return{name:A,description:Q.description,schema:w,formatter:$,requiredPermission:Q.requiredPermission??"public",layout:{component:Q.layout,...Q.fullscreen!==void 0?{fullscreen:Q.fullscreen}:{}},...Q.runtimeScripts?{runtimeScripts:Q.runtimeScripts}:{}}}function MzA(A){return Object.fromEntries(Object.entries(A.sections).map(([Q,B])=>[Q,Hx2(Q,B)]))}KA();var Od0=J.object({namespace:J.string(),sections:J.record(J.any())}),Rd0=J.object({definitions:J.union([Od0,J.array(Od0)]).optional()});tA();function bd0(A,Q){return[MQ(Q,"generate","Generate content for all routes, a specific route, or a specific section",an,async(B,w)=>{let $=A();if(!$)return{success:!1,error:"Site content service not initialized"};if(B.sectionId&&!B.routeId)return{success:!1,error:"sectionId requires routeId to be specified"};let D={rootJobId:`generate-${Date.now()}`,progressToken:w.progressToken,pluginId:Q,operationType:"content_operations",interfaceType:w.interfaceType,channelId:w.channelId},I=await $.generateContent(B,D);return{success:!0,message:`Generated ${I.queuedSections} of ${I.totalSections} sections. ${I.queuedSections>0?"Jobs are running in the background.":"No new content to generate."}`,data:{batchId:I.batchId,jobsQueued:I.queuedSections,totalSections:I.totalSections,jobs:I.jobs}}})]}var Pd0={name:"@brains/site-content",private:!0,version:"0.2.0-alpha.54",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/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 VzA extends Bw{siteContentService;constructor(A={}){super("site-content",Pd0,A,Rd0)}async onRegister(A){A.entities.register("site-content",fx,NzA);for(let Q of oY(this.config.definitions))A.templates.register(MzA(Q),Q.namespace);this.siteContentService=new LzA(A)}async getTools(){return bd0(()=>this.siteContentService,this.id)}}function Cx(A={}){return new VzA(A)}tA();KA();Q8();KA();tA();var kd0=J.enum(["available","early access","coming soon","planned"]),jd0=J.object({title:J.string(),description:J.string()}),qW=J.object({name:J.string(),availability:kd0,order:J.number()}),tn=J.object({tagline:J.string(),promise:J.string(),role:J.string(),purpose:J.string(),audience:J.string(),values:J.array(J.string()).min(1),features:J.array(jd0).min(1).max(6),story:J.string()}),Wx2=qW.pick({name:!0,availability:!0,order:!0}).extend({slug:J.string()}),cE=r1.extend({entityType:J.literal("product"),metadata:Wx2}),en=cE.extend({frontmatter:qW,body:tn,labels:J.record(J.string(),J.string())}),Ao=en.extend({url:J.string().optional(),typeLabel:J.string().optional(),listUrl:J.string().optional(),listLabel:J.string().optional()});tA();KA();KA();class lE extends IB{constructor(){super(tn,{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 OzA extends Q2{constructor(){super({entityType:"product",schema:cE,frontmatterSchema:qW,bodyFormatter:new lE})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,qW);return this.buildMarkdown(Q,B)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,qW),B=t1(Q.name);return{content:A,entityType:"product",metadata:{name:Q.name,slug:B,availability:Q.availability,order:Q.order}}}}var Qo=new OzA;KA();tA();var _d0=J.object({title:J.string(),description:J.string()}),xd0=J.object({title:J.string(),description:J.string()}),Ux2=J.object({title:J.string(),description:J.string()}),vd0=J.object({heading:J.string(),buttonText:J.string(),link:J.string()}),NW=J.object({headline:J.string(),tagline:J.string()}),Gx2=J.object({title:J.string(),description:J.string()}),Bo=J.object({vision:J.string(),pillars:J.array(_d0).min(1).max(6),approach:J.array(Gx2).min(1).max(6),productsIntro:J.string(),technologies:J.array(Ux2).min(1).max(6),benefits:J.array(xd0).min(1).max(6),cta:vd0}),Td0=NW.pick({headline:!0}).extend({slug:J.string()}),pE=r1.extend({entityType:J.literal("products-overview"),metadata:Td0}),Ex=pE.extend({frontmatter:NW,body:Bo,labels:J.record(J.string(),J.string())});tA();KA();KA();class dE extends IB{constructor(){super(Bo,{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 RzA extends Q2{constructor(){super({entityType:"products-overview",schema:pE,frontmatterSchema:NW,bodyFormatter:new dE})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,NW);return this.buildMarkdown(Q,B)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,NW),B=t1(Q.headline);return{content:A,entityType:"products-overview",metadata:{headline:Q.headline,slug:B}}}}var bzA=new RzA;tA();KA();var Jx2=J.object({entityType:J.string(),query:J.object({id:J.string().optional()}).optional()});function Sd0(A,Q){let B=M2(A.content,qW),w=Q.parse(B.content),$=Q.getLabels();return en.parse({...A,frontmatter:B.metadata,body:w,labels:$})}function gd0(A,Q){let B=M2(A.content,NW),w=Q.parse(B.content),$=Q.getLabels();return Ex.parse({...A,frontmatter:B.metadata,body:w,labels:$})}class wo{logger;id="products:entities";name="Products Entity DataSource";description="Fetches products and overview for the products page";overviewFormatter=new dE;productFormatter=new lE;constructor(A){this.logger=A;this.logger.debug("ProductsDataSource initialized")}async fetch(A,Q,B){let w=Jx2.parse(A),$=B.entityService;if(w.entityType==="products-overview"){let H=(await $.listEntities({entityType:"products-overview",options:{limit:1}}))[0];if(!H)throw Error("Products overview entity not found");let U=gd0(H,this.overviewFormatter);return Q.parse(U)}if(w.query?.id){let H=(await $.listEntities({entityType:"product",options:{filter:{metadata:{slug:w.query.id}},limit:1}}))[0];if(!H)throw Error(`Product not found: ${w.query.id}`);return Q.parse({product:Sd0(H,this.productFormatter)})}let[D,I]=await Promise.all([$.listEntities({entityType:"products-overview",options:{limit:1}}),$.listEntities({entityType:"product",options:{sortFields:[{field:"order",direction:"asc"}]}})]),Y=D[0];if(!Y)throw Error("Products overview entity not found");return Q.parse({overview:gd0(Y,this.overviewFormatter),products:I.map((X)=>Sd0(X,this.productFormatter))})}}import{jsxDEV as l0,Fragment as zx2}from"preact/jsx-dev-runtime";var hd0=({overview:A,products:Q})=>{let{frontmatter:B,body:w,labels:$}=A;return l0(zx2,{children:[l0(u2,{title:B.headline,description:B.tagline},void 0,!1,void 0,this),l0("header",{className:"relative w-full min-h-[80vh] flex items-end px-6 md:px-12 bg-brand-dark overflow-hidden",children:[l0("style",{children:`
|
|
4758
4758
|
@keyframes wave-drift {
|
|
4759
4759
|
from { transform: translateX(0); }
|
|
4760
4760
|
to { transform: translateX(-50%); }
|
|
@@ -4782,7 +4782,7 @@ ${JSON.stringify(B,null,2)}`}function mn(A){return A.map((Q)=>Q.detail===null?{t
|
|
|
4782
4782
|
@media (prefers-reduced-motion: reduce) {
|
|
4783
4783
|
.detail-wave { animation: none; }
|
|
4784
4784
|
}
|
|
4785
|
-
`},void 0,!1,void 0,this),_1("div",{className:"absolute inset-0 overflow-hidden pointer-events-none",children:_1("svg",{preserveAspectRatio:"none",width:"200%",height:"100%",viewBox:"0 0 1600 400",className:"block absolute inset-0 detail-wave",children:[_1("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),_1("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),_1("div",{className:"absolute inset-0 cta-bg-pattern pointer-events-none"},void 0,!1,void 0,this),_1("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:[_1("nav",{"aria-label":"Breadcrumb",className:"text-sm text-white/50 mb-8 hero-stagger-1",children:_1("ol",{className:"flex flex-wrap items-center gap-1",children:[_1("li",{className:"flex items-center gap-1",children:_1("a",{href:"/",className:"hover:text-white transition-colors",children:"Home"},void 0,!1,void 0,this)},void 0,!1,void 0,this),_1("li",{className:"flex items-center gap-1",children:[_1("span",{className:"mx-1","aria-hidden":"true",children:"/"},void 0,!1,void 0,this),_1("a",{href:$,className:"hover:text-white transition-colors",children:D},void 0,!1,void 0,this)]},void 0,!0,void 0,this),_1("li",{className:"flex items-center gap-1",children:[_1("span",{className:"mx-1","aria-hidden":"true",children:"/"},void 0,!1,void 0,this),_1("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),_1("div",{className:"mb-6 hero-stagger-1",children:_1(D7,{status:Q.availability},void 0,!1,void 0,this)},void 0,!1,void 0,this),_1("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),_1("div",{className:"w-20 h-1.5 bg-accent mb-6 md:mb-8 hero-stagger-2"},void 0,!1,void 0,this),_1("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),_1("section",{className:"bg-theme-subtle py-20 md:py-28 px-6 md:px-12",children:_1("div",{className:"max-w-4xl mx-auto space-y-16",children:[_1("div",{children:[_1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:w.promise},void 0,!1,void 0,this),_1("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),_1("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-12 md:gap-16",children:[_1("div",{children:[_1("div",{className:"w-8 h-1 bg-accent mb-6"},void 0,!1,void 0,this),_1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-4",children:w.role},void 0,!1,void 0,this),_1("p",{className:"text-lg leading-relaxed text-theme-muted",children:B.role},void 0,!1,void 0,this)]},void 0,!0,void 0,this),_1("div",{children:[_1("div",{className:"w-8 h-1 bg-accent mb-6"},void 0,!1,void 0,this),_1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-4",children:w.purpose},void 0,!1,void 0,this),_1("p",{className:"text-lg leading-relaxed text-theme-muted",children:B.purpose},void 0,!1,void 0,this)]},void 0,!0,void 0,this),_1("div",{children:[_1("div",{className:"w-8 h-1 bg-accent mb-6"},void 0,!1,void 0,this),_1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-4",children:w.audience},void 0,!1,void 0,this),_1("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),_1("div",{className:"flex flex-col md:flex-row md:items-center gap-6 md:gap-12",children:[_1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted whitespace-nowrap",children:w.values},void 0,!1,void 0,this),_1(gC,{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),_1("section",{className:"cta-bg-pattern bg-brand py-20 md:py-32 px-6 md:px-12",children:_1("div",{className:"container mx-auto max-w-5xl",children:[_1("h2",{className:"text-sm tracking-widest uppercase text-white/50 mb-16",children:w.features},void 0,!1,void 0,this),_1("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-12 md:gap-16",children:B.features.map((Y,X)=>_1("div",{children:_1("div",{className:"flex items-start gap-6",children:[_1("span",{className:"text-5xl md:text-6xl font-black text-white/10 leading-none shrink-0",children:String(X+1).padStart(2,"0")},void 0,!1,void 0,this),_1("div",{className:"pt-2",children:[_1("div",{className:"w-8 h-1 bg-accent mb-4"},void 0,!1,void 0,this),_1("h3",{className:"text-xl font-bold text-white mb-3",children:Y.title},void 0,!1,void 0,this),_1("p",{className:"text-white/70 leading-relaxed",children:Y.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},Y.title,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),_1("section",{className:"py-20 md:py-32 px-6 md:px-12",children:_1("div",{className:"max-w-3xl mx-auto",children:[_1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-12",children:w.story},void 0,!1,void 0,this),_1("div",{className:"space-y-6",children:I.map((Y,X)=>_1("p",{className:X===0?"text-2xl md:text-3xl leading-relaxed text-heading font-light":"text-lg leading-relaxed text-theme-muted",children:Y},X,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),_1("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:_1("div",{className:"max-w-4xl mx-auto",children:[_1("p",{className:"text-sm tracking-widest uppercase text-white/60 mb-4",children:Q.name},void 0,!1,void 0,this),_1("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),_1("p",{className:"text-lg text-white/60 mb-10 max-w-xl",children:B.promise},void 0,!1,void 0,this),_1(h6,{href:$,variant:"outline-light",size:"lg",children:D},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};KA();var PzA=J.object({route:J.string().default("/products")});var md0={name:"@brains/products",private:!0,version:"0.2.0-alpha.
|
|
4785
|
+
`},void 0,!1,void 0,this),_1("div",{className:"absolute inset-0 overflow-hidden pointer-events-none",children:_1("svg",{preserveAspectRatio:"none",width:"200%",height:"100%",viewBox:"0 0 1600 400",className:"block absolute inset-0 detail-wave",children:[_1("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),_1("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),_1("div",{className:"absolute inset-0 cta-bg-pattern pointer-events-none"},void 0,!1,void 0,this),_1("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:[_1("nav",{"aria-label":"Breadcrumb",className:"text-sm text-white/50 mb-8 hero-stagger-1",children:_1("ol",{className:"flex flex-wrap items-center gap-1",children:[_1("li",{className:"flex items-center gap-1",children:_1("a",{href:"/",className:"hover:text-white transition-colors",children:"Home"},void 0,!1,void 0,this)},void 0,!1,void 0,this),_1("li",{className:"flex items-center gap-1",children:[_1("span",{className:"mx-1","aria-hidden":"true",children:"/"},void 0,!1,void 0,this),_1("a",{href:$,className:"hover:text-white transition-colors",children:D},void 0,!1,void 0,this)]},void 0,!0,void 0,this),_1("li",{className:"flex items-center gap-1",children:[_1("span",{className:"mx-1","aria-hidden":"true",children:"/"},void 0,!1,void 0,this),_1("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),_1("div",{className:"mb-6 hero-stagger-1",children:_1(D7,{status:Q.availability},void 0,!1,void 0,this)},void 0,!1,void 0,this),_1("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),_1("div",{className:"w-20 h-1.5 bg-accent mb-6 md:mb-8 hero-stagger-2"},void 0,!1,void 0,this),_1("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),_1("section",{className:"bg-theme-subtle py-20 md:py-28 px-6 md:px-12",children:_1("div",{className:"max-w-4xl mx-auto space-y-16",children:[_1("div",{children:[_1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:w.promise},void 0,!1,void 0,this),_1("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),_1("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-12 md:gap-16",children:[_1("div",{children:[_1("div",{className:"w-8 h-1 bg-accent mb-6"},void 0,!1,void 0,this),_1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-4",children:w.role},void 0,!1,void 0,this),_1("p",{className:"text-lg leading-relaxed text-theme-muted",children:B.role},void 0,!1,void 0,this)]},void 0,!0,void 0,this),_1("div",{children:[_1("div",{className:"w-8 h-1 bg-accent mb-6"},void 0,!1,void 0,this),_1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-4",children:w.purpose},void 0,!1,void 0,this),_1("p",{className:"text-lg leading-relaxed text-theme-muted",children:B.purpose},void 0,!1,void 0,this)]},void 0,!0,void 0,this),_1("div",{children:[_1("div",{className:"w-8 h-1 bg-accent mb-6"},void 0,!1,void 0,this),_1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-4",children:w.audience},void 0,!1,void 0,this),_1("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),_1("div",{className:"flex flex-col md:flex-row md:items-center gap-6 md:gap-12",children:[_1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted whitespace-nowrap",children:w.values},void 0,!1,void 0,this),_1(gC,{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),_1("section",{className:"cta-bg-pattern bg-brand py-20 md:py-32 px-6 md:px-12",children:_1("div",{className:"container mx-auto max-w-5xl",children:[_1("h2",{className:"text-sm tracking-widest uppercase text-white/50 mb-16",children:w.features},void 0,!1,void 0,this),_1("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-12 md:gap-16",children:B.features.map((Y,X)=>_1("div",{children:_1("div",{className:"flex items-start gap-6",children:[_1("span",{className:"text-5xl md:text-6xl font-black text-white/10 leading-none shrink-0",children:String(X+1).padStart(2,"0")},void 0,!1,void 0,this),_1("div",{className:"pt-2",children:[_1("div",{className:"w-8 h-1 bg-accent mb-4"},void 0,!1,void 0,this),_1("h3",{className:"text-xl font-bold text-white mb-3",children:Y.title},void 0,!1,void 0,this),_1("p",{className:"text-white/70 leading-relaxed",children:Y.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},Y.title,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),_1("section",{className:"py-20 md:py-32 px-6 md:px-12",children:_1("div",{className:"max-w-3xl mx-auto",children:[_1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-12",children:w.story},void 0,!1,void 0,this),_1("div",{className:"space-y-6",children:I.map((Y,X)=>_1("p",{className:X===0?"text-2xl md:text-3xl leading-relaxed text-heading font-light":"text-lg leading-relaxed text-theme-muted",children:Y},X,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),_1("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:_1("div",{className:"max-w-4xl mx-auto",children:[_1("p",{className:"text-sm tracking-widest uppercase text-white/60 mb-4",children:Q.name},void 0,!1,void 0,this),_1("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),_1("p",{className:"text-lg text-white/60 mb-10 max-w-xl",children:B.promise},void 0,!1,void 0,this),_1(h6,{href:$,variant:"outline-light",size:"lg",children:D},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};KA();var PzA=J.object({route:J.string().default("/products")});var md0={name:"@brains/products",private:!0,version:"0.2.0-alpha.54",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/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 fx2=J.object({overview:Ex,products:J.array(Ao)}),Lx2=J.object({product:Ao});class kzA extends n2{entityType=Qo.entityType;schema=cE;adapter=Qo;constructor(A={}){super("products",md0,A,PzA)}getTemplates(){return{"product-list":G1({name:"product-list",description:"Products page \u2014 overview + brain model cards",schema:fx2,dataSourceId:"products:entities",requiredPermission:"public",layout:{component:hd0}}),"product-detail":G1({name:"product-detail",description:"Individual product detail page",schema:Lx2,dataSourceId:"products:entities",requiredPermission:"public",layout:{component:yd0}})}}getDataSources(){return[new wo(this.logger.child("ProductsDataSource"))]}async onRegister(A){A.entities.register("products-overview",pE,bzA)}}function jzA(A={}){return new kzA(A)}import{join as ux2}from"path";import{jsxDEV as $o,Fragment as Cx2}from"preact/jsx-dev-runtime";var Do=({children:A})=>$o(Cx2,{children:[$o("div",{id:"bgCanvasWrap",className:"rizom-frame-canvas-wrap fixed top-0 left-0 w-full h-full pointer-events-none",children:$o("canvas",{id:"heroCanvas",className:"w-full h-full block"},void 0,!1,void 0,this)},void 0,!1,void 0,this),$o("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 w_B}from"preact/jsx-dev-runtime";import{jsxDEV as X_B}from"preact/jsx-dev-runtime";var Io="px-6 md:px-10 xl:px-20",I_B=`${Io} relative z-[1]`;import{jsxDEV as G_B}from"preact/jsx-dev-runtime";import{jsxDEV as Z_B}from"preact/jsx-dev-runtime";import{jsxDEV as f_B}from"preact/jsx-dev-runtime";import{jsxDEV as M_B}from"preact/jsx-dev-runtime";import{jsxDEV as b_B}from"preact/jsx-dev-runtime";import{Fragment as j_B}from"preact";import{jsxDEV as x_B}from"preact/jsx-dev-runtime";import{jsxDEV as ud0}from"preact/jsx-dev-runtime";var Yo=({sections:A})=>ud0(Do,{children:ud0("main",{children:A},void 0,!1,void 0,this)},void 0,!1,void 0,this);tA();KA();var cd0=`/*
|
|
4786
4786
|
* Shared globals + helpers used by tree / constellation / roots canvas
|
|
4787
4787
|
* scripts. Loaded as a shared static asset by the Rizom runtime package
|
|
4788
4788
|
* so the variant canvases
|
|
@@ -7214,7 +7214,7 @@ explicit decisions, and concrete action items. Never invent facts, owners, or ta
|
|
|
7214
7214
|
Return only the required structured JSON.`});KA();var sx2=J.object({entityType:J.literal(C$),query:J.object({id:J.string().optional(),conversationId:J.string().optional(),limit:J.number().optional()}).optional()});class yzA{logger;id=ad0;name="Summary Entity DataSource";description="Fetches and transforms summary entities for rendering";adapter=new VJ;constructor(A){this.logger=A;this.logger.debug("SummaryDataSource initialized")}async fetch(A,Q,B){let w=sx2.parse(A),$=B.entityService,D=w.query?.conversationId??w.query?.id;if(D){let H=await $.getEntity({entityType:C$,id:D});if(!H)throw Error(`Summary not found: ${D}`);let{entries:U}=this.adapter.parseBody(H.content),F={conversationId:H.metadata.conversationId,channelName:H.metadata.channelName??H.metadata.channelId,entries:U,messageCount:H.metadata.messageCount,entryCount:U.length,updated:H.updated};return Q.parse(F)}let Y=(await $.listEntities({entityType:C$,options:{limit:w.query?.limit??100}})).map((H)=>{let{entries:U}=this.adapter.parseBody(H.content),F=U[U.length-1];return{id:H.id,conversationId:H.metadata.conversationId,channelName:H.metadata.channelName??H.metadata.channelId,entryCount:U.length,messageCount:H.metadata.messageCount,latestEntry:F?.title??"No entries",updated:H.updated,created:H.created}}),X={summaries:Y,totalCount:Y.length};return Q.parse(X)}}KA();var ax2=J.object({role:J.enum(["user","assistant","system"]),content:J.string(),timestamp:J.string().datetime().optional()}),tx2=J.object({conversationId:J.string().default("eval-conversation"),messages:J.array(ax2)}),ex2=J.object({conversationId:J.string()});function wi0(A){let{context:Q,logger:B,config:w}=A;Q.eval.registerHandler("summarizeMessages",async($)=>{let D=tx2.parse($),I=D.messages.map((H,U)=>{let F=H.timestamp??new Date(Date.UTC(2026,0,1,0,U)).toISOString();return{id:`eval-message-${U+1}`,conversationId:D.conversationId,role:H.role,content:H.content,timestamp:F,metadata:{}}});return(await new oE(Q,B,w).extract(I)).map((H)=>({...H,keyPointsText:H.keyPoints.join(`
|
|
7215
7215
|
`),decisionsText:H.decisions.join(`
|
|
7216
7216
|
`),actionItemsText:H.actionItems.join(`
|
|
7217
|
-
`)}))}),Q.eval.registerHandler("projectConversation",async($)=>{let D=ex2.parse($);return new sE(Q,B,w).projectConversation(D.conversationId)})}var $i0={name:"@brains/summary",private:!0,version:"0.2.0-alpha.
|
|
7217
|
+
`)}))}),Q.eval.registerHandler("projectConversation",async($)=>{let D=ex2.parse($);return new sE(Q,B,w).projectConversation(D.conversationId)})}var $i0={name:"@brains/summary",private:!0,version:"0.2.0-alpha.54",description:"Plugin for deriving durable conversation summaries",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/conversation-service":"workspace:*","@brains/plugins":"workspace:*","@brains/templates":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*"},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 Qv2=new VJ,mzA=J.object({conversationId:J.string()});class uzA extends n2{entityType=C$;schema=Vx;adapter=Qv2;constructor(A={}){super(Ho,$i0,A,TzA)}getConfig(){return this.config}getTemplates(){return{"summary-list":Ai0,"summary-detail":Qi0,"ai-response":Bi0}}getDataSources(){return[new yzA(this.logger.child("SummaryDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableProjection)return[];return[{id:"summary-conversation-projection",targetType:C$,job:{type:od0,handler:new Uo(A,this.logger,this.config)},initialSync:{shouldEnqueue:async()=>!await oF(A,C$),jobData:{mode:"rebuild-all",reason:"initial-sync"},jobOptions:{source:xzA,deduplication:"coalesce",deduplicationKey:"summary:rebuild-all:initial-sync",metadata:{operationType:"data_processing",operationTarget:"summary:rebuild-all",pluginId:Ho}}},sourceChange:{sourceKind:Yg,sourceTypes:[Yg],shouldEnqueue:(Q)=>this.shouldEnqueueConversationProjection(A,Q),events:[kO],jobData:(Q)=>{return{mode:"conversation",conversationId:mzA.parse(Q).conversationId,reason:"message-added"}},jobOptions:(Q)=>{let B=mzA.parse(Q);return{priority:5,source:xzA,deduplication:"coalesce",deduplicationKey:`summary:${B.conversationId}`,metadata:{operationType:"data_processing",operationTarget:`summary:${B.conversationId}`,pluginId:Ho}}}}}]}async shouldEnqueueConversationProjection(A,Q){let B=mzA.parse(Q),w=await A.conversations.countMessages(B.conversationId);if(w===0)return!1;let $=null;try{$=await A.entityService.getEntity({entityType:C$,id:B.conversationId})}catch{$=null}if(!$)return w>=this.config.minMessagesBetweenProjections;let D=w-$.metadata.messageCount;if(D>=this.config.minMessagesBetweenProjections)return!0;if(D<=0)return!1;if(this.config.minMinutesBetweenProjections<=0)return!0;return Date.now()-Date.parse($.updated)>=this.config.minMinutesBetweenProjections*60000}async onRegister(A){wi0({context:A,logger:this.logger,config:this.config})}}function czA(A){return new uzA(A)}tA();KA();tA();var fW=J.object({title:J.string(),section:J.string(),order:J.number().int(),sourcePath:J.string(),description:J.string().optional(),slug:J.string().optional()}),Di0=fW.pick({title:!0,section:!0,order:!0,description:!0}).extend({slug:J.string()}),aE=r1.extend({entityType:J.literal("doc"),metadata:Di0}),LW=aE.extend({frontmatter:fW,body:J.string()});tA();KA();class lzA extends Q2{constructor(){super({entityType:"doc",schema:aE,frontmatterSchema:fW})}toMarkdown(A){let Q=this.extractBody(A.content),B=this.parseFrontMatter(A.content,fW);return this.buildMarkdown(Q,B)}fromMarkdown(A){let Q=this.parseFrontMatter(A,fW),B=Q.slug??t1(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 Fo=new lzA;tA();function Ii0(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 Yi0(A){let Q=M2(A.content,fW);return LW.parse({...A,frontmatter:Q.metadata,body:Q.content})}class Zo extends U6{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 Yi0(A)}async fetch(A,Q,B){let w=this.parseQuery(A);if(!w.query.id){let U=await this.fetchList({...w.query,limit:1000,page:void 0,pageSize:void 0},B.entityService);return Q.parse(this.buildListResult(U.items,null,w.query))}let[$,D]=await Promise.all([this.fetchDetail(w.query.id,B.entityService),this.fetchList({limit:1000},B.entityService)]),I=Ii0(D.items),Y=I.findIndex((U)=>U.id===$.item.id),X=Y>0?I[Y-1]:null,H=Y>=0&&Y<I.length-1?I[Y+1]:null;return Q.parse({doc:$.item,docs:I,prevDoc:X,nextDoc:H})}buildDetailResult(A,Q){return{doc:A,docs:[A],prevDoc:Q?.prev??null,nextDoc:Q?.next??null}}buildListResult(A,Q,B){return{docs:Ii0(A),pagination:Q,baseUrl:B.baseUrl}}}tA();Q8();KA();import{jsxDEV as E6}from"preact/jsx-dev-runtime";var Bv2=["I","II","III","IV","V","VI","VII","VIII","IX","X"];function bx(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 zo(A){let Q=new Map;for(let B of bx(A)){let w=B.metadata.section;Q.set(w,[...Q.get(w)??[],B])}return[...Q.entries()].map(([B,w])=>({section:B,docs:w}))}function tE(A){return`/docs/${A.metadata.slug}`}function qo(A){return`section-${A+1}`}function eE(A){return Bv2[A]??String(A+1)}var Ki0="text-[var(--docs-text)] font-bold",Wi0="text-[var(--docs-accent)] font-bold",Ui0="text-[var(--docs-text-muted)]",wv2="docs-font-label text-xs uppercase tracking-[0.18em] text-[var(--docs-accent)]",$v2="docs-font-display text-[var(--docs-heading)]",Xi0="inline-flex items-center justify-center rounded-lg border px-[18px] py-2.5 text-sm font-semibold transition-colors duration-150",Hi0="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",pzA="docs-font-label text-[13px] text-[var(--docs-text-light)] transition-colors duration-150 hover:text-[var(--docs-text)]",QH={wrap:"mx-auto max-w-6xl px-6 pt-20 md:px-12 md:pt-24",label:wv2,display:$v2,button:`${Xi0} border-[var(--docs-text)] text-[var(--docs-text)] hover:border-[var(--docs-accent)] hover:text-[var(--docs-accent)]`,primaryButton:`${Xi0} border-[var(--docs-accent)] bg-[var(--docs-accent)] text-white hover:bg-transparent hover:text-[var(--docs-accent)]`},Gi0=()=>E6("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:[E6("a",{href:"/docs",className:"docs-font-body text-xl font-bold","aria-label":"Brains docs",children:[E6("span",{className:Ki0,children:"brains"},void 0,!1,void 0,this),E6("span",{className:Wi0,children:"."},void 0,!1,void 0,this),E6("span",{className:Ui0,children:"docs"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),E6("div",{className:"docs-header__nav flex items-center gap-4 md:gap-8",children:[E6("a",{className:Hi0,href:"/docs/roadmap",children:"Roadmap"},void 0,!1,void 0,this),E6("a",{className:Hi0,href:"https://github.com/rizom-ai/brains",children:"GitHub"},void 0,!1,void 0,this),E6("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),Ji0=()=>E6("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:[E6("a",{href:"https://rizom.ai",className:"docs-font-body text-[15px] font-bold",children:[E6("span",{className:Ki0,children:"rizom"},void 0,!1,void 0,this),E6("span",{className:Wi0,children:"."},void 0,!1,void 0,this),E6("span",{className:Ui0,children:"ai"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),E6("div",{className:"flex flex-wrap items-center justify-center gap-6 md:justify-end",children:[E6("a",{className:pzA,href:"/docs/roadmap",children:"Roadmap"},void 0,!1,void 0,this),E6("a",{className:pzA,href:"https://github.com/rizom-ai/brains",children:"GitHub"},void 0,!1,void 0,this),E6("a",{className:pzA,href:"https://rizom.ai",children:"Rizom"},void 0,!1,void 0,this),E6("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),Dv2=`
|
|
7218
7218
|
.docs-handbook {
|
|
7219
7219
|
--docs-bg: var(--color-bg, #0d0a1a);
|
|
7220
7220
|
--docs-bg-card: var(--color-bg-card, #1a0a3e);
|
|
@@ -7366,7 +7366,7 @@ Return only the required structured JSON.`});KA();var sx2=J.object({entityType:J
|
|
|
7366
7366
|
background: transparent;
|
|
7367
7367
|
}
|
|
7368
7368
|
|
|
7369
|
-
`,Fi0=()=>E6("style",{children:Dv2},void 0,!1,void 0,this);import{jsxDEV as p1,Fragment as Iv2}from"preact/jsx-dev-runtime";var No=({title:A,description:Q,children:B,detail:w=!1,footer:$=!1,contentClassName:D=""})=>p1(Iv2,{children:[p1(u2,{title:A,description:Q},void 0,!1,void 0,this),p1(Fi0,{},void 0,!1,void 0,this),p1("div",{className:`docs-handbook${w?" docs-handbook--detail":""}`,children:[p1(Gi0,{},void 0,!1,void 0,this),p1("div",{className:`${QH.wrap} ${D}`.trim(),children:[B,$&&p1(Ji0,{},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Zi0=({docsCount:A,sectionsCount:Q,startDoc:B})=>p1("section",{className:"border-b border-[var(--docs-text)] py-14 md:py-24 md:pb-[72px]",children:[p1("p",{className:`${QH.label} mb-8`,children:"Handbook \xB7 Brains docs"},void 0,!1,void 0,this),p1("h1",{className:`${QH.display} m-0 max-w-[16ch] text-5xl leading-[1.05] tracking-[-0.02em] md:text-7xl`,children:["Build, run, and publish"," ",p1("em",{className:"text-[var(--docs-accent)]",children:"brains."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),p1("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),p1("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:[p1("div",{children:[p1("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),p1("div",{children:[p1("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),p1("div",{children:[p1("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),p1("div",{className:"mt-9 flex flex-wrap gap-3.5",children:[B&&p1("a",{className:QH.primaryButton,href:tE(B),children:"Start reading"},void 0,!1,void 0,this),p1("a",{className:QH.button,href:"#sections",children:"Browse sections"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),zi0=({groups:A})=>p1("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:[p1("p",{className:"m-0 mb-3.5 font-medium text-[var(--docs-text)]",children:"Sections"},void 0,!1,void 0,this),p1("ol",{className:"m-0 list-none p-0",children:A.map((Q,B)=>p1("li",{className:"grid grid-cols-[32px_1fr] gap-2 py-1.5",children:[p1("span",{className:"docs-font-display text-[var(--docs-text-light)] italic",children:[eE(B),"."]},void 0,!0,void 0,this),p1("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:`#${qo(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),qi0=({group:A,index:Q})=>p1("article",{className:"mb-16 last:mb-0",id:qo(Q),children:[p1("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:[p1("span",{className:"text-right docs-font-display text-3xl leading-[1.1] text-[var(--docs-accent)] italic md:text-4xl",children:[eE(Q),"."]},void 0,!0,void 0,this),p1("h2",{className:`${QH.display} m-0 text-3xl leading-[1.1] tracking-[-0.015em] md:text-4xl`,children:A.section},void 0,!1,void 0,this),p1("span",{className:"docs-chapter__leader"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),p1("ol",{className:"m-0 list-none p-0",children:A.docs.map((B)=>p1("li",{className:"border-b border-[var(--docs-border-light)] last:border-b-0",children:p1("a",{className:"group block py-[18px] pl-12 md:pl-[68px]",href:tE(B),children:[p1("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&&p1("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),Ni0=({title:A})=>p1("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:[p1("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/",children:"Home"},void 0,!1,void 0,this),p1("span",{children:"/"},void 0,!1,void 0,this),p1("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/docs",children:"Docs"},void 0,!1,void 0,this),p1("span",{children:"/"},void 0,!1,void 0,this),p1("span",{children:A},void 0,!1,void 0,this)]},void 0,!0,void 0,this),fi0=({groups:A,activeGroupIndex:Q,activeSlug:B})=>p1("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:p1("nav",{className:"docs-font-label text-xs tracking-[0.06em] text-[var(--docs-text-light)]",children:[p1("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),p1("ol",{className:"m-0 list-none p-0",children:A.map((w,$)=>{let D=$===Q;return p1("li",{className:D?"mb-[22px]":"mb-3.5",children:[p1("a",{className:`mb-2 flex items-baseline gap-2.5 docs-font-label text-[11px] uppercase leading-[1.4] tracking-[0.06em] transition-colors duration-150 hover:text-[var(--docs-text)] ${D?"text-[var(--docs-text)]":"text-[var(--docs-text-muted)]"}`,href:`/docs#${qo($)}`,children:[p1("span",{className:"docs-font-display text-sm text-[var(--docs-accent)] italic",children:[eE($),"."]},void 0,!0,void 0,this)," ",w.section]},void 0,!0,void 0,this),D&&p1("ol",{className:"mt-0.5 list-none p-0",children:w.docs.map((I)=>{let Y=I.metadata.slug===B;return p1("li",{children:p1("a",{className:`docs-rail__doc relative block py-1.5 docs-font-body text-sm leading-[1.4] tracking-normal transition-[color,padding-left] duration-150 hover:text-[var(--docs-text)] ${Y?"pl-3.5 font-medium text-[var(--docs-accent)]":"text-[var(--docs-text-muted)]"}`,href:tE(I),"aria-current":Y?"page":void 0,children:I.metadata.title},void 0,!1,void 0,this)},I.id,!1,void 0,this)})},void 0,!1,void 0,this)]},w.section,!0,void 0,this)})},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Li0=({prevDoc:A,nextDoc:Q})=>{if(!A&&!Q)return null;return p1("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?p1("a",{className:"group border-t border-[var(--docs-border-light)] pt-[18px] transition-colors duration-150 hover:border-[var(--docs-accent)]",href:tE(A),children:[p1("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),p1("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):p1("span",{},void 0,!1,void 0,this),Q&&p1("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:tE(Q),children:[p1("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),p1("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 AM}from"preact/jsx-dev-runtime";var dzA=({docs:A})=>{let Q=bx(A),B=zo(Q),$=Q.filter((D)=>D.metadata.slug!=="index")[0]??Q[0];return AM(No,{title:"Documentation",description:"Brains documentation",children:[AM(Zi0,{docsCount:A.length,sectionsCount:B.length,startDoc:$},void 0,!1,void 0,this),AM("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:[AM(zi0,{groups:B},void 0,!1,void 0,this),AM("div",{children:B.map((D,I)=>AM(qi0,{group:D,index:I},D.section,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as fD}from"preact/jsx-dev-runtime";var izA=({doc:A,docs:Q,prevDoc:B,nextDoc:w})=>{let $=zo(Q.length>0?Q:[A]),D=bx(Q.length>0?Q:[A]),I=D.findIndex((X)=>X.metadata.slug===A.metadata.slug),Y=Math.max($.findIndex((X)=>X.docs.some((H)=>H.metadata.slug===A.metadata.slug)),0);return fD(No,{title:A.metadata.title,description:A.metadata.description??A.metadata.section,detail:!0,footer:!0,contentClassName:"pt-16",children:[fD(Ni0,{title:A.metadata.title},void 0,!1,void 0,this),fD("div",{className:"grid items-start gap-10 py-8 pb-24 md:grid-cols-[240px_minmax(0,1fr)] md:gap-20",children:[fD(fi0,{groups:$,activeGroupIndex:Y,activeSlug:A.metadata.slug},void 0,!1,void 0,this),fD("article",{className:"min-w-0",children:[fD("header",{className:"mb-10 border-b border-[var(--docs-border)] pb-8",children:[fD("p",{className:`${QH.label} m-0 mb-6 flex items-baseline gap-3`,children:[fD("span",{className:"docs-font-display text-lg leading-none tracking-normal normal-case text-[var(--docs-accent)] italic",children:[eE(Y),"."]},void 0,!0,void 0,this)," ",A.metadata.section,I>=0?` \xB7 ${I+1}/${D.length}`:""]},void 0,!0,void 0,this),fD("h1",{className:`${QH.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&&fD("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),fD("div",{className:"docs-article__body",children:fD(GD,{markdown:A.body},void 0,!1,void 0,this)},void 0,!1,void 0,this),fD(Li0,{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 Yv2=J.object({docs:J.array(LW),pagination:K9.nullable(),baseUrl:J.string().optional()}),Xv2=J.object({doc:LW,docs:J.array(LW),prevDoc:LW.nullable(),nextDoc:LW.nullable()});function Ci0(){return{"doc-list":G1({name:"doc-list",description:"Documentation index template",schema:Yv2,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:dzA}}),"doc-detail":G1({name:"doc-detail",description:"Documentation page template",schema:Xv2,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:izA}})}}var Ei0={name:"@brains/doc",private:!0,version:"0.2.0-alpha.53",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 rzA extends n2{entityType=Fo.entityType;schema=aE;adapter=Fo;constructor(){super("docs",Ei0,{},void 0)}getTemplates(){return Ci0()}getDataSources(){return[new Zo(this.logger.child("DocDataSource"))]}}function nzA(){return new rzA}var Mi0=["prompt","directory-sync","note","link","topics","summary","agents","assessment","cms","dashboard","mcp","webserver","discord","a2a"],Vi0=[...Mi0,"image","site-info","site-content","site-builder"],Wv2=[...Vi0,"docs","decks"],Uv2=["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; "handbook", "doc", "documentation" \u2192 entityType: doc; "deck", "walkthrough", "presentation" \u2192 entityType: deck; "agent", "peer brain", "contact" \u2192 entityType: agent.'],Oi0=QG({name:"relay",version:"0.1.0",model:"gpt-5.4-mini",site:MJ,theme:rE,presets:{core:Mi0,default:Vi0,full:Wv2},evalDisable:["webserver","mcp","discord"],agentInstructions:Uv2,capabilities:[["prompt",bz,void 0],["note",Lz,{}],["link",Ez,{}],["image",sb,void 0],["topics",An,{includeEntityTypes:["base","link","summary","agent","skill","swot","deck","doc","anchor-profile","brain-character"],extractableStatuses:["published","draft"]}],["summary",czA,{}],["docs",nzA,void 0],["decks",y_,void 0],["agents",vn,void 0],["assessment",pn,void 0],["cms",Oz,{}],["dashboard",LJ,void 0],["directory-sync",h3,{seedContent:!0,seedContentPath:Kv2(import.meta.dir,"..","seed-content"),initialSync:!0}],["site-content",Cx,void 0],["rizom-ecosystem",Pz,void 0],["site-info",qz,void 0],["site-builder",zz,{}]],interfaces:[["mcp",XG,()=>({})],["discord",lG,()=>({captureUrls:!0})],["a2a",qC,()=>({})],["webserver",pG,()=>({})]],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 Pg2}from"fs";import{join as kg2}from"path";import{execSync as jg2}from"child_process";import{parseArgs as Fv2}from"util";var Zv2={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"},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 jz(A,Q){let B=A[Q];return typeof B==="boolean"?B:void 0}function Ri0(A){let{values:Q,positionals:B}=Fv2({args:A,options:Zv2,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":jz(Q,"no-interactive"),preview:jz(Q,"preview"),deploy:jz(Q,"deploy"),regen:jz(Q,"regen"),all:jz(Q,"all"),only:CW(Q,"only"),"dry-run":jz(Q,"dry-run"),"startup-check":jz(Q,"startup-check"),remote:CW(Q,"remote"),token:CW(Q,"token")}}}Px();import{mkdirSync as Ng2}from"fs";import{join as fg2}from"path";import{execSync as Lg2}from"child_process";var Lo={name:"@rizom/brain",version:"0.2.0-alpha.53",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/deploy-templates":"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 ci0,writeFileSync as jx,chmodSync as _x,existsSync as BqA,readFileSync as wqA}from"fs";import{basename as $qA,dirname as DqA,join as rw,resolve as mv2}from"path";import{fileURLToPath as uv2}from"url";var bi0=`ARG BUN_VERSION=1.3.10
|
|
7369
|
+
`,Fi0=()=>E6("style",{children:Dv2},void 0,!1,void 0,this);import{jsxDEV as p1,Fragment as Iv2}from"preact/jsx-dev-runtime";var No=({title:A,description:Q,children:B,detail:w=!1,footer:$=!1,contentClassName:D=""})=>p1(Iv2,{children:[p1(u2,{title:A,description:Q},void 0,!1,void 0,this),p1(Fi0,{},void 0,!1,void 0,this),p1("div",{className:`docs-handbook${w?" docs-handbook--detail":""}`,children:[p1(Gi0,{},void 0,!1,void 0,this),p1("div",{className:`${QH.wrap} ${D}`.trim(),children:[B,$&&p1(Ji0,{},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Zi0=({docsCount:A,sectionsCount:Q,startDoc:B})=>p1("section",{className:"border-b border-[var(--docs-text)] py-14 md:py-24 md:pb-[72px]",children:[p1("p",{className:`${QH.label} mb-8`,children:"Handbook \xB7 Brains docs"},void 0,!1,void 0,this),p1("h1",{className:`${QH.display} m-0 max-w-[16ch] text-5xl leading-[1.05] tracking-[-0.02em] md:text-7xl`,children:["Build, run, and publish"," ",p1("em",{className:"text-[var(--docs-accent)]",children:"brains."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),p1("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),p1("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:[p1("div",{children:[p1("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),p1("div",{children:[p1("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),p1("div",{children:[p1("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),p1("div",{className:"mt-9 flex flex-wrap gap-3.5",children:[B&&p1("a",{className:QH.primaryButton,href:tE(B),children:"Start reading"},void 0,!1,void 0,this),p1("a",{className:QH.button,href:"#sections",children:"Browse sections"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),zi0=({groups:A})=>p1("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:[p1("p",{className:"m-0 mb-3.5 font-medium text-[var(--docs-text)]",children:"Sections"},void 0,!1,void 0,this),p1("ol",{className:"m-0 list-none p-0",children:A.map((Q,B)=>p1("li",{className:"grid grid-cols-[32px_1fr] gap-2 py-1.5",children:[p1("span",{className:"docs-font-display text-[var(--docs-text-light)] italic",children:[eE(B),"."]},void 0,!0,void 0,this),p1("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:`#${qo(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),qi0=({group:A,index:Q})=>p1("article",{className:"mb-16 last:mb-0",id:qo(Q),children:[p1("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:[p1("span",{className:"text-right docs-font-display text-3xl leading-[1.1] text-[var(--docs-accent)] italic md:text-4xl",children:[eE(Q),"."]},void 0,!0,void 0,this),p1("h2",{className:`${QH.display} m-0 text-3xl leading-[1.1] tracking-[-0.015em] md:text-4xl`,children:A.section},void 0,!1,void 0,this),p1("span",{className:"docs-chapter__leader"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),p1("ol",{className:"m-0 list-none p-0",children:A.docs.map((B)=>p1("li",{className:"border-b border-[var(--docs-border-light)] last:border-b-0",children:p1("a",{className:"group block py-[18px] pl-12 md:pl-[68px]",href:tE(B),children:[p1("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&&p1("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),Ni0=({title:A})=>p1("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:[p1("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/",children:"Home"},void 0,!1,void 0,this),p1("span",{children:"/"},void 0,!1,void 0,this),p1("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/docs",children:"Docs"},void 0,!1,void 0,this),p1("span",{children:"/"},void 0,!1,void 0,this),p1("span",{children:A},void 0,!1,void 0,this)]},void 0,!0,void 0,this),fi0=({groups:A,activeGroupIndex:Q,activeSlug:B})=>p1("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:p1("nav",{className:"docs-font-label text-xs tracking-[0.06em] text-[var(--docs-text-light)]",children:[p1("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),p1("ol",{className:"m-0 list-none p-0",children:A.map((w,$)=>{let D=$===Q;return p1("li",{className:D?"mb-[22px]":"mb-3.5",children:[p1("a",{className:`mb-2 flex items-baseline gap-2.5 docs-font-label text-[11px] uppercase leading-[1.4] tracking-[0.06em] transition-colors duration-150 hover:text-[var(--docs-text)] ${D?"text-[var(--docs-text)]":"text-[var(--docs-text-muted)]"}`,href:`/docs#${qo($)}`,children:[p1("span",{className:"docs-font-display text-sm text-[var(--docs-accent)] italic",children:[eE($),"."]},void 0,!0,void 0,this)," ",w.section]},void 0,!0,void 0,this),D&&p1("ol",{className:"mt-0.5 list-none p-0",children:w.docs.map((I)=>{let Y=I.metadata.slug===B;return p1("li",{children:p1("a",{className:`docs-rail__doc relative block py-1.5 docs-font-body text-sm leading-[1.4] tracking-normal transition-[color,padding-left] duration-150 hover:text-[var(--docs-text)] ${Y?"pl-3.5 font-medium text-[var(--docs-accent)]":"text-[var(--docs-text-muted)]"}`,href:tE(I),"aria-current":Y?"page":void 0,children:I.metadata.title},void 0,!1,void 0,this)},I.id,!1,void 0,this)})},void 0,!1,void 0,this)]},w.section,!0,void 0,this)})},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Li0=({prevDoc:A,nextDoc:Q})=>{if(!A&&!Q)return null;return p1("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?p1("a",{className:"group border-t border-[var(--docs-border-light)] pt-[18px] transition-colors duration-150 hover:border-[var(--docs-accent)]",href:tE(A),children:[p1("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),p1("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):p1("span",{},void 0,!1,void 0,this),Q&&p1("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:tE(Q),children:[p1("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),p1("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 AM}from"preact/jsx-dev-runtime";var dzA=({docs:A})=>{let Q=bx(A),B=zo(Q),$=Q.filter((D)=>D.metadata.slug!=="index")[0]??Q[0];return AM(No,{title:"Documentation",description:"Brains documentation",children:[AM(Zi0,{docsCount:A.length,sectionsCount:B.length,startDoc:$},void 0,!1,void 0,this),AM("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:[AM(zi0,{groups:B},void 0,!1,void 0,this),AM("div",{children:B.map((D,I)=>AM(qi0,{group:D,index:I},D.section,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as fD}from"preact/jsx-dev-runtime";var izA=({doc:A,docs:Q,prevDoc:B,nextDoc:w})=>{let $=zo(Q.length>0?Q:[A]),D=bx(Q.length>0?Q:[A]),I=D.findIndex((X)=>X.metadata.slug===A.metadata.slug),Y=Math.max($.findIndex((X)=>X.docs.some((H)=>H.metadata.slug===A.metadata.slug)),0);return fD(No,{title:A.metadata.title,description:A.metadata.description??A.metadata.section,detail:!0,footer:!0,contentClassName:"pt-16",children:[fD(Ni0,{title:A.metadata.title},void 0,!1,void 0,this),fD("div",{className:"grid items-start gap-10 py-8 pb-24 md:grid-cols-[240px_minmax(0,1fr)] md:gap-20",children:[fD(fi0,{groups:$,activeGroupIndex:Y,activeSlug:A.metadata.slug},void 0,!1,void 0,this),fD("article",{className:"min-w-0",children:[fD("header",{className:"mb-10 border-b border-[var(--docs-border)] pb-8",children:[fD("p",{className:`${QH.label} m-0 mb-6 flex items-baseline gap-3`,children:[fD("span",{className:"docs-font-display text-lg leading-none tracking-normal normal-case text-[var(--docs-accent)] italic",children:[eE(Y),"."]},void 0,!0,void 0,this)," ",A.metadata.section,I>=0?` \xB7 ${I+1}/${D.length}`:""]},void 0,!0,void 0,this),fD("h1",{className:`${QH.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&&fD("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),fD("div",{className:"docs-article__body",children:fD(GD,{markdown:A.body},void 0,!1,void 0,this)},void 0,!1,void 0,this),fD(Li0,{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 Yv2=J.object({docs:J.array(LW),pagination:K9.nullable(),baseUrl:J.string().optional()}),Xv2=J.object({doc:LW,docs:J.array(LW),prevDoc:LW.nullable(),nextDoc:LW.nullable()});function Ci0(){return{"doc-list":G1({name:"doc-list",description:"Documentation index template",schema:Yv2,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:dzA}}),"doc-detail":G1({name:"doc-detail",description:"Documentation page template",schema:Xv2,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:izA}})}}var Ei0={name:"@brains/doc",private:!0,version:"0.2.0-alpha.54",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 rzA extends n2{entityType=Fo.entityType;schema=aE;adapter=Fo;constructor(){super("docs",Ei0,{},void 0)}getTemplates(){return Ci0()}getDataSources(){return[new Zo(this.logger.child("DocDataSource"))]}}function nzA(){return new rzA}var Mi0=["prompt","directory-sync","note","link","topics","summary","agents","assessment","cms","dashboard","mcp","webserver","discord","a2a"],Vi0=[...Mi0,"image","site-info","site-content","site-builder"],Wv2=[...Vi0,"docs","decks"],Uv2=["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; "handbook", "doc", "documentation" \u2192 entityType: doc; "deck", "walkthrough", "presentation" \u2192 entityType: deck; "agent", "peer brain", "contact" \u2192 entityType: agent.'],Oi0=QG({name:"relay",version:"0.1.0",model:"gpt-5.4-mini",site:MJ,theme:rE,presets:{core:Mi0,default:Vi0,full:Wv2},evalDisable:["webserver","mcp","discord"],agentInstructions:Uv2,capabilities:[["prompt",bz,void 0],["note",Lz,{}],["link",Ez,{}],["image",sb,void 0],["topics",An,{includeEntityTypes:["base","link","summary","agent","skill","swot","deck","doc","anchor-profile","brain-character"],extractableStatuses:["published","draft"]}],["summary",czA,{}],["docs",nzA,void 0],["decks",y_,void 0],["agents",vn,void 0],["assessment",pn,void 0],["cms",Oz,{}],["dashboard",LJ,void 0],["directory-sync",h3,{seedContent:!0,seedContentPath:Kv2(import.meta.dir,"..","seed-content"),initialSync:!0}],["site-content",Cx,void 0],["rizom-ecosystem",Pz,void 0],["site-info",qz,void 0],["site-builder",zz,{}]],interfaces:[["mcp",XG,()=>({})],["discord",lG,()=>({captureUrls:!0})],["a2a",qC,()=>({})],["webserver",pG,()=>({})]],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 Pg2}from"fs";import{join as kg2}from"path";import{execSync as jg2}from"child_process";import{parseArgs as Fv2}from"util";var Zv2={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"},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 jz(A,Q){let B=A[Q];return typeof B==="boolean"?B:void 0}function Ri0(A){let{values:Q,positionals:B}=Fv2({args:A,options:Zv2,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":jz(Q,"no-interactive"),preview:jz(Q,"preview"),deploy:jz(Q,"deploy"),regen:jz(Q,"regen"),all:jz(Q,"all"),only:CW(Q,"only"),"dry-run":jz(Q,"dry-run"),"startup-check":jz(Q,"startup-check"),remote:CW(Q,"remote"),token:CW(Q,"token")}}}Px();import{mkdirSync as Ng2}from"fs";import{join as fg2}from"path";import{execSync as Lg2}from"child_process";var Lo={name:"@rizom/brain",version:"0.2.0-alpha.54",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/deploy-templates":"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 ci0,writeFileSync as jx,chmodSync as _x,existsSync as BqA,readFileSync as wqA}from"fs";import{basename as $qA,dirname as DqA,join as rw,resolve as mv2}from"path";import{fileURLToPath as uv2}from"url";var bi0=`ARG BUN_VERSION=1.3.10
|
|
7370
7370
|
FROM oven/bun:\${BUN_VERSION}-slim AS runtime
|
|
7371
7371
|
|
|
7372
7372
|
WORKDIR /app
|