@rizom/brain 0.2.0-alpha.70 → 0.2.0-alpha.71
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/brain.js +31 -31
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/plugins.d.ts +49 -49
- package/dist/site.js +5 -5
- package/dist/site.js.map +3 -3
- package/package.json +1 -1
package/dist/brain.js
CHANGED
|
@@ -491,7 +491,7 @@ ${G}`,args:{...$,...D,id:I.id,confirmed:!0,contentHash:I.contentHash}}},{visibil
|
|
|
491
491
|
hash text NOT NULL,
|
|
492
492
|
created_at numeric
|
|
493
493
|
)
|
|
494
|
-
`;await A.session.run($);let I=(await A.values(hA`SELECT id, hash, created_at FROM ${hA.identifier(w)} ORDER BY created_at DESC LIMIT 1`))[0]??void 0,D=[];for(let H of B)if(!I||Number(I[2])<H.folderMillis){for(let Y of H.sql)D.push(A.run(hA.raw(Y)));D.push(A.run(hA`INSERT INTO ${hA.identifier(w)} ("hash", "created_at") VALUES(${H.hash}, ${H.folderMillis})`))}await A.session.migrate(D)}var Qd=p(()=>{aw0();z5()});async function tw0(A,Q){let B=Q?.child("entity-migrate")??wQ.getInstance().child("entity-migrate"),{db:w,client:$,url:f}=El(A);B.debug("Running entity database migrations...");try{await Ml($,f);let D=import.meta.url.includes("/dist/")?new URL("./migrations/entity-service",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await oM(w,{migrationsFolder:D}),await Vl($),B.debug("Entity database migrations completed successfully")}catch(I){throw B.error("Entity database migration failed:",I),I}finally{$.close()}}var ew0=p(()=>{Qd();q$A();GA()});async function A80(A,Q){let B=Q?.child("job-queue-migrate")??wQ.getInstance().child("job-queue-migrate"),{db:w,client:$,url:f}=ql(A);B.debug("Running job queue migrations...");try{await Cl($,f);let D=import.meta.url.includes("/dist/")?new URL("./migrations/job-queue",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await oM(w,{migrationsFolder:D}),B.debug("Job queue migrations completed successfully")}catch(I){throw B.error("Job queue migration failed:",I),I}finally{$.close()}}var Q80=p(()=>{Qd();Y$A();GA()});async function B80(A,Q){let B=Q?.child("conversation-migrate")??wQ.getInstance().child("conversation-migrate"),{db:w,client:$,url:f}=hl(A);B.debug("Running conversation database migrations...");try{if(f.startsWith("file:"))await $.execute("PRAGMA journal_mode = WAL");let D=import.meta.url.includes("/dist/")?new URL("./migrations/conversation-service",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await oM(w,{migrationsFolder:D}),B.debug("Conversation database migrations completed successfully")}catch(I){throw B.error("Conversation database migration failed:",I),I}finally{$.close()}}var w80=p(()=>{Qd();A9A();GA()});class mv{logger;migrations;constructor(A,Q){this.logger=A,this.migrations=Q??{getStandardConfigWithDirectories:Jj,migrateEntities:tw0,migrateJobQueue:A80,migrateConversations:B80}}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 $XA=p(()=>{er();ew0();Q80();w80()});var Bd;var fXA=p(()=>{GA();Bd=F.object({theme:F.object({primaryColor:F.string().describe("Primary color for the CLI theme").default("#0066cc"),accentColor:F.string().describe("Accent color for the CLI theme").default("#ff6600")}).describe("Theme configuration for the CLI interface").default({primaryColor:"#0066cc",accentColor:"#ff6600"})})});var f80;var $80=p(()=>{f80={name:"@brains/chat-repl",private:!0,version:"0.2.0-alpha.70",type:"module",main:"./src/index.ts",module:"./src/index.ts",types:"./src/index.ts",files:["src"],scripts:{dev:"tsc --watch",typecheck:"tsc --noEmit",lint:"eslint --max-warnings 0 .","lint:fix":"eslint --fix .",test:"bun test"},dependencies:{"@brains/plugins":"workspace:*",chalk:"^5.4.1",ink:"^6.0.1","ink-spinner":"^5.0.0","ink-text-input":"^6.0.0",marked:"^12.0.0",react:"^19.1.0"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14","@types/react":"^19.0.3",typescript:"^5.3.3"}}});var uQ=v((Cg1,wd)=>{(function(){function A(QA,FA){Object.defineProperty(w.prototype,QA,{get:function(){console.warn("%s(...) is deprecated in plain JavaScript React classes. %s",FA[0],FA[1])}})}function Q(QA){if(QA===null||typeof QA!=="object")return null;return QA=aA&&QA[aA]||QA["@@iterator"],typeof QA==="function"?QA:null}function B(QA,FA){QA=(QA=QA.constructor)&&(QA.displayName||QA.name)||"ReactClass";var cA=QA+"."+FA;ZA[cA]||(console.error("Can't call %s on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign to `this.state` directly or define a `state = {};` class property with the desired state in the %s component.",FA,QA),ZA[cA]=!0)}function w(QA,FA,cA){this.props=QA,this.context=FA,this.refs=uA,this.updater=cA||VA}function $(){}function f(QA,FA,cA){this.props=QA,this.context=FA,this.refs=uA,this.updater=cA||VA}function I(){}function D(QA){return""+QA}function H(QA){try{D(QA);var FA=!1}catch(I0){FA=!0}if(FA){FA=console;var cA=FA.error,w0=typeof Symbol==="function"&&Symbol.toStringTag&&QA[Symbol.toStringTag]||QA.constructor.name||"Object";return cA.call(FA,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",w0),D(QA)}}function Y(QA){if(QA==null)return null;if(typeof QA==="function")return QA.$$typeof===X0?null:QA.displayName||QA.name||null;if(typeof QA==="string")return QA;switch(QA){case BA:return"Fragment";case UA:return"Profiler";case n:return"StrictMode";case K0:return"Suspense";case qA:return"SuspenseList";case EA:return"Activity"}if(typeof QA==="object")switch(typeof QA.tag==="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),QA.$$typeof){case d:return"Portal";case XA:return QA.displayName||"Context";case MA:return(QA._context.displayName||"Context")+".Consumer";case q0:var FA=QA.render;return QA=QA.displayName,QA||(QA=FA.displayName||FA.name||"",QA=QA!==""?"ForwardRef("+QA+")":"ForwardRef"),QA;case g0:return FA=QA.displayName||null,FA!==null?FA:Y(QA.type)||"Memo";case N0:FA=QA._payload,QA=QA._init;try{return Y(QA(FA))}catch(cA){}}return null}function W(QA){if(QA===BA)return"<>";if(typeof QA==="object"&&QA!==null&&QA.$$typeof===N0)return"<...>";try{var FA=Y(QA);return FA?"<"+FA+">":"<...>"}catch(cA){return"<...>"}}function G(){var QA=B0.A;return QA===null?null:QA.getOwner()}function K(){return Error("react-stack-top-frame")}function Z(QA){if(OA.call(QA,"key")){var FA=Object.getOwnPropertyDescriptor(QA,"key").get;if(FA&&FA.isReactWarning)return!1}return QA.key!==void 0}function q(QA,FA){function cA(){wA||(wA=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",FA))}cA.isReactWarning=!0,Object.defineProperty(QA,"key",{get:cA,configurable:!0})}function L(){var QA=Y(this.type);return A1[QA]||(A1[QA]=!0,console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.")),QA=this.props.ref,QA!==void 0?QA:null}function C(QA,FA,cA,w0,I0,b0){var eA=cA.ref;return QA={$$typeof:t,type:QA,key:FA,props:cA,_owner:w0},(eA!==void 0?eA:null)!==null?Object.defineProperty(QA,"ref",{enumerable:!1,get:L}):Object.defineProperty(QA,"ref",{enumerable:!1,value:null}),QA._store={},Object.defineProperty(QA._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(QA,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(QA,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:I0}),Object.defineProperty(QA,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:b0}),Object.freeze&&(Object.freeze(QA.props),Object.freeze(QA)),QA}function R(QA,FA){return FA=C(QA.type,FA,QA.props,QA._owner,QA._debugStack,QA._debugTask),QA._store&&(FA._store.validated=QA._store.validated),FA}function k(QA){_(QA)?QA._store&&(QA._store.validated=1):typeof QA==="object"&&QA!==null&&QA.$$typeof===N0&&(QA._payload.status==="fulfilled"?_(QA._payload.value)&&QA._payload.value._store&&(QA._payload.value._store.validated=1):QA._store&&(QA._store.validated=1))}function _(QA){return typeof QA==="object"&&QA!==null&&QA.$$typeof===t}function o(QA){var FA={"=":"=0",":":"=2"};return"$"+QA.replace(/[=:]/g,function(cA){return FA[cA]})}function r(QA,FA){return typeof QA==="object"&&QA!==null&&QA.key!=null?(H(QA.key),o(""+QA.key)):FA.toString(36)}function S(QA){switch(QA.status){case"fulfilled":return QA.value;case"rejected":throw QA.reason;default:switch(typeof QA.status==="string"?QA.then(I,I):(QA.status="pending",QA.then(function(FA){QA.status==="pending"&&(QA.status="fulfilled",QA.value=FA)},function(FA){QA.status==="pending"&&(QA.status="rejected",QA.reason=FA)})),QA.status){case"fulfilled":return QA.value;case"rejected":throw QA.reason}}throw QA}function x(QA,FA,cA,w0,I0){var b0=typeof QA;if(b0==="undefined"||b0==="boolean")QA=null;var eA=!1;if(QA===null)eA=!0;else switch(b0){case"bigint":case"string":case"number":eA=!0;break;case"object":switch(QA.$$typeof){case t:case d:eA=!0;break;case N0:return eA=QA._init,x(eA(QA._payload),FA,cA,w0,I0)}}if(eA){eA=QA,I0=I0(eA);var t0=w0===""?"."+r(eA,0):w0;return z0(I0)?(cA="",t0!=null&&(cA=t0.replace(gA,"$&/")+"/"),x(I0,FA,cA,"",function(S1){return S1})):I0!=null&&(_(I0)&&(I0.key!=null&&(eA&&eA.key===I0.key||H(I0.key)),cA=R(I0,cA+(I0.key==null||eA&&eA.key===I0.key?"":(""+I0.key).replace(gA,"$&/")+"/")+t0),w0!==""&&eA!=null&&_(eA)&&eA.key==null&&eA._store&&!eA._store.validated&&(cA._store.validated=2),I0=cA),FA.push(I0)),1}if(eA=0,t0=w0===""?".":w0+":",z0(QA))for(var Q1=0;Q1<QA.length;Q1++)w0=QA[Q1],b0=t0+r(w0,Q1),eA+=x(w0,FA,cA,b0,I0);else if(Q1=Q(QA),typeof Q1==="function")for(Q1===QA.entries&&(TA||console.warn("Using Maps as children is not supported. Use an array of keyed ReactElements instead."),TA=!0),QA=Q1.call(QA),Q1=0;!(w0=QA.next()).done;)w0=w0.value,b0=t0+r(w0,Q1++),eA+=x(w0,FA,cA,b0,I0);else if(b0==="object"){if(typeof QA.then==="function")return x(S(QA),FA,cA,w0,I0);throw FA=String(QA),Error("Objects are not valid as a React child (found: "+(FA==="[object Object]"?"object with keys {"+Object.keys(QA).join(", ")+"}":FA)+"). If you meant to render a collection of children, use an array instead.")}return eA}function y(QA,FA,cA){if(QA==null)return QA;var w0=[],I0=0;return x(QA,w0,"","",function(b0){return FA.call(cA,b0,I0++)}),w0}function g(QA){if(QA._status===-1){var FA=QA._ioInfo;FA!=null&&(FA.start=FA.end=performance.now()),FA=QA._result;var cA=FA();if(cA.then(function(I0){if(QA._status===0||QA._status===-1){QA._status=1,QA._result=I0;var b0=QA._ioInfo;b0!=null&&(b0.end=performance.now()),cA.status===void 0&&(cA.status="fulfilled",cA.value=I0)}},function(I0){if(QA._status===0||QA._status===-1){QA._status=2,QA._result=I0;var b0=QA._ioInfo;b0!=null&&(b0.end=performance.now()),cA.status===void 0&&(cA.status="rejected",cA.reason=I0)}}),FA=QA._ioInfo,FA!=null){FA.value=cA;var w0=cA.displayName;typeof w0==="string"&&(FA.name=w0)}QA._status===-1&&(QA._status=0,QA._result=cA)}if(QA._status===1)return FA=QA._result,FA===void 0&&console.error(`lazy: Expected the result of a dynamic import() call. Instead received: %s
|
|
494
|
+
`;await A.session.run($);let I=(await A.values(hA`SELECT id, hash, created_at FROM ${hA.identifier(w)} ORDER BY created_at DESC LIMIT 1`))[0]??void 0,D=[];for(let H of B)if(!I||Number(I[2])<H.folderMillis){for(let Y of H.sql)D.push(A.run(hA.raw(Y)));D.push(A.run(hA`INSERT INTO ${hA.identifier(w)} ("hash", "created_at") VALUES(${H.hash}, ${H.folderMillis})`))}await A.session.migrate(D)}var Qd=p(()=>{aw0();z5()});async function tw0(A,Q){let B=Q?.child("entity-migrate")??wQ.getInstance().child("entity-migrate"),{db:w,client:$,url:f}=El(A);B.debug("Running entity database migrations...");try{await Ml($,f);let D=import.meta.url.includes("/dist/")?new URL("./migrations/entity-service",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await oM(w,{migrationsFolder:D}),await Vl($),B.debug("Entity database migrations completed successfully")}catch(I){throw B.error("Entity database migration failed:",I),I}finally{$.close()}}var ew0=p(()=>{Qd();q$A();GA()});async function A80(A,Q){let B=Q?.child("job-queue-migrate")??wQ.getInstance().child("job-queue-migrate"),{db:w,client:$,url:f}=ql(A);B.debug("Running job queue migrations...");try{await Cl($,f);let D=import.meta.url.includes("/dist/")?new URL("./migrations/job-queue",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await oM(w,{migrationsFolder:D}),B.debug("Job queue migrations completed successfully")}catch(I){throw B.error("Job queue migration failed:",I),I}finally{$.close()}}var Q80=p(()=>{Qd();Y$A();GA()});async function B80(A,Q){let B=Q?.child("conversation-migrate")??wQ.getInstance().child("conversation-migrate"),{db:w,client:$,url:f}=hl(A);B.debug("Running conversation database migrations...");try{if(f.startsWith("file:"))await $.execute("PRAGMA journal_mode = WAL");let D=import.meta.url.includes("/dist/")?new URL("./migrations/conversation-service",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await oM(w,{migrationsFolder:D}),B.debug("Conversation database migrations completed successfully")}catch(I){throw B.error("Conversation database migration failed:",I),I}finally{$.close()}}var w80=p(()=>{Qd();A9A();GA()});class mv{logger;migrations;constructor(A,Q){this.logger=A,this.migrations=Q??{getStandardConfigWithDirectories:Jj,migrateEntities:tw0,migrateJobQueue:A80,migrateConversations:B80}}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 $XA=p(()=>{er();ew0();Q80();w80()});var Bd;var fXA=p(()=>{GA();Bd=F.object({theme:F.object({primaryColor:F.string().describe("Primary color for the CLI theme").default("#0066cc"),accentColor:F.string().describe("Accent color for the CLI theme").default("#ff6600")}).describe("Theme configuration for the CLI interface").default({primaryColor:"#0066cc",accentColor:"#ff6600"})})});var f80;var $80=p(()=>{f80={name:"@brains/chat-repl",private:!0,version:"0.2.0-alpha.71",type:"module",main:"./src/index.ts",module:"./src/index.ts",types:"./src/index.ts",files:["src"],scripts:{dev:"tsc --watch",typecheck:"tsc --noEmit",lint:"eslint --max-warnings 0 .","lint:fix":"eslint --fix .",test:"bun test"},dependencies:{"@brains/plugins":"workspace:*",chalk:"^5.4.1",ink:"^6.0.1","ink-spinner":"^5.0.0","ink-text-input":"^6.0.0",marked:"^12.0.0",react:"^19.1.0"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14","@types/react":"^19.0.3",typescript:"^5.3.3"}}});var uQ=v((Cg1,wd)=>{(function(){function A(QA,FA){Object.defineProperty(w.prototype,QA,{get:function(){console.warn("%s(...) is deprecated in plain JavaScript React classes. %s",FA[0],FA[1])}})}function Q(QA){if(QA===null||typeof QA!=="object")return null;return QA=aA&&QA[aA]||QA["@@iterator"],typeof QA==="function"?QA:null}function B(QA,FA){QA=(QA=QA.constructor)&&(QA.displayName||QA.name)||"ReactClass";var cA=QA+"."+FA;ZA[cA]||(console.error("Can't call %s on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign to `this.state` directly or define a `state = {};` class property with the desired state in the %s component.",FA,QA),ZA[cA]=!0)}function w(QA,FA,cA){this.props=QA,this.context=FA,this.refs=uA,this.updater=cA||VA}function $(){}function f(QA,FA,cA){this.props=QA,this.context=FA,this.refs=uA,this.updater=cA||VA}function I(){}function D(QA){return""+QA}function H(QA){try{D(QA);var FA=!1}catch(I0){FA=!0}if(FA){FA=console;var cA=FA.error,w0=typeof Symbol==="function"&&Symbol.toStringTag&&QA[Symbol.toStringTag]||QA.constructor.name||"Object";return cA.call(FA,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",w0),D(QA)}}function Y(QA){if(QA==null)return null;if(typeof QA==="function")return QA.$$typeof===X0?null:QA.displayName||QA.name||null;if(typeof QA==="string")return QA;switch(QA){case BA:return"Fragment";case UA:return"Profiler";case n:return"StrictMode";case K0:return"Suspense";case qA:return"SuspenseList";case EA:return"Activity"}if(typeof QA==="object")switch(typeof QA.tag==="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),QA.$$typeof){case d:return"Portal";case XA:return QA.displayName||"Context";case MA:return(QA._context.displayName||"Context")+".Consumer";case q0:var FA=QA.render;return QA=QA.displayName,QA||(QA=FA.displayName||FA.name||"",QA=QA!==""?"ForwardRef("+QA+")":"ForwardRef"),QA;case g0:return FA=QA.displayName||null,FA!==null?FA:Y(QA.type)||"Memo";case N0:FA=QA._payload,QA=QA._init;try{return Y(QA(FA))}catch(cA){}}return null}function W(QA){if(QA===BA)return"<>";if(typeof QA==="object"&&QA!==null&&QA.$$typeof===N0)return"<...>";try{var FA=Y(QA);return FA?"<"+FA+">":"<...>"}catch(cA){return"<...>"}}function G(){var QA=B0.A;return QA===null?null:QA.getOwner()}function K(){return Error("react-stack-top-frame")}function Z(QA){if(OA.call(QA,"key")){var FA=Object.getOwnPropertyDescriptor(QA,"key").get;if(FA&&FA.isReactWarning)return!1}return QA.key!==void 0}function q(QA,FA){function cA(){wA||(wA=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",FA))}cA.isReactWarning=!0,Object.defineProperty(QA,"key",{get:cA,configurable:!0})}function L(){var QA=Y(this.type);return A1[QA]||(A1[QA]=!0,console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.")),QA=this.props.ref,QA!==void 0?QA:null}function C(QA,FA,cA,w0,I0,b0){var eA=cA.ref;return QA={$$typeof:t,type:QA,key:FA,props:cA,_owner:w0},(eA!==void 0?eA:null)!==null?Object.defineProperty(QA,"ref",{enumerable:!1,get:L}):Object.defineProperty(QA,"ref",{enumerable:!1,value:null}),QA._store={},Object.defineProperty(QA._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(QA,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(QA,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:I0}),Object.defineProperty(QA,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:b0}),Object.freeze&&(Object.freeze(QA.props),Object.freeze(QA)),QA}function R(QA,FA){return FA=C(QA.type,FA,QA.props,QA._owner,QA._debugStack,QA._debugTask),QA._store&&(FA._store.validated=QA._store.validated),FA}function k(QA){_(QA)?QA._store&&(QA._store.validated=1):typeof QA==="object"&&QA!==null&&QA.$$typeof===N0&&(QA._payload.status==="fulfilled"?_(QA._payload.value)&&QA._payload.value._store&&(QA._payload.value._store.validated=1):QA._store&&(QA._store.validated=1))}function _(QA){return typeof QA==="object"&&QA!==null&&QA.$$typeof===t}function o(QA){var FA={"=":"=0",":":"=2"};return"$"+QA.replace(/[=:]/g,function(cA){return FA[cA]})}function r(QA,FA){return typeof QA==="object"&&QA!==null&&QA.key!=null?(H(QA.key),o(""+QA.key)):FA.toString(36)}function S(QA){switch(QA.status){case"fulfilled":return QA.value;case"rejected":throw QA.reason;default:switch(typeof QA.status==="string"?QA.then(I,I):(QA.status="pending",QA.then(function(FA){QA.status==="pending"&&(QA.status="fulfilled",QA.value=FA)},function(FA){QA.status==="pending"&&(QA.status="rejected",QA.reason=FA)})),QA.status){case"fulfilled":return QA.value;case"rejected":throw QA.reason}}throw QA}function x(QA,FA,cA,w0,I0){var b0=typeof QA;if(b0==="undefined"||b0==="boolean")QA=null;var eA=!1;if(QA===null)eA=!0;else switch(b0){case"bigint":case"string":case"number":eA=!0;break;case"object":switch(QA.$$typeof){case t:case d:eA=!0;break;case N0:return eA=QA._init,x(eA(QA._payload),FA,cA,w0,I0)}}if(eA){eA=QA,I0=I0(eA);var t0=w0===""?"."+r(eA,0):w0;return z0(I0)?(cA="",t0!=null&&(cA=t0.replace(gA,"$&/")+"/"),x(I0,FA,cA,"",function(S1){return S1})):I0!=null&&(_(I0)&&(I0.key!=null&&(eA&&eA.key===I0.key||H(I0.key)),cA=R(I0,cA+(I0.key==null||eA&&eA.key===I0.key?"":(""+I0.key).replace(gA,"$&/")+"/")+t0),w0!==""&&eA!=null&&_(eA)&&eA.key==null&&eA._store&&!eA._store.validated&&(cA._store.validated=2),I0=cA),FA.push(I0)),1}if(eA=0,t0=w0===""?".":w0+":",z0(QA))for(var Q1=0;Q1<QA.length;Q1++)w0=QA[Q1],b0=t0+r(w0,Q1),eA+=x(w0,FA,cA,b0,I0);else if(Q1=Q(QA),typeof Q1==="function")for(Q1===QA.entries&&(TA||console.warn("Using Maps as children is not supported. Use an array of keyed ReactElements instead."),TA=!0),QA=Q1.call(QA),Q1=0;!(w0=QA.next()).done;)w0=w0.value,b0=t0+r(w0,Q1++),eA+=x(w0,FA,cA,b0,I0);else if(b0==="object"){if(typeof QA.then==="function")return x(S(QA),FA,cA,w0,I0);throw FA=String(QA),Error("Objects are not valid as a React child (found: "+(FA==="[object Object]"?"object with keys {"+Object.keys(QA).join(", ")+"}":FA)+"). If you meant to render a collection of children, use an array instead.")}return eA}function y(QA,FA,cA){if(QA==null)return QA;var w0=[],I0=0;return x(QA,w0,"","",function(b0){return FA.call(cA,b0,I0++)}),w0}function g(QA){if(QA._status===-1){var FA=QA._ioInfo;FA!=null&&(FA.start=FA.end=performance.now()),FA=QA._result;var cA=FA();if(cA.then(function(I0){if(QA._status===0||QA._status===-1){QA._status=1,QA._result=I0;var b0=QA._ioInfo;b0!=null&&(b0.end=performance.now()),cA.status===void 0&&(cA.status="fulfilled",cA.value=I0)}},function(I0){if(QA._status===0||QA._status===-1){QA._status=2,QA._result=I0;var b0=QA._ioInfo;b0!=null&&(b0.end=performance.now()),cA.status===void 0&&(cA.status="rejected",cA.reason=I0)}}),FA=QA._ioInfo,FA!=null){FA.value=cA;var w0=cA.displayName;typeof w0==="string"&&(FA.name=w0)}QA._status===-1&&(QA._status=0,QA._result=cA)}if(QA._status===1)return FA=QA._result,FA===void 0&&console.error(`lazy: Expected the result of a dynamic import() call. Instead received: %s
|
|
495
495
|
|
|
496
496
|
Your code should look like:
|
|
497
497
|
const MyComponent = lazy(() => import('./MyComponent'))
|
|
@@ -1703,7 +1703,7 @@ Example bad output: "A dreamlike crystal formation glowing with ethereal light i
|
|
|
1703
1703
|
Title: "${A.entityTitle??D}"
|
|
1704
1704
|
|
|
1705
1705
|
Content:
|
|
1706
|
-
${A.entityContent}`,dp1);H=`${w.trim()} ${R.imagePrompt}`}catch(R){this.logger.warn("AI prompt distillation failed, using fallback",{error:y0(R)})}}await this.reportProgress(B,{progress:vQ.PROCESS,message:"Generating image"});let Y=this.context.identity.get(),W=this.context.identity.getProfile(),K=O70(Y,W)+H,Z;try{Z=await this.context.ai.generateImage(K,{...$&&{aspectRatio:$}})}catch(R){return this.logger.error("Image generation failed",{jobId:Q,error:y0(R)}),C$.failure(R)}await this.reportProgress(B,{progress:vQ.GENERATE,message:"Creating image entity"});let q=U2(D),L=pF.createImageEntity({dataUrl:Z.dataUrl,title:D});if(await this.context.entityService.getEntity({entityType:"image",id:q}))this.logger.debug("Deleting existing image for regeneration",{imageId:q}),await this.context.entityService.deleteEntity({entityType:"image",id:q});if(await this.context.entityService.createEntity({entity:{...L,id:q}}),this.logger.debug("Created image entity",{imageId:q}),f&&I){await this.reportProgress(B,{progress:vQ.SAVE,message:`Updating ${f} with cover image`});let R=await kl(this.context.entityService,f,I,this.logger);if(!R)return C$.failure(Error(`Target entity not found: ${f}/${I}`));let k=Sv(R,q);await this.context.entities.update(k),this.logger.debug("Updated target entity with cover image",{targetEntityType:f,targetEntityId:I,imageId:q})}return await this.reportProgress(B,{progress:vQ.COMPLETE,message:"Image generation complete"}),this.logger.info("Image generation job complete",{jobId:Q,imageId:q,targetEntityType:f,targetEntityId:I}),{success:!0,imageId:q}}catch(H){return this.logger.error("Image generation job failed",{jobId:Q,error:y0(H)}),C$.failure(H)}}summarizeDataForLog(A){return{title:A.title,promptLength:A.prompt.length,aspectRatio:A.aspectRatio,targetEntityType:A.targetEntityType,targetEntityId:A.targetEntityId}}}var R70={name:"@brains/image-plugin",private:!0,version:"0.2.0-alpha.70",description:"Plugin for AI-powered image generation and management",type:"module",main:"./src/index.ts",exports:{".":"./src/index.ts"},scripts:{test:"bun test",typecheck:"tsc --noEmit",lint:"eslint src test --ext .ts","lint:fix":"eslint src test --ext .ts --fix"},dependencies:{"@brains/contracts":"workspace:*","@brains/entity-service":"workspace:*","@brains/image":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","@types/node":"^20.0.0",typescript:"^5.3.3"}};var sp1=F.object({defaultAspectRatio:F.enum(["1:1","16:9","9:16","4:3","3:4"]).default("16:9").describe("Default aspect ratio for generated images")});class qUA extends KQ{entityType=pF.entityType;schema=gv;adapter=pF;constructor(A={}){super("image",R70,A,sp1)}getEntityTypeConfig(){return{embeddable:!1}}async interceptCreate(A,Q,B){if(!A.targetEntityType||!A.targetEntityId)return{kind:"continue",input:A};let w=await ED(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 Ln(A,this.logger)}async onRegister(A){let Q=new Ln(A,this.logger);A.jobs.registerHandler("image-generate",Q)}}function yx(A){return new qUA(A)}f0();import{StdioServerTransport as ap1}from"@modelcontextprotocol/sdk/server/stdio.js";function _70(){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 CUA(){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 En(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 CUA()}class NH{static instance=null;mcpServer=null;transport=null;config;logger;static getInstance(A){return NH.instance??=new NH(A),NH.instance}static resetInstance(){if(NH.instance)NH.instance.stop(),NH.instance=null}static createFresh(A){return new NH(A)}constructor(A={}){this.config=A,this.logger=this.config.logger?En(this.config.logger):_70()}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 ap1,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 P70}from"crypto";import{WebStandardStreamableHTTPServerTransport as tp1}from"@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";import{isInitializeRequest as ep1}from"@modelcontextprotocol/sdk/types.js";var Al1={"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, DELETE, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization, MCP-Session-Id, MCP-Protocol-Version, Last-Event-ID","Access-Control-Allow-Private-Network":"true","X-Content-Type-Options":"nosniff"};function Ql1(A){let Q=new URL(A.url),w=A.headers.get("x-forwarded-proto")?.split(",")[0]?.trim(),$=A.headers.get("x-forwarded-host")??A.headers.get("host");if(!$)return Q.origin;return`${w??Q.protocol.replace(":","")}://${$}`}class iU{static instance=null;transports={};mcpServer=null;mcpTransport=null;agentService=null;server=null;boundPort=null;config;logger;authConfig;constructor(A={}){if(this.config=A,this.logger=this.config.logger?En(this.config.logger):CUA(),this.authConfig=A.auth??{},!this.authConfig.disabled&&!this.authConfig.token&&!this.authConfig.verifyBearerToken)throw Error("MCP HTTP transport requires an auth token or bearer token verifier. Set MCP_AUTH_TOKEN, configure OAuth verification, or pass auth: { disabled: true } for local dev.")}static getInstance(A){return iU.instance??=new iU(A),iU.instance}static resetInstance(){iU.instance=null}static createFresh(A){return new iU(A)}withCors(A){let Q=new Headers(A.headers);for(let[B,w]of Object.entries(Al1))Q.set(B,w);return new Response(A.body,{status:A.status,statusText:A.statusText,headers:Q})}createJsonResponse(A,Q=200){return this.withCors(new Response(JSON.stringify(A),{status:Q,headers:{"Content-Type":"application/json"}}))}createTextResponse(A,Q=200){return this.withCors(new Response(A,{status:Q,headers:{"Content-Type":"text/plain; charset=utf-8"}}))}getAuthErrorResponse(A,Q=401,B){let w=this.createJsonResponse({jsonrpc:"2.0",error:{code:-32001,message:A},id:null},Q);if(!B)return w;let $=new Headers(w.headers);return $.set("WWW-Authenticate",B),new Response(w.body,{status:w.status,statusText:w.statusText,headers:$})}getBearerChallenge(A,Q={}){let w={resource_metadata:`${Ql1(A)}/.well-known/oauth-protected-resource`,...Q};return`Bearer ${Object.entries(w).map(([f,I])=>`${f}="${Bl1(I)}"`).join(", ")}`}async authenticate(A){let Q=new URL(A.url).pathname;if(Q==="/health"||Q==="/status"||Q==="/mcp"&&A.method==="OPTIONS")return null;if(this.authConfig.disabled)return null;let B=A.headers.get("authorization");if(!B?.startsWith("Bearer "))return this.logger.warn("Authentication failed: Missing Bearer token"),this.getAuthErrorResponse("Unauthorized: Bearer token required",401,this.getBearerChallenge(A,{realm:"mcp"}));if(this.authConfig.token){if(B.substring(7)!==this.authConfig.token)return this.logger.warn("Authentication failed: Invalid token"),this.getAuthErrorResponse("Unauthorized: Invalid token",401,this.getBearerChallenge(A,{error:"invalid_token"}));return this.logger.debug("Authentication successful"),null}try{let w=await this.authConfig.verifyBearerToken?.(A);if(!w)return this.logger.warn("Authentication failed: Invalid token"),this.getAuthErrorResponse("Unauthorized: Invalid token",401,this.getBearerChallenge(A,{error:"invalid_token"}));let $=this.authConfig.requiredScopes??[],f=$.filter((I)=>!w.scope?.includes(I));if(f.length>0)return this.logger.warn(`Authentication failed: Missing required scope(s): ${f.join(", ")}`),this.getAuthErrorResponse("Forbidden: Missing required scope",403,this.getBearerChallenge(A,{error:"insufficient_scope",scope:$.join(" ")}));return this.logger.debug("Authentication successful"),null}catch(w){return this.logger.warn("Authentication failed: Invalid token",w),this.getAuthErrorResponse("Unauthorized: Invalid token",401,this.getBearerChallenge(A,{error:"invalid_token"}))}}async handleMcpRequest(A){let Q=A.headers.get("mcp-session-id")??void 0;if(A.method==="GET"){if(!Q||!this.transports[Q])return this.createTextResponse("Invalid or missing session ID",400);return this.logger.debug(`GET /mcp - SSE stream for session ${Q}`),this.withCors(await this.transports[Q].handleRequest(A))}if(A.method==="DELETE"){if(!Q||!this.transports[Q])return this.createTextResponse("Invalid or missing session ID",400);return this.logger.info(`DELETE /mcp - Terminating session ${Q}`),this.withCors(await this.transports[Q].handleRequest(A))}if(A.method==="OPTIONS")return this.withCors(new Response(null,{status:204}));if(A.method!=="POST")return this.createTextResponse("Method Not Allowed",405);if(!this.mcpServer)return this.createJsonResponse({jsonrpc:"2.0",error:{code:-32603,message:"Service Unavailable: MCP server not connected"},id:null},503);let B=await A.json();this.logger.debug(`POST /mcp - Session: ${Q??"new"}`);try{let w;if(Q&&this.transports[Q])w=this.transports[Q];else if(!Q&&ep1(B))w=new tp1({sessionIdGenerator:()=>P70(),onsessioninitialized:(f)=>{this.logger.info(`Session initialized: ${f}`),this.transports[f]=w},onsessionclosed:(f)=>{this.logger.info(`Session closed: ${f}`),delete this.transports[f]}}),await(this.mcpTransport?this.mcpTransport.createMcpServer():this.mcpServer).connect(w);else return this.createJsonResponse({jsonrpc:"2.0",error:{code:-32000,message:"Bad Request: Server not initialized"},id:null},400);return this.withCors(await w.handleRequest(A,{parsedBody:B}))}catch(w){return this.logger.error("MCP transport error:",w),this.createJsonResponse({jsonrpc:"2.0",error:{code:-32603,message:"Internal error"}},500)}}async handleAgentChatRequest(A){if(!this.agentService)return this.createJsonResponse({error:"Agent service not connected"},503);let{message:Q,conversationId:B}=await A.json();if(!Q||typeof Q!=="string")return this.createJsonResponse({error:"Missing or invalid 'message' field"},400);let w=B??P70();this.logger.debug(`POST /api/chat - conversation: ${w}`);try{let $=await this.agentService.chat(Q,w);return this.createJsonResponse($)}catch($){return this.logger.error("Agent chat error:",$),this.createJsonResponse({error:$ instanceof Error?$.message:"Internal error"},500)}}async handleRequest(A){let Q=new URL(A.url);this.logger.debug(`${A.method} ${Q.pathname}`);let B=await this.authenticate(A);if(B)return B;if(Q.pathname==="/health")return this.createJsonResponse({status:"ok",transport:"streamable-http",timestamp:new Date().toISOString()});if(Q.pathname==="/status")return this.createJsonResponse({sessions:Object.keys(this.transports).length,uptime:process.uptime(),memory:process.memoryUsage(),port:this.boundPort??this.config.port??3333});if(Q.pathname==="/mcp")return this.handleMcpRequest(A);if(Q.pathname==="/api/chat"&&A.method==="POST")return this.handleAgentChatRequest(A);return this.createTextResponse("Not Found",404)}connectMCPServer(A,Q){this.mcpServer=A,this.mcpTransport=Q??null,this.logger.debug("MCP server connected to StreamableHTTP transport")}connectAgentService(A){this.agentService=A,this.logger.debug("Agent service connected to StreamableHTTP transport")}async start(){if(this.server)throw Error("Server is already running");let A=Number(this.config.port??3333),Q=this.config.host??"0.0.0.0";try{this.server=Bun.serve({port:A,hostname:Q,fetch:(B)=>this.handleRequest(B)}),this.boundPort=this.server.port??A,this.logger.info(`StreamableHTTP server listening on http://${Q}:${this.boundPort}/mcp`)}catch(B){if(B.code==="EADDRINUSE")this.logger.error(`Port ${A} is already in use`);throw B}}async stop(){for(let A in this.transports)try{let Q=this.transports[A];if(Q)this.logger.debug(`Closing transport for session ${A}`),await Q.close(),delete this.transports[A]}catch(Q){this.logger.error(`Error closing transport for session ${A}:`,Q)}if(this.server)await this.server.stop(),this.logger.info("StreamableHTTP server stopped"),this.server=null,this.boundPort=null}getPort(){if(this.boundPort===null)throw Error("Server is not running");return this.boundPort}getApp(){return{fetch:(A)=>this.handleRequest(A)}}isRunning(){return this.server!==null}getSessionCount(){return Object.keys(this.transports).length}}function Bl1(A){return A.replace(/["\\]/g,(Q)=>`\\${Q}`)}import{randomUUID as $l1}from"crypto";import{mkdir as fl1,readFile as Il1,writeFile as Dl1,chmod as Hl1}from"fs/promises";import{dirname as Yl1,join as Xl1}from"path";function k70(A){let Q=A.toLowerCase();return Q==="localhost"||Q==="[::1]"||Q==="::1"||Q.startsWith("127.")}function j70(A){try{return new URL(A)}catch{return}}function LUA(A,Q){if(A===Q)return!0;let B=j70(A),w=j70(Q);if(!B||!w)return!1;if(!k70(B.hostname)||!k70(w.hostname))return!1;return B.protocol===w.protocol&&B.port===w.port&&wl1(B.pathname,w.pathname)&&B.search===w.search&&B.hash===w.hash}function wl1(A,Q){return A===Q||A===`${Q}/debug`||Q===`${A}/debug`}function EUA(A,Q){return A.some((B)=>LUA(B,Q))}var Wl1="oauth-auth-codes.json",Ul1=600;function v70(){return Math.floor(Date.now()/1000)}function Jl1(A){if(!A||typeof A!=="object")return!1;let Q=A;return typeof Q.code==="string"&&typeof Q.client_id==="string"&&typeof Q.redirect_uri==="string"&&typeof Q.code_challenge==="string"&&Q.code_challenge_method==="S256"&&typeof Q.subject==="string"&&typeof Q.created_at==="number"&&typeof Q.expires_at==="number"}function Gl1(A){if(!A||typeof A!=="object")return{codes:[]};let Q=A.codes;if(!Array.isArray(Q))return{codes:[]};return{codes:Q.filter(Jl1)}}async function Fl1(A){let Q=await crypto.subtle.digest("SHA-256",new TextEncoder().encode(A));return Buffer.from(Q).toString("base64url")}class Mn{storeFile;writeQueue=Promise.resolve();constructor(A){this.storeFile=Xl1(A.storageDir,A.storeFile??Wl1)}async createCode(A){let Q=v70(),B={code:`ocd_${$l1()}`,client_id:A.clientId,redirect_uri:A.redirectUri,code_challenge:A.codeChallenge,code_challenge_method:"S256",...A.scope?{scope:A.scope}:{},subject:A.subject,created_at:Q,expires_at:Q+Ul1};return await this.enqueueWrite(async()=>{let w=await this.readStore();w.codes=w.codes.filter(($)=>$.expires_at>Q),w.codes.push(B),await this.writeStore(w)}),B}async consumeCode(A){let Q=v70(),B;if(await this.enqueueWrite(async()=>{let w=await this.readStore(),$=w.codes.findIndex((D)=>D.code===A.code),f=$>=0?w.codes[$]:void 0;if(!f)throw new zH("Authorization code not found");if(f.consumed_at!==void 0)throw new zH("Authorization code already consumed");if(f.expires_at<=Q)throw new zH("Authorization code expired");if(f.client_id!==A.clientId)throw new zH("Authorization code client mismatch");if(!LUA(f.redirect_uri,A.redirectUri))throw new zH("Authorization code redirect URI mismatch");let I=await Fl1(A.codeVerifier);if(f.code_challenge!==I)throw new zH("PKCE verification failed");B={...f,consumed_at:Q},w.codes[$]=B,await this.writeStore(w)}),!B)throw new zH("Authorization code not consumed");return B}async enqueueWrite(A){return this.writeQueue=this.writeQueue.then(A,A),this.writeQueue}async readStore(){try{return Gl1(JSON.parse(await Il1(this.storeFile,"utf8")))}catch(A){if(A.code==="ENOENT")return{codes:[]};throw A}}async writeStore(A){await fl1(Yl1(this.storeFile),{recursive:!0,mode:448}),await Dl1(this.storeFile,`${JSON.stringify(A,null,2)}
|
|
1706
|
+
${A.entityContent}`,dp1);H=`${w.trim()} ${R.imagePrompt}`}catch(R){this.logger.warn("AI prompt distillation failed, using fallback",{error:y0(R)})}}await this.reportProgress(B,{progress:vQ.PROCESS,message:"Generating image"});let Y=this.context.identity.get(),W=this.context.identity.getProfile(),K=O70(Y,W)+H,Z;try{Z=await this.context.ai.generateImage(K,{...$&&{aspectRatio:$}})}catch(R){return this.logger.error("Image generation failed",{jobId:Q,error:y0(R)}),C$.failure(R)}await this.reportProgress(B,{progress:vQ.GENERATE,message:"Creating image entity"});let q=U2(D),L=pF.createImageEntity({dataUrl:Z.dataUrl,title:D});if(await this.context.entityService.getEntity({entityType:"image",id:q}))this.logger.debug("Deleting existing image for regeneration",{imageId:q}),await this.context.entityService.deleteEntity({entityType:"image",id:q});if(await this.context.entityService.createEntity({entity:{...L,id:q}}),this.logger.debug("Created image entity",{imageId:q}),f&&I){await this.reportProgress(B,{progress:vQ.SAVE,message:`Updating ${f} with cover image`});let R=await kl(this.context.entityService,f,I,this.logger);if(!R)return C$.failure(Error(`Target entity not found: ${f}/${I}`));let k=Sv(R,q);await this.context.entities.update(k),this.logger.debug("Updated target entity with cover image",{targetEntityType:f,targetEntityId:I,imageId:q})}return await this.reportProgress(B,{progress:vQ.COMPLETE,message:"Image generation complete"}),this.logger.info("Image generation job complete",{jobId:Q,imageId:q,targetEntityType:f,targetEntityId:I}),{success:!0,imageId:q}}catch(H){return this.logger.error("Image generation job failed",{jobId:Q,error:y0(H)}),C$.failure(H)}}summarizeDataForLog(A){return{title:A.title,promptLength:A.prompt.length,aspectRatio:A.aspectRatio,targetEntityType:A.targetEntityType,targetEntityId:A.targetEntityId}}}var R70={name:"@brains/image-plugin",private:!0,version:"0.2.0-alpha.71",description:"Plugin for AI-powered image generation and management",type:"module",main:"./src/index.ts",exports:{".":"./src/index.ts"},scripts:{test:"bun test",typecheck:"tsc --noEmit",lint:"eslint src test --ext .ts","lint:fix":"eslint src test --ext .ts --fix"},dependencies:{"@brains/contracts":"workspace:*","@brains/entity-service":"workspace:*","@brains/image":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","@types/node":"^20.0.0",typescript:"^5.3.3"}};var sp1=F.object({defaultAspectRatio:F.enum(["1:1","16:9","9:16","4:3","3:4"]).default("16:9").describe("Default aspect ratio for generated images")});class qUA extends KQ{entityType=pF.entityType;schema=gv;adapter=pF;constructor(A={}){super("image",R70,A,sp1)}getEntityTypeConfig(){return{embeddable:!1}}async interceptCreate(A,Q,B){if(!A.targetEntityType||!A.targetEntityId)return{kind:"continue",input:A};let w=await ED(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 Ln(A,this.logger)}async onRegister(A){let Q=new Ln(A,this.logger);A.jobs.registerHandler("image-generate",Q)}}function yx(A){return new qUA(A)}f0();import{StdioServerTransport as ap1}from"@modelcontextprotocol/sdk/server/stdio.js";function _70(){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 CUA(){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 En(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 CUA()}class NH{static instance=null;mcpServer=null;transport=null;config;logger;static getInstance(A){return NH.instance??=new NH(A),NH.instance}static resetInstance(){if(NH.instance)NH.instance.stop(),NH.instance=null}static createFresh(A){return new NH(A)}constructor(A={}){this.config=A,this.logger=this.config.logger?En(this.config.logger):_70()}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 ap1,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 P70}from"crypto";import{WebStandardStreamableHTTPServerTransport as tp1}from"@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";import{isInitializeRequest as ep1}from"@modelcontextprotocol/sdk/types.js";var Al1={"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, DELETE, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization, MCP-Session-Id, MCP-Protocol-Version, Last-Event-ID","Access-Control-Allow-Private-Network":"true","X-Content-Type-Options":"nosniff"};function Ql1(A){let Q=new URL(A.url),w=A.headers.get("x-forwarded-proto")?.split(",")[0]?.trim(),$=A.headers.get("x-forwarded-host")??A.headers.get("host");if(!$)return Q.origin;return`${w??Q.protocol.replace(":","")}://${$}`}class iU{static instance=null;transports={};mcpServer=null;mcpTransport=null;agentService=null;server=null;boundPort=null;config;logger;authConfig;constructor(A={}){if(this.config=A,this.logger=this.config.logger?En(this.config.logger):CUA(),this.authConfig=A.auth??{},!this.authConfig.disabled&&!this.authConfig.token&&!this.authConfig.verifyBearerToken)throw Error("MCP HTTP transport requires an auth token or bearer token verifier. Set MCP_AUTH_TOKEN, configure OAuth verification, or pass auth: { disabled: true } for local dev.")}static getInstance(A){return iU.instance??=new iU(A),iU.instance}static resetInstance(){iU.instance=null}static createFresh(A){return new iU(A)}withCors(A){let Q=new Headers(A.headers);for(let[B,w]of Object.entries(Al1))Q.set(B,w);return new Response(A.body,{status:A.status,statusText:A.statusText,headers:Q})}createJsonResponse(A,Q=200){return this.withCors(new Response(JSON.stringify(A),{status:Q,headers:{"Content-Type":"application/json"}}))}createTextResponse(A,Q=200){return this.withCors(new Response(A,{status:Q,headers:{"Content-Type":"text/plain; charset=utf-8"}}))}getAuthErrorResponse(A,Q=401,B){let w=this.createJsonResponse({jsonrpc:"2.0",error:{code:-32001,message:A},id:null},Q);if(!B)return w;let $=new Headers(w.headers);return $.set("WWW-Authenticate",B),new Response(w.body,{status:w.status,statusText:w.statusText,headers:$})}getBearerChallenge(A,Q={}){let w={resource_metadata:`${Ql1(A)}/.well-known/oauth-protected-resource`,...Q};return`Bearer ${Object.entries(w).map(([f,I])=>`${f}="${Bl1(I)}"`).join(", ")}`}async authenticate(A){let Q=new URL(A.url).pathname;if(Q==="/health"||Q==="/status"||Q==="/mcp"&&A.method==="OPTIONS")return null;if(this.authConfig.disabled)return null;let B=A.headers.get("authorization");if(!B?.startsWith("Bearer "))return this.logger.warn("Authentication failed: Missing Bearer token"),this.getAuthErrorResponse("Unauthorized: Bearer token required",401,this.getBearerChallenge(A,{realm:"mcp"}));if(this.authConfig.token){if(B.substring(7)!==this.authConfig.token)return this.logger.warn("Authentication failed: Invalid token"),this.getAuthErrorResponse("Unauthorized: Invalid token",401,this.getBearerChallenge(A,{error:"invalid_token"}));return this.logger.debug("Authentication successful"),null}try{let w=await this.authConfig.verifyBearerToken?.(A);if(!w)return this.logger.warn("Authentication failed: Invalid token"),this.getAuthErrorResponse("Unauthorized: Invalid token",401,this.getBearerChallenge(A,{error:"invalid_token"}));let $=this.authConfig.requiredScopes??[],f=$.filter((I)=>!w.scope?.includes(I));if(f.length>0)return this.logger.warn(`Authentication failed: Missing required scope(s): ${f.join(", ")}`),this.getAuthErrorResponse("Forbidden: Missing required scope",403,this.getBearerChallenge(A,{error:"insufficient_scope",scope:$.join(" ")}));return this.logger.debug("Authentication successful"),null}catch(w){return this.logger.warn("Authentication failed: Invalid token",w),this.getAuthErrorResponse("Unauthorized: Invalid token",401,this.getBearerChallenge(A,{error:"invalid_token"}))}}async handleMcpRequest(A){let Q=A.headers.get("mcp-session-id")??void 0;if(A.method==="GET"){if(!Q||!this.transports[Q])return this.createTextResponse("Invalid or missing session ID",400);return this.logger.debug(`GET /mcp - SSE stream for session ${Q}`),this.withCors(await this.transports[Q].handleRequest(A))}if(A.method==="DELETE"){if(!Q||!this.transports[Q])return this.createTextResponse("Invalid or missing session ID",400);return this.logger.info(`DELETE /mcp - Terminating session ${Q}`),this.withCors(await this.transports[Q].handleRequest(A))}if(A.method==="OPTIONS")return this.withCors(new Response(null,{status:204}));if(A.method!=="POST")return this.createTextResponse("Method Not Allowed",405);if(!this.mcpServer)return this.createJsonResponse({jsonrpc:"2.0",error:{code:-32603,message:"Service Unavailable: MCP server not connected"},id:null},503);let B=await A.json();this.logger.debug(`POST /mcp - Session: ${Q??"new"}`);try{let w;if(Q&&this.transports[Q])w=this.transports[Q];else if(!Q&&ep1(B))w=new tp1({sessionIdGenerator:()=>P70(),onsessioninitialized:(f)=>{this.logger.info(`Session initialized: ${f}`),this.transports[f]=w},onsessionclosed:(f)=>{this.logger.info(`Session closed: ${f}`),delete this.transports[f]}}),await(this.mcpTransport?this.mcpTransport.createMcpServer():this.mcpServer).connect(w);else return this.createJsonResponse({jsonrpc:"2.0",error:{code:-32000,message:"Bad Request: Server not initialized"},id:null},400);return this.withCors(await w.handleRequest(A,{parsedBody:B}))}catch(w){return this.logger.error("MCP transport error:",w),this.createJsonResponse({jsonrpc:"2.0",error:{code:-32603,message:"Internal error"}},500)}}async handleAgentChatRequest(A){if(!this.agentService)return this.createJsonResponse({error:"Agent service not connected"},503);let{message:Q,conversationId:B}=await A.json();if(!Q||typeof Q!=="string")return this.createJsonResponse({error:"Missing or invalid 'message' field"},400);let w=B??P70();this.logger.debug(`POST /api/chat - conversation: ${w}`);try{let $=await this.agentService.chat(Q,w);return this.createJsonResponse($)}catch($){return this.logger.error("Agent chat error:",$),this.createJsonResponse({error:$ instanceof Error?$.message:"Internal error"},500)}}async handleRequest(A){let Q=new URL(A.url);this.logger.debug(`${A.method} ${Q.pathname}`);let B=await this.authenticate(A);if(B)return B;if(Q.pathname==="/health")return this.createJsonResponse({status:"ok",transport:"streamable-http",timestamp:new Date().toISOString()});if(Q.pathname==="/status")return this.createJsonResponse({sessions:Object.keys(this.transports).length,uptime:process.uptime(),memory:process.memoryUsage(),port:this.boundPort??this.config.port??3333});if(Q.pathname==="/mcp")return this.handleMcpRequest(A);if(Q.pathname==="/api/chat"&&A.method==="POST")return this.handleAgentChatRequest(A);return this.createTextResponse("Not Found",404)}connectMCPServer(A,Q){this.mcpServer=A,this.mcpTransport=Q??null,this.logger.debug("MCP server connected to StreamableHTTP transport")}connectAgentService(A){this.agentService=A,this.logger.debug("Agent service connected to StreamableHTTP transport")}async start(){if(this.server)throw Error("Server is already running");let A=Number(this.config.port??3333),Q=this.config.host??"0.0.0.0";try{this.server=Bun.serve({port:A,hostname:Q,fetch:(B)=>this.handleRequest(B)}),this.boundPort=this.server.port??A,this.logger.info(`StreamableHTTP server listening on http://${Q}:${this.boundPort}/mcp`)}catch(B){if(B.code==="EADDRINUSE")this.logger.error(`Port ${A} is already in use`);throw B}}async stop(){for(let A in this.transports)try{let Q=this.transports[A];if(Q)this.logger.debug(`Closing transport for session ${A}`),await Q.close(),delete this.transports[A]}catch(Q){this.logger.error(`Error closing transport for session ${A}:`,Q)}if(this.server)await this.server.stop(),this.logger.info("StreamableHTTP server stopped"),this.server=null,this.boundPort=null}getPort(){if(this.boundPort===null)throw Error("Server is not running");return this.boundPort}getApp(){return{fetch:(A)=>this.handleRequest(A)}}isRunning(){return this.server!==null}getSessionCount(){return Object.keys(this.transports).length}}function Bl1(A){return A.replace(/["\\]/g,(Q)=>`\\${Q}`)}import{randomUUID as $l1}from"crypto";import{mkdir as fl1,readFile as Il1,writeFile as Dl1,chmod as Hl1}from"fs/promises";import{dirname as Yl1,join as Xl1}from"path";function k70(A){let Q=A.toLowerCase();return Q==="localhost"||Q==="[::1]"||Q==="::1"||Q.startsWith("127.")}function j70(A){try{return new URL(A)}catch{return}}function LUA(A,Q){if(A===Q)return!0;let B=j70(A),w=j70(Q);if(!B||!w)return!1;if(!k70(B.hostname)||!k70(w.hostname))return!1;return B.protocol===w.protocol&&B.port===w.port&&wl1(B.pathname,w.pathname)&&B.search===w.search&&B.hash===w.hash}function wl1(A,Q){return A===Q||A===`${Q}/debug`||Q===`${A}/debug`}function EUA(A,Q){return A.some((B)=>LUA(B,Q))}var Wl1="oauth-auth-codes.json",Ul1=600;function v70(){return Math.floor(Date.now()/1000)}function Jl1(A){if(!A||typeof A!=="object")return!1;let Q=A;return typeof Q.code==="string"&&typeof Q.client_id==="string"&&typeof Q.redirect_uri==="string"&&typeof Q.code_challenge==="string"&&Q.code_challenge_method==="S256"&&typeof Q.subject==="string"&&typeof Q.created_at==="number"&&typeof Q.expires_at==="number"}function Gl1(A){if(!A||typeof A!=="object")return{codes:[]};let Q=A.codes;if(!Array.isArray(Q))return{codes:[]};return{codes:Q.filter(Jl1)}}async function Fl1(A){let Q=await crypto.subtle.digest("SHA-256",new TextEncoder().encode(A));return Buffer.from(Q).toString("base64url")}class Mn{storeFile;writeQueue=Promise.resolve();constructor(A){this.storeFile=Xl1(A.storageDir,A.storeFile??Wl1)}async createCode(A){let Q=v70(),B={code:`ocd_${$l1()}`,client_id:A.clientId,redirect_uri:A.redirectUri,code_challenge:A.codeChallenge,code_challenge_method:"S256",...A.scope?{scope:A.scope}:{},subject:A.subject,created_at:Q,expires_at:Q+Ul1};return await this.enqueueWrite(async()=>{let w=await this.readStore();w.codes=w.codes.filter(($)=>$.expires_at>Q),w.codes.push(B),await this.writeStore(w)}),B}async consumeCode(A){let Q=v70(),B;if(await this.enqueueWrite(async()=>{let w=await this.readStore(),$=w.codes.findIndex((D)=>D.code===A.code),f=$>=0?w.codes[$]:void 0;if(!f)throw new zH("Authorization code not found");if(f.consumed_at!==void 0)throw new zH("Authorization code already consumed");if(f.expires_at<=Q)throw new zH("Authorization code expired");if(f.client_id!==A.clientId)throw new zH("Authorization code client mismatch");if(!LUA(f.redirect_uri,A.redirectUri))throw new zH("Authorization code redirect URI mismatch");let I=await Fl1(A.codeVerifier);if(f.code_challenge!==I)throw new zH("PKCE verification failed");B={...f,consumed_at:Q},w.codes[$]=B,await this.writeStore(w)}),!B)throw new zH("Authorization code not consumed");return B}async enqueueWrite(A){return this.writeQueue=this.writeQueue.then(A,A),this.writeQueue}async readStore(){try{return Gl1(JSON.parse(await Il1(this.storeFile,"utf8")))}catch(A){if(A.code==="ENOENT")return{codes:[]};throw A}}async writeStore(A){await fl1(Yl1(this.storeFile),{recursive:!0,mode:448}),await Dl1(this.storeFile,`${JSON.stringify(A,null,2)}
|
|
1707
1707
|
`,{mode:384}),await Hl1(this.storeFile,384)}}class zH extends Error{constructor(A){super(A);this.name="InvalidGrantError"}}import{randomUUID as _Y0}from"crypto";GA();import{randomUUID as x70}from"crypto";import{mkdir as Kl1,readFile as Zl1,writeFile as Nl1,chmod as zl1}from"fs/promises";import{dirname as ql1,join as Cl1}from"path";var Ll1="oauth-clients.json",El1=F.enum(["none","client_secret_basic","client_secret_post"]),Ml1=F.object({redirect_uris:F.array(F.string().url()).min(1),token_endpoint_auth_method:El1.default("none"),grant_types:F.array(F.enum(["authorization_code","refresh_token"])).default(["authorization_code","refresh_token"]),response_types:F.array(F.literal("code")).default(["code"]),scope:F.string().optional(),client_name:F.string().optional(),client_uri:F.string().url().optional(),logo_uri:F.string().url().optional(),contacts:F.array(F.string()).optional()});function Vl1(){return Math.floor(Date.now()/1000)}function bl1(){return`ocs_${x70().replaceAll("-","")}`}function Ol1(A){if(!A||typeof A!=="object")return{clients:[]};let Q=A.clients;if(!Array.isArray(Q))return{clients:[]};return{clients:Q.filter(Rl1)}}function Rl1(A){if(!A||typeof A!=="object")return!1;let Q=A;return typeof Q.client_id==="string"&&Array.isArray(Q.redirect_uris)&&Q.redirect_uris.every((B)=>typeof B==="string")&&typeof Q.client_id_issued_at==="number"}class Vn{storeFile;writeQueue=Promise.resolve();constructor(A){this.storeFile=Cl1(A.storageDir,A.storeFile??Ll1)}async registerClient(A){let Q=Ml1.safeParse(A);if(!Q.success)throw new gx(Q.error.message);let B=Q.data,w=Vl1(),$=`oc_${x70()}`,f=B.token_endpoint_auth_method==="none",I={client_id:$,client_id_issued_at:w,redirect_uris:B.redirect_uris,token_endpoint_auth_method:B.token_endpoint_auth_method,grant_types:B.grant_types,response_types:B.response_types,...B.scope?{scope:B.scope}:{},...B.client_name?{client_name:B.client_name}:{},...B.client_uri?{client_uri:B.client_uri}:{},...B.logo_uri?{logo_uri:B.logo_uri}:{},...B.contacts?{contacts:B.contacts}:{},...!f?{client_secret:bl1(),client_secret_expires_at:0}:{}};return await this.enqueueWrite(async()=>{let D=await this.readStore();D.clients.push(I),await this.writeStore(D)}),I}async getClient(A){return(await this.readStore()).clients.find((B)=>B.client_id===A)}async enqueueWrite(A){return this.writeQueue=this.writeQueue.then(A,A),this.writeQueue}async readStore(){try{return Ol1(JSON.parse(await Zl1(this.storeFile,"utf8")))}catch(A){if(A.code==="ENOENT")return{clients:[]};throw A}}async writeStore(A){await Kl1(ql1(this.storeFile),{recursive:!0,mode:448}),await Nl1(this.storeFile,`${JSON.stringify(A,null,2)}
|
|
1708
1708
|
`,{mode:384}),await zl1(this.storeFile,384)}}class gx extends Error{constructor(A){super(A);this.name="InvalidClientMetadataError"}}function h70(A){return Buffer.from(JSON.stringify(A)).toString("base64url")}function _l1(A){let Q=new Uint8Array(A);if(Q.length===64)return Q;if(Q[0]!==48)return Q;let B=2;if(Q[1]&&Q[1]>128)B+=Q[1]-128;if(Q[B]!==2)throw Error("Invalid DER ECDSA signature");let w=Q[B+1];if(w===void 0)throw Error("Invalid DER ECDSA signature");let $=B+2,f=Q.slice($,$+w);if(B=$+w,Q[B]!==2)throw Error("Invalid DER ECDSA signature");let I=Q[B+1];if(I===void 0)throw Error("Invalid DER ECDSA signature");let D=B+2,H=Q.slice(D,D+I);return new Uint8Array([...y70(f),...y70(H)])}function y70(A){let Q=A;while(Q.length>32&&Q[0]===0)Q=Q.slice(1);if(Q.length>32)throw Error("Invalid P-256 signature component length");if(Q.length===32)return Q;let B=new Uint8Array(32);return B.set(Q,32-Q.length),B}async function MUA(A,Q){let B={typ:"JWT",alg:"ES256",kid:A.kid},w=`${h70(B)}.${h70(Q)}`,$=await crypto.subtle.importKey("jwk",A,{name:"ECDSA",namedCurve:"P-256"},!1,["sign"]),f=await crypto.subtle.sign({name:"ECDSA",hash:"SHA-256"},$,new TextEncoder().encode(w));return`${w}.${Buffer.from(_l1(f)).toString("base64url")}`}import{createHash as Pl1}from"crypto";import{mkdir as kl1,readFile as jl1,writeFile as vl1,chmod as xl1}from"fs/promises";import{dirname as hl1,join as yl1}from"path";var gl1="oauth-signing-key.jwk";function g70(A){if(!A||typeof A!=="object")return!1;let Q=A;return Q.kty==="EC"&&Q.crv==="P-256"&&typeof Q.x==="string"&&typeof Q.y==="string"&&typeof Q.d==="string"}function T70(A){let Q=JSON.stringify({crv:A.crv,kty:A.kty,x:A.x,y:A.y});return Pl1("sha256").update(Q).digest("base64url")}function Tl1(A){return{kty:"EC",crv:"P-256",x:A.x,y:A.y,kid:A.kid,use:"sig",alg:"ES256"}}async function Sl1(){let A=await crypto.subtle.generateKey({name:"ECDSA",namedCurve:"P-256"},!0,["sign","verify"]),Q=await crypto.subtle.exportKey("jwk",A.privateKey);if(!g70(Q))throw Error("Generated OAuth signing key is not a P-256 private JWK");let B=T70(Q);return{...Q,kid:B,use:"sig",alg:"ES256"}}class bn{keyFile;cachedKey;loadPromise;constructor(A){this.keyFile=yl1(A.storageDir,A.keyFile??gl1)}async getPrivateJwk(){if(this.cachedKey)return this.cachedKey;this.loadPromise??=this.loadOrCreateKey();try{return this.cachedKey=await this.loadPromise,this.cachedKey}catch(A){throw this.loadPromise=void 0,A}}async loadOrCreateKey(){let A=await this.readExistingKey();if(A)return A;let Q=await Sl1();return await kl1(hl1(this.keyFile),{recursive:!0,mode:448}),await vl1(this.keyFile,`${JSON.stringify(Q,null,2)}
|
|
1709
1709
|
`,{mode:384}),await xl1(this.keyFile,384),Q}async getPublicJwk(){return Tl1(await this.getPrivateJwk())}async readExistingKey(){try{let A=JSON.parse(await jl1(this.keyFile,"utf8"));if(!g70(A))throw Error(`OAuth signing key at ${this.keyFile} is not a private P-256 JWK`);let Q=typeof A.kid==="string"?A.kid:T70(A);return{...A,kid:Q,use:"sig",alg:"ES256"}}catch(A){if(A.code==="ENOENT")return;throw A}}}var S2={};OB(S2,{trimPadding:()=>m70,toUTF8String:()=>nl1,toBuffer:()=>ll1,toBase64:()=>rl1,isBase64URL:()=>sl1,isBase64:()=>ol1,fromUTF8String:()=>dl1,fromBuffer:()=>il1});var S70=(A)=>{let Q=typeof Uint8Array>"u"?[]:new Uint8Array(256),B=64;for(let w=0;w<64;w++)Q[A.charCodeAt(w)]=w;return Q},ml1=S70("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"),ul1=S70("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"),cl1=/^[-A-Za-z0-9\-_]*$/,pl1=/^[-A-Za-z0-9+/]*={0,3}$/,ZX={};ZX.toArrayBuffer=(A,Q)=>{let B=A.length,w=A.length*0.75,$,f=0,I,D,H,Y;if(A[A.length-1]==="="){if(w--,A[A.length-2]==="=")w--}let W=new ArrayBuffer(w),G=new Uint8Array(W),K=Q?ul1:ml1;for($=0;$<B;$+=4)I=K[A.charCodeAt($)],D=K[A.charCodeAt($+1)],H=K[A.charCodeAt($+2)],Y=K[A.charCodeAt($+3)],G[f++]=I<<2|D>>4,G[f++]=(D&15)<<4|H>>2,G[f++]=(H&3)<<6|Y&63;return W};ZX.fromArrayBuffer=(A,Q)=>{let B=new Uint8Array(A),w,$="",f=B.length,I=Q?"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_":"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";for(w=0;w<f;w+=3)$+=I[B[w]>>2],$+=I[(B[w]&3)<<4|B[w+1]>>4],$+=I[(B[w+1]&15)<<2|B[w+2]>>6],$+=I[B[w+2]&63];let D=f%3;if(D===2)$=$.substring(0,$.length-1)+(Q?"":"=");else if(D===1)$=$.substring(0,$.length-2)+(Q?"":"==");return $};ZX.toString=(A,Q)=>{return new TextDecoder().decode(ZX.toArrayBuffer(A,Q))};ZX.fromString=(A,Q)=>{return ZX.fromArrayBuffer(new TextEncoder().encode(A),Q)};ZX.validate=(A,Q)=>{if(!(typeof A==="string"||A instanceof String))return!1;try{return Q?cl1.test(A):pl1.test(A)}catch(B){return!1}};ZX.base64=ZX;var rU=ZX;function ll1(A,Q="base64url"){let B=rU.toArrayBuffer(A,Q==="base64url");return new Uint8Array(B)}function il1(A,Q="base64url"){let B=new Uint8Array(A);return rU.fromArrayBuffer(B.buffer,Q==="base64url")}function rl1(A){let Q=rU.toArrayBuffer(A,!0);return rU.fromArrayBuffer(Q)}function dl1(A){return rU.fromString(A,!0)}function nl1(A){return rU.toString(A,!0)}function ol1(A){return rU.validate(A,!1)}function sl1(A){return A=m70(A),rU.validate(A,!0)}function m70(A){return A.replace(/=/g,"")}var W7={};OB(W7,{encode:()=>Zi1,decodeFirst:()=>Ki1});function RV(A,Q,B){if(Q<24)return[Q,1];let w=A.byteLength-B-1,$=new DataView(A.buffer,B+1),f,I=0;switch(Q){case 24:{if(w>0)f=$.getUint8(0),I=2;break}case 25:{if(w>1)f=$.getUint16(0,!1),I=3;break}case 26:{if(w>3)f=$.getUint32(0,!1),I=5;break}case 27:{if(w>7){let D=$.getBigUint64(0,!1);if(D>=24n&&D<=Number.MAX_SAFE_INTEGER)return[Number(D),9]}break}}if(f&&f>=24)return[f,I];throw Error("Length not supported or not well formed")}var On=0,Tx=1,VUA=2,bUA=3,OUA=4,RUA=5,_UA=6,u70=7;function NX(A,Q){let B=A<<5;if(Q<0)throw Error("CBOR Data Item argument must not be negative");let w;if(typeof Q=="number"){if(!Number.isInteger(Q))throw Error("CBOR Data Item argument must be an integer");w=BigInt(Q)}else w=Q;if(A==Tx){if(w==0n)throw Error("CBOR Data Item argument cannot be zero when negative");w=w-1n}if(w>18446744073709551615n)throw Error("CBOR number out of range");let $=new Uint8Array(8);if(new DataView($.buffer).setBigUint64(0,w,!1),w<=23)return[B|$[7]];else if(w<=255)return[B|24,$[7]];else if(w<=65535)return[B|25,...$.slice(6)];else if(w<=4294967295)return[B|26,...$.slice(4)];else return[B|27,...$]}class _n{constructor(A,Q){Object.defineProperty(this,"tagId",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"tagValue",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.tagId=A,this.tagValue=Q}get tag(){return this.tagId}get value(){return this.tagValue}}function c70(A,Q,B){return RV(A,Q,B)}function al1(A,Q,B){let[w,$]=c70(A,Q,B);return[-w-1,$]}function p70(A,Q,B){let[w,$]=RV(A,Q,B),f=B+$;return[new Uint8Array(A.buffer.slice(f,f+w)),$+w]}var tl1=new TextDecoder;function el1(A,Q,B){let[w,$]=p70(A,Q,B);return[tl1.decode(w),$]}function Ai1(A,Q,B){if(Q===0)return[[],1];let[w,$]=RV(A,Q,B),f=$,I=[];for(let D=0;D<w;D++){if(A.byteLength-B-f<=0)throw Error("array is not supported or well formed");let[Y,W]=Gz(A,B+f);I.push(Y),f+=W}return[I,f]}var Rn="Map is not supported or well formed";function Qi1(A,Q,B){if(Q===0)return[new Map,1];let[w,$]=RV(A,Q,B),f=$,I=new Map;for(let D=0;D<w;D++){let H=A.byteLength-B-f;if(H<=0)throw Error(Rn);let[Y,W]=Gz(A,B+f);if(f+=W,H-=W,H<=0)throw Error(Rn);if(typeof Y!=="string"&&typeof Y!=="number")throw Error(Rn);if(I.has(Y))throw Error(Rn);let[G,K]=Gz(A,B+f);f+=K,I.set(Y,G)}return[I,f]}function Bi1(A,Q){if(Q+3>A.byteLength)throw Error("CBOR stream ended before end of Float 16");let B=A.getUint16(Q+1,!1);if(B==31744)return[1/0,3];else if(B==32256)return[NaN,3];else if(B==64512)return[-1/0,3];throw Error("Float16 data is unsupported")}function wi1(A,Q){if(Q+5>A.byteLength)throw Error("CBOR stream ended before end of Float 32");return[A.getFloat32(Q+1,!1),5]}function $i1(A,Q){if(Q+9>A.byteLength)throw Error("CBOR stream ended before end of Float 64");return[A.getFloat64(Q+1,!1),9]}function fi1(A,Q,B){let[w,$]=RV(A,Q,B),[f,I]=Gz(A,B+$);return[new _n(w,f),$+I]}function Gz(A,Q){if(Q>=A.byteLength)throw Error("CBOR stream ended before tag value");let B=A.getUint8(Q),w=B>>5,$=B&31;switch(w){case On:return c70(A,$,Q);case Tx:return al1(A,$,Q);case VUA:return p70(A,$,Q);case bUA:return el1(A,$,Q);case OUA:return Ai1(A,$,Q);case RUA:return Qi1(A,$,Q);case _UA:return fi1(A,$,Q);case u70:switch($){case 20:return[!1,1];case 21:return[!0,1];case 22:return[null,1];case 23:return[void 0,1];case 25:return Bi1(A,Q);case 26:return wi1(A,Q);case 27:return $i1(A,Q)}}throw Error(`Unsupported or not well formed at ${Q}`)}function Ii1(A){if(A===!0)return 245;else if(A===!1)return 244;else if(A===null)return 246;return 247}function Di1(A){if(Math.fround(A)==A||!Number.isFinite(A)||Number.isNaN(A)){let Q=new Uint8Array(5);return Q[0]=250,new DataView(Q.buffer).setFloat32(1,A,!1),Q}else{let Q=new Uint8Array(9);return Q[0]=251,new DataView(Q.buffer).setFloat64(1,A,!1),Q}}function Hi1(A){if(typeof A=="number"){if(Number.isSafeInteger(A))if(A<0)return NX(Tx,Math.abs(A));else return NX(On,A);return[Di1(A)]}else if(A<0n)return NX(Tx,A*-1n);else return NX(On,A)}var Yi1=new TextEncoder;function Xi1(A,Q){Q.push(...NX(bUA,A.length)),Q.push(Yi1.encode(A))}function Wi1(A,Q){Q.push(...NX(VUA,A.length)),Q.push(A)}function Ui1(A,Q){Q.push(...NX(OUA,A.length));for(let B of A)Sx(B,Q)}function Ji1(A,Q){Q.push(new Uint8Array(NX(RUA,A.size)));for(let[B,w]of A.entries())Sx(B,Q),Sx(w,Q)}function Gi1(A,Q){Q.push(...NX(_UA,A.tag)),Sx(A.value,Q)}function Sx(A,Q){if(typeof A=="boolean"||A===null||A==null){Q.push(Ii1(A));return}if(typeof A=="number"||typeof A=="bigint"){Q.push(...Hi1(A));return}if(typeof A=="string"){Xi1(A,Q);return}if(A instanceof Uint8Array){Wi1(A,Q);return}if(Array.isArray(A)){Ui1(A,Q);return}if(A instanceof Map){Ji1(A,Q);return}if(A instanceof _n){Gi1(A,Q);return}throw Error("Not implemented")}function PUA(A,Q){if(A.byteLength===0||A.byteLength<=Q||Q<0)throw Error("No data");if(A instanceof Uint8Array)return Gz(new DataView(A.buffer),Q);else if(A instanceof ArrayBuffer)return Gz(new DataView(A),Q);return Gz(A,Q)}function kUA(A){let Q=[];Sx(A,Q);let B=0;for(let f of Q)if(typeof f=="number")B+=1;else B+=f.length;let w=new Uint8Array(B),$=0;for(let f of Q)if(typeof f=="number")w[$]=f,$+=1;else w.set(f,$),$+=f.length;return w}function Ki1(A){let Q=new Uint8Array(A),B=PUA(Q,0),[w]=B;return w}function Zi1(A){return kUA(A)}var qX={};OB(qX,{verify:()=>MH0,getRandomValues:()=>n70,digest:()=>d70});function l70(A){let Q=A.get(g2.kty);return jUA(Q)&&Q===NI.OKP}function fK(A){let Q=A.get(g2.kty);return jUA(Q)&&Q===NI.EC2}function _V(A){let Q=A.get(g2.kty);return jUA(Q)&&Q===NI.RSA}var g2;(function(A){A[A.kty=1]="kty",A[A.alg=3]="alg",A[A.crv=-1]="crv",A[A.x=-2]="x",A[A.y=-3]="y",A[A.n=-1]="n",A[A.e=-2]="e"})(g2||(g2={}));var NI;(function(A){A[A.OKP=1]="OKP",A[A.EC2=2]="EC2",A[A.RSA=3]="RSA"})(NI||(NI={}));function jUA(A){return Object.values(NI).indexOf(A)>=0}var K9;(function(A){A[A.P256=1]="P256",A[A.P384=2]="P384",A[A.P521=3]="P521",A[A.ED25519=6]="ED25519",A[A.SECP256K1=8]="SECP256K1"})(K9||(K9={}));function i70(A){return Object.values(K9).indexOf(A)>=0}var IQ;(function(A){A[A.ES256=-7]="ES256",A[A.EdDSA=-8]="EdDSA",A[A.ES384=-35]="ES384",A[A.ES512=-36]="ES512",A[A.PS256=-37]="PS256",A[A.PS384=-38]="PS384",A[A.PS512=-39]="PS512",A[A.ES256K=-47]="ES256K",A[A.RS256=-257]="RS256",A[A.RS384=-258]="RS384",A[A.RS512=-259]="RS512",A[A.RS1=-65535]="RS1"})(IQ||(IQ={}));function zX(A){return Object.values(IQ).indexOf(A)>=0}function IK(A){if([IQ.RS1].indexOf(A)>=0)return"SHA-1";else if([IQ.ES256,IQ.PS256,IQ.RS256].indexOf(A)>=0)return"SHA-256";else if([IQ.ES384,IQ.PS384,IQ.RS384].indexOf(A)>=0)return"SHA-384";else if([IQ.ES512,IQ.PS512,IQ.RS512,IQ.EdDSA].indexOf(A)>=0)return"SHA-512";throw Error(`Could not map COSE alg value of ${A} to a WebCrypto alg`)}var mx=void 0;function wf(){return new Promise((Q,B)=>{if(mx)return Q(mx);let w=zi1.stubThisGlobalThisCrypto();if(w)return mx=w,Q(mx);return B(new r70)})}class r70 extends Error{constructor(){super("An instance of the Crypto API could not be located");this.name="MissingWebCrypto"}}var zi1={stubThisGlobalThisCrypto:()=>globalThis.crypto,setCachedCrypto:(A)=>{mx=A}};async function d70(A,Q){let B=await wf(),w=IK(Q),$=await B.subtle.digest(w,A);return new Uint8Array($)}async function n70(A){return(await wf()).getRandomValues(A),A}async function PV(A){let Q=await wf(),{keyData:B,algorithm:w}=A;return Q.subtle.importKey("jwk",B,w,!1,["verify"])}async function Pn(A){let{cosePublicKey:Q,signature:B,data:w,shaHashOverride:$}=A,f=await wf(),I=Q.get(g2.alg),D=Q.get(g2.crv),H=Q.get(g2.x),Y=Q.get(g2.y);if(!I)throw Error("Public key was missing alg (EC2)");if(!D)throw Error("Public key was missing crv (EC2)");if(!H)throw Error("Public key was missing x (EC2)");if(!Y)throw Error("Public key was missing y (EC2)");let W;if(D===K9.P256)W="P-256";else if(D===K9.P384)W="P-384";else if(D===K9.P521)W="P-521";else throw Error(`Unexpected COSE crv value of ${D} (EC2)`);let G={kty:"EC",crv:W,x:S2.fromBuffer(H),y:S2.fromBuffer(Y),ext:!1},Z=await PV({keyData:G,algorithm:{name:"ECDSA",namedCurve:W}}),q=IK(I);if($)q=IK($);let L={name:"ECDSA",hash:{name:q}};return f.subtle.verify(L,Z,B,w)}function vUA(A){if([IQ.EdDSA].indexOf(A)>=0)return"Ed25519";else if([IQ.ES256,IQ.ES384,IQ.ES512,IQ.ES256K].indexOf(A)>=0)return"ECDSA";else if([IQ.RS256,IQ.RS384,IQ.RS512,IQ.RS1].indexOf(A)>=0)return"RSASSA-PKCS1-v1_5";else if([IQ.PS256,IQ.PS384,IQ.PS512].indexOf(A)>=0)return"RSA-PSS";throw Error(`Could not map COSE alg value of ${A} to a WebCrypto key alg name`)}async function kn(A){let{cosePublicKey:Q,signature:B,data:w,shaHashOverride:$}=A,f=await wf(),I=Q.get(g2.alg),D=Q.get(g2.n),H=Q.get(g2.e);if(!I)throw Error("Public key was missing alg (RSA)");if(!zX(I))throw Error(`Public key had invalid alg ${I} (RSA)`);if(!D)throw Error("Public key was missing n (RSA)");if(!H)throw Error("Public key was missing e (RSA)");let Y={kty:"RSA",alg:"",n:S2.fromBuffer(D),e:S2.fromBuffer(H),ext:!1},W={name:vUA(I),hash:{name:IK(I)}},G={name:vUA(I)};if($)W.hash.name=IK($);if(W.name==="RSASSA-PKCS1-v1_5"){if(W.hash.name==="SHA-256")Y.alg="RS256";else if(W.hash.name==="SHA-384")Y.alg="RS384";else if(W.hash.name==="SHA-512")Y.alg="RS512";else if(W.hash.name==="SHA-1")Y.alg="RS1"}else if(W.name==="RSA-PSS"){let Z=0;if(W.hash.name==="SHA-256")Y.alg="PS256",Z=32;else if(W.hash.name==="SHA-384")Y.alg="PS384",Z=48;else if(W.hash.name==="SHA-512")Y.alg="PS512",Z=64;G.saltLength=Z}else throw Error(`Unexpected RSA key algorithm ${I} (${W.name})`);let K=await PV({keyData:Y,algorithm:W});return f.subtle.verify(G,K,B,w)}function jn(A){let Q=H2.toHex(A);return[Q.slice(0,8),Q.slice(8,12),Q.slice(12,16),Q.slice(16,20),Q.slice(20,32)].join("-")}function a6(A){let Q;if(typeof A==="string")if(S2.isBase64URL(A))Q=S2.toBase64(A);else if(S2.isBase64(A))Q=A;else throw Error("Certificate is not a valid base64 or base64url string");else Q=S2.fromBuffer(A,"base64");let B="";for(let w=0;w<Math.ceil(Q.length/64);w+=1){let $=64*w;B+=`${Q.substr($,64)}
|
|
@@ -2281,7 +2281,7 @@ ${R}`)}if(w!==void 0&&f?.algorithms!==void 0){let C=f.algorithms.map((R)=>R.alg)
|
|
|
2281
2281
|
</form>
|
|
2282
2282
|
</main>
|
|
2283
2283
|
</body>
|
|
2284
|
-
</html>`}function uFA(A){return new Response(A,{headers:{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store"}})}function cFA(A){let Q=`${new URL(A.url).pathname}${new URL(A.url).search}`;return new Response(yY0(Q,"Operator login required"),{status:401,headers:{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store"}})}function Us(A){let Q=Ds(A),B=new URL(Q);return{origin:B.origin,rpID:B.hostname}}function hX(A){return A.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""")}f0();GA();var TY0={name:"@brains/auth-service",private:!0,version:"0.2.0-alpha.70",description:"Embedded OAuth/OIDC auth service for brain operator authentication",type:"module",main:"./src/index.ts",types:"./src/index.ts",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*","@simplewebauthn/server":"^13.3.0",jose:"^6.2.3"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","@types/node":"^20.0.0",typescript:"^5.3.3"},files:["src"]};var nn1=F.object({issuer:F.string().optional(),trustedIssuers:F.array(F.string()).default([]),allowLocalhostIssuers:F.boolean().optional(),storageDir:F.string().default("./data/auth")}),on1=F.object({}),Gs;function nb(){return Gs}class lFA extends Ww{service;constructor(A={}){super("auth-service",TY0,A,nn1)}async onRegister(A){await super.onRegister(A);let Q=this.config.issuer??(A.preferLocalUrls?A.localSiteUrl??A.siteUrl:A.siteUrl??A.localSiteUrl);this.service=new Js({storageDir:this.config.storageDir,...Q?{issuer:Q}:{},trustedIssuers:this.config.trustedIssuers,...this.config.allowLocalhostIssuers!==void 0?{allowLocalhostIssuers:this.config.allowLocalhostIssuers}:{},logger:A.logger}),await this.service.initialize(),Gs=this.service}async onShutdown(){if(Gs===this.service)Gs=void 0;this.service=void 0}async getTools(){return[xQ(this.id,"get_passkey_setup_url","Get the first-passkey setup URL when operator setup is required. Anchor-only.",on1,async()=>{let A=this.getService();if(await A.hasPasskeyCredentials())return P8({status:"complete"});let Q=await A.getOperatorSetupRequired();if(Q)return P8({status:"setup_required",setupUrl:Q.setupUrl,expiresAt:Q.expiresAt});return P8({status:"unavailable",reason:"Passkey setup URL is not available."})},{visibility:"anchor"})]}getWebRoutes(){let A=(Q)=>this.getService().handleRequest(Q);return[{path:"/.well-known/oauth-authorization-server",method:"GET",public:!0,handler:A},{path:"/.well-known/oauth-authorization-server",method:"OPTIONS",public:!0,handler:A},{path:"/.well-known/jwks.json",method:"GET",public:!0,handler:A},{path:"/.well-known/jwks.json",method:"OPTIONS",public:!0,handler:A},{path:"/.well-known/oauth-protected-resource",method:"GET",public:!0,handler:A},{path:"/.well-known/oauth-protected-resource",method:"OPTIONS",public:!0,handler:A},{path:"/setup",method:"GET",public:!0,handler:A},{path:"/login",method:"GET",public:!0,handler:A},{path:"/logout",method:"GET",public:!0,handler:A},{path:"/logout",method:"POST",public:!0,handler:A},{path:"/authorize",method:"GET",public:!0,handler:A},{path:"/authorize",method:"POST",public:!0,handler:A},{path:"/register",method:"POST",public:!0,handler:A},{path:"/register",method:"OPTIONS",public:!0,handler:A},{path:"/token",method:"POST",public:!0,handler:A},{path:"/token",method:"OPTIONS",public:!0,handler:A},{path:"/revoke",method:"POST",public:!0,handler:A},{path:"/revoke",method:"OPTIONS",public:!0,handler:A},{path:"/webauthn/register/options",method:"POST",public:!0,handler:A},{path:"/webauthn/register/verify",method:"POST",public:!0,handler:A},{path:"/webauthn/auth/options",method:"POST",public:!0,handler:A},{path:"/webauthn/auth/verify",method:"POST",public:!0,handler:A}]}getService(){if(!this.service)throw Error("AuthServicePlugin has not been registered");return this.service}}function Vy(A){return new lFA(A)}GA();var iFA=F.object({transport:F.enum(["stdio","http"]).default("http"),httpPort:F.number().describe("Port for HTTP transport (only used when transport is 'http')").default(3333),authToken:F.string().describe("Bearer token for HTTP transport authentication").optional()});function SY0(A,Q){return[]}f0();function rFA(A,Q){A.messaging.subscribe("job-progress",async(B)=>{let w=gE.safeParse(B.payload);if(!w.success)return Q.warn("Received invalid job-progress message",{error:w.error.message}),{success:!1};let $=w.data,f=$.type,I=$.status,D=$.id;if(Q.debug(`${f} ${D} - ${I}:`,{id:$.id,message:$.message,progress:$.progress,metadata:$.metadata}),$.batchDetails)Q.debug(`Batch details for ${D}:`,{totalOperations:$.batchDetails.totalOperations,completedOperations:$.batchDetails.completedOperations,failedOperations:$.batchDetails.failedOperations,currentOperation:$.batchDetails.currentOperation,errors:$.batchDetails.errors});if($.jobDetails)Q.debug(`Job details for ${D}:`,{jobType:$.jobDetails.jobType,priority:$.jobDetails.priority,retryCount:$.jobDetails.retryCount});return{success:!0}}),Q.debug("Subscribed to job progress events")}var mY0={name:"@brains/mcp",private:!0,version:"0.2.0-alpha.70",type:"module",main:"./src/index.ts",module:"./src/index.ts",types:"./src/index.ts",files:["src"],scripts:{typecheck:"tsc --noEmit",lint:"eslint --max-warnings 0 .","lint:fix":"eslint --fix .",test:"bun test"},dependencies:{"@brains/auth-service":"workspace:*","@brains/mcp-service":"workspace:*","@brains/plugins":"workspace:*","@modelcontextprotocol/sdk":"^1.24.0",cors:"^2.8.5",express:"^4.18.0","express-async-handler":"^1.2.0"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14","@types/cors":"^2.8.17","@types/express":"^4.17.21",typescript:"^5.3.3"}};class hK extends aY{mcpTransport;stdioServer;httpServer;domain;constructor(A={}){let Q={...A,authToken:A.authToken??process.env.MCP_AUTH_TOKEN};super("mcp",mY0,Q,iFA)}async getTools(){return SY0(this.id,()=>this.context)}async getResources(){return[]}async onRegister(A){if(this.domain=A.domain,this.config.transport==="http"&&!A.plugins.has("webserver"))throw Error("MCP HTTP transport requires the webserver interface. Standalone HTTP listeners have been removed.");if(this.logger.debug(`MCP interface initialized with ${this.config.transport} transport`),this.config.transport==="http")A.endpoints.register({label:"MCP",url:"/mcp",priority:30,visibility:"trusted"}),A.interactions.register({id:"mcp",label:"MCP",description:"Connect a trusted client through the Model Context Protocol.",href:"/mcp",kind:"protocol",priority:30,visibility:"trusted"});rFA(A,this.logger)}getOrCreateHttpServer(){if(this.httpServer)return this.httpServer;let A=nb();return this.httpServer=iU.createFresh({port:this.config.httpPort,logger:this.logger,auth:this.config.authToken?{token:this.config.authToken}:A?{requiredScopes:["mcp"],verifyBearerToken:async(Q)=>A.verifyBearerToken(Q)}:{disabled:!0}}),this.httpServer}getWebRoutes(){if(this.config.transport!=="http")return[];let A=(Q)=>this.getOrCreateHttpServer().handleRequest(Q);return[{path:"/status",method:"GET",public:!0,handler:A},{path:"/mcp",method:"GET",public:!0,handler:A},{path:"/mcp",method:"POST",public:!0,handler:A},{path:"/mcp",method:"DELETE",public:!0,handler:A},{path:"/mcp",method:"OPTIONS",public:!0,handler:A}]}createDaemon(){return{start:async()=>{await this.startServer()},stop:async()=>{await this.stopServer()},healthCheck:async()=>{let A=this.isServerRunning(),Q="MCP server not running";if(A)if(this.config.transport==="http")Q=`MCP HTTP: ${this.domain?`https://${this.domain}/mcp`:"http://localhost:8080/mcp"}`;else Q="MCP stdio server running";return{status:A?"healthy":"error",message:Q,lastCheck:new Date,details:{transport:this.config.transport,url:this.config.transport==="http"?this.domain?`https://${this.domain}/mcp`:"http://localhost:8080/mcp":void 0,running:A}}}}}isServerRunning(){if(this.config.transport==="stdio")return this.stdioServer!==void 0&&this.mcpTransport!==void 0;else return this.httpServer!==void 0&&this.mcpTransport!==void 0}async startServer(){if(!this.context)throw Error("Context not initialized");let A=this.context;this.mcpTransport=A.mcpTransport;let Q=this.config.transport==="stdio"?"stdio":"http",B=this.context.permissions.getUserLevel("mcp",Q);if(this.config.transport==="http"&&(this.config.authToken||nb()))B="anchor",this.logger.debug("HTTP authentication configured - authenticated users will have anchor permissions");if(this.mcpTransport.setPermissionLevel(B),this.logger.debug(`Starting MCP ${this.config.transport} transport with ${B} permissions`),this.config.transport==="stdio"){this.stdioServer=NH.createFresh();let w=this.mcpTransport.getMcpServer();this.stdioServer.connectMCPServer(w),await this.stdioServer.start(),this.logger.debug("MCP STDIO transport started")}else{this.httpServer=this.getOrCreateHttpServer();let w=this.mcpTransport.getMcpServer();this.httpServer.connectMCPServer(w,this.mcpTransport),this.httpServer.connectAgentService(A.agent),this.logger.debug("MCP HTTP transport mounted on shared webserver host")}}async stopServer(){if(this.logger.debug(`Stopping MCP ${this.config.transport} transport`),this.stdioServer)this.stdioServer.stop(),this.stdioServer=void 0;if(this.httpServer)await this.httpServer.stop(),this.httpServer=void 0;this.mcpTransport=void 0}async handleProgressEvent(A,Q){}async onShutdown(){NH.resetInstance(),iU.resetInstance()}}f0();GA();var eD=D1(PS0(),1);GA();f0();var OCA=F.object({botToken:F.string().min(1).describe("Discord bot token"),allowedChannels:F.array(F.string()).default([]),requireMention:F.boolean().default(!0),allowDMs:F.boolean().default(!0),showTypingIndicator:F.boolean().default(!0),statusMessage:F.string().default("Mention me to chat"),useThreads:F.boolean().default(!0),threadAutoArchive:F.union([F.literal(60),F.literal(1440),F.literal(4320),F.literal(10080)]).default(1440),...Yj.shape,captureUrlEmoji:F.string().default("\uD83D\uDD16")});var kS0={name:"@brains/discord",private:!0,version:"0.2.0-alpha.70",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 RCA=2000,WC2=8000,UC2=100;function Ze(A){return!!A&&typeof A==="object"&&"send"in A&&"sendTyping"in A}class KZ extends EN{client=null;fetchText;pendingConfirmations=new Map;typingIntervals=new Map;constructor(A,Q={}){super("discord",kS0,A,OCA);this.fetchText=Q.fetchText??Pp}async onRegister(A){await super.onRegister(A),this.client=new eD.Client({intents:[eD.GatewayIntentBits.Guilds,eD.GatewayIntentBits.GuildMessages,eD.GatewayIntentBits.MessageContent,eD.GatewayIntentBits.DirectMessages],partials:[eD.Partials.Channel]}),this.client.on(eD.Events.MessageCreate,(Q)=>{this.handleMessage(Q)}),this.client.once(eD.Events.ClientReady,()=>{this.logger.info("Discord bot connected",{tag:this.client?.user?.tag})})}createDaemon(){return{start:async()=>{if(!this.client)throw Error("Discord client not initialized");await this.client.login(this.config.botToken)},stop:async()=>{for(let A of this.typingIntervals.values())clearInterval(A);if(this.typingIntervals.clear(),this.client)await this.client.destroy(),this.client=null},healthCheck:async()=>({status:this.client?.user?"healthy":"error",message:this.client?.user?`Connected as ${this.client.user.tag}`:"Not connected",lastCheck:new Date})}}sendMessageToChannel({channelId:A,message:Q}){if(!A||!this.client)return;let B=this.client.channels.cache.get(A);if(!Ze(B))return;let w=Gk(Q,RCA);for(let $ of w)B.send($).catch((f)=>this.logger.error("Failed to send message",{error:f}))}async sendMessageWithId({channelId:A,message:Q}){if(!A||!this.client)return;let B=this.client.channels.cache.get(A);if(!Ze(B))return;let w=Gk(Q,RCA),$;for(let f of w)$=(await B.send(f)).id;return $}async editMessage({channelId:A,messageId:Q,newMessage:B}){if(!A||!this.client)return!1;let w=this.client.channels.cache.get(A);if(!Ze(w))return!1;try{return await(await w.messages.fetch(Q)).edit(B.slice(0,RCA)),!0}catch{return!1}}supportsMessageEditing(){return!0}async handleMessage(A){if(A.author.id===this.client?.user?.id)return;if(!this.context)return;let Q=!A.guild,B=A.channel.isThread();if(Q&&!this.config.allowDMs)return;let w=!!this.client?.user&&A.mentions.has(this.client.user,{ignoreEveryone:!0});if(A.author.bot&&!w)return;let $=B&&"ownerId"in A.channel&&A.channel.ownerId===this.client?.user?.id,f=this.getSpaceChannelId(A),I=!Q&&this.isConfiguredSpace(f),D={channelId:f,isBot:A.author.bot};if(this.config.allowedChannels.length>0&&!Q&&!this.isAllowedChannel(A.channel.id,f))return;let H=Q||$||!this.config.requireMention||w;if(I&&(!H||this.willRouteUseNonSpaceConversation(A)))await this.capturePassiveSpaceMessage(A,f).catch((G)=>this.logger.error("Passive Discord space capture failed",{error:G,channelId:f}));if(!H){if(this.config.captureUrls){let G=this.extractCaptureableUrls(A.content,this.config.blockedUrlDomains);if(G.length>0){await A.react(this.config.captureUrlEmoji).catch((K)=>this.logger.debug("React failed",{error:K}));for(let K of G)await this.captureUrlViaAgent(K,A.channel.id,A.author.id,"discord",D).catch((Z)=>this.logger.error("URL capture failed",{error:Z,url:K}))}}return}let Y=this.stripMention(A.content);if(A.attachments.size>0){let G=this.context.permissions.getUserLevel("discord",A.author.id,D);if(G==="anchor"||G==="trusted")for(let Z of A.attachments.values()){let q=Z.name,L=Z.contentType??void 0,C=Z.size;if(!this.isUploadableTextFile(q,L))continue;if(!this.isFileSizeAllowed(C))continue;try{let R=await this.fetchText(Z.url);Y+=`
|
|
2284
|
+
</html>`}function uFA(A){return new Response(A,{headers:{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store"}})}function cFA(A){let Q=`${new URL(A.url).pathname}${new URL(A.url).search}`;return new Response(yY0(Q,"Operator login required"),{status:401,headers:{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store"}})}function Us(A){let Q=Ds(A),B=new URL(Q);return{origin:B.origin,rpID:B.hostname}}function hX(A){return A.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""")}f0();GA();var TY0={name:"@brains/auth-service",private:!0,version:"0.2.0-alpha.71",description:"Embedded OAuth/OIDC auth service for brain operator authentication",type:"module",main:"./src/index.ts",types:"./src/index.ts",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*","@simplewebauthn/server":"^13.3.0",jose:"^6.2.3"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","@types/node":"^20.0.0",typescript:"^5.3.3"},files:["src"]};var nn1=F.object({issuer:F.string().optional(),trustedIssuers:F.array(F.string()).default([]),allowLocalhostIssuers:F.boolean().optional(),storageDir:F.string().default("./data/auth")}),on1=F.object({}),Gs;function nb(){return Gs}class lFA extends Ww{service;constructor(A={}){super("auth-service",TY0,A,nn1)}async onRegister(A){await super.onRegister(A);let Q=this.config.issuer??(A.preferLocalUrls?A.localSiteUrl??A.siteUrl:A.siteUrl??A.localSiteUrl);this.service=new Js({storageDir:this.config.storageDir,...Q?{issuer:Q}:{},trustedIssuers:this.config.trustedIssuers,...this.config.allowLocalhostIssuers!==void 0?{allowLocalhostIssuers:this.config.allowLocalhostIssuers}:{},logger:A.logger}),await this.service.initialize(),Gs=this.service}async onShutdown(){if(Gs===this.service)Gs=void 0;this.service=void 0}async getTools(){return[xQ(this.id,"get_passkey_setup_url","Get the first-passkey setup URL when operator setup is required. Anchor-only.",on1,async()=>{let A=this.getService();if(await A.hasPasskeyCredentials())return P8({status:"complete"});let Q=await A.getOperatorSetupRequired();if(Q)return P8({status:"setup_required",setupUrl:Q.setupUrl,expiresAt:Q.expiresAt});return P8({status:"unavailable",reason:"Passkey setup URL is not available."})},{visibility:"anchor"})]}getWebRoutes(){let A=(Q)=>this.getService().handleRequest(Q);return[{path:"/.well-known/oauth-authorization-server",method:"GET",public:!0,handler:A},{path:"/.well-known/oauth-authorization-server",method:"OPTIONS",public:!0,handler:A},{path:"/.well-known/jwks.json",method:"GET",public:!0,handler:A},{path:"/.well-known/jwks.json",method:"OPTIONS",public:!0,handler:A},{path:"/.well-known/oauth-protected-resource",method:"GET",public:!0,handler:A},{path:"/.well-known/oauth-protected-resource",method:"OPTIONS",public:!0,handler:A},{path:"/setup",method:"GET",public:!0,handler:A},{path:"/login",method:"GET",public:!0,handler:A},{path:"/logout",method:"GET",public:!0,handler:A},{path:"/logout",method:"POST",public:!0,handler:A},{path:"/authorize",method:"GET",public:!0,handler:A},{path:"/authorize",method:"POST",public:!0,handler:A},{path:"/register",method:"POST",public:!0,handler:A},{path:"/register",method:"OPTIONS",public:!0,handler:A},{path:"/token",method:"POST",public:!0,handler:A},{path:"/token",method:"OPTIONS",public:!0,handler:A},{path:"/revoke",method:"POST",public:!0,handler:A},{path:"/revoke",method:"OPTIONS",public:!0,handler:A},{path:"/webauthn/register/options",method:"POST",public:!0,handler:A},{path:"/webauthn/register/verify",method:"POST",public:!0,handler:A},{path:"/webauthn/auth/options",method:"POST",public:!0,handler:A},{path:"/webauthn/auth/verify",method:"POST",public:!0,handler:A}]}getService(){if(!this.service)throw Error("AuthServicePlugin has not been registered");return this.service}}function Vy(A){return new lFA(A)}GA();var iFA=F.object({transport:F.enum(["stdio","http"]).default("http"),httpPort:F.number().describe("Port for HTTP transport (only used when transport is 'http')").default(3333),authToken:F.string().describe("Bearer token for HTTP transport authentication").optional()});function SY0(A,Q){return[]}f0();function rFA(A,Q){A.messaging.subscribe("job-progress",async(B)=>{let w=gE.safeParse(B.payload);if(!w.success)return Q.warn("Received invalid job-progress message",{error:w.error.message}),{success:!1};let $=w.data,f=$.type,I=$.status,D=$.id;if(Q.debug(`${f} ${D} - ${I}:`,{id:$.id,message:$.message,progress:$.progress,metadata:$.metadata}),$.batchDetails)Q.debug(`Batch details for ${D}:`,{totalOperations:$.batchDetails.totalOperations,completedOperations:$.batchDetails.completedOperations,failedOperations:$.batchDetails.failedOperations,currentOperation:$.batchDetails.currentOperation,errors:$.batchDetails.errors});if($.jobDetails)Q.debug(`Job details for ${D}:`,{jobType:$.jobDetails.jobType,priority:$.jobDetails.priority,retryCount:$.jobDetails.retryCount});return{success:!0}}),Q.debug("Subscribed to job progress events")}var mY0={name:"@brains/mcp",private:!0,version:"0.2.0-alpha.71",type:"module",main:"./src/index.ts",module:"./src/index.ts",types:"./src/index.ts",files:["src"],scripts:{typecheck:"tsc --noEmit",lint:"eslint --max-warnings 0 .","lint:fix":"eslint --fix .",test:"bun test"},dependencies:{"@brains/auth-service":"workspace:*","@brains/mcp-service":"workspace:*","@brains/plugins":"workspace:*","@modelcontextprotocol/sdk":"^1.24.0",cors:"^2.8.5",express:"^4.18.0","express-async-handler":"^1.2.0"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14","@types/cors":"^2.8.17","@types/express":"^4.17.21",typescript:"^5.3.3"}};class hK extends aY{mcpTransport;stdioServer;httpServer;domain;constructor(A={}){let Q={...A,authToken:A.authToken??process.env.MCP_AUTH_TOKEN};super("mcp",mY0,Q,iFA)}async getTools(){return SY0(this.id,()=>this.context)}async getResources(){return[]}async onRegister(A){if(this.domain=A.domain,this.config.transport==="http"&&!A.plugins.has("webserver"))throw Error("MCP HTTP transport requires the webserver interface. Standalone HTTP listeners have been removed.");if(this.logger.debug(`MCP interface initialized with ${this.config.transport} transport`),this.config.transport==="http")A.endpoints.register({label:"MCP",url:"/mcp",priority:30,visibility:"trusted"}),A.interactions.register({id:"mcp",label:"MCP",description:"Connect a trusted client through the Model Context Protocol.",href:"/mcp",kind:"protocol",priority:30,visibility:"trusted"});rFA(A,this.logger)}getOrCreateHttpServer(){if(this.httpServer)return this.httpServer;let A=nb();return this.httpServer=iU.createFresh({port:this.config.httpPort,logger:this.logger,auth:this.config.authToken?{token:this.config.authToken}:A?{requiredScopes:["mcp"],verifyBearerToken:async(Q)=>A.verifyBearerToken(Q)}:{disabled:!0}}),this.httpServer}getWebRoutes(){if(this.config.transport!=="http")return[];let A=(Q)=>this.getOrCreateHttpServer().handleRequest(Q);return[{path:"/status",method:"GET",public:!0,handler:A},{path:"/mcp",method:"GET",public:!0,handler:A},{path:"/mcp",method:"POST",public:!0,handler:A},{path:"/mcp",method:"DELETE",public:!0,handler:A},{path:"/mcp",method:"OPTIONS",public:!0,handler:A}]}createDaemon(){return{start:async()=>{await this.startServer()},stop:async()=>{await this.stopServer()},healthCheck:async()=>{let A=this.isServerRunning(),Q="MCP server not running";if(A)if(this.config.transport==="http")Q=`MCP HTTP: ${this.domain?`https://${this.domain}/mcp`:"http://localhost:8080/mcp"}`;else Q="MCP stdio server running";return{status:A?"healthy":"error",message:Q,lastCheck:new Date,details:{transport:this.config.transport,url:this.config.transport==="http"?this.domain?`https://${this.domain}/mcp`:"http://localhost:8080/mcp":void 0,running:A}}}}}isServerRunning(){if(this.config.transport==="stdio")return this.stdioServer!==void 0&&this.mcpTransport!==void 0;else return this.httpServer!==void 0&&this.mcpTransport!==void 0}async startServer(){if(!this.context)throw Error("Context not initialized");let A=this.context;this.mcpTransport=A.mcpTransport;let Q=this.config.transport==="stdio"?"stdio":"http",B=this.context.permissions.getUserLevel("mcp",Q);if(this.config.transport==="http"&&(this.config.authToken||nb()))B="anchor",this.logger.debug("HTTP authentication configured - authenticated users will have anchor permissions");if(this.mcpTransport.setPermissionLevel(B),this.logger.debug(`Starting MCP ${this.config.transport} transport with ${B} permissions`),this.config.transport==="stdio"){this.stdioServer=NH.createFresh();let w=this.mcpTransport.getMcpServer();this.stdioServer.connectMCPServer(w),await this.stdioServer.start(),this.logger.debug("MCP STDIO transport started")}else{this.httpServer=this.getOrCreateHttpServer();let w=this.mcpTransport.getMcpServer();this.httpServer.connectMCPServer(w,this.mcpTransport),this.httpServer.connectAgentService(A.agent),this.logger.debug("MCP HTTP transport mounted on shared webserver host")}}async stopServer(){if(this.logger.debug(`Stopping MCP ${this.config.transport} transport`),this.stdioServer)this.stdioServer.stop(),this.stdioServer=void 0;if(this.httpServer)await this.httpServer.stop(),this.httpServer=void 0;this.mcpTransport=void 0}async handleProgressEvent(A,Q){}async onShutdown(){NH.resetInstance(),iU.resetInstance()}}f0();GA();var eD=D1(PS0(),1);GA();f0();var OCA=F.object({botToken:F.string().min(1).describe("Discord bot token"),allowedChannels:F.array(F.string()).default([]),requireMention:F.boolean().default(!0),allowDMs:F.boolean().default(!0),showTypingIndicator:F.boolean().default(!0),statusMessage:F.string().default("Mention me to chat"),useThreads:F.boolean().default(!0),threadAutoArchive:F.union([F.literal(60),F.literal(1440),F.literal(4320),F.literal(10080)]).default(1440),...Yj.shape,captureUrlEmoji:F.string().default("\uD83D\uDD16")});var kS0={name:"@brains/discord",private:!0,version:"0.2.0-alpha.71",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 RCA=2000,WC2=8000,UC2=100;function Ze(A){return!!A&&typeof A==="object"&&"send"in A&&"sendTyping"in A}class KZ extends EN{client=null;fetchText;pendingConfirmations=new Map;typingIntervals=new Map;constructor(A,Q={}){super("discord",kS0,A,OCA);this.fetchText=Q.fetchText??Pp}async onRegister(A){await super.onRegister(A),this.client=new eD.Client({intents:[eD.GatewayIntentBits.Guilds,eD.GatewayIntentBits.GuildMessages,eD.GatewayIntentBits.MessageContent,eD.GatewayIntentBits.DirectMessages],partials:[eD.Partials.Channel]}),this.client.on(eD.Events.MessageCreate,(Q)=>{this.handleMessage(Q)}),this.client.once(eD.Events.ClientReady,()=>{this.logger.info("Discord bot connected",{tag:this.client?.user?.tag})})}createDaemon(){return{start:async()=>{if(!this.client)throw Error("Discord client not initialized");await this.client.login(this.config.botToken)},stop:async()=>{for(let A of this.typingIntervals.values())clearInterval(A);if(this.typingIntervals.clear(),this.client)await this.client.destroy(),this.client=null},healthCheck:async()=>({status:this.client?.user?"healthy":"error",message:this.client?.user?`Connected as ${this.client.user.tag}`:"Not connected",lastCheck:new Date})}}sendMessageToChannel({channelId:A,message:Q}){if(!A||!this.client)return;let B=this.client.channels.cache.get(A);if(!Ze(B))return;let w=Gk(Q,RCA);for(let $ of w)B.send($).catch((f)=>this.logger.error("Failed to send message",{error:f}))}async sendMessageWithId({channelId:A,message:Q}){if(!A||!this.client)return;let B=this.client.channels.cache.get(A);if(!Ze(B))return;let w=Gk(Q,RCA),$;for(let f of w)$=(await B.send(f)).id;return $}async editMessage({channelId:A,messageId:Q,newMessage:B}){if(!A||!this.client)return!1;let w=this.client.channels.cache.get(A);if(!Ze(w))return!1;try{return await(await w.messages.fetch(Q)).edit(B.slice(0,RCA)),!0}catch{return!1}}supportsMessageEditing(){return!0}async handleMessage(A){if(A.author.id===this.client?.user?.id)return;if(!this.context)return;let Q=!A.guild,B=A.channel.isThread();if(Q&&!this.config.allowDMs)return;let w=!!this.client?.user&&A.mentions.has(this.client.user,{ignoreEveryone:!0});if(A.author.bot&&!w)return;let $=B&&"ownerId"in A.channel&&A.channel.ownerId===this.client?.user?.id,f=this.getSpaceChannelId(A),I=!Q&&this.isConfiguredSpace(f),D={channelId:f,isBot:A.author.bot};if(this.config.allowedChannels.length>0&&!Q&&!this.isAllowedChannel(A.channel.id,f))return;let H=Q||$||!this.config.requireMention||w;if(I&&(!H||this.willRouteUseNonSpaceConversation(A)))await this.capturePassiveSpaceMessage(A,f).catch((G)=>this.logger.error("Passive Discord space capture failed",{error:G,channelId:f}));if(!H){if(this.config.captureUrls){let G=this.extractCaptureableUrls(A.content,this.config.blockedUrlDomains);if(G.length>0){await A.react(this.config.captureUrlEmoji).catch((K)=>this.logger.debug("React failed",{error:K}));for(let K of G)await this.captureUrlViaAgent(K,A.channel.id,A.author.id,"discord",D).catch((Z)=>this.logger.error("URL capture failed",{error:Z,url:K}))}}return}let Y=this.stripMention(A.content);if(A.attachments.size>0){let G=this.context.permissions.getUserLevel("discord",A.author.id,D);if(G==="anchor"||G==="trusted")for(let Z of A.attachments.values()){let q=Z.name,L=Z.contentType??void 0,C=Z.size;if(!this.isUploadableTextFile(q,L))continue;if(!this.isFileSizeAllowed(C))continue;try{let R=await this.fetchText(Z.url);Y+=`
|
|
2285
2285
|
|
|
2286
2286
|
`+this.formatFileUploadMessage(q,R)}catch(R){this.logger.error("Failed to download attachment",{error:R,filename:q})}}}if(Y=Y.trim(),!Y)return;let W=A.channel.id;await this.routeToAgent(Y,W,A,D)}async capturePassiveSpaceMessage(A,Q){if(!this.context)return;let B=this.stripMention(A.content).trim();if(!B)return;let w=`discord-${Q}`,$=this.getChannelName(A);await this.context.conversations.start({sessionId:w,interfaceType:"discord",channelId:Q,metadata:{channelName:$,interfaceType:"discord",channelId:Q}}),await this.context.conversations.addMessage({conversationId:w,role:"user",content:B,metadata:this.buildUserMessageMetadata(A,Q,$,{threadId:A.channel.isThread()?A.channel.id:void 0})})}async routeToAgent(A,Q,B,w){if(!this.context)return;let $=this.context.agent,f=Q;if(this.config.useThreads&&B.guild&&!B.channel.isThread())try{f=(await B.startThread({name:cY(A,UC2),autoArchiveDuration:this.config.threadAutoArchive})).id}catch(Y){this.logger.error("Failed to create thread",{error:Y})}let I=`discord-${f}`,D=this.context.permissions.getUserLevel("discord",B.author.id,w),H=this.getChannelName(B);this.startProcessingInput(f);try{let Y=this.client?.channels.cache.get(f);if(Ze(Y))this.startTypingIndicator(Y);if(this.pendingConfirmations.has(I)){await this.handleConfirmationResponse(A,I,f);return}let W=await $.chat(A,I,{userPermissionLevel:D,interfaceType:"discord",channelId:f,channelName:H,...this.buildUserMessageMetadata(B,Q,H,{threadId:f!==Q||B.channel.isThread()?f:void 0})});if(W.pendingConfirmation)this.pendingConfirmations.set(I,!0);let G=await this.sendMessageWithId({channelId:f,message:W.text});if(G&&W.toolResults){for(let K of W.toolResults)if(K.jobId)this.trackAgentResponseForJob(K.jobId,G,f)}}catch(Y){this.logger.error("Error handling message",{error:Y,channelId:f}),this.sendMessageToChannel({channelId:f,message:`**Error:** ${Y instanceof Error?Y.message:"Unknown error"}`})}finally{this.endProcessingInput(),this.stopTypingIndicator(f)}}async handleConfirmationResponse(A,Q,B){let w=sE(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}))},WC2);this.typingIntervals.set(A.id,Q)}stopTypingIndicator(A){let Q=this.typingIntervals.get(A);if(Q)clearInterval(Q),this.typingIntervals.delete(A)}getAuthorDisplayName(A){return A.member?.displayName??A.author.globalName??A.author.username}getChannelName(A){return A.guild?.name??"DM"}getSpaceChannelId(A){if(!A.channel.isThread())return A.channel.id;if("parentId"in A.channel&&typeof A.channel.parentId==="string")return A.channel.parentId;if("parent"in A.channel&&A.channel.parent&&typeof A.channel.parent==="object"&&"id"in A.channel.parent&&typeof A.channel.parent.id==="string")return A.channel.parent.id;return A.channel.id}isConfiguredSpace(A){let Q=`discord:${A}`;return this.context?.spaces.some((B)=>ZU(B,Q))??!1}isAllowedChannel(A,Q){return this.config.allowedChannels.includes(A)||this.config.allowedChannels.includes(Q)}willRouteUseNonSpaceConversation(A){if(A.channel.isThread())return this.getSpaceChannelId(A)!==A.channel.id;return this.config.useThreads&&Boolean(A.guild)}buildUserMessageMetadata(A,Q,B,w={}){return{actor:{actorId:`discord:${A.author.id}`,interfaceType:"discord",role:"user",displayName:this.getAuthorDisplayName(A),username:A.author.username,isBot:Boolean(A.author.bot)},source:{messageId:A.id,channelId:Q,channelName:B,...w.threadId?{threadId:w.threadId}:{},metadata:{...A.guild?.id?{guildId:A.guild.id}:{},...A.guild?.name?{guildName:A.guild.name}:{}}}}}stripMention(A){if(!this.client?.user)return A;return A.replace(new RegExp(`<@!?${this.client.user.id}>`,"g"),"").trim()}}f0();import{resolve as eO,join as tC2}from"path";var _CA=(A,Q,B)=>{return(w,$)=>{let f=-1;return I(0);async function I(D){if(D<=f)throw Error("next() called multiple times");f=D;let H,Y=!1,W;if(A[D])W=A[D][0][0],w.req.routeIndex=D;else W=D===A.length&&$||void 0;if(W)try{H=await W(w,()=>I(D+1))}catch(G){if(G instanceof Error&&Q)w.error=G,H=await Q(G,w),Y=!0;else throw G}else if(w.finalized===!1&&B)H=await B(w);if(H&&(w.finalized===!1||Y))w.res=H;return w}}};var jS0=Symbol();var vS0=async(A,Q=Object.create(null))=>{let{all:B=!1,dot:w=!1}=Q,f=(A instanceof Ne?A.raw.headers:A.headers).get("Content-Type");if(f?.startsWith("multipart/form-data")||f?.startsWith("application/x-www-form-urlencoded"))return JC2(A,{all:B,dot:w});return{}};async function JC2(A,Q){let B=await A.formData();if(B)return GC2(B,Q);return{}}function GC2(A,Q){let B=Object.create(null);if(A.forEach((w,$)=>{if(!(Q.all||$.endsWith("[]")))B[$]=w;else FC2(B,$,w)}),Q.dot)Object.entries(B).forEach(([w,$])=>{if(w.includes("."))KC2(B,w,$),delete B[w]});return B}var FC2=(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]},KC2=(A,Q,B)=>{let w=A,$=Q.split(".");$.forEach((f,I)=>{if(I===$.length-1)w[f]=B;else{if(!w[f]||typeof w[f]!=="object"||Array.isArray(w[f])||w[f]instanceof File)w[f]=Object.create(null);w=w[f]}})};var kCA=(A)=>{let Q=A.split("/");if(Q[0]==="")Q.shift();return Q},xS0=(A)=>{let{groups:Q,path:B}=ZC2(A),w=kCA(B);return NC2(w,Q)},ZC2=(A)=>{let Q=[];return A=A.replace(/\{[^}]+\}/g,(B,w)=>{let $=`@${w}`;return Q.push([$,B]),$}),{groups:Q,path:A}},NC2=(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},ze={},hS0=(A,Q)=>{if(A==="*")return"*";let B=A.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);if(B){let w=`${A}#${Q}`;if(!ze[w])if(B[2])ze[w]=Q&&Q[0]!==":"&&Q[0]!=="*"?[w,B[1],new RegExp(`^${B[2]}(?=/${Q})`)]:[A,B[1],new RegExp(`^${B[2]}$`)];else ze[w]=[A,B[1],!0];return ze[w]}return null},qe=(A,Q)=>{try{return Q(A)}catch{return A.replace(/(?:%[0-9A-Fa-f]{2})+/g,(B)=>{try{return Q(B)}catch{return B}})}},jCA=(A)=>qe(A,decodeURI),vCA=(A)=>{let Q=A.url,B=Q.indexOf("/",Q.indexOf(":")+4),w=B;for(;w<Q.length;w++){let $=Q.charCodeAt(w);if($===37){let f=Q.indexOf("?",w),I=Q.indexOf("#",w),D=f===-1?I===-1?void 0:I:I===-1?f:Math.min(f,I),H=Q.slice(B,D);return jCA(H.includes("%25")?H.replace(/%25/g,"%2525"):H)}else if($===63||$===35)break}return Q.slice(B,w)};var yS0=(A)=>{let Q=vCA(A);return Q.length>1&&Q.at(-1)==="/"?Q.slice(0,-1):Q},cq=(A,Q,...B)=>{if(B.length)Q=cq(Q,...B);return`${A?.[0]==="/"?"":"/"}${A}${Q==="/"?"":`${A?.at(-1)==="/"?"":"/"}${Q?.[0]==="/"?Q.slice(1):Q}`}`},Ce=(A)=>{if(A.charCodeAt(A.length-1)!==63||!A.includes(":"))return null;let Q=A.split("/"),B=[],w="";return Q.forEach(($)=>{if($!==""&&!/\:/.test($))w+="/"+$;else if(/\:/.test($))if(/\?/.test($)){if(B.length===0&&w==="")B.push("/");else B.push(w);let f=$.replace("?","");w+="/"+f,B.push(w)}else w+="/"+$}),B.filter(($,f,I)=>I.indexOf($)===f)},PCA=(A)=>{if(!/[%+]/.test(A))return A;if(A.indexOf("+")!==-1)A=A.replace(/\+/g," ");return A.indexOf("%")!==-1?qe(A,xCA):A},gS0=(A,Q,B)=>{let w;if(!B&&Q&&!/[%+]/.test(Q)){let I=A.indexOf("?",8);if(I===-1)return;if(!A.startsWith(Q,I+1))I=A.indexOf(`&${Q}`,I+1);while(I!==-1){let D=A.charCodeAt(I+Q.length+1);if(D===61){let H=I+Q.length+2,Y=A.indexOf("&",H);return PCA(A.slice(H,Y===-1?void 0:Y))}else if(D==38||isNaN(D))return"";I=A.indexOf(`&${Q}`,I+1)}if(w=/[%+]/.test(A),!w)return}let $={};w??=/[%+]/.test(A);let f=A.indexOf("?",8);while(f!==-1){let I=A.indexOf("&",f+1),D=A.indexOf("=",f);if(D>I&&I!==-1)D=-1;let H=A.slice(f+1,D===-1?I===-1?void 0:I:D);if(w)H=PCA(H);if(f=I,H==="")continue;let Y;if(D===-1)Y="";else if(Y=A.slice(D+1,I===-1?void 0:I),w)Y=PCA(Y);if(B){if(!($[H]&&Array.isArray($[H])))$[H]=[];$[H].push(Y)}else $[H]??=Y}return Q?$[Q]:$},TS0=gS0,SS0=(A,Q)=>{return gS0(A,Q,!0)},xCA=decodeURIComponent;var mS0=(A)=>qe(A,xCA),Ne=class{raw;#A;#Q;routeIndex=0;path;bodyCache={};constructor(A,Q="/",B=[[]]){this.raw=A,this.path=Q,this.#Q=B,this.#A={}}param(A){return A?this.#B(A):this.#f()}#B(A){let Q=this.#Q[0][this.routeIndex][1][A],B=this.#$(Q);return B&&/\%/.test(B)?mS0(B):B}#f(){let A={},Q=Object.keys(this.#Q[0][this.routeIndex][1]);for(let B of Q){let w=this.#$(this.#Q[0][this.routeIndex][1][B]);if(w!==void 0)A[B]=/\%/.test(w)?mS0(w):w}return A}#$(A){return this.#Q[1]?this.#Q[1][A]:A}query(A){return TS0(this.url,A)}queries(A){return SS0(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 vS0(this,A)}#w=(A)=>{let{bodyCache:Q,raw:B}=this,w=Q[A];if(w)return w;let $=Object.keys(Q)[0];if($)return Q[$].then((f)=>{if($==="json")f=JSON.stringify(f);return new Response(f)[A]()});return Q[A]=B[A]()};json(){return this.#w("text").then((A)=>JSON.parse(A))}text(){return this.#w("text")}arrayBuffer(){return this.#w("arrayBuffer")}blob(){return this.#w("blob")}formData(){return this.#w("formData")}addValidatedData(A,Q){this.#A[A]=Q}valid(A){return this.#A[A]}get url(){return this.raw.url}get method(){return this.raw.method}get[jS0](){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 uS0={Stringify:1,BeforeStream:2,Stream:3},cS0=(A,Q)=>{let B=new String(A);return B.isEscaped=!0,B.callbacks=Q,B};var hCA=async(A,Q,B,w,$)=>{if(typeof A==="object"&&!(A instanceof String)){if(!(A instanceof Promise))A=A.toString();if(A instanceof Promise)A=await A}let f=A.callbacks;if(!f?.length)return Promise.resolve(A);if($)$[0]+=A;else $=[A];let I=Promise.all(f.map((D)=>D({phase:Q,buffer:$,context:w}))).then((D)=>Promise.all(D.filter(Boolean).map((H)=>hCA(H,Q,!1,w,$))).then(()=>$[0]));if(B)return cS0(await I,f);else return I};var zC2="text/plain; charset=UTF-8",yCA=(A,Q)=>{return{"Content-Type":A,...Q}},YT=(A,Q)=>new Response(A,Q),pS0=class{#A;#Q;env={};#B;finalized=!1;error;#f;#$;#w;#X;#H;#Y;#D;#W;#U;constructor(A,Q){if(this.#A=A,Q)this.#$=Q.executionCtx,this.env=Q.env,this.#Y=Q.notFoundHandler,this.#U=Q.path,this.#W=Q.matchResult}get req(){return this.#Q??=new Ne(this.#A,this.#U,this.#W),this.#Q}get event(){if(this.#$&&"respondWith"in this.#$)return this.#$;else throw Error("This context has no FetchEvent")}get executionCtx(){if(this.#$)return this.#$;else throw Error("This context has no ExecutionContext")}get res(){return this.#w||=YT(null,{headers:this.#D??=new Headers})}set res(A){if(this.#w&&A){A=YT(A.body,A);for(let[Q,B]of this.#w.headers.entries()){if(Q==="content-type")continue;if(Q==="set-cookie"){let w=this.#w.headers.getSetCookie();A.headers.delete("set-cookie");for(let $ of w)A.headers.append("set-cookie",$)}else A.headers.set(Q,B)}}this.#w=A,this.finalized=!0}render=(...A)=>{return this.#H??=(Q)=>this.html(Q),this.#H(...A)};setLayout=(A)=>this.#X=A;getLayout=()=>this.#X;setRenderer=(A)=>{this.#H=A};header=(A,Q,B)=>{if(this.finalized)this.#w=YT(this.#w.body,this.#w);let w=this.#w?this.#w.headers:this.#D??=new Headers;if(Q===void 0)w.delete(A);else if(B?.append)w.append(A,Q);else w.set(A,Q)};status=(A)=>{this.#f=A};set=(A,Q)=>{this.#B??=new Map,this.#B.set(A,Q)};get=(A)=>{return this.#B?this.#B.get(A):void 0};get var(){if(!this.#B)return{};return Object.fromEntries(this.#B)}#I(A,Q,B){let w=this.#w?new Headers(this.#w.headers):this.#D??new Headers;if(typeof Q==="object"&&"headers"in Q){let f=Q.headers instanceof Headers?Q.headers:new Headers(Q.headers);for(let[I,D]of f)if(I.toLowerCase()==="set-cookie")w.append(I,D);else w.set(I,D)}if(B)for(let[f,I]of Object.entries(B))if(typeof I==="string")w.set(f,I);else{w.delete(f);for(let D of I)w.append(f,D)}let $=typeof Q==="number"?Q:Q?.status??this.#f;return YT(A,{status:$,headers:w})}newResponse=(...A)=>this.#I(...A);body=(A,Q,B)=>this.#I(A,Q,B);text=(A,Q,B)=>{return!this.#D&&!this.#f&&!Q&&!B&&!this.finalized?new Response(A):this.#I(A,Q,yCA(zC2,B))};json=(A,Q,B)=>{return this.#I(JSON.stringify(A),Q,yCA("application/json",B))};html=(A,Q,B)=>{let w=($)=>this.#I($,Q,yCA("text/html; charset=UTF-8",B));return typeof A==="object"?hCA(A,uS0.Stringify,!1,{}).then(w):w(A)};redirect=(A,Q)=>{let B=String(A);return this.header("Location",!/[^\x00-\xFF]/.test(B)?B:encodeURI(B)),this.newResponse(null,Q??302)};notFound=()=>{return this.#Y??=()=>YT(),this.#Y(this)}};var Kw="ALL",lS0="all",iS0=["get","post","put","delete","options","patch"],Le="Can not add a route since the matcher is already built.",Ee=class extends Error{};var gCA="__COMPOSED_HANDLER";var qC2=(A)=>{return A.text("404 Not Found",404)},rS0=(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)},dS0=class A{get;post;put;delete;options;patch;all;on;use;router;getPath;_basePath="/";#A="/";routes=[];constructor(Q={}){[...iS0,lS0].forEach((f)=>{this[f]=(I,...D)=>{if(typeof I==="string")this.#A=I;else this.#f(f,this.#A,I);return D.forEach((H)=>{this.#f(f,this.#A,H)}),this}}),this.on=(f,I,...D)=>{for(let H of[I].flat()){this.#A=H;for(let Y of[f].flat())D.map((W)=>{this.#f(Y.toUpperCase(),this.#A,W)})}return this},this.use=(f,...I)=>{if(typeof f==="string")this.#A=f;else this.#A="*",I.unshift(f);return I.forEach((D)=>{this.#f(Kw,this.#A,D)}),this};let{strict:w,...$}=Q;Object.assign(this,$),this.getPath=w??!0?Q.getPath??vCA:yS0}#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=qC2;errorHandler=rS0;route(Q,B){let w=this.basePath(Q);return B.routes.map(($)=>{let f;if(B.errorHandler===rS0)f=$.handler;else f=async(I,D)=>(await _CA([],B.errorHandler)(I,()=>$.handler(I,D))).res,f[gCA]=$.handler;w.#f($.method,$.path,f)}),this}basePath(Q){let B=this.#Q();return B._basePath=cq(this._basePath,Q),B}onError=(Q)=>{return this.errorHandler=Q,this};notFound=(Q)=>{return this.#B=Q,this};mount(Q,B,w){let $,f;if(w)if(typeof w==="function")f=w;else if(f=w.optionHandler,w.replaceRequest===!1)$=(H)=>H;else $=w.replaceRequest;let I=f?(H)=>{let Y=f(H);return Array.isArray(Y)?Y:[Y]}:(H)=>{let Y=void 0;try{Y=H.executionCtx}catch{}return[H.env,Y]};$||=(()=>{let H=cq(this._basePath,Q),Y=H==="/"?0:H.length;return(W)=>{let G=new URL(W.url);return G.pathname=G.pathname.slice(Y)||"/",new Request(G,W)}})();let D=async(H,Y)=>{let W=await B($(H.req.raw),...I(H));if(W)return W;await Y()};return this.#f(Kw,cq(Q,"*"),D),this}#f(Q,B,w){Q=Q.toUpperCase(),B=cq(this._basePath,B);let $={basePath:this._basePath,path:B,method:Q,handler:w};this.router.add(Q,B,[w,$]),this.routes.push($)}#$(Q,B){if(Q instanceof Error)return this.errorHandler(Q,B);throw Q}#w(Q,B,w,$){if($==="HEAD")return(async()=>new Response(null,await this.#w(Q,B,w,"GET")))();let f=this.getPath(Q,{env:w}),I=this.router.match($,f),D=new pS0(Q,{path:f,matchResult:I,env:w,executionCtx:B,notFoundHandler:this.#B});if(I[0].length===1){let Y;try{Y=I[0][0][0][0](D,async()=>{D.res=await this.#B(D)})}catch(W){return this.#$(W,D)}return Y instanceof Promise?Y.then((W)=>W||(D.finalized?D.res:this.#B(D))).catch((W)=>this.#$(W,D)):Y??this.#B(D)}let H=_CA(I[0],this.errorHandler,this.#B);return(async()=>{try{let Y=await H(D);if(!Y.finalized)throw Error("Context is not finalized. Did you forget to return a Response object or `await next()`?");return Y.res}catch(Y){return this.#$(Y,D)}})()}fetch=(Q,...B)=>{return this.#w(Q,B[1],B[0],Q.method)};request=(Q,B,w,$)=>{if(Q instanceof Request)return this.fetch(B?new Request(Q,B):Q,w,$);return Q=Q.toString(),this.fetch(new Request(/^https?:\/\//.test(Q)?Q:`http://localhost${cq("/",Q)}`,B),w,$)};fire=()=>{addEventListener("fetch",(Q)=>{Q.respondWith(this.#w(Q.request,Q,void 0,Q.request.method))})}};var XT=[];function Me(A,Q){let B=this.buildAllMatchers(),w=($,f)=>{let I=B[$]||B[Kw],D=I[2][f];if(D)return D;let H=f.match(I[0]);if(!H)return[[],XT];let Y=H.indexOf("",1);return[I[1][Y],H]};return this.match=w,w(A,Q)}var Ve="[^/]+",WT=".*",UT="(?:|/.*)",pq=Symbol(),CC2=new Set(".\\+*[^]$()");function LC2(A,Q){if(A.length===1)return Q.length===1?A<Q?-1:1:-1;if(Q.length===1)return 1;if(A===WT||A===UT)return 1;else if(Q===WT||Q===UT)return-1;if(A===Ve)return 1;else if(Q===Ve)return-1;return A.length===Q.length?A<Q?-1:1:Q.length-A.length}var nS0=class A{#A;#Q;#B=Object.create(null);insert(Q,B,w,$,f){if(Q.length===0){if(this.#A!==void 0)throw pq;if(f)return;this.#A=B;return}let[I,...D]=Q,H=I==="*"?D.length===0?["","",WT]:["","",Ve]:I==="/*"?["","",UT]:I.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/),Y;if(H){let W=H[1],G=H[2]||Ve;if(W&&H[2]){if(G===".*")throw pq;if(G=G.replace(/^\((?!\?:)(?=[^)]+\)$)/,"(?:"),/\((?!\?:)/.test(G))throw pq}if(Y=this.#B[G],!Y){if(Object.keys(this.#B).some((K)=>K!==WT&&K!==UT))throw pq;if(f)return;if(Y=this.#B[G]=new A,W!=="")Y.#Q=$.varIndex++}if(!f&&W!=="")w.push([W,Y.#Q])}else if(Y=this.#B[I],!Y){if(Object.keys(this.#B).some((W)=>W.length>1&&W!==WT&&W!==UT))throw pq;if(f)return;Y=this.#B[I]=new A}Y.insert(D,B,w,$,f)}buildRegExpStr(){let B=Object.keys(this.#B).sort(LC2).map((w)=>{let $=this.#B[w];return(typeof $.#Q==="number"?`(${w})@${$.#Q}`:CC2.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 oS0=class{#A={varIndex:0};#Q=new nS0;insert(A,Q,B){let w=[],$=[];for(let I=0;;){let D=!1;if(A=A.replace(/\{[^}]+\}/g,(H)=>{let Y=`@\\${I}`;return $[I]=[Y,H],I++,D=!0,Y}),!D)break}let f=A.match(/(?::[^\/]+)|(?:\/\*$)|./g)||[];for(let I=$.length-1;I>=0;I--){let[D]=$[I];for(let H=f.length-1;H>=0;H--)if(f[H].indexOf(D)!==-1){f[H]=f[H].replace(D,$[I][1]);break}}return this.#Q.insert(f,Q,w,this.#A,B),w}buildRegExp(){let A=this.#Q.buildRegExpStr();if(A==="")return[/^$/,[],[]];let Q=0,B=[],w=[];return A=A.replace(/#(\d+)|@(\d+)|\.\*\$/g,($,f,I)=>{if(f!==void 0)return B[++Q]=Number(f),"$()";if(I!==void 0)return w[Number(I)]=++Q,"";return""}),[new RegExp(`^${A}`),B,w]}};var EC2=[/^$/,[],Object.create(null)],sS0=Object.create(null);function aS0(A){return sS0[A]??=new RegExp(A==="*"?"":`^${A.replace(/\/\*$|([.\\+*[^\]$()])/g,(Q,B)=>B?`\\${B}`:"(?:|/.*)")}$`)}function MC2(){sS0=Object.create(null)}function VC2(A){let Q=new oS0,B=[];if(A.length===0)return EC2;let w=A.map((Y)=>[!/\*|\/:/.test(Y[0]),...Y]).sort(([Y,W],[G,K])=>Y?1:G?-1:W.length-K.length),$=Object.create(null);for(let Y=0,W=-1,G=w.length;Y<G;Y++){let[K,Z,q]=w[Y];if(K)$[Z]=[q.map(([C])=>[C,Object.create(null)]),XT];else W++;let L;try{L=Q.insert(Z,W,K)}catch(C){throw C===pq?new Ee(Z):C}if(K)continue;B[W]=q.map(([C,R])=>{let k=Object.create(null);R-=1;for(;R>=0;R--){let[_,o]=L[R];k[_]=o}return[C,k]})}let[f,I,D]=Q.buildRegExp();for(let Y=0,W=B.length;Y<W;Y++)for(let G=0,K=B[Y].length;G<K;G++){let Z=B[Y][G]?.[1];if(!Z)continue;let q=Object.keys(Z);for(let L=0,C=q.length;L<C;L++)Z[q[L]]=D[Z[q[L]]]}let H=[];for(let Y in I)H[Y]=B[I[Y]];return[f,H,$]}function sO(A,Q){if(!A)return;for(let B of Object.keys(A).sort((w,$)=>$.length-w.length))if(aS0(B).test(Q))return[...A[B]];return}var be=class{name="RegExpRouter";#A;#Q;constructor(){this.#A={[Kw]:Object.create(null)},this.#Q={[Kw]:Object.create(null)}}add(A,Q,B){let w=this.#A,$=this.#Q;if(!w||!$)throw Error(Le);if(!w[A])[w,$].forEach((D)=>{D[A]=Object.create(null),Object.keys(D[Kw]).forEach((H)=>{D[A][H]=[...D[Kw][H]]})});if(Q==="/*")Q="*";let f=(Q.match(/\/:/g)||[]).length;if(/\*$/.test(Q)){let D=aS0(Q);if(A===Kw)Object.keys(w).forEach((H)=>{w[H][Q]||=sO(w[H],Q)||sO(w[Kw],Q)||[]});else w[A][Q]||=sO(w[A],Q)||sO(w[Kw],Q)||[];Object.keys(w).forEach((H)=>{if(A===Kw||A===H)Object.keys(w[H]).forEach((Y)=>{D.test(Y)&&w[H][Y].push([B,f])})}),Object.keys($).forEach((H)=>{if(A===Kw||A===H)Object.keys($[H]).forEach((Y)=>D.test(Y)&&$[H][Y].push([B,f]))});return}let I=Ce(Q)||[Q];for(let D=0,H=I.length;D<H;D++){let Y=I[D];Object.keys($).forEach((W)=>{if(A===Kw||A===W)$[W][Y]||=[...sO(w[W],Y)||sO(w[Kw],Y)||[]],$[W][Y].push([B,f-H+D+1])})}}match=Me;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,MC2(),A}#B(A){let Q=[],B=A===Kw;if([this.#A,this.#Q].forEach((w)=>{let $=w[A]?Object.keys(w[A]).map((f)=>[f,w[A][f]]):[];if($.length!==0)B||=!0,Q.push(...$);else if(A!==Kw)Q.push(...Object.keys(w[Kw]).map((f)=>[f,w[Kw][f]]))}),!B)return null;else return VC2(Q)}};var bC2=class{name="PreparedRegExpRouter";#A;#Q;constructor(A,Q){this.#A=A,this.#Q=Q}#B(A,Q){let B=this.#A[A];B[1].forEach((w)=>w&&w.push(Q)),Object.values(B[2]).forEach((w)=>w[0].push(Q))}#f(A,Q,B,w,$){let f=this.#A[A];if(!$)f[2][Q][0].push([B,{}]);else w.forEach((I)=>{if(typeof I==="number")f[1][I].push([B,$]);else f[2][I||Q][0].push([B,$])})}add(A,Q,B){if(!this.#A[A]){let $=this.#A[Kw],f={};for(let I in $[2])f[I]=[$[2][I][0].slice(),XT];this.#A[A]=[$[0],$[1].map((I)=>Array.isArray(I)?I.slice():0),f]}if(Q==="/*"||Q==="*"){let $=[B,{}];if(A===Kw)for(let f in this.#A)this.#B(f,$);else this.#B(A,$);return}let w=this.#Q[Q];if(!w)throw Error(`Path ${Q} is not registered`);for(let[$,f]of w)if(A===Kw)for(let I in this.#A)this.#f(I,Q,B,$,f);else this.#f(A,Q,B,$,f)}buildAllMatchers(){return this.#A}match=Me};var TCA=class{name="SmartRouter";#A=[];#Q=[];constructor(A){this.#A=A.routers}add(A,Q,B){if(!this.#Q)throw Error(Le);this.#Q.push([A,Q,B])}match(A,Q){if(!this.#Q)throw Error("Fatal error");let B=this.#A,w=this.#Q,$=B.length,f=0,I;for(;f<$;f++){let D=B[f];try{for(let H=0,Y=w.length;H<Y;H++)D.add(...w[H]);I=D.match(A,Q)}catch(H){if(H instanceof Ee)continue;throw H}this.match=D.match.bind(D),this.#A=[D],this.#Q=void 0;break}if(f===$)throw Error("Fatal error");return this.name=`SmartRouter + ${this.activeRouter.name}`,I}get activeRouter(){if(this.#Q||this.#A.length!==1)throw Error("No active router has been determined yet.");return this.#A[0]}};var JT=Object.create(null),OC2=(A)=>{for(let Q in A)return!0;return!1},tS0=class A{#A;#Q;#B;#f=0;#$=JT;constructor(Q,B,w){if(this.#Q=w||Object.create(null),this.#A=[],Q&&B){let $=Object.create(null);$[Q]={handler:B,possibleKeys:[],score:0},this.#A=[$]}this.#B=[]}insert(Q,B,w){this.#f=++this.#f;let $=this,f=xS0(B),I=[];for(let D=0,H=f.length;D<H;D++){let Y=f[D],W=f[D+1],G=hS0(Y,W),K=Array.isArray(G)?G[0]:Y;if(K in $.#Q){if($=$.#Q[K],G)I.push(G[1]);continue}if($.#Q[K]=new A,G)$.#B.push(G),I.push(G[1]);$=$.#Q[K]}return $.#A.push({[Q]:{handler:w,possibleKeys:I.filter((D,H,Y)=>Y.indexOf(D)===H),score:this.#f}}),$}#w(Q,B,w,$,f){for(let I=0,D=B.#A.length;I<D;I++){let H=B.#A[I],Y=H[w]||H[Kw],W={};if(Y!==void 0){if(Y.params=Object.create(null),Q.push(Y),$!==JT||f&&f!==JT)for(let G=0,K=Y.possibleKeys.length;G<K;G++){let Z=Y.possibleKeys[G],q=W[Y.score];Y.params[Z]=f?.[Z]&&!q?f[Z]:$[Z]??f?.[Z],W[Y.score]=!0}}}}search(Q,B){let w=[];this.#$=JT;let f=[this],I=kCA(B),D=[],H=I.length,Y=null;for(let W=0;W<H;W++){let G=I[W],K=W===H-1,Z=[];for(let L=0,C=f.length;L<C;L++){let R=f[L],k=R.#Q[G];if(k)if(k.#$=R.#$,K){if(k.#Q["*"])this.#w(w,k.#Q["*"],Q,R.#$);this.#w(w,k,Q,R.#$)}else Z.push(k);for(let _=0,o=R.#B.length;_<o;_++){let r=R.#B[_],S=R.#$===JT?{}:{...R.#$};if(r==="*"){let c=R.#Q["*"];if(c)this.#w(w,c,Q,R.#$),c.#$=S,Z.push(c);continue}let[x,y,g]=r;if(!G&&!(g instanceof RegExp))continue;let AA=R.#Q[x];if(g instanceof RegExp){if(Y===null){Y=Array(H);let HA=B[0]==="/"?1:0;for(let P=0;P<H;P++)Y[P]=HA,HA+=I[P].length+1}let c=B.substring(Y[W]),JA=g.exec(c);if(JA){if(S[y]=JA[0],this.#w(w,AA,Q,R.#$,S),OC2(AA.#Q)){AA.#$=S;let HA=JA[0].match(/\//)?.length??0;(D[HA]||=[]).push(AA)}continue}}if(g===!0||g.test(G))if(S[y]=G,K){if(this.#w(w,AA,Q,S,R.#$),AA.#Q["*"])this.#w(w,AA.#Q["*"],Q,S,R.#$)}else AA.#$=S,Z.push(AA)}}let q=D.shift();f=q?Z.concat(q):Z}if(w.length>1)w.sort((W,G)=>{return W.score-G.score});return[w.map(({handler:W,params:G})=>[W,G])]}};var SCA=class{name="TrieRouter";#A;constructor(){this.#A=new tS0}add(A,Q,B){let w=Ce(Q);if(w){for(let $=0,f=w.length;$<f;$++)this.#A.insert(A,w[$],B);return}this.#A.insert(A,Q,B)}match(A,Q){return this.#A.search(A,Q)}};var aO=class extends dS0{constructor(A={}){super(A);this.router=A.router??new TCA({routers:[new be,new SCA]})}};import{stat as jC2}from"fs/promises";import{join as vC2}from"path";var tO=/^\s*(?:text\/(?!event-stream(?:[;\s]|$))[^;\s]+|application\/(?:javascript|json|xml|xml-dtd|ecmascript|dart|postscript|rtf|tar|toml|vnd\.dart|vnd\.ms-fontobject|vnd\.ms-opentype|wasm|x-httpd-php|x-javascript|x-ns-proxy-autoconfig|x-sh|x-tar|x-virtualbox-hdd|x-virtualbox-ova|x-virtualbox-ovf|x-virtualbox-vbox|x-virtualbox-vdi|x-virtualbox-vhd|x-virtualbox-vmdk|x-www-form-urlencoded)|font\/(?:otf|ttf)|image\/(?:bmp|vnd\.adobe\.photoshop|vnd\.microsoft\.icon|vnd\.ms-dds|x-icon|x-ms-bmp)|message\/rfc822|model\/gltf-binary|x-shader\/x-fragment|x-shader\/x-vertex|[^;\s]+?\+(?:json|text|xml|yaml))(?:[;\s]|$)/i;var mCA=(A,Q=_C2)=>{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 RC2={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"},_C2=RC2;var eS0=(...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 Am0={br:".br",zstd:".zst",gzip:".gz"},PC2=Object.keys(Am0),kC2="index.html",Qm0=(A)=>{let Q=A.root??"./",B=A.path,w=A.join??eS0;return async($,f)=>{if($.finalized)return f();let I;if(A.path)I=A.path;else try{if(I=jCA($.req.path),/(?:^|[\/\\])\.\.(?:$|[\/\\])/.test(I))throw Error()}catch{return await A.onNotFound?.($.req.path,$),f()}let D=w(Q,!B&&A.rewriteRequestPath?A.rewriteRequestPath(I):I);if(A.isDir&&await A.isDir(D))D=w(D,kC2);let H=A.getContent,Y=await H(D,$);if(Y instanceof Response)return $.newResponse(Y.body,Y);if(Y){let W=A.mimes&&mCA(D,A.mimes)||mCA(D);if($.header("Content-Type",W||"application/octet-stream"),A.precompressed&&(!W||tO.test(W))){let G=new Set($.req.header("Accept-Encoding")?.split(",").map((K)=>K.trim()));for(let K of PC2){if(!G.has(K))continue;let Z=await H(D+Am0[K],$);if(Z){Y=Z,$.header("Content-Encoding",K),$.header("Vary","Accept-Encoding",{append:!0});break}}}return await A.onFound?.(D,$),$.body(Y)}await A.onNotFound?.(D,$),await f();return}};var uCA=(A)=>{return async function(B,w){return Qm0({...A,getContent:async(I)=>{let D=Bun.file(I);return await D.exists()?D:null},join:vC2,isDir:async(I)=>{let D;try{D=(await jC2(I)).isDirectory()}catch{}return D}})(B,w)}};var cCA="x-hono-disable-ssg",PyB=(()=>{try{return new Response("SSG is disabled",{status:404,headers:{[cCA]:"true"}})}catch{return null}})();var{write:WgB}=Bun;var yC2=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 Bm0=(A)=>{return(...Q)=>{if(typeof Q[0]==="function"){let[B,w]=Q;return async function(f,I){let D=await B(f),H=await A(f,D,w);if(H)return H;await I()}}else{let[B,w,$]=Q;return(async()=>{let f=await A(B,w,$);if(!f)throw Error("Failed to upgrade WebSocket");return f})()}}};var Oe=(A)=>("server"in A.env)?A.env.server:A.env;var gC2=Bm0((A,Q)=>{let B=Oe(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 TC2=["gzip","deflate"],SC2=/(?:^|,)\s*?no-transform\s*?(?:,|$)/i,wm0=(A)=>{let Q=A?.threshold??1024;return async function(w,$){await $();let f=w.res.headers.get("Content-Length");if(w.res.headers.has("Content-Encoding")||w.res.headers.has("Transfer-Encoding")||w.req.method==="HEAD"||f&&Number(f)<Q||!mC2(w.res)||!uC2(w.res))return;let I=w.req.header("Accept-Encoding"),D=A?.encoding??TC2.find((Y)=>I?.includes(Y));if(!D||!w.res.body)return;let H=new CompressionStream(D);w.res=new Response(w.res.body.pipeThrough(H),w.res),w.res.headers.delete("Content-Length"),w.res.headers.set("Content-Encoding",D)}},mC2=(A)=>{let Q=A.headers.get("Content-Type");return Q&&tO.test(Q)},uC2=(A)=>{let Q=A.headers.get("Cache-Control");return!Q||!SC2.test(Q)};import{Readable as $m0}from"stream";import{createDeflate as cC2,createGzip as pC2}from"zlib";var lC2=["gzip","deflate"],iC2=/(?:^|,)\s*?no-transform\s*?(?:,|$)/i,fm0=(A)=>{if(typeof CompressionStream<"u")return wm0(A);let Q=A?.threshold??1024;return async function(w,$){await $();let f=w.res.headers.get("Content-Length");if(w.res.headers.has("Content-Encoding")||w.res.headers.has("Transfer-Encoding")||w.req.method==="HEAD"||f&&Number(f)<Q||!rC2(w.res)||!dC2(w.res))return;let I=w.req.header("Accept-Encoding"),D=A?.encoding??lC2.find((H)=>I?.includes(H));if(!D||!w.res.body)return;try{let H=D==="gzip"?pC2():cC2(),Y=w.res.body,G=$m0.fromWeb(Y).pipe(H),K=$m0.toWeb(G);w.res=new Response(K,w.res),w.res.headers.delete("Content-Length"),w.res.headers.set("Content-Encoding",D)}catch(H){console.error("Compression error:",H)}}},rC2=(A)=>{let Q=A.headers.get("Content-Type");return Q&&tO.test(Q)},dC2=(A)=>{let Q=A.headers.get("Cache-Control");return!Q||!iC2.test(Q)};var nC2=(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},Im0=async(A,Q)=>{if(!A)return null;let B=void 0,w=A.getReader();for(;;){let{value:$,done:f}=await w.read();if(f)break;B=await Q(nC2(B,$))}if(!B)return null;return Array.prototype.map.call(new Uint8Array(B),($)=>$.toString(16).padStart(2,"0")).join("")};var oC2=["cache-control","content-location","date","etag","expires","vary"],Dm0=(A)=>A.replace(/^W\//,"");function sC2(A,Q){return Q!=null&&Q.split(/,\s*/).some((B)=>Dm0(B)===Dm0(A))}function aC2(A){if(!A){if(crypto&&crypto.subtle)A=(Q)=>crypto.subtle.digest({name:"SHA-1"},Q)}return A}var Hm0=(A)=>{let Q=A?.retainedHeaders??oC2,B=A?.weak??!1,w=aC2(A?.generateDigest);return async function(f,I){let D=f.req.header("If-None-Match")??null;await I();let H=f.res,Y=H.headers.get("ETag");if(!Y){if(!w)return;let W=await Im0(H.clone().body,w);if(W===null)return;Y=B?`W/"${W}"`:`"${W}"`}if(sC2(Y,D))f.res=new Response(null,{status:304,statusText:"Not Modified",headers:{ETag:Y}}),f.res.headers.forEach((W,G)=>{if(Q.indexOf(G.toLowerCase())===-1)f.res.headers.delete(G)});else f.res.headers.set("ETag",Y)}};f0();function Re(A,Q){return async(B)=>{let w=B.req.raw,$=w.headers.get("content-type")??"",f=w.headers.get("accept")?.includes("application/json"),I={};if($.includes("application/json"))I=await w.json();else if($.includes("form")){let Z=await w.formData();for(let[q,L]of Z.entries())I[q]=L}let D=`${A.pluginId}_${A.definition.tool}`,H=await Q.send({type:`plugin:${A.pluginId}:tool:execute`,payload:{toolName:D,args:I,interfaceType:"webserver",userId:"anonymous"},sender:"webserver"}),Y=typeof H==="object"&&"data"in H?H.data:H,W=_k.safeParse(Y),G=W.success?W.data:Y,K=W.success&&W.data.success===!0;if(f)return B.json(G,K?200:400);if(K&&A.definition.successRedirect)return B.redirect(A.definition.successRedirect);if(!K&&A.definition.errorRedirect)return B.redirect(A.definition.errorRedirect);return B.json(G,K?200:400)}}var Ym0="public, max-age=31536000, immutable";class _e{logger;options;productionServer=null;isPreviewHost(A){if(!A)return!1;let Q=A.replace(/:\d+$/,"").toLowerCase();return/^(?:preview\..+|.+-preview\..+)$/.test(Q)}constructor(A){this.logger=A.logger,this.options={...A,productionDistDir:eO(process.cwd(),A.productionDistDir),sharedImagesDir:eO(process.cwd(),A.sharedImagesDir),...A.previewDistDir&&{previewDistDir:eO(process.cwd(),A.previewDistDir)}}}async start(){if(this.productionServer){this.logger.warn("Webserver already running");return}let A=this.createApp({distDir:this.options.productionDistDir,compress:!0,defaultCache:"public, max-age=3600",immutableExtensions:/\.(js|css|jpg|jpeg|png|gif|ico|woff|woff2)$/,healthEndpoint:!0}),Q=this.options.previewDistDir?this.createApp({distDir:this.options.previewDistDir,compress:!1,defaultCache:"no-cache",immutableExtensions:/\.(jpg|jpeg|png|gif|ico|webp|svg|woff|woff2)$/,healthEndpoint:!1}):void 0;try{this.productionServer=Bun.serve({port:this.options.productionPort,fetch:async(B)=>{let w=await this.serveImageFastPath(B);if(w)return w;if(Q&&this.isPreviewHost(B.headers.get("host")))return Q.fetch(B);return A.fetch(B)}})}catch(B){let w=String(B);if(w.includes("EADDRINUSE")||w.includes("address already in use"))throw Error(`Port ${this.options.productionPort} is already in use. Another brain may be running \u2014 stop it first or configure a different port.`);throw B}this.logger.info(`Production server listening on http://localhost:${this.productionServer.port}`)}async stop(){if(this.productionServer)await this.productionServer.stop(),this.productionServer=null;this.logger.debug("Webserver stopped")}getStatus(){return{running:this.productionServer!==null,productionUrl:this.productionServer?`http://localhost:${this.productionServer.port}`:void 0,previewUrl:this.productionServer&&this.options.previewDistDir?`http://localhost:${this.productionServer.port}`:void 0}}createApp(A){let Q=new aO;if(A.healthEndpoint)Q.get("/health",async(B)=>{if(this.options.getHealthData){let w=await this.options.getHealthData();return B.json({status:"healthy",...w},200)}return B.json({status:"healthy"},200)});if(Q.use("/*",async(B,w)=>{let $=await this.handleDynamicRoute(B,A);if($)return $;return w()}),A.compress)Q.use("/*",fm0());return Q.use("/*",Hm0()),Q.use("/*",async(B,w)=>{if(await w(),A.immutableExtensions.test(B.req.path))B.header("Cache-Control",Ym0);else B.header("Cache-Control",A.defaultCache)}),Q.use("/*",this.createCleanUrlMiddleware(A.distDir)),Q.use("/*",uCA({root:A.distDir})),Q.notFound(async(B)=>{let w=Bun.file(tC2(A.distDir,"404.html"));if(await w.exists())return B.html(await w.text(),404);return B.text("Not Found",404)}),Q}getCurrentWebRoutes(){return this.options.getWebRoutes?.()??this.options.webRoutes??[]}getCurrentApiRoutes(){return this.options.getApiRoutes?.()??this.options.apiRoutes??[]}async handleDynamicRoute(A,Q){if(!Q.healthEndpoint)return null;let B=A.req.method.toUpperCase(),w=A.req.path,$=this.getCurrentWebRoutes().find((I)=>{let D=I.definition.method??"GET";return I.fullPath===w&&D===B});if($)return $.definition.handler(A.req.raw);let f=this.getCurrentApiRoutes().find((I)=>{let D=I.definition.method;return I.fullPath===w&&D===B});if(f&&this.options.messageBus)return Re(f,this.options.messageBus)(A);return null}async serveImageFastPath(A){let Q;try{Q=new URL(A.url)}catch{return null}if(!Q.pathname.startsWith("/images/"))return null;let B=Q.pathname.slice(8),w=eO(this.options.sharedImagesDir,B);if(!w.startsWith(this.options.sharedImagesDir))return null;let $=Bun.file(w);if(!await $.exists())return null;return new Response($,{headers:{"Cache-Control":Ym0}})}createCleanUrlMiddleware(A){return async(Q,B)=>{let w=Q.req.path;if(w.includes(".")||w==="/"){await B();return}let $=eO(A,`.${w}`,"index.html");if(!$.startsWith(A)){await B();return}let f=Bun.file($);if(await f.exists())return Q.html(await f.text());let I=eO(A,`.${w}.html`);if(I.startsWith(A)){let D=Bun.file(I);if(await D.exists())return Q.html(await D.text())}await B()}}}import{existsSync as Wm0}from"fs";import{join as Um0}from"path";GA();var pCA=F.object({enablePreview:F.boolean().default(!0).describe("Enable the preview site server when preview assets are configured"),previewDistDir:F.string().default("./dist/site-preview").describe("Directory for preview site files"),productionDistDir:F.string().describe("Directory for production site files").default("./dist/site-production"),sharedImagesDir:F.string().default("./dist/images").describe("Shared directory for optimized images"),previewPort:F.number().default(4321).describe("Port for preview server"),productionPort:F.number().describe("Port for production server").default(8080),apiPort:F.number().describe("Port for API route server (plugin HTTP endpoints)").default(3335)});var lCA=`<!DOCTYPE html>
|
|
2287
2287
|
<html lang="en">
|
|
@@ -2350,7 +2350,7 @@ ${R}`)}if(w!==void 0&&f?.algorithms!==void 0){let C=f.algorithms.map((R)=>R.alg)
|
|
|
2350
2350
|
<p>Once built, this page will be replaced with your actual website.</p>
|
|
2351
2351
|
</div>
|
|
2352
2352
|
</body>
|
|
2353
|
-
</html>`;var Xm0={name:"@brains/webserver",private:!0,version:"0.2.0-alpha.
|
|
2353
|
+
</html>`;var Xm0={name:"@brains/webserver",private:!0,version:"0.2.0-alpha.71",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts"},dependencies:{"@brains/plugins":"workspace:*","@hono/bun-compress":"^0.1.0",hono:"^4.7.10"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/messaging-service":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14","@types/node":"^20.0.0",eslint:"^8.56.0",typescript:"^5.3.3"}};class ZZ extends aY{serverManager;siteUrl;previewUrl;constructor(A={}){super("webserver",Xm0,A,pCA)}async onRegister(A){if(this.siteUrl=A.siteUrl,this.previewUrl=A.previewUrl,this.siteUrl)A.endpoints.register({label:"Site",url:this.siteUrl,priority:10}),A.interactions.register({id:"site",label:"Public site",description:"Visit the published public site for this brain.",href:this.siteUrl,kind:"human",priority:10});if(this.config.enablePreview&&this.previewUrl)A.endpoints.register({label:"Preview",url:this.previewUrl,priority:20,visibility:"anchor"}),A.interactions.register({id:"preview",label:"Preview site",description:"Open the private preview build.",href:this.previewUrl,kind:"admin",priority:20,visibility:"anchor"});this.serverManager=new _e({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&&!Wm0(this.config.previewDistDir))await A(this.config.previewDistDir,{recursive:!0}),await Q(Um0(this.config.previewDistDir,"index.html"),lCA),this.logger.debug(`Created preview directory at ${this.config.previewDistDir}`);if(!Wm0(this.config.productionDistDir))await A(this.config.productionDistDir,{recursive:!0}),await Q(Um0(this.config.productionDistDir,"index.html"),lCA),this.logger.debug(`Created production directory at ${this.config.productionDistDir}`)}}f0();GA();var Jm0=F.object({port:F.number().default(3334),organization:F.string().optional(),trustedTokens:F.record(F.string()).optional(),outboundTokens:F.record(F.string()).optional(),requestTimeoutMs:F.number().positive().default(30000),streamIdleTimeoutMs:F.number().positive().default(60000),maxNetworkAttempts:F.number().int().positive().default(2)});f0();function AL2(A,Q){return`${A.name} is ${Q.name}'s ${A.role}. Its purpose is: ${A.purpose}.`}function Gm0(A){let{character:Q,profile:B,version:w,domain:$,organization:f,tools:I}=A,H=`${A.baseUrl??($?`https://${$}`:"http://localhost:8080")}/a2a`,Y=A.skills&&A.skills.length>0?A.skills.map((K)=>({id:K.name.toLowerCase().replace(/\s+/g,"-"),name:K.name,description:K.description,tags:K.tags,examples:K.examples})):I.map((K)=>({id:K.name,name:K.name,description:K.description,tags:[],examples:[]})),W={name:B.name};if(A.kind)W.kind=A.kind;if(B.description)W.description=B.description;if(f)W.organization=f;let G=[{uri:cl,description:"Anchor (operator) identity for this brain",params:W}];return{name:Q.name,description:AL2(Q,B),url:H,version:w,protocolVersion:"0.2.2",capabilities:{streaming:!0,pushNotifications:!1,extensions:G},skills:Y,defaultInputModes:["text/plain"],defaultOutputModes:["text/plain"],...f&&{provider:{organization:f,url:H}},...A.authEnabled&&{securitySchemes:{bearerAuth:{type:"http",scheme:"bearer"}},security:[{bearerAuth:[]}]}}}f0();var iCA=new Set(["completed","failed","canceled","rejected"]);class rCA{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(iCA.has(B.task.status.state)&&A-new Date(B.updatedAt).getTime()>=this.ttlMs)this.tasks.delete(Q)}createTask(A,Q){this.evictExpired();let B=crypto.randomUUID(),w=Q??crypto.randomUUID(),$=new Date().toISOString(),f={kind:"message",messageId:crypto.randomUUID(),role:"user",parts:[{kind:"text",text:A}],contextId:w,taskId:B},D={task:{id:B,contextId:w,kind:"task",status:{state:"submitted",timestamp:$},history:[f]},conversationId:`a2a:${B}`,createdAt:$,updatedAt:$};return this.tasks.set(B,D),D}getTask(A){return this.tasks.get(A)}updateState(A,Q,B){let w=this.tasks.get(A);if(!w)return;let $=new Date().toISOString();if(w.task.status={state:Q,timestamp:$},w.updatedAt=$,Q==="working")w.workingStartedAt=$;if(B){let f={kind:"message",messageId:crypto.randomUUID(),role:"agent",parts:[{kind:"text",text:B}],contextId:w.task.contextId,taskId:A};w.task.status.message=f,w.task.history??=[],w.task.history.push(f)}return w}addArtifact(A,Q,B){let w=this.tasks.get(A);if(!w)return;return w.task.artifacts??=[],w.task.artifacts.push({artifactId:crypto.randomUUID(),name:Q,parts:B}),w.updatedAt=new Date().toISOString(),w}getTaskWithHistory(A,Q){let B=this.tasks.get(A);if(!B)return;if(B.task.status.state==="working"&&B.workingStartedAt&&Date.now()-new Date(B.workingStartedAt).getTime()>=this.processingTimeoutMs)this.updateState(A,"failed","Processing timed out");if(Q===void 0||!B.task.history)return B.task;return{...B.task,history:B.task.history.slice(-Q)}}deleteTask(A){return this.tasks.delete(A)}get size(){return this.tasks.size}}GA();var Fm0=F.array(F.object({kind:F.string(),text:F.string().optional(),data:F.record(F.unknown()).optional()})),QL2=F.object({message:F.object({kind:F.literal("message").optional(),messageId:F.string().optional(),role:F.enum(["user","agent"]).optional(),parts:Fm0,contextId:F.string().optional(),taskId:F.string().optional()}),configuration:F.object({historyLength:F.number().optional()}).optional()}),Km0=F.object({id:F.string(),historyLength:F.number().optional()});function dCA(A,Q){return{jsonrpc:"2.0",id:A,result:Q}}function sX(A,Q,B){return{jsonrpc:"2.0",id:A,error:{code:Q,message:B}}}var Zm0=F.object({jsonrpc:F.string(),id:F.union([F.string(),F.number()]),method:F.string(),params:F.record(F.unknown()).optional()});async function Nm0(A,Q){let{id:B,method:w,params:$}=A;switch(w){case"message/send":return BL2(B,$??{},Q);case"tasks/get":return $L2(B,$??{},Q);case"tasks/cancel":return fL2(B,$??{},Q);default:return sX(B,-32601,`Method not found: ${w}`)}}async function BL2(A,Q,B){let w=QL2.safeParse(Q);if(!w.success)return sX(A,-32602,`Invalid params: ${w.error.message}`);let $=w.data.message.parts.filter((W)=>W.kind==="text"&&typeof W.text==="string");if($.length===0)return sX(A,-32602,"Message must contain at least one text part");let f=$.map((W)=>W.text).join(`
|
|
2354
2354
|
`),I=w.data.message.contextId,D=B.taskManager.createTask(f,I),H=D.task.id;B.taskManager.updateState(H,"working"),wL2(H,f,D.conversationId,B);let Y=B.taskManager.getTask(H);if(!Y)return sX(A,-32603,"Internal error: task disappeared");return dCA(A,Y.task)}function wL2(A,Q,B,w){w.agentService.chat(Q,B,{userPermissionLevel:w.callerPermissionLevel,interfaceType:"a2a"}).then(($)=>{w.taskManager.updateState(A,"completed",$.text)}).catch(($)=>{let f=$ instanceof Error?$.message:"Unknown error";w.taskManager.updateState(A,"failed",`Error: ${f}`)})}var zm0=F.object({message:F.object({kind:F.string(),parts:Fm0,contextId:F.string().optional()})});function qm0(A,Q,B){let $=Q.parts.filter((Y)=>Y.kind==="text"&&typeof Y.text==="string").map((Y)=>Y.text).join(`
|
|
2355
2355
|
`)||"No message text",f=B.taskManager.createTask($,Q.contextId),I=f.task.id;B.taskManager.updateState(I,"working");let D=new TextEncoder,H=new ReadableStream({start(Y){let W=!1;function G(L){if(W)return;try{Y.enqueue(D.encode(`data: ${JSON.stringify(L)}
|
|
2356
2356
|
|
|
@@ -2358,7 +2358,7 @@ ${R}`)}if(w!==void 0&&f?.algorithms!==void 0){let C=f.algorithms.map((R)=>R.alg)
|
|
|
2358
2358
|
|
|
2359
2359
|
`);$=I.pop()??"";for(let D of I){let H=D.split(`
|
|
2360
2360
|
`).find((C)=>C.startsWith("data: "));if(!H)continue;let Y;try{Y=JSON.parse(H.slice(6))}catch{return B.cancel().catch(()=>{}),{success:!1,error:"Malformed SSE event from remote agent"}}let W=Y.result;if(!W)continue;if(W.final!==!0)continue;B.cancel().catch(()=>{});let K=W.status,Z=K?.state??"unknown",L=(K?.message?.parts??[]).filter((C)=>C.kind==="text"&&typeof C.text==="string").map((C)=>C.text).join(`
|
|
2361
|
-
`)||"No response text";return{success:!0,data:{state:Z,response:L}}}f=await Lm0(B,Q)}return{success:!1,error:"Stream ended without a terminal event"}}class GT extends Error{timeoutMs;constructor(A){super(`request timed out after ${A}ms`);this.timeoutMs=A;this.name="A2ARequestTimeoutError"}}class FT extends Error{timeoutMs;constructor(A){super(`A2A stream stalled waiting for final event after ${A}ms`);this.timeoutMs=A;this.name="A2AStreamIdleTimeoutError"}}async function JL2(A,Q,B,w){let $=new AbortController,f;try{return await Promise.race([A(Q,{...B,signal:$.signal}),new Promise((I,D)=>{f=setTimeout(()=>{$.abort(),D(new GT(w))},w)})])}catch(I){if(I instanceof GT)throw I;if($.signal.aborted)throw new GT(w);throw I}finally{if(f)clearTimeout(f)}}async function Lm0(A,Q){let B;try{return await Promise.race([A.read(),new Promise((w,$)=>{B=setTimeout(()=>$(new FT(Q)),Q)})])}catch(w){if(w instanceof FT)A.cancel().catch(()=>{});throw w}finally{if(B)clearTimeout(B)}}function GL2(A){if(A instanceof GT||A instanceof FT)return!0;return A instanceof Error}function FL2(A,Q){let B=Q>1?` after ${Q} attempts`:"";if(A instanceof FT)return`${A.message}${B}`;let w=A instanceof Error?A.message:"Unknown network error";return`Failed to reach remote agent${B}: ${w}`}function Mm0(A={}){let Q=A.fetch??globalThis.fetch,B={requestTimeoutMs:A.requestTimeoutMs??IL2,streamIdleTimeoutMs:A.streamIdleTimeoutMs??DL2,maxNetworkAttempts:A.maxNetworkAttempts??HL2};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:Cm0,visibility:"anchor",handler:async(w)=>{let $=F.object(Cm0).safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};let{agent:f,message:I}=$.data,D=YL2(f);if(!D)return{success:!1,error:"Invalid agent id. Use a saved agent id from your directory, not a URL."};if(!A.entityService)return{success:!1,error:"Agent directory is unavailable. Add the agent first, then try again."};let H=await A.entityService.getEntity({entityType:"agent",id:D});if(!H)return{success:!1,error:`Agent ${D} is not in your directory. Add it first.`};if(H.metadata.status!=="approved")return{success:!1,error:`Agent ${D} is discovered but not approved yet. Approve it first.`};let Y=`https://${D}`,W=await XL2(Y,Q);if(!W)return{success:!1,error:`Could not fetch Agent Card from ${Y}`};let G=W.url,K;if(A.outboundTokens)try{let Z=new URL(G).hostname;K=A.outboundTokens[Z]}catch{}return WL2(G,I,Q,K,B)}}}var nCA={name:"@brains/a2a",private:!0,version:"0.2.0-alpha.70",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 ZL2={"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization","X-Content-Type-Options":"nosniff"};class AR extends aY{agentCard;taskManager=new rCA;agentService;permissionContext;app;hasWebserver=!1;constructor(A={}){super("a2a",nCA,A,Jm0)}async onRegister(A){if(await super.onRegister(A),this.hasWebserver=A.plugins.has("webserver"),this.agentService=A.agent,this.permissionContext=A.permissions,this.hasWebserver)A.endpoints.register({label:"A2A",url:"/a2a",priority:25}),A.interactions.register({id:"a2a",label:"A2A",description:"Let other agents discover and talk to this brain.",href:"/a2a",kind:"agent",priority:25}),this.logger.info("A2A interface registered",{domain:A.domain});else this.logger.info("A2A interface registered in tool-only mode",{domain:A.domain})}async onReady(A){await this.rebuildAgentCard(A)}async rebuildAgentCard(A){let Q=A.identity.get(),B=A.identity.getProfile(),w=A.tools.listForPermissionLevel("public"),$=this.config.trustedTokens&&Object.keys(this.config.trustedTokens).length>0,f;if(A.entityService.hasEntityType("skill"))try{let I=await A.entityService.listEntities({entityType:"skill"});if(I.length>0)f=I.map((D)=>HI.safeParse(D.metadata)).filter((D)=>D.success).map((D)=>D.data)}catch{}this.agentCard=Gm0({character:Q,profile:B,version:nCA.version,domain:A.domain,organization:this.config.organization,tools:w,skills:f,authEnabled:$}),this.logger.debug("Agent Card rebuilt",{skills:this.agentCard.skills.length})}getAgentCard(){return this.agentCard}resolveCallerPermission(A){if(!A?.startsWith("Bearer ")||!this.config.trustedTokens)return"public";let Q=A.slice(7),B=this.config.trustedTokens[Q];if(!B||!this.permissionContext)return"public";return this.permissionContext.getUserLevel("a2a",B)}withCors(A){let Q=new Headers(A.headers);for(let[B,w]of Object.entries(ZL2))Q.set(B,w);return new Response(A.body,{status:A.status,statusText:A.statusText,headers:Q})}getOrCreateApp(){if(this.app)return this.app;let A=new aO;return A.get("/.well-known/agent-card.json",(Q)=>{if(!this.agentCard)return this.withCors(Q.json({error:"Agent Card not ready"},503));return this.withCors(Q.json(this.agentCard))}),A.get("/a2a",(Q)=>{return this.withCors(Q.json({error:"Use POST with JSON-RPC 2.0 requests.",agentCard:"/.well-known/agent-card.json"},405))}),A.options("/a2a",()=>this.withCors(new Response(null,{status:204}))),A.post("/a2a",async(Q)=>{if(!this.agentService)return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32603,message:"Agent service not ready"},id:null},503));let B;try{B=await Q.req.json()}catch{return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32700,message:"Parse error"},id:null}))}let w=Zm0.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=zm0.safeParse(w.data.params??{});if(!I.success)return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32602,message:`Invalid params: ${I.error.message}`},id:w.data.id}));let{stream:D}=qm0(w.data.id,I.data.message,{taskManager:this.taskManager,agentService:this.agentService,callerPermissionLevel:$});return this.withCors(new Response(D,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}}))}let f=await Nm0(w.data,{taskManager:this.taskManager,agentService:this.agentService,callerPermissionLevel:$});return this.withCors(Q.json(f))}),this.app=A,A}getWebRoutes(){if(!this.hasWebserver)return[];let A=(Q)=>Promise.resolve(this.getOrCreateApp().fetch(Q));return[{path:"/.well-known/agent-card.json",method:"GET",public:!0,handler:A},{path:"/a2a",method:"GET",public:!0,handler:A},{path:"/a2a",method:"POST",public:!0,handler:A},{path:"/a2a",method:"OPTIONS",public:!0,handler:A}]}async getTools(){return[Mm0({outboundTokens:this.config.outboundTokens,requestTimeoutMs:this.config.requestTimeoutMs,streamIdleTimeoutMs:this.config.streamIdleTimeoutMs,maxNetworkAttempts:this.config.maxNetworkAttempts,entityService:this.getContext().entityService})]}async getInstructions(){return"## Agent-to-agent calls\n- Use `a2a_call` only for agents already saved in the local `agent` directory.\n- Pass only the saved local agent id to `a2a_call` (for example `yeehaa.io`). Never pass a full URL or a display name like `Brain`.\n- If the user asks you to ask, message, or contact a saved approved agent, treat that as an agent-directory request first and call `a2a_call` in the same turn. Do not stop after listing the agent, drafting the question, or searching general content locally.\n- If the user gives a full URL for an agent, do not pass that URL to `a2a_call`. Use a saved local agent id only. If that URL is not already saved in the local directory, tell the user to add it first.\n- If the user refers to an agent by name, first make sure that name resolves to exactly one saved agent id. If multiple saved agents could match, ask a concise clarification question naming the matching saved agent ids and do not call any agent yet. Never choose the first match.\n- After asking that clarification question, end the turn. Do not call `a2a_call` later in the same turn.\n- If the target agent is not in the directory, do not create a wish, reminder, todo, note, fallback task, or any new entity. Tell the user to add it first.\n- In these invalid agent-target cases, do not call any tool unless the user explicitly asks you to add/save the agent.\n- Only use creation tools for an agent if the user explicitly asks you to add or save that agent.\n- If the target agent is discovered but not approved yet, do not call it and do not create a wish. Tell the user it must be approved first."}createDaemon(){return{start:async()=>{if(this.hasWebserver)this.logger.info("A2A mounted on shared webserver host");else this.logger.info("A2A running without webserver routes")},stop:async()=>{this.logger.info("A2A server stopped")}}}}f0();class oCA{logger;handleImport;handleDelete;deleteOnFileRemoval;fileOperations;constructor(A,Q,B,w,$=!0){if(this.logger=A,this.fileOperations=w,this.deleteOnFileRemoval=$,B)this.handleImport=async(f)=>{let I=await B({type:"directory-import",data:{paths:[f]}});this.logger.debug("Queued import job for file change",{jobId:I,path:f})},this.handleDelete=async(f)=>{if(!this.deleteOnFileRemoval){this.logger.warn("File deleted but deleteOnFileRemoval is disabled",{path:f});return}try{let{entityType:I,id:D}=this.fileOperations.parseEntityFromPath(f),H=await B({type:"directory-delete",data:{entityId:D,entityType:I,filePath:f}});this.logger.info("Queued delete job for removed file",{jobId:H,path:f,entityId:D,entityType:I})}catch(I){this.logger.warn("Could not extract entity info from deleted file",{path:f,error:I})}};else this.handleImport=async(f)=>{await Q([f])},this.handleDelete=async(f)=>{this.logger.warn("File deleted but no job queue available",{path:f})}}async handleFileChange(A,Q){this.logger.debug("Processing file change",{event:A,path:Q});try{switch(A){case"add":case"change":await this.handleImport(Q);break;case"delete":case"unlink":await this.handleDelete(Q);break;default:this.logger.debug("Unhandled file event",{event:A,path:Q})}}catch(B){this.logger.error("Failed to handle file change",{event:A,path:Q,error:B})}}}var cc0=D1(Sc0(),1);import{extname as FO2}from"path";var oe=[".png",".jpg",".jpeg",".webp",".gif",".svg"];function dq(A){let Q=FO2(A).toLowerCase();return oe.includes(Q)}function mc0(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 nLA(A){switch(A.toLowerCase()){case"jpeg":return".jpg";case"svg+xml":return".svg";default:return`.${A.toLowerCase()}`}}import{isAbsolute as KO2,relative as ZO2,sep as uc0,join as NO2}from"path";function A4(A,Q){return KO2(Q)?Q:NO2(A,Q)}function DR(A,Q){let B=A4(A,Q),w=ZO2(A,B);return uc0==="/"?w:w.split(uc0).join("/")}function zO2(A,Q){if(!DR(Q,A).startsWith("image/"))return!1;return dq(A)}function qO2(A,Q){if(DR(Q,A).split("/")[0]?.startsWith("_"))return!1;if(A.endsWith(".md"))return!0;return zO2(A,Q)}class oLA{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=cc0.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(!qO2(Q,this.syncPath))return;this.logger.debug("File change detected",{event:A,path:Q});let B=DR(this.syncPath,Q);if(this.pendingChanges.set(B,A),this.batchTimeout)clearTimeout(this.batchTimeout);this.batchTimeout=setTimeout(()=>{this.processPendingChanges()},500)}async processPendingChanges(){if(this.pendingChanges.size===0)return;let A=new Map(this.pendingChanges);this.pendingChanges.clear(),this.batchTimeout=void 0,this.logger.debug("Processing batched file changes",{changeCount:A.size});for(let[Q,B]of A){let w=A4(this.syncPath,Q);try{if(this.onFileChange)await this.onFileChange(B,w)}catch($){this.logger.error("Error processing file change",{path:Q,event:B,error:$})}}}isWatching(){return!!this.watcher}getPendingChangesCount(){return this.pendingChanges.size}}async function pc0(A,Q){if(A?.isWatching())return Q.logger.debug("Already watching directory"),A;return CO2(Q)}function lc0(A){if(A)A.stop();return}function ic0(A,Q){if(A)A.setCallback(Q)}async function CO2(A){let{logger:Q,syncPath:B,watchInterval:w,importEntities:$,jobQueueCallback:f,fileOperations:I,deleteOnFileRemoval:D}=A,H=new oCA(Q,$,f,I,D),Y=new oLA({syncPath:B,watchInterval:w,logger:Q,onFileChange:async(W,G)=>{await H.handleFileChange(W,G)}});return await Y.start(),Y}async function rc0(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:$}}f0();class sLA{logger;syncPath;deleteOnFileRemoval;constructor(A){this.logger=A.logger,this.syncPath=A.syncPath,this.deleteOnFileRemoval=A.deleteOnFileRemoval}prepareBatchOperations(A){let Q=[],B=this.createImportOperations(A);Q.push(...B);let w=B.length;if(this.deleteOnFileRemoval)Q.push({type:"directory-cleanup",data:{}});let $=A.length;return this.logger.debug("Prepared batch operations",{exportOperationsCount:0,importOperationsCount:w,totalFiles:$}),{operations:Q,exportOperationsCount:0,importOperationsCount:w,totalFiles:$}}async queueSyncBatch(A,Q,B,w){let $=this.prepareBatchOperations(B);if($.operations.length===0)return this.logger.debug("No sync operations needed",{source:Q}),null;return{batchId:await A.jobs.enqueueBatch($.operations,{source:Q,rootJobId:w?.rootJobId??Z5(),metadata:{progressToken:w?.progressToken,operationType:"file_operations",operationTarget:this.syncPath,pluginId:w?.pluginId??"directory-sync",interfaceType:w?.interfaceType,channelId:w?.channelId}}),operationCount:$.operations.length,exportOperationsCount:$.exportOperationsCount,importOperationsCount:$.importOperationsCount,totalFiles:$.totalFiles}}createImportOperations(A){if(A.length===0)return[];let Q=50,B=[];for(let w=0;w<A.length;w+=Q){let $=A.slice(w,w+Q);B.push({type:"directory-import",data:{batchIndex:Math.floor(w/Q),paths:$,batchSize:$.length}})}return B}}class aLA{syncInProgress=!1;logger;fileOperations;batchOperationsManager;constructor(A){this.logger=A.logger,this.fileOperations=A.fileOperations,this.batchOperationsManager=new sLA({logger:A.logger,syncPath:A.syncPath,deleteOnFileRemoval:A.deleteOnFileRemoval})}async queueSyncBatch(A,Q,B){if(this.syncInProgress)return this.logger.debug("Sync already in progress, skipping",{source:Q}),null;this.syncInProgress=!0;try{let w=await this.fileOperations.getAllSyncFiles();return await this.batchOperationsManager.queueSyncBatch(A,Q,w,B)}finally{this.syncInProgress=!1}}}class tLA{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 bO2,extname as OO2}from"path";import{extname as LO2,join as se}from"path";function ae(A,Q){let w=DR(A,Q).split("/"),$,f;if(w.length===1)$="base",f=w;else if(w.length>1&&w[0])$=w[0],f=w.slice(1);else $="base",f=w;let I;if(f.length>1){let D=f[f.length-1];if(D)f[f.length-1]=dc0(D);I=f.join(":")}else I=dc0(f[0]??"");return{entityType:$,id:I}}function nc0(A,Q,B,w=".md"){let $=Q.split(":").filter((Y)=>Y.length>0),f=B==="base";if($.length===1)return f?se(A,`${$[0]}${w}`):se(A,B,`${$[0]}${w}`);let I=$;if($[0]===B)I=$.slice(1);let D=I[I.length-1],H=I.slice(0,-1);if(f)return se(A,...H,`${D}${w}`);return se(A,B,...H,`${D}${w}`)}function oc0(A){if(A.entityType!=="image")return".md";let Q=A.metadata.format;if(Q)return nLA(Q);let B=A.content.match(/^data:image\/([a-z+]+);base64,/i);return B?.[1]?nLA(B[1]):".md"}function dc0(A){let Q=LO2(A).toLowerCase();return Q===".md"||oe.includes(Q)?A.slice(0,-Q.length):A}LD();import{mkdir as RO2,readFile as ee,writeFile as Qp0,stat as _O2,utimes as PO2}from"fs/promises";import{join as te}from"path";import{mkdir as sc0,readdir as MO2,stat as VO2}from"fs/promises";import{access as EO2}from"fs/promises";async function w$(A){try{return await EO2(A),!0}catch{return!1}}async function eLA(A,Q){return Ap0(A,Q,{includeImages:!1})}async function ac0(A,Q){return Ap0(A,Q,{includeImages:!0})}async function tc0(A,Q){if(!await w$(A))await sc0(A,{recursive:!0});for(let B of Q)if(B!=="base")await sc0(te(A,B),{recursive:!0})}async function ec0(A,Q){let B=[],w={totalFiles:0,byEntityType:{}};if(!await w$(A))return{files:B,stats:w};let $=await eLA(A,Q);for(let f of $)try{let I=te(A,f),D=await VO2(I),{entityType:H}=ae(A,f);B.push({path:f,entityType:H,modified:D.mtime}),w.totalFiles++,w.byEntityType[H]=(w.byEntityType[H]??0)+1}catch{continue}return{files:B,stats:w}}async function Ap0(A,Q,B){let w=[];if(!await w$(A))return w;let $=async(f,I="",D=!1)=>{let H=await MO2(f,{withFileTypes:!0});for(let Y of H){let W=I?te(I,Y.name):Y.name;if(Y.isFile()&&!Y.name.endsWith(".invalid")){if(Y.name.endsWith(".md"))w.push(W);else if(B.includeImages&&D&&dq(Y.name))w.push(W)}else if(Y.isDirectory()&&!Y.name.startsWith(".")){if(I===""&&!Q.hasEntityType(Y.name))continue;let G=te(f,Y.name),K=Y.name==="image"&&I==="";await $(G,W,D||K)}}};return await $(A),w}class AEA{syncPath;entityService;constructor(A,Q){this.syncPath=A,this.entityService=Q}parseEntityFromPath(A){return ae(this.syncPath,A)}async readEntity(A){let Q=A4(this.syncPath,A),B=await _O2(Q),{entityType:w,id:$}=this.parseEntityFromPath(A),f=B.birthtime.getTime()>0?B.birthtime:B.mtime,I=B.mtime,D;if(dq(A)){let Y=(await ee(Q)).toString("base64"),W=OO2(A);D=`data:${mc0(W)};base64,${Y}`}else D=await ee(Q,"utf-8");return{entityType:w,id:$,content:D,created:f,updated:I}}async writeEntity(A){let Q=this.getEntityFilePath(A),B=A.entityType==="image",w;if(B){let f=A.content.match(/^data:image\/[a-z+]+;base64,(.+)$/i);w=f?.[1]?Buffer.from(f[1],"base64"):Buffer.from(A.content,"base64")}else w=this.entityService.serializeEntity(A);if(await w$(Q)){let f=B?await ee(Q):await ee(Q,"utf-8"),I=xB(B?f.toString("base64"):f),D=xB(B?w.toString("base64"):w);if(I===D)return}if(A.entityType!=="base")await RO2(bO2(Q),{recursive:!0});if(B)await Qp0(Q,w);else await Qp0(Q,w,"utf-8");let $=new Date(A.updated);await PO2(Q,$,$)}getFilePath(A,Q,B=".md"){return nc0(this.syncPath,A,Q,B)}getEntityFilePath(A){return this.getFilePath(A.id,A.entityType,oc0(A))}async getAllMarkdownFiles(){return eLA(this.syncPath,this.entityService)}async getAllSyncFiles(){return ac0(this.syncPath,this.entityService)}async ensureDirectoryStructure(A){await tc0(this.syncPath,A)}shouldUpdateEntity(A,Q){let B=xB(Q.content);return A.contentHash!==B}async gatherFileStatus(){return ec0(this.syncPath,this.entityService)}async syncDirectoryExists(){return w$(this.syncPath)}async fileExists(A){return w$(A)}}Bf();GA();Bf();async function AAA(A,Q,B,w){let{sourceUrl:$}=A,f=await Q.listEntities({entityType:"image",options:{filter:{metadata:{sourceUrl:$}},limit:1}});if(f[0])return w.debug("Reusing existing image entity",{sourceUrl:$,imageId:f[0].id}),f[0].id;let I=await B($),{base64:D}=uF(I),H=oN(D),Y=cF(D);if(!H||!Y)throw Error("Could not detect image format or dimensions");let W=await Q.createEntity({entity:{id:A.id,entityType:"image",content:I,metadata:{title:A.title,alt:A.alt,format:H,width:Y.width,height:Y.height,sourceUrl:$}}});return w.debug("Created image entity from URL",{sourceUrl:$,imageId:W.entityId}),W.entityId}var Bp0=F.object({title:F.string(),slug:F.string().optional(),coverImageUrl:F.string().url(),coverImageId:F.string().optional(),coverImageAlt:F.string().optional()});class QEA{entityService;fetcher;logger;constructor(A,Q,B=WH){this.entityService=A;this.fetcher=B;this.logger=Q.child("FrontmatterImageConverter")}detectCoverImageUrl(A){let Q;try{Q=JF(A)}catch{return null}let{frontmatter:B}=Q,w=Bp0.safeParse(B);if(!w.success)return null;if(w.data.coverImageId)return null;let{title:$,slug:f,coverImageUrl:I,coverImageAlt:D}=w.data;if(!JU(I))return null;return{sourceUrl:I,postTitle:$,postSlug:f??U2($),customAlt:D}}async convert(A){let Q;try{Q=JF(A)}catch(Y){return this.logger.debug("Parse failed",{error:Y}),{content:A,converted:!1}}let{frontmatter:B}=Q,w=Bp0.safeParse(B);if(!w.success)return{content:A,converted:!1};if(w.data.coverImageId)return{content:A,converted:!1};let{title:$,slug:f,coverImageUrl:I,coverImageAlt:D}=w.data;if(!JU(I))return{content:A,converted:!1};let H={postTitle:$,postSlug:f??U2($),sourceUrl:I,customAlt:D};try{let Y=await this.createImageEntity(H),W={...B};return delete W.coverImageUrl,delete W.coverImageAlt,W.coverImageId=Y,{content:$N(W,Q.content),converted:!0,imageId:Y}}catch(Y){return this.logger.warn("Failed to convert coverImageUrl",{url:I,error:y0(Y)}),{content:A,converted:!1}}}async createImageEntity(A){let{postTitle:Q,postSlug:B,sourceUrl:w,customAlt:$}=A,f=`Cover image for ${Q}`;return AAA({id:`${B}-cover`,title:f,alt:$??f,sourceUrl:w},this.entityService,this.fetcher,this.logger)}}Bf();GA();class _T{entityService;fetcher;logger;constructor(A,Q,B=WH){this.entityService=A;this.fetcher=B;this.logger=Q.child("MarkdownImageConverter")}detectInlineImages(A,Q){let B=[],w=AXA(A);for(let $ of w){if(!JU($.url))continue;if($.url.startsWith("entity://"))continue;let f=this.reconstructMarkdown($);B.push({sourceUrl:$.url,alt:$.alt,originalMarkdown:f,postSlug:Q})}return B}reconstructMarkdown(A){if(A.title)return``;return``}async convert(A,Q){let B=this.detectInlineImages(A,Q);if(B.length===0)return{content:A,converted:!1,convertedCount:0};let w=A,$=0,f=0;for(let I of B)try{let D=await this.createImageEntity(I,f++),H=``;w=w.replace(I.originalMarkdown,H),$++,this.logger.debug("Converted inline image",{sourceUrl:I.sourceUrl,imageId:D})}catch(D){this.logger.warn("Failed to convert inline image",{sourceUrl:I.sourceUrl,error:y0(D)})}return{content:w,converted:$>0,convertedCount:$}}async createImageEntity(A,Q){let{sourceUrl:B,alt:w,postSlug:$}=A;return AAA({id:`${$}-inline-${Q}`,title:w||`Inline image ${Q+1} for ${$}`,alt:w||"",sourceUrl:B},this.entityService,this.fetcher,this.logger)}}class BEA{logger;entityService;fileOperations;constructor(A,Q,B){this.logger=A,this.entityService=Q,this.fileOperations=B}async importEntitiesWithProgress(A,Q,B,w){this.logger.debug("Importing entities with progress reporting");let $={imported:0,skipped:0,failed:0,quarantined:0,quarantinedFiles:[],errors:[],jobIds:[]},f=A??await this.fileOperations.getAllSyncFiles(),I=f.length;await Q.report({progress:0,message:`Starting import of ${I} files`});for(let D=0;D<I;D+=B){let H=f.slice(D,D+B),Y=await w(H);$.imported+=Y.imported,$.skipped+=Y.skipped,$.failed+=Y.failed,$.quarantined+=Y.quarantined,$.errors.push(...Y.errors),$.quarantinedFiles.push(...Y.quarantinedFiles),$.jobIds.push(...Y.jobIds);let W=Math.min(D+B,I),G=Math.round(W/I*40);await Q.report({progress:G,message:`Imported ${W}/${I} files`})}return $}async exportEntitiesWithProgress(A,Q,B,w){this.logger.debug("Exporting entities with progress reporting");let $=A??this.entityService.getEntityTypes();await Q.report({progress:50,message:`Starting export of ${$.length} entity types`});let f=await w(A);return await Q.report({progress:100,message:`Exported ${f.exported} entities`}),this.logger.debug("Export completed",f),f}}GA();import{rename as kO2,appendFile as jO2,readFile as vO2,writeFile as xO2,access as hO2}from"fs/promises";import{join as wp0}from"path";class wEA{logger;syncPath;constructor(A,Q){this.logger=A;this.syncPath=Q}isValidationError(A){if(A instanceof F.ZodError)return!0;let Q=y0(A);return Q.includes("invalid_type")||Q.includes("invalid_enum_value")||Q.includes("Required")||Q.includes("Invalid frontmatter")||Q.includes("Unknown entity type")}async quarantineInvalidFile(A,Q,B,w){let $=w(A),f=`${$}.invalid`;try{await kO2($,f),B.quarantined++,B.quarantinedFiles.push(A);let I=wp0(this.syncPath,".import-errors.log"),D=new Date().toISOString(),H=y0(Q),Y=`${D} - ${A}: ${H}
|
|
2361
|
+
`)||"No response text";return{success:!0,data:{state:Z,response:L}}}f=await Lm0(B,Q)}return{success:!1,error:"Stream ended without a terminal event"}}class GT extends Error{timeoutMs;constructor(A){super(`request timed out after ${A}ms`);this.timeoutMs=A;this.name="A2ARequestTimeoutError"}}class FT extends Error{timeoutMs;constructor(A){super(`A2A stream stalled waiting for final event after ${A}ms`);this.timeoutMs=A;this.name="A2AStreamIdleTimeoutError"}}async function JL2(A,Q,B,w){let $=new AbortController,f;try{return await Promise.race([A(Q,{...B,signal:$.signal}),new Promise((I,D)=>{f=setTimeout(()=>{$.abort(),D(new GT(w))},w)})])}catch(I){if(I instanceof GT)throw I;if($.signal.aborted)throw new GT(w);throw I}finally{if(f)clearTimeout(f)}}async function Lm0(A,Q){let B;try{return await Promise.race([A.read(),new Promise((w,$)=>{B=setTimeout(()=>$(new FT(Q)),Q)})])}catch(w){if(w instanceof FT)A.cancel().catch(()=>{});throw w}finally{if(B)clearTimeout(B)}}function GL2(A){if(A instanceof GT||A instanceof FT)return!0;return A instanceof Error}function FL2(A,Q){let B=Q>1?` after ${Q} attempts`:"";if(A instanceof FT)return`${A.message}${B}`;let w=A instanceof Error?A.message:"Unknown network error";return`Failed to reach remote agent${B}: ${w}`}function Mm0(A={}){let Q=A.fetch??globalThis.fetch,B={requestTimeoutMs:A.requestTimeoutMs??IL2,streamIdleTimeoutMs:A.streamIdleTimeoutMs??DL2,maxNetworkAttempts:A.maxNetworkAttempts??HL2};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:Cm0,visibility:"anchor",handler:async(w)=>{let $=F.object(Cm0).safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};let{agent:f,message:I}=$.data,D=YL2(f);if(!D)return{success:!1,error:"Invalid agent id. Use a saved agent id from your directory, not a URL."};if(!A.entityService)return{success:!1,error:"Agent directory is unavailable. Add the agent first, then try again."};let H=await A.entityService.getEntity({entityType:"agent",id:D});if(!H)return{success:!1,error:`Agent ${D} is not in your directory. Add it first.`};if(H.metadata.status!=="approved")return{success:!1,error:`Agent ${D} is discovered but not approved yet. Approve it first.`};let Y=`https://${D}`,W=await XL2(Y,Q);if(!W)return{success:!1,error:`Could not fetch Agent Card from ${Y}`};let G=W.url,K;if(A.outboundTokens)try{let Z=new URL(G).hostname;K=A.outboundTokens[Z]}catch{}return WL2(G,I,Q,K,B)}}}var nCA={name:"@brains/a2a",private:!0,version:"0.2.0-alpha.71",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 ZL2={"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization","X-Content-Type-Options":"nosniff"};class AR extends aY{agentCard;taskManager=new rCA;agentService;permissionContext;app;hasWebserver=!1;constructor(A={}){super("a2a",nCA,A,Jm0)}async onRegister(A){if(await super.onRegister(A),this.hasWebserver=A.plugins.has("webserver"),this.agentService=A.agent,this.permissionContext=A.permissions,this.hasWebserver)A.endpoints.register({label:"A2A",url:"/a2a",priority:25}),A.interactions.register({id:"a2a",label:"A2A",description:"Let other agents discover and talk to this brain.",href:"/a2a",kind:"agent",priority:25}),this.logger.info("A2A interface registered",{domain:A.domain});else this.logger.info("A2A interface registered in tool-only mode",{domain:A.domain})}async onReady(A){await this.rebuildAgentCard(A)}async rebuildAgentCard(A){let Q=A.identity.get(),B=A.identity.getProfile(),w=A.tools.listForPermissionLevel("public"),$=this.config.trustedTokens&&Object.keys(this.config.trustedTokens).length>0,f;if(A.entityService.hasEntityType("skill"))try{let I=await A.entityService.listEntities({entityType:"skill"});if(I.length>0)f=I.map((D)=>HI.safeParse(D.metadata)).filter((D)=>D.success).map((D)=>D.data)}catch{}this.agentCard=Gm0({character:Q,profile:B,version:nCA.version,domain:A.domain,organization:this.config.organization,tools:w,skills:f,authEnabled:$}),this.logger.debug("Agent Card rebuilt",{skills:this.agentCard.skills.length})}getAgentCard(){return this.agentCard}resolveCallerPermission(A){if(!A?.startsWith("Bearer ")||!this.config.trustedTokens)return"public";let Q=A.slice(7),B=this.config.trustedTokens[Q];if(!B||!this.permissionContext)return"public";return this.permissionContext.getUserLevel("a2a",B)}withCors(A){let Q=new Headers(A.headers);for(let[B,w]of Object.entries(ZL2))Q.set(B,w);return new Response(A.body,{status:A.status,statusText:A.statusText,headers:Q})}getOrCreateApp(){if(this.app)return this.app;let A=new aO;return A.get("/.well-known/agent-card.json",(Q)=>{if(!this.agentCard)return this.withCors(Q.json({error:"Agent Card not ready"},503));return this.withCors(Q.json(this.agentCard))}),A.get("/a2a",(Q)=>{return this.withCors(Q.json({error:"Use POST with JSON-RPC 2.0 requests.",agentCard:"/.well-known/agent-card.json"},405))}),A.options("/a2a",()=>this.withCors(new Response(null,{status:204}))),A.post("/a2a",async(Q)=>{if(!this.agentService)return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32603,message:"Agent service not ready"},id:null},503));let B;try{B=await Q.req.json()}catch{return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32700,message:"Parse error"},id:null}))}let w=Zm0.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=zm0.safeParse(w.data.params??{});if(!I.success)return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32602,message:`Invalid params: ${I.error.message}`},id:w.data.id}));let{stream:D}=qm0(w.data.id,I.data.message,{taskManager:this.taskManager,agentService:this.agentService,callerPermissionLevel:$});return this.withCors(new Response(D,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}}))}let f=await Nm0(w.data,{taskManager:this.taskManager,agentService:this.agentService,callerPermissionLevel:$});return this.withCors(Q.json(f))}),this.app=A,A}getWebRoutes(){if(!this.hasWebserver)return[];let A=(Q)=>Promise.resolve(this.getOrCreateApp().fetch(Q));return[{path:"/.well-known/agent-card.json",method:"GET",public:!0,handler:A},{path:"/a2a",method:"GET",public:!0,handler:A},{path:"/a2a",method:"POST",public:!0,handler:A},{path:"/a2a",method:"OPTIONS",public:!0,handler:A}]}async getTools(){return[Mm0({outboundTokens:this.config.outboundTokens,requestTimeoutMs:this.config.requestTimeoutMs,streamIdleTimeoutMs:this.config.streamIdleTimeoutMs,maxNetworkAttempts:this.config.maxNetworkAttempts,entityService:this.getContext().entityService})]}async getInstructions(){return"## Agent-to-agent calls\n- Use `a2a_call` only for agents already saved in the local `agent` directory.\n- Pass only the saved local agent id to `a2a_call` (for example `yeehaa.io`). Never pass a full URL or a display name like `Brain`.\n- If the user asks you to ask, message, or contact a saved approved agent, treat that as an agent-directory request first and call `a2a_call` in the same turn. Do not stop after listing the agent, drafting the question, or searching general content locally.\n- If the user gives a full URL for an agent, do not pass that URL to `a2a_call`. Use a saved local agent id only. If that URL is not already saved in the local directory, tell the user to add it first.\n- If the user refers to an agent by name, first make sure that name resolves to exactly one saved agent id. If multiple saved agents could match, ask a concise clarification question naming the matching saved agent ids and do not call any agent yet. Never choose the first match.\n- After asking that clarification question, end the turn. Do not call `a2a_call` later in the same turn.\n- If the target agent is not in the directory, do not create a wish, reminder, todo, note, fallback task, or any new entity. Tell the user to add it first.\n- In these invalid agent-target cases, do not call any tool unless the user explicitly asks you to add/save the agent.\n- Only use creation tools for an agent if the user explicitly asks you to add or save that agent.\n- If the target agent is discovered but not approved yet, do not call it and do not create a wish. Tell the user it must be approved first."}createDaemon(){return{start:async()=>{if(this.hasWebserver)this.logger.info("A2A mounted on shared webserver host");else this.logger.info("A2A running without webserver routes")},stop:async()=>{this.logger.info("A2A server stopped")}}}}f0();class oCA{logger;handleImport;handleDelete;deleteOnFileRemoval;fileOperations;constructor(A,Q,B,w,$=!0){if(this.logger=A,this.fileOperations=w,this.deleteOnFileRemoval=$,B)this.handleImport=async(f)=>{let I=await B({type:"directory-import",data:{paths:[f]}});this.logger.debug("Queued import job for file change",{jobId:I,path:f})},this.handleDelete=async(f)=>{if(!this.deleteOnFileRemoval){this.logger.warn("File deleted but deleteOnFileRemoval is disabled",{path:f});return}try{let{entityType:I,id:D}=this.fileOperations.parseEntityFromPath(f),H=await B({type:"directory-delete",data:{entityId:D,entityType:I,filePath:f}});this.logger.info("Queued delete job for removed file",{jobId:H,path:f,entityId:D,entityType:I})}catch(I){this.logger.warn("Could not extract entity info from deleted file",{path:f,error:I})}};else this.handleImport=async(f)=>{await Q([f])},this.handleDelete=async(f)=>{this.logger.warn("File deleted but no job queue available",{path:f})}}async handleFileChange(A,Q){this.logger.debug("Processing file change",{event:A,path:Q});try{switch(A){case"add":case"change":await this.handleImport(Q);break;case"delete":case"unlink":await this.handleDelete(Q);break;default:this.logger.debug("Unhandled file event",{event:A,path:Q})}}catch(B){this.logger.error("Failed to handle file change",{event:A,path:Q,error:B})}}}var cc0=D1(Sc0(),1);import{extname as FO2}from"path";var oe=[".png",".jpg",".jpeg",".webp",".gif",".svg"];function dq(A){let Q=FO2(A).toLowerCase();return oe.includes(Q)}function mc0(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 nLA(A){switch(A.toLowerCase()){case"jpeg":return".jpg";case"svg+xml":return".svg";default:return`.${A.toLowerCase()}`}}import{isAbsolute as KO2,relative as ZO2,sep as uc0,join as NO2}from"path";function A4(A,Q){return KO2(Q)?Q:NO2(A,Q)}function DR(A,Q){let B=A4(A,Q),w=ZO2(A,B);return uc0==="/"?w:w.split(uc0).join("/")}function zO2(A,Q){if(!DR(Q,A).startsWith("image/"))return!1;return dq(A)}function qO2(A,Q){if(DR(Q,A).split("/")[0]?.startsWith("_"))return!1;if(A.endsWith(".md"))return!0;return zO2(A,Q)}class oLA{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=cc0.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(!qO2(Q,this.syncPath))return;this.logger.debug("File change detected",{event:A,path:Q});let B=DR(this.syncPath,Q);if(this.pendingChanges.set(B,A),this.batchTimeout)clearTimeout(this.batchTimeout);this.batchTimeout=setTimeout(()=>{this.processPendingChanges()},500)}async processPendingChanges(){if(this.pendingChanges.size===0)return;let A=new Map(this.pendingChanges);this.pendingChanges.clear(),this.batchTimeout=void 0,this.logger.debug("Processing batched file changes",{changeCount:A.size});for(let[Q,B]of A){let w=A4(this.syncPath,Q);try{if(this.onFileChange)await this.onFileChange(B,w)}catch($){this.logger.error("Error processing file change",{path:Q,event:B,error:$})}}}isWatching(){return!!this.watcher}getPendingChangesCount(){return this.pendingChanges.size}}async function pc0(A,Q){if(A?.isWatching())return Q.logger.debug("Already watching directory"),A;return CO2(Q)}function lc0(A){if(A)A.stop();return}function ic0(A,Q){if(A)A.setCallback(Q)}async function CO2(A){let{logger:Q,syncPath:B,watchInterval:w,importEntities:$,jobQueueCallback:f,fileOperations:I,deleteOnFileRemoval:D}=A,H=new oCA(Q,$,f,I,D),Y=new oLA({syncPath:B,watchInterval:w,logger:Q,onFileChange:async(W,G)=>{await H.handleFileChange(W,G)}});return await Y.start(),Y}async function rc0(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:$}}f0();class sLA{logger;syncPath;deleteOnFileRemoval;constructor(A){this.logger=A.logger,this.syncPath=A.syncPath,this.deleteOnFileRemoval=A.deleteOnFileRemoval}prepareBatchOperations(A){let Q=[],B=this.createImportOperations(A);Q.push(...B);let w=B.length;if(this.deleteOnFileRemoval)Q.push({type:"directory-cleanup",data:{}});let $=A.length;return this.logger.debug("Prepared batch operations",{exportOperationsCount:0,importOperationsCount:w,totalFiles:$}),{operations:Q,exportOperationsCount:0,importOperationsCount:w,totalFiles:$}}async queueSyncBatch(A,Q,B,w){let $=this.prepareBatchOperations(B);if($.operations.length===0)return this.logger.debug("No sync operations needed",{source:Q}),null;return{batchId:await A.jobs.enqueueBatch($.operations,{source:Q,rootJobId:w?.rootJobId??Z5(),metadata:{progressToken:w?.progressToken,operationType:"file_operations",operationTarget:this.syncPath,pluginId:w?.pluginId??"directory-sync",interfaceType:w?.interfaceType,channelId:w?.channelId}}),operationCount:$.operations.length,exportOperationsCount:$.exportOperationsCount,importOperationsCount:$.importOperationsCount,totalFiles:$.totalFiles}}createImportOperations(A){if(A.length===0)return[];let Q=50,B=[];for(let w=0;w<A.length;w+=Q){let $=A.slice(w,w+Q);B.push({type:"directory-import",data:{batchIndex:Math.floor(w/Q),paths:$,batchSize:$.length}})}return B}}class aLA{syncInProgress=!1;logger;fileOperations;batchOperationsManager;constructor(A){this.logger=A.logger,this.fileOperations=A.fileOperations,this.batchOperationsManager=new sLA({logger:A.logger,syncPath:A.syncPath,deleteOnFileRemoval:A.deleteOnFileRemoval})}async queueSyncBatch(A,Q,B){if(this.syncInProgress)return this.logger.debug("Sync already in progress, skipping",{source:Q}),null;this.syncInProgress=!0;try{let w=await this.fileOperations.getAllSyncFiles();return await this.batchOperationsManager.queueSyncBatch(A,Q,w,B)}finally{this.syncInProgress=!1}}}class tLA{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 bO2,extname as OO2}from"path";import{extname as LO2,join as se}from"path";function ae(A,Q){let w=DR(A,Q).split("/"),$,f;if(w.length===1)$="base",f=w;else if(w.length>1&&w[0])$=w[0],f=w.slice(1);else $="base",f=w;let I;if(f.length>1){let D=f[f.length-1];if(D)f[f.length-1]=dc0(D);I=f.join(":")}else I=dc0(f[0]??"");return{entityType:$,id:I}}function nc0(A,Q,B,w=".md"){let $=Q.split(":").filter((Y)=>Y.length>0),f=B==="base";if($.length===1)return f?se(A,`${$[0]}${w}`):se(A,B,`${$[0]}${w}`);let I=$;if($[0]===B)I=$.slice(1);let D=I[I.length-1],H=I.slice(0,-1);if(f)return se(A,...H,`${D}${w}`);return se(A,B,...H,`${D}${w}`)}function oc0(A){if(A.entityType!=="image")return".md";let Q=A.metadata.format;if(Q)return nLA(Q);let B=A.content.match(/^data:image\/([a-z+]+);base64,/i);return B?.[1]?nLA(B[1]):".md"}function dc0(A){let Q=LO2(A).toLowerCase();return Q===".md"||oe.includes(Q)?A.slice(0,-Q.length):A}LD();import{mkdir as RO2,readFile as ee,writeFile as Qp0,stat as _O2,utimes as PO2}from"fs/promises";import{join as te}from"path";import{mkdir as sc0,readdir as MO2,stat as VO2}from"fs/promises";import{access as EO2}from"fs/promises";async function w$(A){try{return await EO2(A),!0}catch{return!1}}async function eLA(A,Q){return Ap0(A,Q,{includeImages:!1})}async function ac0(A,Q){return Ap0(A,Q,{includeImages:!0})}async function tc0(A,Q){if(!await w$(A))await sc0(A,{recursive:!0});for(let B of Q)if(B!=="base")await sc0(te(A,B),{recursive:!0})}async function ec0(A,Q){let B=[],w={totalFiles:0,byEntityType:{}};if(!await w$(A))return{files:B,stats:w};let $=await eLA(A,Q);for(let f of $)try{let I=te(A,f),D=await VO2(I),{entityType:H}=ae(A,f);B.push({path:f,entityType:H,modified:D.mtime}),w.totalFiles++,w.byEntityType[H]=(w.byEntityType[H]??0)+1}catch{continue}return{files:B,stats:w}}async function Ap0(A,Q,B){let w=[];if(!await w$(A))return w;let $=async(f,I="",D=!1)=>{let H=await MO2(f,{withFileTypes:!0});for(let Y of H){let W=I?te(I,Y.name):Y.name;if(Y.isFile()&&!Y.name.endsWith(".invalid")){if(Y.name.endsWith(".md"))w.push(W);else if(B.includeImages&&D&&dq(Y.name))w.push(W)}else if(Y.isDirectory()&&!Y.name.startsWith(".")){if(I===""&&!Q.hasEntityType(Y.name))continue;let G=te(f,Y.name),K=Y.name==="image"&&I==="";await $(G,W,D||K)}}};return await $(A),w}class AEA{syncPath;entityService;constructor(A,Q){this.syncPath=A,this.entityService=Q}parseEntityFromPath(A){return ae(this.syncPath,A)}async readEntity(A){let Q=A4(this.syncPath,A),B=await _O2(Q),{entityType:w,id:$}=this.parseEntityFromPath(A),f=B.birthtime.getTime()>0?B.birthtime:B.mtime,I=B.mtime,D;if(dq(A)){let Y=(await ee(Q)).toString("base64"),W=OO2(A);D=`data:${mc0(W)};base64,${Y}`}else D=await ee(Q,"utf-8");return{entityType:w,id:$,content:D,created:f,updated:I}}async writeEntity(A){let Q=this.getEntityFilePath(A),B=A.entityType==="image",w;if(B){let f=A.content.match(/^data:image\/[a-z+]+;base64,(.+)$/i);w=f?.[1]?Buffer.from(f[1],"base64"):Buffer.from(A.content,"base64")}else w=this.entityService.serializeEntity(A);if(await w$(Q)){let f=B?await ee(Q):await ee(Q,"utf-8"),I=xB(B?f.toString("base64"):f),D=xB(B?w.toString("base64"):w);if(I===D)return}if(A.entityType!=="base")await RO2(bO2(Q),{recursive:!0});if(B)await Qp0(Q,w);else await Qp0(Q,w,"utf-8");let $=new Date(A.updated);await PO2(Q,$,$)}getFilePath(A,Q,B=".md"){return nc0(this.syncPath,A,Q,B)}getEntityFilePath(A){return this.getFilePath(A.id,A.entityType,oc0(A))}async getAllMarkdownFiles(){return eLA(this.syncPath,this.entityService)}async getAllSyncFiles(){return ac0(this.syncPath,this.entityService)}async ensureDirectoryStructure(A){await tc0(this.syncPath,A)}shouldUpdateEntity(A,Q){let B=xB(Q.content);return A.contentHash!==B}async gatherFileStatus(){return ec0(this.syncPath,this.entityService)}async syncDirectoryExists(){return w$(this.syncPath)}async fileExists(A){return w$(A)}}Bf();GA();Bf();async function AAA(A,Q,B,w){let{sourceUrl:$}=A,f=await Q.listEntities({entityType:"image",options:{filter:{metadata:{sourceUrl:$}},limit:1}});if(f[0])return w.debug("Reusing existing image entity",{sourceUrl:$,imageId:f[0].id}),f[0].id;let I=await B($),{base64:D}=uF(I),H=oN(D),Y=cF(D);if(!H||!Y)throw Error("Could not detect image format or dimensions");let W=await Q.createEntity({entity:{id:A.id,entityType:"image",content:I,metadata:{title:A.title,alt:A.alt,format:H,width:Y.width,height:Y.height,sourceUrl:$}}});return w.debug("Created image entity from URL",{sourceUrl:$,imageId:W.entityId}),W.entityId}var Bp0=F.object({title:F.string(),slug:F.string().optional(),coverImageUrl:F.string().url(),coverImageId:F.string().optional(),coverImageAlt:F.string().optional()});class QEA{entityService;fetcher;logger;constructor(A,Q,B=WH){this.entityService=A;this.fetcher=B;this.logger=Q.child("FrontmatterImageConverter")}detectCoverImageUrl(A){let Q;try{Q=JF(A)}catch{return null}let{frontmatter:B}=Q,w=Bp0.safeParse(B);if(!w.success)return null;if(w.data.coverImageId)return null;let{title:$,slug:f,coverImageUrl:I,coverImageAlt:D}=w.data;if(!JU(I))return null;return{sourceUrl:I,postTitle:$,postSlug:f??U2($),customAlt:D}}async convert(A){let Q;try{Q=JF(A)}catch(Y){return this.logger.debug("Parse failed",{error:Y}),{content:A,converted:!1}}let{frontmatter:B}=Q,w=Bp0.safeParse(B);if(!w.success)return{content:A,converted:!1};if(w.data.coverImageId)return{content:A,converted:!1};let{title:$,slug:f,coverImageUrl:I,coverImageAlt:D}=w.data;if(!JU(I))return{content:A,converted:!1};let H={postTitle:$,postSlug:f??U2($),sourceUrl:I,customAlt:D};try{let Y=await this.createImageEntity(H),W={...B};return delete W.coverImageUrl,delete W.coverImageAlt,W.coverImageId=Y,{content:$N(W,Q.content),converted:!0,imageId:Y}}catch(Y){return this.logger.warn("Failed to convert coverImageUrl",{url:I,error:y0(Y)}),{content:A,converted:!1}}}async createImageEntity(A){let{postTitle:Q,postSlug:B,sourceUrl:w,customAlt:$}=A,f=`Cover image for ${Q}`;return AAA({id:`${B}-cover`,title:f,alt:$??f,sourceUrl:w},this.entityService,this.fetcher,this.logger)}}Bf();GA();class _T{entityService;fetcher;logger;constructor(A,Q,B=WH){this.entityService=A;this.fetcher=B;this.logger=Q.child("MarkdownImageConverter")}detectInlineImages(A,Q){let B=[],w=AXA(A);for(let $ of w){if(!JU($.url))continue;if($.url.startsWith("entity://"))continue;let f=this.reconstructMarkdown($);B.push({sourceUrl:$.url,alt:$.alt,originalMarkdown:f,postSlug:Q})}return B}reconstructMarkdown(A){if(A.title)return``;return``}async convert(A,Q){let B=this.detectInlineImages(A,Q);if(B.length===0)return{content:A,converted:!1,convertedCount:0};let w=A,$=0,f=0;for(let I of B)try{let D=await this.createImageEntity(I,f++),H=``;w=w.replace(I.originalMarkdown,H),$++,this.logger.debug("Converted inline image",{sourceUrl:I.sourceUrl,imageId:D})}catch(D){this.logger.warn("Failed to convert inline image",{sourceUrl:I.sourceUrl,error:y0(D)})}return{content:w,converted:$>0,convertedCount:$}}async createImageEntity(A,Q){let{sourceUrl:B,alt:w,postSlug:$}=A;return AAA({id:`${$}-inline-${Q}`,title:w||`Inline image ${Q+1} for ${$}`,alt:w||"",sourceUrl:B},this.entityService,this.fetcher,this.logger)}}class BEA{logger;entityService;fileOperations;constructor(A,Q,B){this.logger=A,this.entityService=Q,this.fileOperations=B}async importEntitiesWithProgress(A,Q,B,w){this.logger.debug("Importing entities with progress reporting");let $={imported:0,skipped:0,failed:0,quarantined:0,quarantinedFiles:[],errors:[],jobIds:[]},f=A??await this.fileOperations.getAllSyncFiles(),I=f.length;await Q.report({progress:0,message:`Starting import of ${I} files`});for(let D=0;D<I;D+=B){let H=f.slice(D,D+B),Y=await w(H);$.imported+=Y.imported,$.skipped+=Y.skipped,$.failed+=Y.failed,$.quarantined+=Y.quarantined,$.errors.push(...Y.errors),$.quarantinedFiles.push(...Y.quarantinedFiles),$.jobIds.push(...Y.jobIds);let W=Math.min(D+B,I),G=Math.round(W/I*40);await Q.report({progress:G,message:`Imported ${W}/${I} files`})}return $}async exportEntitiesWithProgress(A,Q,B,w){this.logger.debug("Exporting entities with progress reporting");let $=A??this.entityService.getEntityTypes();await Q.report({progress:50,message:`Starting export of ${$.length} entity types`});let f=await w(A);return await Q.report({progress:100,message:`Exported ${f.exported} entities`}),this.logger.debug("Export completed",f),f}}GA();import{rename as kO2,appendFile as jO2,readFile as vO2,writeFile as xO2,access as hO2}from"fs/promises";import{join as wp0}from"path";class wEA{logger;syncPath;constructor(A,Q){this.logger=A;this.syncPath=Q}isValidationError(A){if(A instanceof F.ZodError)return!0;let Q=y0(A);return Q.includes("invalid_type")||Q.includes("invalid_enum_value")||Q.includes("Required")||Q.includes("Invalid frontmatter")||Q.includes("Unknown entity type")}async quarantineInvalidFile(A,Q,B,w){let $=w(A),f=`${$}.invalid`;try{await kO2($,f),B.quarantined++,B.quarantinedFiles.push(A);let I=wp0(this.syncPath,".import-errors.log"),D=new Date().toISOString(),H=y0(Q),Y=`${D} - ${A}: ${H}
|
|
2362
2362
|
\u2192 ${A}.invalid
|
|
2363
2363
|
|
|
2364
2364
|
`;await jO2(I,Y),this.logger.warn("Quarantined invalid entity file",{originalPath:A,quarantinePath:`${A}.invalid`,error:H})}catch(I){this.logger.error("Failed to quarantine invalid file",{path:A,error:I}),B.failed++,B.errors.push({path:A,error:"Failed to quarantine invalid file"})}}async markAsRecoveredIfNeeded(A){let Q=wp0(this.syncPath,".import-errors.log");try{await hO2(Q)}catch{return}try{let B=await vO2(Q,"utf-8");if(B.includes(A)){let $=`${new Date().toISOString()} - [RECOVERED] ${A}
|
|
@@ -2385,7 +2385,7 @@ ${R}`)}if(w!==void 0&&f?.algorithms!==void 0){let C=f.algorithms.map((R)=>R.alg)
|
|
|
2385
2385
|
*...and ${A.files.length-10} more files*`)}if(A.exists&&A.stats.totalFiles===0)Q.push(`
|
|
2386
2386
|
## Getting Started
|
|
2387
2387
|
`),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(`
|
|
2388
|
-
`)}}f0();class OAA extends ow{directorySync;constructor(A,Q,B){super(A,{schema:BMA,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}}}f0();class RAA extends ow{directorySync;constructor(A,Q,B){super(A,{schema:QMA,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}}}f0();class _AA extends ow{directorySync;context;constructor(A,Q,B){super(A,{schema:AMA,jobTypeName:"directory-sync"});this.context=Q,this.directorySync=B}async process(A,Q,B){let w=Date.now(),$=A.syncDirection??"both";this.logger.info("Starting directory sync job",{jobId:Q,operation:A.operation,syncDirection:$});let f={imported:0,skipped:0,failed:0,quarantined:0,quarantinedFiles:[],errors:[],jobIds:[]},I={exported:0,failed:0,errors:[]};if($!=="export")if(await B.report({progress:10,message:"Scanning directory for changes"}),f=await this.importWithProgress(A.paths,B),$==="import")await this.waitForImportJobs(f.jobIds,B),await B.report({progress:100,message:`Import complete: ${f.imported} imported`});else await B.report({progress:50,message:`Imported ${f.imported} entities`}),await this.waitForImportJobs(f.jobIds,B),await B.report({progress:56,message:"Processing complete, starting export"});if($!=="import"){let H=$==="export"?10:60;await B.report({progress:H,message:"Exporting entities to directory"}),I=await this.exportWithProgress(A.entityTypes,B),await B.report({progress:100,message:$==="export"?`Export complete: ${I.exported} exported`:`Sync complete: ${f.imported} imported, ${I.exported} exported`})}let D=Date.now()-w;return this.logger.info("Directory sync job completed",{jobId:Q,duration:D,imported:f.imported,exported:I.exported}),{import:f,export:I,duration:D}}async importWithProgress(A,Q){try{return await this.directorySync.importEntitiesWithProgress(A,Q,10)}catch(B){throw this.logger.error("Import phase failed",{error:B}),B}}async exportWithProgress(A,Q){try{return await this.directorySync.exportEntitiesWithProgress(A,Q,10)}catch(B){throw this.logger.error("Export phase failed",{error:B}),B}}async waitForImportJobs(A,Q){if(A.length===0)return;this.logger.debug(`Waiting for ${A.length} import jobs to complete`);let{entityService:B}=this.context,w=300000,$=500,f=Date.now(),I=async()=>{let H=(await Promise.all(A.map((W)=>B.getAsyncJobStatus(W)))).filter((W)=>W&&(W.status==="completed"||W.status==="failed")).length;if(H===A.length){this.logger.debug("All import jobs completed");return}if(Date.now()-f>w){this.logger.warn(`Timeout waiting for import jobs (${H}/${A.length} completed)`);return}let Y=Math.round(H/A.length*100);return await Q.report({progress:50+Math.round(Y*0.05),message:`Processing ${H}/${A.length} entities`}),await new Promise((W)=>setTimeout(W,$)),I()};return I()}summarizeDataForLog(A){return{operation:A.operation,syncDirection:A.syncDirection}}}f0();class PAA extends ow{context;constructor(A,Q,B){super(A,{schema:VAA,jobTypeName:"directory-delete"});this.context=Q}async process(A,Q,B){let w=VAA.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}}}f0();GA();var Pk2=F.object({});class kAA extends ow{directorySync;constructor(A,Q){super(A,{schema:Pk2,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}}f0();Bf();GA();L$();Bf();import{readFile as kk2,writeFile as jk2}from"fs/promises";var vk2=wMA;class jAA extends ow{context;fetcher;constructor(A,Q,B=WH){super(Q,{schema:vk2,jobTypeName:"cover-image-convert"});this.context=A,this.fetcher=B}async process(A,Q,B){let{filePath:w,sourceUrl:$,postTitle:f,postSlug:I,customAlt:D}=A;this.logger.debug("Starting image conversion job",{jobId:Q,filePath:w,sourceUrl:$,postSlug:I});try{await this.reportProgress(B,{progress:vQ.INIT,message:`Reading file: ${w}`});let H;try{H=await kk2(w,"utf-8")}catch(L){return this.logger.error("Failed to read file",{filePath:w,error:y0(L)}),C$.failure(L)}let Y;try{Y=JF(H)}catch(L){return this.logger.warn("Failed to parse markdown",{filePath:w,error:y0(L)}),C$.failure(L)}let W=Y.frontmatter;if(W.coverImageId)return this.logger.debug("File already has coverImageId, skipping",{filePath:w}),await this.reportProgress(B,{progress:vQ.COMPLETE,message:"Already converted"}),{success:!0,skipped:!0};await this.reportProgress(B,{progress:vQ.FETCH,message:"Checking for existing image"});let G=await this.context.entityService.listEntities({entityType:"image",options:{filter:{metadata:{sourceUrl:$}},limit:1}}),K;if(G[0])K=G[0].id,this.logger.debug("Reusing existing image entity",{sourceUrl:$,imageId:K}),await this.reportProgress(B,{progress:vQ.EXTRACT,message:`Reusing existing image: ${K}`});else{await this.reportProgress(B,{progress:vQ.PROCESS,message:`Fetching image from ${$}`});let L;try{L=await this.fetcher($)}catch(r){return this.logger.error("Failed to fetch image",{sourceUrl:$,error:y0(r)}),C$.failure(r)}await this.reportProgress(B,{progress:vQ.GENERATE,message:"Creating image entity"});let{base64:C}=uF(L),R=oN(C),k=cF(C);if(!R||!k)return this.logger.error("Could not detect image format or dimensions",{sourceUrl:$}),C$.failure(Error("Could not detect image format or dimensions"));K=`${I}-cover`;let _=`Cover image for ${f}`,o=D??_;await this.context.entityService.createEntity({entity:{id:K,entityType:"image",content:L,metadata:{title:_,alt:o,format:R,width:k.width,height:k.height,sourceUrl:$}}}),this.logger.debug("Created image entity",{imageId:K,sourceUrl:$}),await this.reportProgress(B,{progress:vQ.EXTRACT,message:`Created image: ${K}`})}await this.reportProgress(B,{progress:vQ.SAVE,message:"Updating file"});let Z={...W};delete Z.coverImageUrl,delete Z.coverImageAlt,Z.coverImageId=K;let q=$N(Z,Y.content);try{await jk2(w,q,"utf-8")}catch(L){return this.logger.error("Failed to write file",{filePath:w,error:y0(L)}),C$.failure(L)}return await this.reportProgress(B,{progress:vQ.COMPLETE,message:"Conversion complete"}),this.logger.info("Image conversion complete",{filePath:w,imageId:K,sourceUrl:$}),{success:!0,imageId:K}}catch(H){return this.logger.error("Image conversion job failed",{jobId:Q,filePath:w,error:y0(H)}),C$.failure(H)}}summarizeDataForLog(A){return{filePath:A.filePath,sourceUrl:A.sourceUrl,postSlug:A.postSlug}}}f0();Bf();GA();L$();import{readFile as xk2,writeFile as hk2}from"fs/promises";class vAA extends ow{converter;constructor(A,Q,B=WH){super(Q,{schema:$MA,jobTypeName:"inline-image-convert"});this.converter=new _T(A.entityService,Q,B)}async process(A,Q,B){let{filePath:w,postSlug:$}=A;this.logger.debug("Starting inline image conversion job",{jobId:Q,filePath:w,postSlug:$});try{await this.reportProgress(B,{progress:vQ.INIT,message:`Reading file: ${w}`});let f;try{f=await xk2(w,"utf-8")}catch(H){let Y=y0(H);return this.logger.error("Failed to read file",{filePath:w,error:Y}),{success:!1,error:Y}}await this.reportProgress(B,{progress:vQ.FETCH,message:"Detecting inline images"});let I=this.converter.detectInlineImages(f,$);if(I.length===0)return this.logger.debug("No inline images to convert",{filePath:w}),await this.reportProgress(B,{progress:vQ.COMPLETE,message:"No images to convert"}),{success:!0,skipped:!0,convertedCount:0};this.logger.debug("Found inline images to convert",{filePath:w,count:I.length}),await this.reportProgress(B,{progress:vQ.PROCESS,message:`Converting ${I.length} images`});let D=await this.converter.convert(f,$);if(!D.converted)return this.logger.debug("No images were converted",{filePath:w}),await this.reportProgress(B,{progress:vQ.COMPLETE,message:"No images converted"}),{success:!0,skipped:!0,convertedCount:0};await this.reportProgress(B,{progress:vQ.SAVE,message:"Writing updated file"});try{await hk2(w,D.content,"utf-8")}catch(H){let Y=y0(H);return this.logger.error("Failed to write file",{filePath:w,error:Y}),{success:!1,error:Y}}return await this.reportProgress(B,{progress:vQ.COMPLETE,message:"Conversion complete"}),this.logger.info("Inline image conversion complete",{filePath:w,convertedCount:D.convertedCount}),{success:!0,convertedCount:D.convertedCount}}catch(f){let I=y0(f);return this.logger.error("Inline image conversion job failed",{jobId:Q,filePath:w,error:I}),{success:!1,error:I}}}summarizeDataForLog(A){return{filePath:A.filePath,postSlug:A.postSlug}}}function xr0(A,Q,B){let w=($)=>B.child($);A.jobs.registerHandler("directory-sync",new _AA(w("DirectorySyncJobHandler"),A,Q)),A.jobs.registerHandler("directory-export",new OAA(w("DirectoryExportJobHandler"),A,Q)),A.jobs.registerHandler("directory-import",new RAA(w("DirectoryImportJobHandler"),A,Q)),A.jobs.registerHandler("directory-delete",new PAA(w("DirectoryDeleteJobHandler"),A,Q)),A.jobs.registerHandler("directory-cleanup",new kAA(w("DirectoryCleanupJobHandler"),Q)),A.jobs.registerHandler("cover-image-convert",new jAA(A,w("CoverImageConversionJobHandler"))),A.jobs.registerHandler("inline-image-convert",new vAA(A,w("InlineImageConversionJobHandler"))),B.debug("Registered async job handlers")}f0();import{unlink as yk2,access as gk2}from"fs/promises";function hr0(A,Q,B,w){let{subscribe:$}=A.messaging,{entityService:f}=A;$("entity:created",async(I)=>{let{entity:D}=I.payload;try{await Q.fileOps.writeEntity(D),B.debug("Auto-exported created entity",{id:D.id,entityType:D.entityType})}catch(H){B.error("Auto-export FAILED for created entity",{id:D.id,entityType:D.entityType,error:H instanceof Error?H.message:String(H),stack:H instanceof Error?H.stack:void 0})}return{success:!0}}),$("entity:updated",async(I)=>{let{entityType:D,entityId:H}=I.payload;try{let Y=await f.getEntity({entityType:D,id:H});if(!Y)return B.debug("Entity not found in DB, skipping export",{entityType:D,entityId:H}),{success:!1};await Q.fileOps.writeEntity(Y),B.debug("Auto-exported updated entity",{id:Y.id,entityType:Y.entityType})}catch(Y){B.error("Auto-export FAILED for updated entity",{entityType:D,entityId:H,error:Y instanceof Error?Y.message:String(Y),stack:Y instanceof Error?Y.stack:void 0})}return{success:!0}}),$("entity:deleted",async(I)=>{let{entityId:D,entityType:H}=I.payload,Y=Q.fileOps.getFilePath(D,H);if(await gk2(Y).then(()=>!0,()=>!1))await yk2(Y),B.debug("Auto-deleted entity file",{id:D,entityType:H,path:Y});return{success:!0}}),B.debug("Setup auto-sync for entity events",{entityTypes:w})}function yr0(A,Q,B){Q.setJobQueueCallback(async(w)=>{let $=[{type:w.type,data:w.data}];return A.jobs.enqueueBatch($,{priority:5,source:"directory-sync-watcher",rootJobId:Z5(),metadata:{operationType:"file_operations",operationTarget:B,pluginId:"directory-sync"}})})}GA();f0();import{readdir as Sr0,mkdir as Sk2,copyFile as mk2}from"fs/promises";import{join as Tr0,resolve as fMA}from"path";import{join as Tk2}from"path";async function gr0(A){if(!await w$(Tk2(A,".git")))return!1;try{return await gJ(A).revparse(["--verify","HEAD"]),!0}catch{return!1}}async function uk2(A,Q){if(!await w$(A))return!0;if((await Sr0(A)).filter(($)=>!$.startsWith(".")&&!$.startsWith("_")).length>0)return!1;if(await gr0(A))return Q.debug("Git repository with history detected - skipping seed content",{path:A}),!1;return!0}async function mr0(A,Q){let B=await Sr0(A,{withFileTypes:!0});for(let w of B){let $=Tr0(A,w.name),f=Tr0(Q,w.name);if(w.isDirectory()){if(!await w$(f))await Sk2(f,{recursive:!0});await mr0($,f)}else await mk2($,f)}}async function ur0(A,Q,B){let w=fMA(process.cwd(),A);B=B?fMA(B):fMA(process.cwd(),"seed-content");let $=await uk2(w,Q);if($&&await w$(B))Q.debug("Copying seed content to brain-data directory"),await mr0(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 cr0(A,Q,B,w,$){let f=!1,I=async()=>{if(f)return;f=!0;let D=Q();if(B.seedContent){let H=B.syncPath??A.dataDir;await ur0(H,w,B.seedContentPath)}try{if($){w.debug("Git enabled \u2014 pulling before import");let Y=await $.pull();if(Y.files.length>0)w.info("Pulled changes from remote",{filesChanged:Y.files.length})}w.debug("Starting initial sync");let H=await D.sync();w.debug("Initial sync completed",{imported:H.import.imported,failed:H.import.failed,duration:H.duration}),await A.messaging.send({type:CN.initialSyncCompleted,payload:{success:!0},...{broadcast:!0}})}catch(H){w.error("Initial sync failed",H),await A.messaging.send({type:CN.initialSyncCompleted,payload:{success:!1,error:y0(H)},...{broadcast:!0}})}};A.messaging.subscribe(CN.pluginsRegistered,async()=>{return w.debug("Plugins registered, starting initial sync"),await I(),{success:!0}})}GA();function pr0(A,Q,B,w){let $=new UN(()=>{Q.withLock(async()=>{try{await Q.commit(),await Q.push()}catch(D){w.error("Git auto-commit failed",{error:D})}})},B),f=["entity:created","entity:updated","entity:deleted"],I=[];for(let D of f){let H=A.subscribe(D,async()=>{return $.trigger(),{success:!0}});I.push(H)}return()=>{$.dispose();for(let D of I)D()}}function lr0(A,Q,B,w,$){if(w<=0)return()=>{};let f=w*60*1000,I=!1,D=async()=>{if(I)return;I=!0;try{let{files:Y,result:W}=await A.withLock(async()=>{let G=await A.pull();if(G.files.length===0)return{files:[],result:null};let K=await Q.queueSyncBatch(B,"periodic-sync");return{files:G.files,result:K}});if(Y.length>0)$.info("Periodic sync: pulled changes",{filesChanged:Y.length});if(W)$.debug("Periodic sync: queued imports",{importOperations:W.importOperationsCount,totalFiles:W.totalFiles})}catch(Y){$.error("Periodic git sync failed",{error:Y})}finally{I=!1}},H=setInterval(()=>{D()},f);return $.info("Started periodic git sync",{intervalMinutes:w}),()=>{clearInterval(H)}}import{spawnSync as rr0}from"child_process";import{cpSync as ck2,existsSync as ir0,mkdirSync as pk2,mkdtempSync as lk2,rmSync as ik2}from"fs";import{tmpdir as rk2}from"os";import{fileURLToPath as dk2}from"url";import{join as nk2,resolve as ok2}from"path";function qZ(A,Q){let B=rr0("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 sk2(A){return A.startsWith("file://")}function ak2(A){return dk2(A)}function tk2(A,Q){return rr0("git",["--git-dir",A,"show-ref","--verify","--quiet",`refs/heads/${Q}`]).status===0}async function dr0(A){if(!A.bootstrapFromSeed)return;if(!A.gitUrl||!sk2(A.gitUrl))return;if(!A.seedContentPath)throw Error("directory-sync git.bootstrapFromSeed requires seedContentPath for local file:// remotes");let Q=A.branch??"main",B=ak2(A.gitUrl),w=ok2(A.seedContentPath);if(!ir0(w))throw Error(`Seed content path not found: ${w}`);if(!ir0(B))A.logger.debug("Creating local bare content remote",{remotePath:B,branch:Q}),pk2(B,{recursive:!0}),qZ(process.cwd(),["init","--bare",`--initial-branch=${Q}`,B]);if(tk2(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 $=lk2(nk2(rk2(),"directory-sync-seed-"));try{qZ($,["init",`--initial-branch=${Q}`]),qZ($,["config","user.name",A.authorName??"Brain"]),qZ($,["config","user.email",A.authorEmail??"brain@localhost"]),ck2(w,$,{recursive:!0}),qZ($,["add","."]),qZ($,["commit","-m","seed content remote"]),qZ($,["remote","add","origin",A.gitUrl]),qZ($,["push","-u","origin",Q])}finally{ik2($,{recursive:!0,force:!0})}}function nr0(A,Q,B,w,$){let{subscribe:f}=A.messaging;f("entity:export:request",async(I)=>{try{return{success:!0,data:await Q().exportEntities(I.payload.entityTypes)}}catch(D){return{success:!1,error:D instanceof Error?D.message:"Export failed"}}}),f("entity:import:request",async(I)=>{try{let D=Q(),H=I.payload.paths,Y=await D.importEntities(H);if(H&&H.length>0)await D.removeOrphanedEntities();return{success:!0,data:Y}}catch(D){return{success:!1,error:D instanceof Error?D.message:"Import failed"}}}),f("sync:status:request",async()=>{try{let D=await Q().getStatus();return{success:!0,data:{syncPath:D.syncPath,isInitialized:D.exists,watchEnabled:D.watching}}}catch(I){return{success:!1,error:I instanceof Error?I.message:"Status check failed"}}}),f("sync:configure:request",async(I)=>{try{return await B({syncPath:I.payload.syncPath}),{success:!0,data:{syncPath:I.payload.syncPath,configured:!0}}}catch(D){return{success:!1,error:D instanceof Error?D.message:"Configuration failed"}}}),f("git-sync:get-repo-info",async()=>{if(!$?.repo)return{success:!1,error:"Git not configured"};return{success:!0,data:{repo:$.repo,branch:$.branch??"main"}}}),w.debug("Registered message handlers")}f0();GA();f0();GA();function or0(A,Q){return xQ(A,"history","Get version history for an entity from git. Without sha: returns commit list. With sha: returns entity content at that version.",F.object({entityType:F.string().describe("Entity type (e.g. post, note, link)"),id:F.string().describe("Entity ID"),sha:F.string().optional().describe("Commit SHA to retrieve content at. Omit to list commit history."),limit:F.number().int().positive().optional().default(10).describe("Max commits to return (list mode only)")}),async(B)=>{let w=`${B.entityType}/${B.id}.md`;try{if(B.sha){let f=await Q.show(B.sha,w);return P8({sha:B.sha,entityType:B.entityType,id:B.id,content:f},`Content at ${B.sha.slice(0,7)}`)}let $=await Q.log(w,B.limit);if($.length===0)return P8({commits:[]},`No history found for ${B.entityType}/${B.id}`);return P8({commits:$,entityType:B.entityType,id:B.id},`${$.length} version${$.length===1?"":"s"} found`)}catch($){return E$($ instanceof Error?$.message:"History lookup failed")}})}function sr0(A,Q,B,w){let $=[xQ(B,"sync","Sync brain entities with the filesystem. Use this for refresh, pull, sync, or backup-to-git requests. Pulls from git if configured, then imports files. Git commit and push happen automatically after imports complete.",F.object({}),async(f,I)=>{try{let D=I.channelId?`${I.interfaceType}:${I.channelId}`:`plugin:${B}`,H={interfaceType:I.interfaceType,channelId:I.channelId},Y=w!==void 0,W=()=>A.queueSyncBatch(Q,D,H),G=w?await w.withLock(async()=>{return await w.pull(),W()}):await W();if(!G)return P8({gitPulled:Y},"No files to sync");return P8({batchId:G.batchId,importOperations:G.importOperationsCount,totalFiles:G.totalFiles,gitPulled:Y},`Sync started: ${G.importOperationsCount} import jobs queued for ${G.totalFiles} files${Y?" (pulled from git)":""}`)}catch(D){return E$(D instanceof Error?D.message:"Sync failed")}},{cli:{name:"sync"}}),xQ(B,"status","Get sync and git repository status \u2014 last sync time, watching state, pending git changes. Use this for status questions, not for actually syncing or backing up.",F.object({}),async()=>{try{let f=await A.getStatus(),I={syncPath:f.syncPath,lastSync:f.lastSync?.toISOString(),watching:f.watching};if(w){let D=await w.getStatus();I.git={isRepo:D.isRepo,branch:D.branch,hasChanges:D.hasChanges,ahead:D.ahead,behind:D.behind,remote:D.remote}}return P8(I)}catch(f){return E$(f instanceof Error?f.message:"Status check failed")}},{visibility:"public"})];if(w)$.push(or0(B,w));return $}var ar0={name:"@brains/directory-sync",private:!0,version:"0.2.0-alpha.70",description:"Directory-based entity synchronization plugin for Brains",type:"module",main:"./src/index.ts",types:"./src/index.ts",exports:{".":{types:"./src/index.ts",import:"./src/index.ts"}},scripts:{test:"bun test",typecheck:"tsc --noEmit",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",clean:"rm -rf .turbo"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/image":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*",chokidar:"^3.5.3","simple-git":"^3.21.0"},devDependencies:{"@types/bun":"latest","@types/node":"^20.0.0",typescript:"^5.3.3"},peerDependencies:{}};class IMA extends Ww{directorySync;gitSync;gitCleanups=[];constructor(A={}){super("directory-sync",ar0,A,uT)}requireDirectorySync(){if(!this.directorySync)throw Error("DirectorySync service not initialized");return this.directorySync}hasGitSync(){return this.gitSync!==void 0}async onRegister(A){let{logger:Q,entityService:B}=A;A.templates.register({status:{name:"status",description:"Directory synchronization status",schema:cT,basePrompt:"",formatter:new bAA,requiredPermission:"anchor"}});let w=this.config.syncPath??A.dataDir;this.directorySync=new PT({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(hr0(A,$,this.logger,this.config.entityTypes),this.config.autoSync)yr0(A,$,this.config.syncPath??A.dataDir);let f=this.config.git!==void 0&&(this.config.git.repo!==void 0||this.config.git.gitUrl!==void 0);if(this.config.git&&!f)this.logger.debug("Git block present but no repo/gitUrl configured \u2014 git sync disabled");if(f&&this.config.git){await dr0({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 eEA({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(pr0(A.messaging,this.gitSync,this.config.commitDebounce,this.logger.child("GitAutoCommit"))),this.config.autoSync)this.gitCleanups.push(lr0(this.gitSync,this.requireDirectorySync(),A,this.config.syncInterval,this.logger.child("GitPeriodicSync")))}if(this.config.initialSync)cr0(A,()=>this.requireDirectorySync(),this.config,this.logger,this.gitSync);nr0(A,()=>this.requireDirectorySync(),(I)=>this.configure(I),this.logger,this.config.git)}async getTools(){let A=this.requireDirectorySync();return sr0(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 PT({...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){xr0(A,this.requireDirectorySync(),this.logger)}}function aq(A={}){return new IMA(A)}f0();import{render as nQ1}from"preact-render-to-string";import{h as _C}from"preact";function tr0(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=tr0(A[Q]))&&(w&&(w+=" "),w+=B)}else for(B in A)A[B]&&(w&&(w+=" "),w+=B);return w}function JR(){for(var A,Q,B=0,w="",$=arguments.length;B<$;B++)(A=arguments[B])&&(Q=tr0(A))&&(w&&(w+=" "),w+=Q);return w}var Aj2=(A)=>{let Q=Bj2(A),{conflictingClassGroups:B,conflictingClassGroupModifiers:w}=A;return{getClassGroupId:(I)=>{let D=I.split("-");if(D[0]===""&&D.length!==1)D.shift();return wd0(D,Q)||Qj2(I)},getConflictingClassGroupIds:(I,D)=>{let H=B[I]||[];if(D&&w[I])return[...H,...w[I]];return H}}},wd0=(A,Q)=>{if(A.length===0)return Q.classGroupId;let B=A[0],w=Q.nextPart.get(B),$=w?wd0(A.slice(1),w):void 0;if($)return $;if(Q.validators.length===0)return;let f=A.join("-");return Q.validators.find(({validator:I})=>I(f))?.classGroupId},er0=/^\[(.+)\]$/,Qj2=(A)=>{if(er0.test(A)){let Q=er0.exec(A)[1],B=Q?.substring(0,Q.indexOf(":"));if(B)return"arbitrary.."+B}},Bj2=(A)=>{let{theme:Q,prefix:B}=A,w={nextPart:new Map,validators:[]};return $j2(Object.entries(A.classGroups),B).forEach(([f,I])=>{HMA(I,w,f,Q)}),w},HMA=(A,Q,B,w)=>{A.forEach(($)=>{if(typeof $==="string"){let f=$===""?Q:Ad0(Q,$);f.classGroupId=B;return}if(typeof $==="function"){if(wj2($)){HMA($(w),Q,B,w);return}Q.validators.push({validator:$,classGroupId:B});return}Object.entries($).forEach(([f,I])=>{HMA(I,Ad0(Q,f),B,w)})})},Ad0=(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},wj2=(A)=>A.isThemeGetter,$j2=(A,Q)=>{if(!Q)return A;return A.map(([B,w])=>{let $=w.map((f)=>{if(typeof f==="string")return Q+f;if(typeof f==="object")return Object.fromEntries(Object.entries(f).map(([I,D])=>[Q+I,D]));return f});return[B,$]})},fj2=(A)=>{if(A<1)return{get:()=>{return},set:()=>{}};let Q=0,B=new Map,w=new Map,$=(f,I)=>{if(B.set(f,I),Q++,Q>A)Q=0,w=B,B=new Map};return{get(f){let I=B.get(f);if(I!==void 0)return I;if((I=w.get(f))!==void 0)return $(f,I),I},set(f,I){if(B.has(f))B.set(f,I);else $(f,I)}}};var Ij2=(A)=>{let{separator:Q,experimentalParseClassName:B}=A,w=Q.length===1,$=Q[0],f=Q.length,I=(D)=>{let H=[],Y=0,W=0,G;for(let C=0;C<D.length;C++){let R=D[C];if(Y===0){if(R===$&&(w||D.slice(C,C+f)===Q)){H.push(D.slice(W,C)),W=C+f;continue}if(R==="/"){G=C;continue}}if(R==="[")Y++;else if(R==="]")Y--}let K=H.length===0?D:D.substring(W),Z=K.startsWith("!"),q=Z?K.substring(1):K,L=G&&G>W?G-W:void 0;return{modifiers:H,hasImportantModifier:Z,baseClassName:q,maybePostfixModifierPosition:L}};if(B)return(D)=>B({className:D,parseClassName:I});return I},Dj2=(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},Hj2=(A)=>({cache:fj2(A.cacheSize),parseClassName:Ij2(A),...Aj2(A)}),Yj2=/\s+/,Xj2=(A,Q)=>{let{parseClassName:B,getClassGroupId:w,getConflictingClassGroupIds:$}=Q,f=[],I=A.trim().split(Yj2),D="";for(let H=I.length-1;H>=0;H-=1){let Y=I[H],{modifiers:W,hasImportantModifier:G,baseClassName:K,maybePostfixModifierPosition:Z}=B(Y),q=Boolean(Z),L=w(q?K.substring(0,Z):K);if(!L){if(!q){D=Y+(D.length>0?" "+D:D);continue}if(L=w(K),!L){D=Y+(D.length>0?" "+D:D);continue}q=!1}let C=Dj2(W).join(":"),R=G?C+"!":C,k=R+L;if(f.includes(k))continue;f.push(k);let _=$(L,q);for(let o=0;o<_.length;++o){let r=_[o];f.push(R+r)}D=Y+(D.length>0?" "+D:D)}return D};function Wj2(){let A=0,Q,B,w="";while(A<arguments.length)if(Q=arguments[A++]){if(B=$d0(Q))w&&(w+=" "),w+=B}return w}var $d0=(A)=>{if(typeof A==="string")return A;let Q,B="";for(let w=0;w<A.length;w++)if(A[w]){if(Q=$d0(A[w]))B&&(B+=" "),B+=Q}return B};function Qd0(A,...Q){let B,w,$,f=I;function I(H){let Y=Q.reduce((W,G)=>G(W),A());return B=Hj2(Y),w=B.cache.get,$=B.cache.set,f=D,D(H)}function D(H){let Y=w(H);if(Y)return Y;let W=Xj2(H,B);return $(H,W),W}return function(){return f(Wj2.apply(null,arguments))}}var B8=(A)=>{let Q=(B)=>B[A]||[];return Q.isThemeGetter=!0,Q},fd0=/^\[(?:([a-z-]+):)?(.+)\]$/i,Uj2=/^\d+\/\d+$/,Jj2=new Set(["px","full","screen"]),Gj2=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,Fj2=/\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$/,Kj2=/^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/,Zj2=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,Nj2=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,TJ=(A)=>GR(A)||Jj2.has(A)||Uj2.test(A),CZ=(A)=>FR(A,"length",bj2),GR=(A)=>Boolean(A)&&!Number.isNaN(Number(A)),DMA=(A)=>FR(A,"number",GR),pT=(A)=>Boolean(A)&&Number.isInteger(Number(A)),zj2=(A)=>A.endsWith("%")&&GR(A.slice(0,-1)),PQ=(A)=>fd0.test(A),LZ=(A)=>Gj2.test(A),qj2=new Set(["length","size","percentage"]),Cj2=(A)=>FR(A,qj2,Id0),Lj2=(A)=>FR(A,"position",Id0),Ej2=new Set(["image","url"]),Mj2=(A)=>FR(A,Ej2,Rj2),Vj2=(A)=>FR(A,"",Oj2),lT=()=>!0,FR=(A,Q,B)=>{let w=fd0.exec(A);if(w){if(w[1])return typeof Q==="string"?w[1]===Q:Q.has(w[1]);return B(w[2])}return!1},bj2=(A)=>Fj2.test(A)&&!Kj2.test(A),Id0=()=>!1,Oj2=(A)=>Zj2.test(A),Rj2=(A)=>Nj2.test(A);var Bd0=()=>{let A=B8("colors"),Q=B8("spacing"),B=B8("blur"),w=B8("brightness"),$=B8("borderColor"),f=B8("borderRadius"),I=B8("borderSpacing"),D=B8("borderWidth"),H=B8("contrast"),Y=B8("grayscale"),W=B8("hueRotate"),G=B8("invert"),K=B8("gap"),Z=B8("gradientColorStops"),q=B8("gradientColorStopPositions"),L=B8("inset"),C=B8("margin"),R=B8("opacity"),k=B8("padding"),_=B8("saturate"),o=B8("scale"),r=B8("sepia"),S=B8("skew"),x=B8("space"),y=B8("translate"),g=()=>["auto","contain","none"],AA=()=>["auto","hidden","clip","visible","scroll"],c=()=>["auto",PQ,Q],JA=()=>[PQ,Q],HA=()=>["",TJ,CZ],P=()=>["auto",GR,PQ],O=()=>["bottom","center","left","left-bottom","left-top","right","right-bottom","right-top","top"],j=()=>["solid","dashed","dotted","double","none"],t=()=>["normal","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity"],d=()=>["start","end","center","between","around","evenly","stretch"],BA=()=>["","0",PQ],n=()=>["auto","avoid","all","avoid-page","page","left","right","column"],UA=()=>[GR,PQ];return{cacheSize:500,separator:":",theme:{colors:[lT],spacing:[TJ,CZ],blur:["none","",LZ,PQ],brightness:UA(),borderColor:[A],borderRadius:["none","","full",LZ,PQ],borderSpacing:JA(),borderWidth:HA(),contrast:UA(),grayscale:BA(),hueRotate:UA(),invert:BA(),gap:JA(),gradientColorStops:[A],gradientColorStopPositions:[zj2,CZ],inset:c(),margin:c(),opacity:UA(),padding:JA(),saturate:UA(),scale:UA(),sepia:BA(),skew:UA(),space:JA(),translate:JA()},classGroups:{aspect:[{aspect:["auto","square","video",PQ]}],container:["container"],columns:[{columns:[LZ]}],"break-after":[{"break-after":n()}],"break-before":[{"break-before":n()}],"break-inside":[{"break-inside":["auto","avoid","avoid-page","avoid-column"]}],"box-decoration":[{"box-decoration":["slice","clone"]}],box:[{box:["border","content"]}],display:["block","inline-block","inline","flex","inline-flex","table","inline-table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row-group","table-row","flow-root","grid","inline-grid","contents","list-item","hidden"],float:[{float:["right","left","none","start","end"]}],clear:[{clear:["left","right","both","none","start","end"]}],isolation:["isolate","isolation-auto"],"object-fit":[{object:["contain","cover","fill","none","scale-down"]}],"object-position":[{object:[...O(),PQ]}],overflow:[{overflow:AA()}],"overflow-x":[{"overflow-x":AA()}],"overflow-y":[{"overflow-y":AA()}],overscroll:[{overscroll:g()}],"overscroll-x":[{"overscroll-x":g()}],"overscroll-y":[{"overscroll-y":g()}],position:["static","fixed","absolute","relative","sticky"],inset:[{inset:[L]}],"inset-x":[{"inset-x":[L]}],"inset-y":[{"inset-y":[L]}],start:[{start:[L]}],end:[{end:[L]}],top:[{top:[L]}],right:[{right:[L]}],bottom:[{bottom:[L]}],left:[{left:[L]}],visibility:["visible","invisible","collapse"],z:[{z:["auto",pT,PQ]}],basis:[{basis:c()}],"flex-direction":[{flex:["row","row-reverse","col","col-reverse"]}],"flex-wrap":[{flex:["wrap","wrap-reverse","nowrap"]}],flex:[{flex:["1","auto","initial","none",PQ]}],grow:[{grow:BA()}],shrink:[{shrink:BA()}],order:[{order:["first","last","none",pT,PQ]}],"grid-cols":[{"grid-cols":[lT]}],"col-start-end":[{col:["auto",{span:["full",pT,PQ]},PQ]}],"col-start":[{"col-start":P()}],"col-end":[{"col-end":P()}],"grid-rows":[{"grid-rows":[lT]}],"row-start-end":[{row:["auto",{span:[pT,PQ]},PQ]}],"row-start":[{"row-start":P()}],"row-end":[{"row-end":P()}],"grid-flow":[{"grid-flow":["row","col","dense","row-dense","col-dense"]}],"auto-cols":[{"auto-cols":["auto","min","max","fr",PQ]}],"auto-rows":[{"auto-rows":["auto","min","max","fr",PQ]}],gap:[{gap:[K]}],"gap-x":[{"gap-x":[K]}],"gap-y":[{"gap-y":[K]}],"justify-content":[{justify:["normal",...d()]}],"justify-items":[{"justify-items":["start","end","center","stretch"]}],"justify-self":[{"justify-self":["auto","start","end","center","stretch"]}],"align-content":[{content:["normal",...d(),"baseline"]}],"align-items":[{items:["start","end","center","baseline","stretch"]}],"align-self":[{self:["auto","start","end","center","stretch","baseline"]}],"place-content":[{"place-content":[...d(),"baseline"]}],"place-items":[{"place-items":["start","end","center","baseline","stretch"]}],"place-self":[{"place-self":["auto","start","end","center","stretch"]}],p:[{p:[k]}],px:[{px:[k]}],py:[{py:[k]}],ps:[{ps:[k]}],pe:[{pe:[k]}],pt:[{pt:[k]}],pr:[{pr:[k]}],pb:[{pb:[k]}],pl:[{pl:[k]}],m:[{m:[C]}],mx:[{mx:[C]}],my:[{my:[C]}],ms:[{ms:[C]}],me:[{me:[C]}],mt:[{mt:[C]}],mr:[{mr:[C]}],mb:[{mb:[C]}],ml:[{ml:[C]}],"space-x":[{"space-x":[x]}],"space-x-reverse":["space-x-reverse"],"space-y":[{"space-y":[x]}],"space-y-reverse":["space-y-reverse"],w:[{w:["auto","min","max","fit","svw","lvw","dvw",PQ,Q]}],"min-w":[{"min-w":[PQ,Q,"min","max","fit"]}],"max-w":[{"max-w":[PQ,Q,"none","full","min","max","fit","prose",{screen:[LZ]},LZ]}],h:[{h:[PQ,Q,"auto","min","max","fit","svh","lvh","dvh"]}],"min-h":[{"min-h":[PQ,Q,"min","max","fit","svh","lvh","dvh"]}],"max-h":[{"max-h":[PQ,Q,"min","max","fit","svh","lvh","dvh"]}],size:[{size:[PQ,Q,"auto","min","max","fit"]}],"font-size":[{text:["base",LZ,CZ]}],"font-smoothing":["antialiased","subpixel-antialiased"],"font-style":["italic","not-italic"],"font-weight":[{font:["thin","extralight","light","normal","medium","semibold","bold","extrabold","black",DMA]}],"font-family":[{font:[lT]}],"fvn-normal":["normal-nums"],"fvn-ordinal":["ordinal"],"fvn-slashed-zero":["slashed-zero"],"fvn-figure":["lining-nums","oldstyle-nums"],"fvn-spacing":["proportional-nums","tabular-nums"],"fvn-fraction":["diagonal-fractions","stacked-fractions"],tracking:[{tracking:["tighter","tight","normal","wide","wider","widest",PQ]}],"line-clamp":[{"line-clamp":["none",GR,DMA]}],leading:[{leading:["none","tight","snug","normal","relaxed","loose",TJ,PQ]}],"list-image":[{"list-image":["none",PQ]}],"list-style-type":[{list:["none","disc","decimal",PQ]}],"list-style-position":[{list:["inside","outside"]}],"placeholder-color":[{placeholder:[A]}],"placeholder-opacity":[{"placeholder-opacity":[R]}],"text-alignment":[{text:["left","center","right","justify","start","end"]}],"text-color":[{text:[A]}],"text-opacity":[{"text-opacity":[R]}],"text-decoration":["underline","overline","line-through","no-underline"],"text-decoration-style":[{decoration:[...j(),"wavy"]}],"text-decoration-thickness":[{decoration:["auto","from-font",TJ,CZ]}],"underline-offset":[{"underline-offset":["auto",TJ,PQ]}],"text-decoration-color":[{decoration:[A]}],"text-transform":["uppercase","lowercase","capitalize","normal-case"],"text-overflow":["truncate","text-ellipsis","text-clip"],"text-wrap":[{text:["wrap","nowrap","balance","pretty"]}],indent:[{indent:JA()}],"vertical-align":[{align:["baseline","top","middle","bottom","text-top","text-bottom","sub","super",PQ]}],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",PQ]}],"bg-attachment":[{bg:["fixed","local","scroll"]}],"bg-clip":[{"bg-clip":["border","padding","content","text"]}],"bg-opacity":[{"bg-opacity":[R]}],"bg-origin":[{"bg-origin":["border","padding","content"]}],"bg-position":[{bg:[...O(),Lj2]}],"bg-repeat":[{bg:["no-repeat",{repeat:["","x","y","round","space"]}]}],"bg-size":[{bg:["auto","cover","contain",Cj2]}],"bg-image":[{bg:["none",{"gradient-to":["t","tr","r","br","b","bl","l","tl"]},Mj2]}],"bg-color":[{bg:[A]}],"gradient-from-pos":[{from:[q]}],"gradient-via-pos":[{via:[q]}],"gradient-to-pos":[{to:[q]}],"gradient-from":[{from:[Z]}],"gradient-via":[{via:[Z]}],"gradient-to":[{to:[Z]}],rounded:[{rounded:[f]}],"rounded-s":[{"rounded-s":[f]}],"rounded-e":[{"rounded-e":[f]}],"rounded-t":[{"rounded-t":[f]}],"rounded-r":[{"rounded-r":[f]}],"rounded-b":[{"rounded-b":[f]}],"rounded-l":[{"rounded-l":[f]}],"rounded-ss":[{"rounded-ss":[f]}],"rounded-se":[{"rounded-se":[f]}],"rounded-ee":[{"rounded-ee":[f]}],"rounded-es":[{"rounded-es":[f]}],"rounded-tl":[{"rounded-tl":[f]}],"rounded-tr":[{"rounded-tr":[f]}],"rounded-br":[{"rounded-br":[f]}],"rounded-bl":[{"rounded-bl":[f]}],"border-w":[{border:[D]}],"border-w-x":[{"border-x":[D]}],"border-w-y":[{"border-y":[D]}],"border-w-s":[{"border-s":[D]}],"border-w-e":[{"border-e":[D]}],"border-w-t":[{"border-t":[D]}],"border-w-r":[{"border-r":[D]}],"border-w-b":[{"border-b":[D]}],"border-w-l":[{"border-l":[D]}],"border-opacity":[{"border-opacity":[R]}],"border-style":[{border:[...j(),"hidden"]}],"divide-x":[{"divide-x":[D]}],"divide-x-reverse":["divide-x-reverse"],"divide-y":[{"divide-y":[D]}],"divide-y-reverse":["divide-y-reverse"],"divide-opacity":[{"divide-opacity":[R]}],"divide-style":[{divide:j()}],"border-color":[{border:[$]}],"border-color-x":[{"border-x":[$]}],"border-color-y":[{"border-y":[$]}],"border-color-s":[{"border-s":[$]}],"border-color-e":[{"border-e":[$]}],"border-color-t":[{"border-t":[$]}],"border-color-r":[{"border-r":[$]}],"border-color-b":[{"border-b":[$]}],"border-color-l":[{"border-l":[$]}],"divide-color":[{divide:[$]}],"outline-style":[{outline:["",...j()]}],"outline-offset":[{"outline-offset":[TJ,PQ]}],"outline-w":[{outline:[TJ,CZ]}],"outline-color":[{outline:[A]}],"ring-w":[{ring:HA()}],"ring-w-inset":["ring-inset"],"ring-color":[{ring:[A]}],"ring-opacity":[{"ring-opacity":[R]}],"ring-offset-w":[{"ring-offset":[TJ,CZ]}],"ring-offset-color":[{"ring-offset":[A]}],shadow:[{shadow:["","inner","none",LZ,Vj2]}],"shadow-color":[{shadow:[lT]}],opacity:[{opacity:[R]}],"mix-blend":[{"mix-blend":[...t(),"plus-lighter","plus-darker"]}],"bg-blend":[{"bg-blend":t()}],filter:[{filter:["","none"]}],blur:[{blur:[B]}],brightness:[{brightness:[w]}],contrast:[{contrast:[H]}],"drop-shadow":[{"drop-shadow":["","none",LZ,PQ]}],grayscale:[{grayscale:[Y]}],"hue-rotate":[{"hue-rotate":[W]}],invert:[{invert:[G]}],saturate:[{saturate:[_]}],sepia:[{sepia:[r]}],"backdrop-filter":[{"backdrop-filter":["","none"]}],"backdrop-blur":[{"backdrop-blur":[B]}],"backdrop-brightness":[{"backdrop-brightness":[w]}],"backdrop-contrast":[{"backdrop-contrast":[H]}],"backdrop-grayscale":[{"backdrop-grayscale":[Y]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[W]}],"backdrop-invert":[{"backdrop-invert":[G]}],"backdrop-opacity":[{"backdrop-opacity":[R]}],"backdrop-saturate":[{"backdrop-saturate":[_]}],"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",PQ]}],duration:[{duration:UA()}],ease:[{ease:["linear","in","out","in-out",PQ]}],delay:[{delay:UA()}],animate:[{animate:["none","spin","ping","pulse","bounce",PQ]}],transform:[{transform:["","gpu","none"]}],scale:[{scale:[o]}],"scale-x":[{"scale-x":[o]}],"scale-y":[{"scale-y":[o]}],rotate:[{rotate:[pT,PQ]}],"translate-x":[{"translate-x":[y]}],"translate-y":[{"translate-y":[y]}],"skew-x":[{"skew-x":[S]}],"skew-y":[{"skew-y":[S]}],"transform-origin":[{origin:["center","top","top-right","right","bottom-right","bottom","bottom-left","left","top-left",PQ]}],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",PQ]}],"caret-color":[{caret:[A]}],"pointer-events":[{"pointer-events":["none","auto"]}],resize:[{resize:["none","y","x",""]}],"scroll-behavior":[{scroll:["auto","smooth"]}],"scroll-m":[{"scroll-m":JA()}],"scroll-mx":[{"scroll-mx":JA()}],"scroll-my":[{"scroll-my":JA()}],"scroll-ms":[{"scroll-ms":JA()}],"scroll-me":[{"scroll-me":JA()}],"scroll-mt":[{"scroll-mt":JA()}],"scroll-mr":[{"scroll-mr":JA()}],"scroll-mb":[{"scroll-mb":JA()}],"scroll-ml":[{"scroll-ml":JA()}],"scroll-p":[{"scroll-p":JA()}],"scroll-px":[{"scroll-px":JA()}],"scroll-py":[{"scroll-py":JA()}],"scroll-ps":[{"scroll-ps":JA()}],"scroll-pe":[{"scroll-pe":JA()}],"scroll-pt":[{"scroll-pt":JA()}],"scroll-pr":[{"scroll-pr":JA()}],"scroll-pb":[{"scroll-pb":JA()}],"scroll-pl":[{"scroll-pl":JA()}],"snap-align":[{snap:["start","end","center","align-none"]}],"snap-stop":[{snap:["normal","always"]}],"snap-type":[{snap:["none","x","y","both"]}],"snap-strictness":[{snap:["mandatory","proximity"]}],touch:[{touch:["auto","none","manipulation"]}],"touch-x":[{"touch-pan":["x","left","right"]}],"touch-y":[{"touch-pan":["y","up","down"]}],"touch-pz":["touch-pinch-zoom"],select:[{select:["none","text","all","auto"]}],"will-change":[{"will-change":["auto","scroll","contents","transform",PQ]}],fill:[{fill:[A,"none"]}],"stroke-w":[{stroke:[TJ,CZ,DMA]}],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"]}}},_j2=(A,{cacheSize:Q,prefix:B,separator:w,experimentalParseClassName:$,extend:f={},override:I={}})=>{iT(A,"cacheSize",Q),iT(A,"prefix",B),iT(A,"separator",w),iT(A,"experimentalParseClassName",$);for(let D in I)Pj2(A[D],I[D]);for(let D in f)kj2(A[D],f[D]);return A},iT=(A,Q,B)=>{if(B!==void 0)A[Q]=B},Pj2=(A,Q)=>{if(Q)for(let B in Q)iT(A,B,Q[B])},kj2=(A,Q)=>{if(Q)for(let B in Q){let w=Q[B];if(w!==void 0)A[B]=(A[B]||[]).concat(w)}},xAA=(A,...Q)=>typeof A==="function"?Qd0(Bd0,A,...Q):Qd0(()=>_j2(Bd0(),A),...Q);var jj2=xAA({extend:{classGroups:{"font-size":[{text:["display-2xl","display-xl","display-lg","display-md","display-sm","heading-lg","heading-md","heading-sm","body-xl","body-lg","body-md","body-sm","body-xs","label-md","label-sm","label-xs"]}]}}});function s1(...A){return jj2(JR(A))}var Dd0=(A)=>typeof A==="boolean"?`${A}`:A===0?"0":A,Hd0=JR,Zw=(A,Q)=>(B)=>{var w;if((Q===null||Q===void 0?void 0:Q.variants)==null)return Hd0(A,B===null||B===void 0?void 0:B.class,B===null||B===void 0?void 0:B.className);let{variants:$,defaultVariants:f}=Q,I=Object.keys($).map((Y)=>{let W=B===null||B===void 0?void 0:B[Y],G=f===null||f===void 0?void 0:f[Y];if(W===null)return null;let K=Dd0(W)||Dd0(G);return $[Y][K]}),D=B&&Object.entries(B).reduce((Y,W)=>{let[G,K]=W;if(K===void 0)return Y;return Y[G]=K,Y},{}),H=Q===null||Q===void 0?void 0:(w=Q.compoundVariants)===null||w===void 0?void 0:w.reduce((Y,W)=>{let{class:G,className:K,...Z}=W;return Object.entries(Z).every((q)=>{let[L,C]=q;return Array.isArray(C)?C.includes({...f,...D}[L]):{...f,...D}[L]===C})?[...Y,G,K]:Y},[]);return Hd0(A,I,H,B===null||B===void 0?void 0:B.class,B===null||B===void 0?void 0:B.className)};import{jsxDEV as YMA}from"preact/jsx-dev-runtime";var Yd0=Zw("p-4 rounded-lg border",{variants:{variant:{warning:"bg-warning border-warning text-warning",error:"bg-error border-error text-error",success:"bg-success border-success text-success",info:"bg-info border-info text-info"}},defaultVariants:{variant:"info"}});function XMA({variant:A,title:Q,children:B,className:w}){return YMA("div",{className:s1(Yd0({variant:A}),w),role:"alert",children:[Q&&YMA("p",{className:"font-medium text-current opacity-90",children:Q},void 0,!1,void 0,this),YMA("div",{className:s1(Q&&"mt-1","text-sm text-current opacity-75"),children:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}import{jsxDEV as vj2}from"preact/jsx-dev-runtime";var Xd0=Zw("inline-flex items-center justify-center font-bold transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed",{variants:{variant:{default:"bg-brand hover:bg-brand-dark text-theme-inverse",secondary:"bg-theme-muted hover:bg-theme-subtle text-theme border border-theme",ghost:"hover:bg-theme-subtle text-theme"},size:{sm:"h-8 px-3 text-sm rounded-md",md:"h-10 px-4 py-2 text-sm rounded-lg",lg:"h-12 px-6 text-base rounded-lg"}},defaultVariants:{variant:"default",size:"md"}});function tq({variant:A,size:Q,className:B,children:w,ssrOnClick:$,type:f="button",...I}){return vj2("button",{type:f,className:s1(Xd0({variant:A,size:Q}),B),...I,...$&&{onclick:$},children:w},void 0,!1,void 0,this)}import{jsxDEV as xj2}from"preact/jsx-dev-runtime";var Wd0=Zw("inline-flex items-center justify-center font-semibold transition-all text-center",{variants:{variant:{primary:"bg-brand text-theme-inverse hover:bg-brand-dark focus:ring-brand/20 focus:outline-none focus:ring-4",accent:"bg-accent text-theme-inverse hover:bg-accent-dark focus:ring-accent/20 focus:outline-none focus:ring-4",secondary:"bg-theme-muted text-theme hover:bg-theme-muted-dark focus:outline-none focus:ring-4",outline:"border-2 border-brand text-brand hover:bg-brand hover:text-theme-inverse focus:ring-brand/20 focus:outline-none focus:ring-4","outline-light":"border-2 border-theme-light text-theme-inverse hover:bg-theme-inverse hover:text-brand hover:border-theme-inverse focus:outline-none focus:ring-4",unstyled:""},size:{icon:"w-10 h-10 rounded-full",sm:"px-3 py-1.5 text-sm rounded-lg",md:"px-4 py-2 text-sm rounded-lg",lg:"px-6 py-3 text-base rounded-xl",xl:"px-8 py-4 text-lg rounded-xl","2xl":"px-10 py-5 text-lg rounded-2xl"}},defaultVariants:{size:"md"}});function b5({href:A,children:Q,variant:B,size:w,external:$=!1,className:f,"aria-label":I}){let D=$?{target:"_blank",rel:"noopener noreferrer"}:{};return xj2("a",{href:A,className:s1(Wd0({variant:B,size:w}),f),"aria-label":I,...D,children:Q},void 0,!1,void 0,this)}import{jsxDEV as hAA}from"preact/jsx-dev-runtime";var Ud0=Zw("transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-2",{variants:{variant:{default:"rounded-[10px] bg-theme-subtle border border-theme text-theme-muted hover:text-accent hover:border-brand/40",light:"rounded-[10px] bg-theme-subtle border border-theme text-theme-muted hover:text-accent",dark:"rounded-[10px] bg-theme-dark hover:bg-theme-muted text-theme-inverse",footer:"rounded-full bg-theme-toggle hover:bg-theme-toggle-hover text-theme-toggle-icon"},size:{sm:"p-1.5",md:"p-2",lg:"p-3"}},defaultVariants:{variant:"default",size:"md"}}),hj2={sm:"w-4 h-4",md:"w-5 h-5",lg:"w-6 h-6"};function KR({variant:A,size:Q,className:B}){let w=hj2[Q??"md"];return hAA("button",{onclick:"toggleTheme()",type:"button",className:s1(Ud0({variant:A,size:Q}),B),"aria-label":"Toggle dark mode",children:hAA("svg",{className:s1(w,"transition-colors"),fill:"none",stroke:"currentColor",strokeWidth:1.6,viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:[hAA("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),hAA("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 WMA}from"preact/jsx-dev-runtime";var Jd0=Zw("flex flex-wrap",{variants:{orientation:{horizontal:"justify-center gap-6 items-center",vertical:"flex-col gap-2.5"}},defaultVariants:{orientation:"horizontal"}});function yAA({items:A,className:Q,linkClassName:B="hover:text-accent transition-colors",orientation:w,children:$}){if(A.length===0&&!$)return null;let f=[...A].sort((I,D)=>I.priority-D.priority);return WMA("ul",{className:s1(Jd0({orientation:w}),Q),children:[f.map((I)=>WMA("li",{children:WMA("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 ViB}from"preact/jsx-dev-runtime";import{jsxDEV as RiB}from"preact/jsx-dev-runtime";import{createContext as gj2,h as Tj2}from"preact";import{useContext as Sj2}from"preact/hooks";AUA();var yj2=new Px({gfm:!0,breaks:!0});function UMA(A,Q){let{imageRenderer:B}=Q??{},$=(B?new Px({gfm:!0,breaks:!0}).use({renderer:{image(f,I,D){return B(f,I,D)??!1}}}):yj2).parse(A);return $=$.replace(/<\/blockquote>\s*<p>(\u2014|--|\u2013)([\s\S]*?)<\/p>/g,`</blockquote>
|
|
2388
|
+
`)}}f0();class OAA extends ow{directorySync;constructor(A,Q,B){super(A,{schema:BMA,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}}}f0();class RAA extends ow{directorySync;constructor(A,Q,B){super(A,{schema:QMA,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}}}f0();class _AA extends ow{directorySync;context;constructor(A,Q,B){super(A,{schema:AMA,jobTypeName:"directory-sync"});this.context=Q,this.directorySync=B}async process(A,Q,B){let w=Date.now(),$=A.syncDirection??"both";this.logger.info("Starting directory sync job",{jobId:Q,operation:A.operation,syncDirection:$});let f={imported:0,skipped:0,failed:0,quarantined:0,quarantinedFiles:[],errors:[],jobIds:[]},I={exported:0,failed:0,errors:[]};if($!=="export")if(await B.report({progress:10,message:"Scanning directory for changes"}),f=await this.importWithProgress(A.paths,B),$==="import")await this.waitForImportJobs(f.jobIds,B),await B.report({progress:100,message:`Import complete: ${f.imported} imported`});else await B.report({progress:50,message:`Imported ${f.imported} entities`}),await this.waitForImportJobs(f.jobIds,B),await B.report({progress:56,message:"Processing complete, starting export"});if($!=="import"){let H=$==="export"?10:60;await B.report({progress:H,message:"Exporting entities to directory"}),I=await this.exportWithProgress(A.entityTypes,B),await B.report({progress:100,message:$==="export"?`Export complete: ${I.exported} exported`:`Sync complete: ${f.imported} imported, ${I.exported} exported`})}let D=Date.now()-w;return this.logger.info("Directory sync job completed",{jobId:Q,duration:D,imported:f.imported,exported:I.exported}),{import:f,export:I,duration:D}}async importWithProgress(A,Q){try{return await this.directorySync.importEntitiesWithProgress(A,Q,10)}catch(B){throw this.logger.error("Import phase failed",{error:B}),B}}async exportWithProgress(A,Q){try{return await this.directorySync.exportEntitiesWithProgress(A,Q,10)}catch(B){throw this.logger.error("Export phase failed",{error:B}),B}}async waitForImportJobs(A,Q){if(A.length===0)return;this.logger.debug(`Waiting for ${A.length} import jobs to complete`);let{entityService:B}=this.context,w=300000,$=500,f=Date.now(),I=async()=>{let H=(await Promise.all(A.map((W)=>B.getAsyncJobStatus(W)))).filter((W)=>W&&(W.status==="completed"||W.status==="failed")).length;if(H===A.length){this.logger.debug("All import jobs completed");return}if(Date.now()-f>w){this.logger.warn(`Timeout waiting for import jobs (${H}/${A.length} completed)`);return}let Y=Math.round(H/A.length*100);return await Q.report({progress:50+Math.round(Y*0.05),message:`Processing ${H}/${A.length} entities`}),await new Promise((W)=>setTimeout(W,$)),I()};return I()}summarizeDataForLog(A){return{operation:A.operation,syncDirection:A.syncDirection}}}f0();class PAA extends ow{context;constructor(A,Q,B){super(A,{schema:VAA,jobTypeName:"directory-delete"});this.context=Q}async process(A,Q,B){let w=VAA.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}}}f0();GA();var Pk2=F.object({});class kAA extends ow{directorySync;constructor(A,Q){super(A,{schema:Pk2,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}}f0();Bf();GA();L$();Bf();import{readFile as kk2,writeFile as jk2}from"fs/promises";var vk2=wMA;class jAA extends ow{context;fetcher;constructor(A,Q,B=WH){super(Q,{schema:vk2,jobTypeName:"cover-image-convert"});this.context=A,this.fetcher=B}async process(A,Q,B){let{filePath:w,sourceUrl:$,postTitle:f,postSlug:I,customAlt:D}=A;this.logger.debug("Starting image conversion job",{jobId:Q,filePath:w,sourceUrl:$,postSlug:I});try{await this.reportProgress(B,{progress:vQ.INIT,message:`Reading file: ${w}`});let H;try{H=await kk2(w,"utf-8")}catch(L){return this.logger.error("Failed to read file",{filePath:w,error:y0(L)}),C$.failure(L)}let Y;try{Y=JF(H)}catch(L){return this.logger.warn("Failed to parse markdown",{filePath:w,error:y0(L)}),C$.failure(L)}let W=Y.frontmatter;if(W.coverImageId)return this.logger.debug("File already has coverImageId, skipping",{filePath:w}),await this.reportProgress(B,{progress:vQ.COMPLETE,message:"Already converted"}),{success:!0,skipped:!0};await this.reportProgress(B,{progress:vQ.FETCH,message:"Checking for existing image"});let G=await this.context.entityService.listEntities({entityType:"image",options:{filter:{metadata:{sourceUrl:$}},limit:1}}),K;if(G[0])K=G[0].id,this.logger.debug("Reusing existing image entity",{sourceUrl:$,imageId:K}),await this.reportProgress(B,{progress:vQ.EXTRACT,message:`Reusing existing image: ${K}`});else{await this.reportProgress(B,{progress:vQ.PROCESS,message:`Fetching image from ${$}`});let L;try{L=await this.fetcher($)}catch(r){return this.logger.error("Failed to fetch image",{sourceUrl:$,error:y0(r)}),C$.failure(r)}await this.reportProgress(B,{progress:vQ.GENERATE,message:"Creating image entity"});let{base64:C}=uF(L),R=oN(C),k=cF(C);if(!R||!k)return this.logger.error("Could not detect image format or dimensions",{sourceUrl:$}),C$.failure(Error("Could not detect image format or dimensions"));K=`${I}-cover`;let _=`Cover image for ${f}`,o=D??_;await this.context.entityService.createEntity({entity:{id:K,entityType:"image",content:L,metadata:{title:_,alt:o,format:R,width:k.width,height:k.height,sourceUrl:$}}}),this.logger.debug("Created image entity",{imageId:K,sourceUrl:$}),await this.reportProgress(B,{progress:vQ.EXTRACT,message:`Created image: ${K}`})}await this.reportProgress(B,{progress:vQ.SAVE,message:"Updating file"});let Z={...W};delete Z.coverImageUrl,delete Z.coverImageAlt,Z.coverImageId=K;let q=$N(Z,Y.content);try{await jk2(w,q,"utf-8")}catch(L){return this.logger.error("Failed to write file",{filePath:w,error:y0(L)}),C$.failure(L)}return await this.reportProgress(B,{progress:vQ.COMPLETE,message:"Conversion complete"}),this.logger.info("Image conversion complete",{filePath:w,imageId:K,sourceUrl:$}),{success:!0,imageId:K}}catch(H){return this.logger.error("Image conversion job failed",{jobId:Q,filePath:w,error:y0(H)}),C$.failure(H)}}summarizeDataForLog(A){return{filePath:A.filePath,sourceUrl:A.sourceUrl,postSlug:A.postSlug}}}f0();Bf();GA();L$();import{readFile as xk2,writeFile as hk2}from"fs/promises";class vAA extends ow{converter;constructor(A,Q,B=WH){super(Q,{schema:$MA,jobTypeName:"inline-image-convert"});this.converter=new _T(A.entityService,Q,B)}async process(A,Q,B){let{filePath:w,postSlug:$}=A;this.logger.debug("Starting inline image conversion job",{jobId:Q,filePath:w,postSlug:$});try{await this.reportProgress(B,{progress:vQ.INIT,message:`Reading file: ${w}`});let f;try{f=await xk2(w,"utf-8")}catch(H){let Y=y0(H);return this.logger.error("Failed to read file",{filePath:w,error:Y}),{success:!1,error:Y}}await this.reportProgress(B,{progress:vQ.FETCH,message:"Detecting inline images"});let I=this.converter.detectInlineImages(f,$);if(I.length===0)return this.logger.debug("No inline images to convert",{filePath:w}),await this.reportProgress(B,{progress:vQ.COMPLETE,message:"No images to convert"}),{success:!0,skipped:!0,convertedCount:0};this.logger.debug("Found inline images to convert",{filePath:w,count:I.length}),await this.reportProgress(B,{progress:vQ.PROCESS,message:`Converting ${I.length} images`});let D=await this.converter.convert(f,$);if(!D.converted)return this.logger.debug("No images were converted",{filePath:w}),await this.reportProgress(B,{progress:vQ.COMPLETE,message:"No images converted"}),{success:!0,skipped:!0,convertedCount:0};await this.reportProgress(B,{progress:vQ.SAVE,message:"Writing updated file"});try{await hk2(w,D.content,"utf-8")}catch(H){let Y=y0(H);return this.logger.error("Failed to write file",{filePath:w,error:Y}),{success:!1,error:Y}}return await this.reportProgress(B,{progress:vQ.COMPLETE,message:"Conversion complete"}),this.logger.info("Inline image conversion complete",{filePath:w,convertedCount:D.convertedCount}),{success:!0,convertedCount:D.convertedCount}}catch(f){let I=y0(f);return this.logger.error("Inline image conversion job failed",{jobId:Q,filePath:w,error:I}),{success:!1,error:I}}}summarizeDataForLog(A){return{filePath:A.filePath,postSlug:A.postSlug}}}function xr0(A,Q,B){let w=($)=>B.child($);A.jobs.registerHandler("directory-sync",new _AA(w("DirectorySyncJobHandler"),A,Q)),A.jobs.registerHandler("directory-export",new OAA(w("DirectoryExportJobHandler"),A,Q)),A.jobs.registerHandler("directory-import",new RAA(w("DirectoryImportJobHandler"),A,Q)),A.jobs.registerHandler("directory-delete",new PAA(w("DirectoryDeleteJobHandler"),A,Q)),A.jobs.registerHandler("directory-cleanup",new kAA(w("DirectoryCleanupJobHandler"),Q)),A.jobs.registerHandler("cover-image-convert",new jAA(A,w("CoverImageConversionJobHandler"))),A.jobs.registerHandler("inline-image-convert",new vAA(A,w("InlineImageConversionJobHandler"))),B.debug("Registered async job handlers")}f0();import{unlink as yk2,access as gk2}from"fs/promises";function hr0(A,Q,B,w){let{subscribe:$}=A.messaging,{entityService:f}=A;$("entity:created",async(I)=>{let{entity:D}=I.payload;try{await Q.fileOps.writeEntity(D),B.debug("Auto-exported created entity",{id:D.id,entityType:D.entityType})}catch(H){B.error("Auto-export FAILED for created entity",{id:D.id,entityType:D.entityType,error:H instanceof Error?H.message:String(H),stack:H instanceof Error?H.stack:void 0})}return{success:!0}}),$("entity:updated",async(I)=>{let{entityType:D,entityId:H}=I.payload;try{let Y=await f.getEntity({entityType:D,id:H});if(!Y)return B.debug("Entity not found in DB, skipping export",{entityType:D,entityId:H}),{success:!1};await Q.fileOps.writeEntity(Y),B.debug("Auto-exported updated entity",{id:Y.id,entityType:Y.entityType})}catch(Y){B.error("Auto-export FAILED for updated entity",{entityType:D,entityId:H,error:Y instanceof Error?Y.message:String(Y),stack:Y instanceof Error?Y.stack:void 0})}return{success:!0}}),$("entity:deleted",async(I)=>{let{entityId:D,entityType:H}=I.payload,Y=Q.fileOps.getFilePath(D,H);if(await gk2(Y).then(()=>!0,()=>!1))await yk2(Y),B.debug("Auto-deleted entity file",{id:D,entityType:H,path:Y});return{success:!0}}),B.debug("Setup auto-sync for entity events",{entityTypes:w})}function yr0(A,Q,B){Q.setJobQueueCallback(async(w)=>{let $=[{type:w.type,data:w.data}];return A.jobs.enqueueBatch($,{priority:5,source:"directory-sync-watcher",rootJobId:Z5(),metadata:{operationType:"file_operations",operationTarget:B,pluginId:"directory-sync"}})})}GA();f0();import{readdir as Sr0,mkdir as Sk2,copyFile as mk2}from"fs/promises";import{join as Tr0,resolve as fMA}from"path";import{join as Tk2}from"path";async function gr0(A){if(!await w$(Tk2(A,".git")))return!1;try{return await gJ(A).revparse(["--verify","HEAD"]),!0}catch{return!1}}async function uk2(A,Q){if(!await w$(A))return!0;if((await Sr0(A)).filter(($)=>!$.startsWith(".")&&!$.startsWith("_")).length>0)return!1;if(await gr0(A))return Q.debug("Git repository with history detected - skipping seed content",{path:A}),!1;return!0}async function mr0(A,Q){let B=await Sr0(A,{withFileTypes:!0});for(let w of B){let $=Tr0(A,w.name),f=Tr0(Q,w.name);if(w.isDirectory()){if(!await w$(f))await Sk2(f,{recursive:!0});await mr0($,f)}else await mk2($,f)}}async function ur0(A,Q,B){let w=fMA(process.cwd(),A);B=B?fMA(B):fMA(process.cwd(),"seed-content");let $=await uk2(w,Q);if($&&await w$(B))Q.debug("Copying seed content to brain-data directory"),await mr0(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 cr0(A,Q,B,w,$){let f=!1,I=async()=>{if(f)return;f=!0;let D=Q();if(B.seedContent){let H=B.syncPath??A.dataDir;await ur0(H,w,B.seedContentPath)}try{if($){w.debug("Git enabled \u2014 pulling before import");let Y=await $.pull();if(Y.files.length>0)w.info("Pulled changes from remote",{filesChanged:Y.files.length})}w.debug("Starting initial sync");let H=await D.sync();w.debug("Initial sync completed",{imported:H.import.imported,failed:H.import.failed,duration:H.duration}),await A.messaging.send({type:CN.initialSyncCompleted,payload:{success:!0},...{broadcast:!0}})}catch(H){w.error("Initial sync failed",H),await A.messaging.send({type:CN.initialSyncCompleted,payload:{success:!1,error:y0(H)},...{broadcast:!0}})}};A.messaging.subscribe(CN.pluginsRegistered,async()=>{return w.debug("Plugins registered, starting initial sync"),await I(),{success:!0}})}GA();function pr0(A,Q,B,w){let $=new UN(()=>{Q.withLock(async()=>{try{await Q.commit(),await Q.push()}catch(D){w.error("Git auto-commit failed",{error:D})}})},B),f=["entity:created","entity:updated","entity:deleted"],I=[];for(let D of f){let H=A.subscribe(D,async()=>{return $.trigger(),{success:!0}});I.push(H)}return()=>{$.dispose();for(let D of I)D()}}function lr0(A,Q,B,w,$){if(w<=0)return()=>{};let f=w*60*1000,I=!1,D=async()=>{if(I)return;I=!0;try{let{files:Y,result:W}=await A.withLock(async()=>{let G=await A.pull();if(G.files.length===0)return{files:[],result:null};let K=await Q.queueSyncBatch(B,"periodic-sync");return{files:G.files,result:K}});if(Y.length>0)$.info("Periodic sync: pulled changes",{filesChanged:Y.length});if(W)$.debug("Periodic sync: queued imports",{importOperations:W.importOperationsCount,totalFiles:W.totalFiles})}catch(Y){$.error("Periodic git sync failed",{error:Y})}finally{I=!1}},H=setInterval(()=>{D()},f);return $.info("Started periodic git sync",{intervalMinutes:w}),()=>{clearInterval(H)}}import{spawnSync as rr0}from"child_process";import{cpSync as ck2,existsSync as ir0,mkdirSync as pk2,mkdtempSync as lk2,rmSync as ik2}from"fs";import{tmpdir as rk2}from"os";import{fileURLToPath as dk2}from"url";import{join as nk2,resolve as ok2}from"path";function qZ(A,Q){let B=rr0("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 sk2(A){return A.startsWith("file://")}function ak2(A){return dk2(A)}function tk2(A,Q){return rr0("git",["--git-dir",A,"show-ref","--verify","--quiet",`refs/heads/${Q}`]).status===0}async function dr0(A){if(!A.bootstrapFromSeed)return;if(!A.gitUrl||!sk2(A.gitUrl))return;if(!A.seedContentPath)throw Error("directory-sync git.bootstrapFromSeed requires seedContentPath for local file:// remotes");let Q=A.branch??"main",B=ak2(A.gitUrl),w=ok2(A.seedContentPath);if(!ir0(w))throw Error(`Seed content path not found: ${w}`);if(!ir0(B))A.logger.debug("Creating local bare content remote",{remotePath:B,branch:Q}),pk2(B,{recursive:!0}),qZ(process.cwd(),["init","--bare",`--initial-branch=${Q}`,B]);if(tk2(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 $=lk2(nk2(rk2(),"directory-sync-seed-"));try{qZ($,["init",`--initial-branch=${Q}`]),qZ($,["config","user.name",A.authorName??"Brain"]),qZ($,["config","user.email",A.authorEmail??"brain@localhost"]),ck2(w,$,{recursive:!0}),qZ($,["add","."]),qZ($,["commit","-m","seed content remote"]),qZ($,["remote","add","origin",A.gitUrl]),qZ($,["push","-u","origin",Q])}finally{ik2($,{recursive:!0,force:!0})}}function nr0(A,Q,B,w,$){let{subscribe:f}=A.messaging;f("entity:export:request",async(I)=>{try{return{success:!0,data:await Q().exportEntities(I.payload.entityTypes)}}catch(D){return{success:!1,error:D instanceof Error?D.message:"Export failed"}}}),f("entity:import:request",async(I)=>{try{let D=Q(),H=I.payload.paths,Y=await D.importEntities(H);if(H&&H.length>0)await D.removeOrphanedEntities();return{success:!0,data:Y}}catch(D){return{success:!1,error:D instanceof Error?D.message:"Import failed"}}}),f("sync:status:request",async()=>{try{let D=await Q().getStatus();return{success:!0,data:{syncPath:D.syncPath,isInitialized:D.exists,watchEnabled:D.watching}}}catch(I){return{success:!1,error:I instanceof Error?I.message:"Status check failed"}}}),f("sync:configure:request",async(I)=>{try{return await B({syncPath:I.payload.syncPath}),{success:!0,data:{syncPath:I.payload.syncPath,configured:!0}}}catch(D){return{success:!1,error:D instanceof Error?D.message:"Configuration failed"}}}),f("git-sync:get-repo-info",async()=>{if(!$?.repo)return{success:!1,error:"Git not configured"};return{success:!0,data:{repo:$.repo,branch:$.branch??"main"}}}),w.debug("Registered message handlers")}f0();GA();f0();GA();function or0(A,Q){return xQ(A,"history","Get version history for an entity from git. Without sha: returns commit list. With sha: returns entity content at that version.",F.object({entityType:F.string().describe("Entity type (e.g. post, note, link)"),id:F.string().describe("Entity ID"),sha:F.string().optional().describe("Commit SHA to retrieve content at. Omit to list commit history."),limit:F.number().int().positive().optional().default(10).describe("Max commits to return (list mode only)")}),async(B)=>{let w=`${B.entityType}/${B.id}.md`;try{if(B.sha){let f=await Q.show(B.sha,w);return P8({sha:B.sha,entityType:B.entityType,id:B.id,content:f},`Content at ${B.sha.slice(0,7)}`)}let $=await Q.log(w,B.limit);if($.length===0)return P8({commits:[]},`No history found for ${B.entityType}/${B.id}`);return P8({commits:$,entityType:B.entityType,id:B.id},`${$.length} version${$.length===1?"":"s"} found`)}catch($){return E$($ instanceof Error?$.message:"History lookup failed")}})}function sr0(A,Q,B,w){let $=[xQ(B,"sync","Sync brain entities with the filesystem. Use this for refresh, pull, sync, or backup-to-git requests. Pulls from git if configured, then imports files. Git commit and push happen automatically after imports complete.",F.object({}),async(f,I)=>{try{let D=I.channelId?`${I.interfaceType}:${I.channelId}`:`plugin:${B}`,H={interfaceType:I.interfaceType,channelId:I.channelId},Y=w!==void 0,W=()=>A.queueSyncBatch(Q,D,H),G=w?await w.withLock(async()=>{return await w.pull(),W()}):await W();if(!G)return P8({gitPulled:Y},"No files to sync");return P8({batchId:G.batchId,importOperations:G.importOperationsCount,totalFiles:G.totalFiles,gitPulled:Y},`Sync started: ${G.importOperationsCount} import jobs queued for ${G.totalFiles} files${Y?" (pulled from git)":""}`)}catch(D){return E$(D instanceof Error?D.message:"Sync failed")}},{cli:{name:"sync"}}),xQ(B,"status","Get sync and git repository status \u2014 last sync time, watching state, pending git changes. Use this for status questions, not for actually syncing or backing up.",F.object({}),async()=>{try{let f=await A.getStatus(),I={syncPath:f.syncPath,lastSync:f.lastSync?.toISOString(),watching:f.watching};if(w){let D=await w.getStatus();I.git={isRepo:D.isRepo,branch:D.branch,hasChanges:D.hasChanges,ahead:D.ahead,behind:D.behind,remote:D.remote}}return P8(I)}catch(f){return E$(f instanceof Error?f.message:"Status check failed")}},{visibility:"public"})];if(w)$.push(or0(B,w));return $}var ar0={name:"@brains/directory-sync",private:!0,version:"0.2.0-alpha.71",description:"Directory-based entity synchronization plugin for Brains",type:"module",main:"./src/index.ts",types:"./src/index.ts",exports:{".":{types:"./src/index.ts",import:"./src/index.ts"}},scripts:{test:"bun test",typecheck:"tsc --noEmit",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",clean:"rm -rf .turbo"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/image":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*",chokidar:"^3.5.3","simple-git":"^3.21.0"},devDependencies:{"@types/bun":"latest","@types/node":"^20.0.0",typescript:"^5.3.3"},peerDependencies:{}};class IMA extends Ww{directorySync;gitSync;gitCleanups=[];constructor(A={}){super("directory-sync",ar0,A,uT)}requireDirectorySync(){if(!this.directorySync)throw Error("DirectorySync service not initialized");return this.directorySync}hasGitSync(){return this.gitSync!==void 0}async onRegister(A){let{logger:Q,entityService:B}=A;A.templates.register({status:{name:"status",description:"Directory synchronization status",schema:cT,basePrompt:"",formatter:new bAA,requiredPermission:"anchor"}});let w=this.config.syncPath??A.dataDir;this.directorySync=new PT({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(hr0(A,$,this.logger,this.config.entityTypes),this.config.autoSync)yr0(A,$,this.config.syncPath??A.dataDir);let f=this.config.git!==void 0&&(this.config.git.repo!==void 0||this.config.git.gitUrl!==void 0);if(this.config.git&&!f)this.logger.debug("Git block present but no repo/gitUrl configured \u2014 git sync disabled");if(f&&this.config.git){await dr0({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 eEA({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(pr0(A.messaging,this.gitSync,this.config.commitDebounce,this.logger.child("GitAutoCommit"))),this.config.autoSync)this.gitCleanups.push(lr0(this.gitSync,this.requireDirectorySync(),A,this.config.syncInterval,this.logger.child("GitPeriodicSync")))}if(this.config.initialSync)cr0(A,()=>this.requireDirectorySync(),this.config,this.logger,this.gitSync);nr0(A,()=>this.requireDirectorySync(),(I)=>this.configure(I),this.logger,this.config.git)}async getTools(){let A=this.requireDirectorySync();return sr0(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 PT({...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){xr0(A,this.requireDirectorySync(),this.logger)}}function aq(A={}){return new IMA(A)}f0();import{render as nQ1}from"preact-render-to-string";import{h as _C}from"preact";function tr0(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=tr0(A[Q]))&&(w&&(w+=" "),w+=B)}else for(B in A)A[B]&&(w&&(w+=" "),w+=B);return w}function JR(){for(var A,Q,B=0,w="",$=arguments.length;B<$;B++)(A=arguments[B])&&(Q=tr0(A))&&(w&&(w+=" "),w+=Q);return w}var Aj2=(A)=>{let Q=Bj2(A),{conflictingClassGroups:B,conflictingClassGroupModifiers:w}=A;return{getClassGroupId:(I)=>{let D=I.split("-");if(D[0]===""&&D.length!==1)D.shift();return wd0(D,Q)||Qj2(I)},getConflictingClassGroupIds:(I,D)=>{let H=B[I]||[];if(D&&w[I])return[...H,...w[I]];return H}}},wd0=(A,Q)=>{if(A.length===0)return Q.classGroupId;let B=A[0],w=Q.nextPart.get(B),$=w?wd0(A.slice(1),w):void 0;if($)return $;if(Q.validators.length===0)return;let f=A.join("-");return Q.validators.find(({validator:I})=>I(f))?.classGroupId},er0=/^\[(.+)\]$/,Qj2=(A)=>{if(er0.test(A)){let Q=er0.exec(A)[1],B=Q?.substring(0,Q.indexOf(":"));if(B)return"arbitrary.."+B}},Bj2=(A)=>{let{theme:Q,prefix:B}=A,w={nextPart:new Map,validators:[]};return $j2(Object.entries(A.classGroups),B).forEach(([f,I])=>{HMA(I,w,f,Q)}),w},HMA=(A,Q,B,w)=>{A.forEach(($)=>{if(typeof $==="string"){let f=$===""?Q:Ad0(Q,$);f.classGroupId=B;return}if(typeof $==="function"){if(wj2($)){HMA($(w),Q,B,w);return}Q.validators.push({validator:$,classGroupId:B});return}Object.entries($).forEach(([f,I])=>{HMA(I,Ad0(Q,f),B,w)})})},Ad0=(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},wj2=(A)=>A.isThemeGetter,$j2=(A,Q)=>{if(!Q)return A;return A.map(([B,w])=>{let $=w.map((f)=>{if(typeof f==="string")return Q+f;if(typeof f==="object")return Object.fromEntries(Object.entries(f).map(([I,D])=>[Q+I,D]));return f});return[B,$]})},fj2=(A)=>{if(A<1)return{get:()=>{return},set:()=>{}};let Q=0,B=new Map,w=new Map,$=(f,I)=>{if(B.set(f,I),Q++,Q>A)Q=0,w=B,B=new Map};return{get(f){let I=B.get(f);if(I!==void 0)return I;if((I=w.get(f))!==void 0)return $(f,I),I},set(f,I){if(B.has(f))B.set(f,I);else $(f,I)}}};var Ij2=(A)=>{let{separator:Q,experimentalParseClassName:B}=A,w=Q.length===1,$=Q[0],f=Q.length,I=(D)=>{let H=[],Y=0,W=0,G;for(let C=0;C<D.length;C++){let R=D[C];if(Y===0){if(R===$&&(w||D.slice(C,C+f)===Q)){H.push(D.slice(W,C)),W=C+f;continue}if(R==="/"){G=C;continue}}if(R==="[")Y++;else if(R==="]")Y--}let K=H.length===0?D:D.substring(W),Z=K.startsWith("!"),q=Z?K.substring(1):K,L=G&&G>W?G-W:void 0;return{modifiers:H,hasImportantModifier:Z,baseClassName:q,maybePostfixModifierPosition:L}};if(B)return(D)=>B({className:D,parseClassName:I});return I},Dj2=(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},Hj2=(A)=>({cache:fj2(A.cacheSize),parseClassName:Ij2(A),...Aj2(A)}),Yj2=/\s+/,Xj2=(A,Q)=>{let{parseClassName:B,getClassGroupId:w,getConflictingClassGroupIds:$}=Q,f=[],I=A.trim().split(Yj2),D="";for(let H=I.length-1;H>=0;H-=1){let Y=I[H],{modifiers:W,hasImportantModifier:G,baseClassName:K,maybePostfixModifierPosition:Z}=B(Y),q=Boolean(Z),L=w(q?K.substring(0,Z):K);if(!L){if(!q){D=Y+(D.length>0?" "+D:D);continue}if(L=w(K),!L){D=Y+(D.length>0?" "+D:D);continue}q=!1}let C=Dj2(W).join(":"),R=G?C+"!":C,k=R+L;if(f.includes(k))continue;f.push(k);let _=$(L,q);for(let o=0;o<_.length;++o){let r=_[o];f.push(R+r)}D=Y+(D.length>0?" "+D:D)}return D};function Wj2(){let A=0,Q,B,w="";while(A<arguments.length)if(Q=arguments[A++]){if(B=$d0(Q))w&&(w+=" "),w+=B}return w}var $d0=(A)=>{if(typeof A==="string")return A;let Q,B="";for(let w=0;w<A.length;w++)if(A[w]){if(Q=$d0(A[w]))B&&(B+=" "),B+=Q}return B};function Qd0(A,...Q){let B,w,$,f=I;function I(H){let Y=Q.reduce((W,G)=>G(W),A());return B=Hj2(Y),w=B.cache.get,$=B.cache.set,f=D,D(H)}function D(H){let Y=w(H);if(Y)return Y;let W=Xj2(H,B);return $(H,W),W}return function(){return f(Wj2.apply(null,arguments))}}var B8=(A)=>{let Q=(B)=>B[A]||[];return Q.isThemeGetter=!0,Q},fd0=/^\[(?:([a-z-]+):)?(.+)\]$/i,Uj2=/^\d+\/\d+$/,Jj2=new Set(["px","full","screen"]),Gj2=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,Fj2=/\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$/,Kj2=/^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/,Zj2=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,Nj2=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,TJ=(A)=>GR(A)||Jj2.has(A)||Uj2.test(A),CZ=(A)=>FR(A,"length",bj2),GR=(A)=>Boolean(A)&&!Number.isNaN(Number(A)),DMA=(A)=>FR(A,"number",GR),pT=(A)=>Boolean(A)&&Number.isInteger(Number(A)),zj2=(A)=>A.endsWith("%")&&GR(A.slice(0,-1)),PQ=(A)=>fd0.test(A),LZ=(A)=>Gj2.test(A),qj2=new Set(["length","size","percentage"]),Cj2=(A)=>FR(A,qj2,Id0),Lj2=(A)=>FR(A,"position",Id0),Ej2=new Set(["image","url"]),Mj2=(A)=>FR(A,Ej2,Rj2),Vj2=(A)=>FR(A,"",Oj2),lT=()=>!0,FR=(A,Q,B)=>{let w=fd0.exec(A);if(w){if(w[1])return typeof Q==="string"?w[1]===Q:Q.has(w[1]);return B(w[2])}return!1},bj2=(A)=>Fj2.test(A)&&!Kj2.test(A),Id0=()=>!1,Oj2=(A)=>Zj2.test(A),Rj2=(A)=>Nj2.test(A);var Bd0=()=>{let A=B8("colors"),Q=B8("spacing"),B=B8("blur"),w=B8("brightness"),$=B8("borderColor"),f=B8("borderRadius"),I=B8("borderSpacing"),D=B8("borderWidth"),H=B8("contrast"),Y=B8("grayscale"),W=B8("hueRotate"),G=B8("invert"),K=B8("gap"),Z=B8("gradientColorStops"),q=B8("gradientColorStopPositions"),L=B8("inset"),C=B8("margin"),R=B8("opacity"),k=B8("padding"),_=B8("saturate"),o=B8("scale"),r=B8("sepia"),S=B8("skew"),x=B8("space"),y=B8("translate"),g=()=>["auto","contain","none"],AA=()=>["auto","hidden","clip","visible","scroll"],c=()=>["auto",PQ,Q],JA=()=>[PQ,Q],HA=()=>["",TJ,CZ],P=()=>["auto",GR,PQ],O=()=>["bottom","center","left","left-bottom","left-top","right","right-bottom","right-top","top"],j=()=>["solid","dashed","dotted","double","none"],t=()=>["normal","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity"],d=()=>["start","end","center","between","around","evenly","stretch"],BA=()=>["","0",PQ],n=()=>["auto","avoid","all","avoid-page","page","left","right","column"],UA=()=>[GR,PQ];return{cacheSize:500,separator:":",theme:{colors:[lT],spacing:[TJ,CZ],blur:["none","",LZ,PQ],brightness:UA(),borderColor:[A],borderRadius:["none","","full",LZ,PQ],borderSpacing:JA(),borderWidth:HA(),contrast:UA(),grayscale:BA(),hueRotate:UA(),invert:BA(),gap:JA(),gradientColorStops:[A],gradientColorStopPositions:[zj2,CZ],inset:c(),margin:c(),opacity:UA(),padding:JA(),saturate:UA(),scale:UA(),sepia:BA(),skew:UA(),space:JA(),translate:JA()},classGroups:{aspect:[{aspect:["auto","square","video",PQ]}],container:["container"],columns:[{columns:[LZ]}],"break-after":[{"break-after":n()}],"break-before":[{"break-before":n()}],"break-inside":[{"break-inside":["auto","avoid","avoid-page","avoid-column"]}],"box-decoration":[{"box-decoration":["slice","clone"]}],box:[{box:["border","content"]}],display:["block","inline-block","inline","flex","inline-flex","table","inline-table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row-group","table-row","flow-root","grid","inline-grid","contents","list-item","hidden"],float:[{float:["right","left","none","start","end"]}],clear:[{clear:["left","right","both","none","start","end"]}],isolation:["isolate","isolation-auto"],"object-fit":[{object:["contain","cover","fill","none","scale-down"]}],"object-position":[{object:[...O(),PQ]}],overflow:[{overflow:AA()}],"overflow-x":[{"overflow-x":AA()}],"overflow-y":[{"overflow-y":AA()}],overscroll:[{overscroll:g()}],"overscroll-x":[{"overscroll-x":g()}],"overscroll-y":[{"overscroll-y":g()}],position:["static","fixed","absolute","relative","sticky"],inset:[{inset:[L]}],"inset-x":[{"inset-x":[L]}],"inset-y":[{"inset-y":[L]}],start:[{start:[L]}],end:[{end:[L]}],top:[{top:[L]}],right:[{right:[L]}],bottom:[{bottom:[L]}],left:[{left:[L]}],visibility:["visible","invisible","collapse"],z:[{z:["auto",pT,PQ]}],basis:[{basis:c()}],"flex-direction":[{flex:["row","row-reverse","col","col-reverse"]}],"flex-wrap":[{flex:["wrap","wrap-reverse","nowrap"]}],flex:[{flex:["1","auto","initial","none",PQ]}],grow:[{grow:BA()}],shrink:[{shrink:BA()}],order:[{order:["first","last","none",pT,PQ]}],"grid-cols":[{"grid-cols":[lT]}],"col-start-end":[{col:["auto",{span:["full",pT,PQ]},PQ]}],"col-start":[{"col-start":P()}],"col-end":[{"col-end":P()}],"grid-rows":[{"grid-rows":[lT]}],"row-start-end":[{row:["auto",{span:[pT,PQ]},PQ]}],"row-start":[{"row-start":P()}],"row-end":[{"row-end":P()}],"grid-flow":[{"grid-flow":["row","col","dense","row-dense","col-dense"]}],"auto-cols":[{"auto-cols":["auto","min","max","fr",PQ]}],"auto-rows":[{"auto-rows":["auto","min","max","fr",PQ]}],gap:[{gap:[K]}],"gap-x":[{"gap-x":[K]}],"gap-y":[{"gap-y":[K]}],"justify-content":[{justify:["normal",...d()]}],"justify-items":[{"justify-items":["start","end","center","stretch"]}],"justify-self":[{"justify-self":["auto","start","end","center","stretch"]}],"align-content":[{content:["normal",...d(),"baseline"]}],"align-items":[{items:["start","end","center","baseline","stretch"]}],"align-self":[{self:["auto","start","end","center","stretch","baseline"]}],"place-content":[{"place-content":[...d(),"baseline"]}],"place-items":[{"place-items":["start","end","center","baseline","stretch"]}],"place-self":[{"place-self":["auto","start","end","center","stretch"]}],p:[{p:[k]}],px:[{px:[k]}],py:[{py:[k]}],ps:[{ps:[k]}],pe:[{pe:[k]}],pt:[{pt:[k]}],pr:[{pr:[k]}],pb:[{pb:[k]}],pl:[{pl:[k]}],m:[{m:[C]}],mx:[{mx:[C]}],my:[{my:[C]}],ms:[{ms:[C]}],me:[{me:[C]}],mt:[{mt:[C]}],mr:[{mr:[C]}],mb:[{mb:[C]}],ml:[{ml:[C]}],"space-x":[{"space-x":[x]}],"space-x-reverse":["space-x-reverse"],"space-y":[{"space-y":[x]}],"space-y-reverse":["space-y-reverse"],w:[{w:["auto","min","max","fit","svw","lvw","dvw",PQ,Q]}],"min-w":[{"min-w":[PQ,Q,"min","max","fit"]}],"max-w":[{"max-w":[PQ,Q,"none","full","min","max","fit","prose",{screen:[LZ]},LZ]}],h:[{h:[PQ,Q,"auto","min","max","fit","svh","lvh","dvh"]}],"min-h":[{"min-h":[PQ,Q,"min","max","fit","svh","lvh","dvh"]}],"max-h":[{"max-h":[PQ,Q,"min","max","fit","svh","lvh","dvh"]}],size:[{size:[PQ,Q,"auto","min","max","fit"]}],"font-size":[{text:["base",LZ,CZ]}],"font-smoothing":["antialiased","subpixel-antialiased"],"font-style":["italic","not-italic"],"font-weight":[{font:["thin","extralight","light","normal","medium","semibold","bold","extrabold","black",DMA]}],"font-family":[{font:[lT]}],"fvn-normal":["normal-nums"],"fvn-ordinal":["ordinal"],"fvn-slashed-zero":["slashed-zero"],"fvn-figure":["lining-nums","oldstyle-nums"],"fvn-spacing":["proportional-nums","tabular-nums"],"fvn-fraction":["diagonal-fractions","stacked-fractions"],tracking:[{tracking:["tighter","tight","normal","wide","wider","widest",PQ]}],"line-clamp":[{"line-clamp":["none",GR,DMA]}],leading:[{leading:["none","tight","snug","normal","relaxed","loose",TJ,PQ]}],"list-image":[{"list-image":["none",PQ]}],"list-style-type":[{list:["none","disc","decimal",PQ]}],"list-style-position":[{list:["inside","outside"]}],"placeholder-color":[{placeholder:[A]}],"placeholder-opacity":[{"placeholder-opacity":[R]}],"text-alignment":[{text:["left","center","right","justify","start","end"]}],"text-color":[{text:[A]}],"text-opacity":[{"text-opacity":[R]}],"text-decoration":["underline","overline","line-through","no-underline"],"text-decoration-style":[{decoration:[...j(),"wavy"]}],"text-decoration-thickness":[{decoration:["auto","from-font",TJ,CZ]}],"underline-offset":[{"underline-offset":["auto",TJ,PQ]}],"text-decoration-color":[{decoration:[A]}],"text-transform":["uppercase","lowercase","capitalize","normal-case"],"text-overflow":["truncate","text-ellipsis","text-clip"],"text-wrap":[{text:["wrap","nowrap","balance","pretty"]}],indent:[{indent:JA()}],"vertical-align":[{align:["baseline","top","middle","bottom","text-top","text-bottom","sub","super",PQ]}],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",PQ]}],"bg-attachment":[{bg:["fixed","local","scroll"]}],"bg-clip":[{"bg-clip":["border","padding","content","text"]}],"bg-opacity":[{"bg-opacity":[R]}],"bg-origin":[{"bg-origin":["border","padding","content"]}],"bg-position":[{bg:[...O(),Lj2]}],"bg-repeat":[{bg:["no-repeat",{repeat:["","x","y","round","space"]}]}],"bg-size":[{bg:["auto","cover","contain",Cj2]}],"bg-image":[{bg:["none",{"gradient-to":["t","tr","r","br","b","bl","l","tl"]},Mj2]}],"bg-color":[{bg:[A]}],"gradient-from-pos":[{from:[q]}],"gradient-via-pos":[{via:[q]}],"gradient-to-pos":[{to:[q]}],"gradient-from":[{from:[Z]}],"gradient-via":[{via:[Z]}],"gradient-to":[{to:[Z]}],rounded:[{rounded:[f]}],"rounded-s":[{"rounded-s":[f]}],"rounded-e":[{"rounded-e":[f]}],"rounded-t":[{"rounded-t":[f]}],"rounded-r":[{"rounded-r":[f]}],"rounded-b":[{"rounded-b":[f]}],"rounded-l":[{"rounded-l":[f]}],"rounded-ss":[{"rounded-ss":[f]}],"rounded-se":[{"rounded-se":[f]}],"rounded-ee":[{"rounded-ee":[f]}],"rounded-es":[{"rounded-es":[f]}],"rounded-tl":[{"rounded-tl":[f]}],"rounded-tr":[{"rounded-tr":[f]}],"rounded-br":[{"rounded-br":[f]}],"rounded-bl":[{"rounded-bl":[f]}],"border-w":[{border:[D]}],"border-w-x":[{"border-x":[D]}],"border-w-y":[{"border-y":[D]}],"border-w-s":[{"border-s":[D]}],"border-w-e":[{"border-e":[D]}],"border-w-t":[{"border-t":[D]}],"border-w-r":[{"border-r":[D]}],"border-w-b":[{"border-b":[D]}],"border-w-l":[{"border-l":[D]}],"border-opacity":[{"border-opacity":[R]}],"border-style":[{border:[...j(),"hidden"]}],"divide-x":[{"divide-x":[D]}],"divide-x-reverse":["divide-x-reverse"],"divide-y":[{"divide-y":[D]}],"divide-y-reverse":["divide-y-reverse"],"divide-opacity":[{"divide-opacity":[R]}],"divide-style":[{divide:j()}],"border-color":[{border:[$]}],"border-color-x":[{"border-x":[$]}],"border-color-y":[{"border-y":[$]}],"border-color-s":[{"border-s":[$]}],"border-color-e":[{"border-e":[$]}],"border-color-t":[{"border-t":[$]}],"border-color-r":[{"border-r":[$]}],"border-color-b":[{"border-b":[$]}],"border-color-l":[{"border-l":[$]}],"divide-color":[{divide:[$]}],"outline-style":[{outline:["",...j()]}],"outline-offset":[{"outline-offset":[TJ,PQ]}],"outline-w":[{outline:[TJ,CZ]}],"outline-color":[{outline:[A]}],"ring-w":[{ring:HA()}],"ring-w-inset":["ring-inset"],"ring-color":[{ring:[A]}],"ring-opacity":[{"ring-opacity":[R]}],"ring-offset-w":[{"ring-offset":[TJ,CZ]}],"ring-offset-color":[{"ring-offset":[A]}],shadow:[{shadow:["","inner","none",LZ,Vj2]}],"shadow-color":[{shadow:[lT]}],opacity:[{opacity:[R]}],"mix-blend":[{"mix-blend":[...t(),"plus-lighter","plus-darker"]}],"bg-blend":[{"bg-blend":t()}],filter:[{filter:["","none"]}],blur:[{blur:[B]}],brightness:[{brightness:[w]}],contrast:[{contrast:[H]}],"drop-shadow":[{"drop-shadow":["","none",LZ,PQ]}],grayscale:[{grayscale:[Y]}],"hue-rotate":[{"hue-rotate":[W]}],invert:[{invert:[G]}],saturate:[{saturate:[_]}],sepia:[{sepia:[r]}],"backdrop-filter":[{"backdrop-filter":["","none"]}],"backdrop-blur":[{"backdrop-blur":[B]}],"backdrop-brightness":[{"backdrop-brightness":[w]}],"backdrop-contrast":[{"backdrop-contrast":[H]}],"backdrop-grayscale":[{"backdrop-grayscale":[Y]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[W]}],"backdrop-invert":[{"backdrop-invert":[G]}],"backdrop-opacity":[{"backdrop-opacity":[R]}],"backdrop-saturate":[{"backdrop-saturate":[_]}],"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",PQ]}],duration:[{duration:UA()}],ease:[{ease:["linear","in","out","in-out",PQ]}],delay:[{delay:UA()}],animate:[{animate:["none","spin","ping","pulse","bounce",PQ]}],transform:[{transform:["","gpu","none"]}],scale:[{scale:[o]}],"scale-x":[{"scale-x":[o]}],"scale-y":[{"scale-y":[o]}],rotate:[{rotate:[pT,PQ]}],"translate-x":[{"translate-x":[y]}],"translate-y":[{"translate-y":[y]}],"skew-x":[{"skew-x":[S]}],"skew-y":[{"skew-y":[S]}],"transform-origin":[{origin:["center","top","top-right","right","bottom-right","bottom","bottom-left","left","top-left",PQ]}],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",PQ]}],"caret-color":[{caret:[A]}],"pointer-events":[{"pointer-events":["none","auto"]}],resize:[{resize:["none","y","x",""]}],"scroll-behavior":[{scroll:["auto","smooth"]}],"scroll-m":[{"scroll-m":JA()}],"scroll-mx":[{"scroll-mx":JA()}],"scroll-my":[{"scroll-my":JA()}],"scroll-ms":[{"scroll-ms":JA()}],"scroll-me":[{"scroll-me":JA()}],"scroll-mt":[{"scroll-mt":JA()}],"scroll-mr":[{"scroll-mr":JA()}],"scroll-mb":[{"scroll-mb":JA()}],"scroll-ml":[{"scroll-ml":JA()}],"scroll-p":[{"scroll-p":JA()}],"scroll-px":[{"scroll-px":JA()}],"scroll-py":[{"scroll-py":JA()}],"scroll-ps":[{"scroll-ps":JA()}],"scroll-pe":[{"scroll-pe":JA()}],"scroll-pt":[{"scroll-pt":JA()}],"scroll-pr":[{"scroll-pr":JA()}],"scroll-pb":[{"scroll-pb":JA()}],"scroll-pl":[{"scroll-pl":JA()}],"snap-align":[{snap:["start","end","center","align-none"]}],"snap-stop":[{snap:["normal","always"]}],"snap-type":[{snap:["none","x","y","both"]}],"snap-strictness":[{snap:["mandatory","proximity"]}],touch:[{touch:["auto","none","manipulation"]}],"touch-x":[{"touch-pan":["x","left","right"]}],"touch-y":[{"touch-pan":["y","up","down"]}],"touch-pz":["touch-pinch-zoom"],select:[{select:["none","text","all","auto"]}],"will-change":[{"will-change":["auto","scroll","contents","transform",PQ]}],fill:[{fill:[A,"none"]}],"stroke-w":[{stroke:[TJ,CZ,DMA]}],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"]}}},_j2=(A,{cacheSize:Q,prefix:B,separator:w,experimentalParseClassName:$,extend:f={},override:I={}})=>{iT(A,"cacheSize",Q),iT(A,"prefix",B),iT(A,"separator",w),iT(A,"experimentalParseClassName",$);for(let D in I)Pj2(A[D],I[D]);for(let D in f)kj2(A[D],f[D]);return A},iT=(A,Q,B)=>{if(B!==void 0)A[Q]=B},Pj2=(A,Q)=>{if(Q)for(let B in Q)iT(A,B,Q[B])},kj2=(A,Q)=>{if(Q)for(let B in Q){let w=Q[B];if(w!==void 0)A[B]=(A[B]||[]).concat(w)}},xAA=(A,...Q)=>typeof A==="function"?Qd0(Bd0,A,...Q):Qd0(()=>_j2(Bd0(),A),...Q);var jj2=xAA({extend:{classGroups:{"font-size":[{text:["display-2xl","display-xl","display-lg","display-md","display-sm","heading-lg","heading-md","heading-sm","body-xl","body-lg","body-md","body-sm","body-xs","label-md","label-sm","label-xs"]}]}}});function s1(...A){return jj2(JR(A))}var Dd0=(A)=>typeof A==="boolean"?`${A}`:A===0?"0":A,Hd0=JR,Zw=(A,Q)=>(B)=>{var w;if((Q===null||Q===void 0?void 0:Q.variants)==null)return Hd0(A,B===null||B===void 0?void 0:B.class,B===null||B===void 0?void 0:B.className);let{variants:$,defaultVariants:f}=Q,I=Object.keys($).map((Y)=>{let W=B===null||B===void 0?void 0:B[Y],G=f===null||f===void 0?void 0:f[Y];if(W===null)return null;let K=Dd0(W)||Dd0(G);return $[Y][K]}),D=B&&Object.entries(B).reduce((Y,W)=>{let[G,K]=W;if(K===void 0)return Y;return Y[G]=K,Y},{}),H=Q===null||Q===void 0?void 0:(w=Q.compoundVariants)===null||w===void 0?void 0:w.reduce((Y,W)=>{let{class:G,className:K,...Z}=W;return Object.entries(Z).every((q)=>{let[L,C]=q;return Array.isArray(C)?C.includes({...f,...D}[L]):{...f,...D}[L]===C})?[...Y,G,K]:Y},[]);return Hd0(A,I,H,B===null||B===void 0?void 0:B.class,B===null||B===void 0?void 0:B.className)};import{jsxDEV as YMA}from"preact/jsx-dev-runtime";var Yd0=Zw("p-4 rounded-lg border",{variants:{variant:{warning:"bg-warning border-warning text-warning",error:"bg-error border-error text-error",success:"bg-success border-success text-success",info:"bg-info border-info text-info"}},defaultVariants:{variant:"info"}});function XMA({variant:A,title:Q,children:B,className:w}){return YMA("div",{className:s1(Yd0({variant:A}),w),role:"alert",children:[Q&&YMA("p",{className:"font-medium text-current opacity-90",children:Q},void 0,!1,void 0,this),YMA("div",{className:s1(Q&&"mt-1","text-sm text-current opacity-75"),children:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}import{jsxDEV as vj2}from"preact/jsx-dev-runtime";var Xd0=Zw("inline-flex items-center justify-center font-bold transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed",{variants:{variant:{default:"bg-brand hover:bg-brand-dark text-theme-inverse",secondary:"bg-theme-muted hover:bg-theme-subtle text-theme border border-theme",ghost:"hover:bg-theme-subtle text-theme"},size:{sm:"h-8 px-3 text-sm rounded-md",md:"h-10 px-4 py-2 text-sm rounded-lg",lg:"h-12 px-6 text-base rounded-lg"}},defaultVariants:{variant:"default",size:"md"}});function tq({variant:A,size:Q,className:B,children:w,ssrOnClick:$,type:f="button",...I}){return vj2("button",{type:f,className:s1(Xd0({variant:A,size:Q}),B),...I,...$&&{onclick:$},children:w},void 0,!1,void 0,this)}import{jsxDEV as xj2}from"preact/jsx-dev-runtime";var Wd0=Zw("inline-flex items-center justify-center font-semibold transition-all text-center",{variants:{variant:{primary:"bg-brand text-theme-inverse hover:bg-brand-dark focus:ring-brand/20 focus:outline-none focus:ring-4",accent:"bg-accent text-theme-inverse hover:bg-accent-dark focus:ring-accent/20 focus:outline-none focus:ring-4",secondary:"bg-theme-muted text-theme hover:bg-theme-muted-dark focus:outline-none focus:ring-4",outline:"border-2 border-brand text-brand hover:bg-brand hover:text-theme-inverse focus:ring-brand/20 focus:outline-none focus:ring-4","outline-light":"border-2 border-theme-light text-theme-inverse hover:bg-theme-inverse hover:text-brand hover:border-theme-inverse focus:outline-none focus:ring-4",unstyled:""},size:{icon:"w-10 h-10 rounded-full",sm:"px-3 py-1.5 text-sm rounded-lg",md:"px-4 py-2 text-sm rounded-lg",lg:"px-6 py-3 text-base rounded-xl",xl:"px-8 py-4 text-lg rounded-xl","2xl":"px-10 py-5 text-lg rounded-2xl"}},defaultVariants:{size:"md"}});function b5({href:A,children:Q,variant:B,size:w,external:$=!1,className:f,"aria-label":I}){let D=$?{target:"_blank",rel:"noopener noreferrer"}:{};return xj2("a",{href:A,className:s1(Wd0({variant:B,size:w}),f),"aria-label":I,...D,children:Q},void 0,!1,void 0,this)}import{jsxDEV as hAA}from"preact/jsx-dev-runtime";var Ud0=Zw("transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-2",{variants:{variant:{default:"rounded-[10px] bg-theme-subtle border border-theme text-theme-muted hover:text-accent hover:border-brand/40",light:"rounded-[10px] bg-theme-subtle border border-theme text-theme-muted hover:text-accent",dark:"rounded-[10px] bg-theme-dark hover:bg-theme-muted text-theme-inverse",footer:"rounded-full bg-theme-toggle hover:bg-theme-toggle-hover text-theme-toggle-icon"},size:{sm:"p-1.5",md:"p-2",lg:"p-3"}},defaultVariants:{variant:"default",size:"md"}}),hj2={sm:"w-4 h-4",md:"w-5 h-5",lg:"w-6 h-6"};function KR({variant:A,size:Q,className:B}){let w=hj2[Q??"md"];return hAA("button",{onclick:"toggleTheme()",type:"button",className:s1(Ud0({variant:A,size:Q}),B),"aria-label":"Toggle dark mode",children:hAA("svg",{className:s1(w,"transition-colors"),fill:"none",stroke:"currentColor",strokeWidth:1.6,viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:[hAA("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),hAA("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 WMA}from"preact/jsx-dev-runtime";var Jd0=Zw("flex flex-wrap",{variants:{orientation:{horizontal:"justify-center gap-6 items-center",vertical:"flex-col gap-2.5"}},defaultVariants:{orientation:"horizontal"}});function yAA({items:A,className:Q,linkClassName:B="hover:text-accent transition-colors",orientation:w,children:$}){if(A.length===0&&!$)return null;let f=[...A].sort((I,D)=>I.priority-D.priority);return WMA("ul",{className:s1(Jd0({orientation:w}),Q),children:[f.map((I)=>WMA("li",{children:WMA("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 ViB}from"preact/jsx-dev-runtime";import{jsxDEV as RiB}from"preact/jsx-dev-runtime";import{createContext as gj2,h as Tj2}from"preact";import{useContext as Sj2}from"preact/hooks";AUA();var yj2=new Px({gfm:!0,breaks:!0});function UMA(A,Q){let{imageRenderer:B}=Q??{},$=(B?new Px({gfm:!0,breaks:!0}).use({renderer:{image(f,I,D){return B(f,I,D)??!1}}}):yj2).parse(A);return $=$.replace(/<\/blockquote>\s*<p>(\u2014|--|\u2013)([\s\S]*?)<\/p>/g,`</blockquote>
|
|
2389
2389
|
<cite class="block-attribution"><span class="emdash">$1</span>$2</cite>`),$}var Gd0=gj2(null);function gAA({imageRenderer:A,children:Q}){return Tj2(Gd0.Provider,{value:A??null},Q)}function Fd0(){return Sj2(Gd0)}function eq(){let A=Fd0();return(Q)=>UMA(Q,A?{imageRenderer:A}:void 0)}var mj2=/<pre><code class="language-mermaid">([\s\S]*?)<\/code><\/pre>/g,uj2={"&":"&","<":"<",">":">",""":'"',"'":"'"},cj2=/&(?:amp|lt|gt|quot|#39);/g;function pj2(A){return A.replace(cj2,(Q)=>uj2[Q]??Q)}function JMA(A){return A.replace(mj2,(Q,B)=>{return`<div class="mermaid">${pj2(B)}</div>`})}var Kd0=/<!--\s*\.slide:\s*(.*?)\s*-->/g;function Zd0(A){let Q={};for(let w of A.matchAll(Kd0)){let $=w[1]??"";for(let I of $.matchAll(/([\w-]+)=["']([^"']*?)["']/g)){let D=I[1],H=I[2];if(D&&H!==void 0)Q[D]=H}let f=$.replace(/([\w-]+)=["']([^"']*?)["']/g,"").trim();if(f)for(let I of f.matchAll(/(?:^|\s)([\w-]+)(?=\s|$)/g)){let D=I[1];if(D)Q[D]="true"}}let B=A.replace(Kd0,"").replace(/^\n+/,"").replace(/\n{3,}/g,`
|
|
2390
2390
|
|
|
2391
2391
|
`).trim();return{attributes:Q,markdown:B}}var lj2=/<!--\s*\.break\s*-->/;function Nd0(A){let Q=A.split(lj2);return Q.length>1?Q:null}import{jsxDEV as SJ}from"preact/jsx-dev-runtime";var GMA=({markdown:A})=>{let Q=eq(),w=A.split(/^---$/gm).map((I)=>I.trim()).map((I)=>{let{attributes:D,markdown:H}=Zd0(I),Y=Nd0(H),W;if(Y)W=`<div class="slide-columns">${Y.map((K)=>`<div class="slide-column">${JMA(Q(K.trim()))}</div>`).join("")}</div>`;else W=JMA(Q(H));return{attributes:D,htmlContent:W}}),$=w.some((I)=>I.htmlContent.includes('class="mermaid"')),f=w.map(({attributes:I,htmlContent:D},H)=>SJ("section",{...I,dangerouslySetInnerHTML:{__html:D}},H,!1,void 0,this));return SJ("section",{className:"presentation-section",children:[SJ("link",{rel:"stylesheet",href:"https://cdn.jsdelivr.net/npm/reveal.js@5.1.0/dist/reveal.min.css"},void 0,!1,void 0,this),SJ("div",{className:"reveal",children:SJ("div",{className:"slides",children:f},void 0,!1,void 0,this)},void 0,!1,void 0,this),SJ("script",{src:"https://cdn.jsdelivr.net/npm/reveal.js@5.1.0/dist/reveal.min.js",defer:!0},void 0,!1,void 0,this),$&&SJ("script",{src:"https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js",defer:!0},void 0,!1,void 0,this),SJ("script",{dangerouslySetInnerHTML:{__html:`
|
|
@@ -2936,7 +2936,7 @@ ${R}`)}if(w!==void 0&&f?.algorithms!==void 0){let C=f.algorithms.map((R)=>R.alg)
|
|
|
2936
2936
|
prose-pre:rounded-lg prose-pre:my-6 prose-pre:p-4 prose-pre:overflow-x-auto prose-pre:text-sm
|
|
2937
2937
|
prose-blockquote:border-l-2 prose-blockquote:border-brand prose-blockquote:pl-6 prose-blockquote:py-2 prose-blockquote:mt-8 prose-blockquote:mb-2 prose-blockquote:text-lg prose-blockquote:leading-relaxed prose-blockquote:font-light prose-blockquote:not-italic
|
|
2938
2938
|
prose-hr:my-12
|
|
2939
|
-
prose-img:rounded-lg prose-img:shadow-md prose-img:my-8`,Q),dangerouslySetInnerHTML:{__html:A}},void 0,!1,void 0,this)};import{jsxDEV as CrB}from"preact/jsx-dev-runtime";var nj2=Zw("",{variants:{level:{1:"text-4xl font-bold mb-8 mt-0 leading-tight tracking-tight",2:"text-3xl font-semibold mt-16 mb-6 border-b pb-4 leading-snug tracking-tight",3:"text-2xl font-semibold mt-10 mb-4 leading-snug tracking-tight"}},defaultVariants:{level:1}});import{jsxDEV as LMA}from"preact/jsx-dev-runtime";var qd0=Zw("bg-theme-subtle rounded-lg border border-theme hover:shadow-lg transition-shadow",{variants:{variant:{vertical:"flex flex-col p-6",horizontal:"flex flex-col sm:flex-row items-start gap-4 p-6",compact:"flex flex-col p-4"}},defaultVariants:{variant:"vertical"}}),UB=({href:A,variant:Q,className:B,children:w})=>{let $=s1(qd0({variant:Q}),B);if(A)return LMA("article",{className:s1($,"group"),children:LMA("a",{href:A,className:"contents",children:w},void 0,!1,void 0,this)},void 0,!1,void 0,this);return LMA("article",{className:$,children:w},void 0,!1,void 0,this)};import{jsxDEV as oj2}from"preact/jsx-dev-runtime";var Cd0=Zw("object-cover rounded-lg",{variants:{size:{small:"w-full sm:w-32 h-48 sm:h-32 flex-shrink-0",medium:"w-full sm:w-48 h-48",large:"w-full h-48"}},defaultVariants:{size:"medium"}}),EMA=({src:A,alt:Q,size:B,className:w})=>{return oj2("img",{src:A,alt:Q,loading:"lazy",decoding:"async",className:s1(Cd0({size:B}),w)},void 0,!1,void 0,this)};import{jsxDEV as Ld0}from"preact/jsx-dev-runtime";var mJ=({src:A,alt:Q,width:B,height:w,srcset:$,sizes:f,className:I})=>{return Ld0("div",{className:s1("w-full overflow-hidden",I),children:Ld0("img",{src:A,alt:Q,width:B,height:w,...$&&{srcset:$},...f&&{sizes:f},loading:"lazy",decoding:"async",style:{aspectRatio:`${B}/${w}`},className:"w-full h-auto rounded-lg"},void 0,!1,void 0,this)},void 0,!1,void 0,this)};import{jsxDEV as MMA}from"preact/jsx-dev-runtime";var f$=({href:A,children:Q,className:B})=>{let w=s1("text-2xl font-semibold mb-2 text-theme",B);if(A)return MMA("h2",{className:w,children:MMA("a",{href:A,className:"hover:text-brand",children:Q},void 0,!1,void 0,this)},void 0,!1,void 0,this);return MMA("h2",{className:w,children:Q},void 0,!1,void 0,this)};import{jsxDEV as sj2}from"preact/jsx-dev-runtime";var h$=({children:A,className:Q})=>{return sj2("div",{className:s1("mb-3",Q),children:A},void 0,!1,void 0,this)};import{jsxDEV as VMA}from"preact/jsx-dev-runtime";var SI=({message:A,description:Q,className:B})=>{return VMA("div",{className:s1("text-center py-12",B),children:[VMA("p",{className:"text-theme-muted",children:A},void 0,!1,void 0,this),Q&&VMA("p",{className:"text-sm text-theme-muted mt-2",children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as bMA}from"preact/jsx-dev-runtime";var lH=({title:A,count:Q,singularLabel:B,pluralLabel:w,description:$,className:f})=>{let I=Q!==void 0&&B?`${Q} ${Q===1?B:w??`${B}s`}`:null,D=I&&$?`${I} ${$}`:I??$;return bMA("div",{className:s1("mb-8",f),children:[bMA("h1",{className:"text-3xl font-bold mb-2 text-theme",children:A},void 0,!1,void 0,this),D&&bMA("p",{className:"text-theme-muted",children:D},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};var Q6=(A,Q={})=>{let{style:B="short",includeTime:w=!1}=Q,$=typeof A==="string"?new Date(A):A;if(w)return $.toLocaleString();switch(B){case"long":return $.toLocaleDateString(void 0,{year:"numeric",month:"long",day:"numeric"});case"full":return $.toLocaleDateString(void 0,{weekday:"long",year:"numeric",month:"long",day:"numeric"});case"short":default:return $.toLocaleDateString()}};import{jsxDEV as OMA}from"preact/jsx-dev-runtime";var rT=Zw("rounded-full",{variants:{variant:{default:"bg-theme-muted text-theme",muted:"bg-theme text-theme-muted",accent:"bg-accent/10 text-accent"},size:{xs:"text-xs px-2 py-1",sm:"text-sm px-3 py-1",md:"text-sm px-3 py-1 font-medium",lg:"text-sm px-4 py-2 font-medium"}},defaultVariants:{variant:"default",size:"xs"}}),NR=({tags:A,maxVisible:Q=5,variant:B,size:w,className:$})=>{let f=A.slice(0,Q),I=A.length-Q;return OMA("div",{className:s1("flex flex-wrap gap-2",$),children:[f.map((D)=>OMA("span",{className:s1(rT({variant:B,size:w})),children:D},D,!1,void 0,this)),I>0&&OMA("span",{className:s1(rT({size:w}),"bg-transparent text-theme-muted"),children:["+",I," more"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as Ed0}from"preact/jsx-dev-runtime";var AC=({href:A,children:Q,className:B})=>{return Ed0("nav",{className:s1("mt-8 pt-6 border-t border-theme",B),children:Ed0("a",{href:A,className:"text-brand hover:text-brand-dark text-sm",children:["\u2190 ",Q]},void 0,!0,void 0,this)},void 0,!1,void 0,this)};import{jsxDEV as QC}from"preact/jsx-dev-runtime";var Md0=Zw("",{variants:{titleSize:{"3xl":"text-3xl","4xl":"text-4xl"}},defaultVariants:{titleSize:"4xl"}}),BC=({title:A,created:Q,updated:B,summary:w,metadata:$,titleSize:f,useSemanticHeader:I=!0,className:D})=>{return QC(I?"header":"div",{className:s1("mb-8",D),children:[QC("h1",{className:s1(Md0({titleSize:f}),"font-bold mb-4 text-theme"),children:A},void 0,!1,void 0,this),(Q??B??$)&&QC("div",{className:"text-sm text-theme-muted mb-4",children:[Q&&QC("time",{dateTime:Q,children:["Created ",Q6(Q)]},void 0,!0,void 0,this),Q&&B&&" \u2022 ",B&&!Q&&QC("time",{dateTime:B,children:["Last updated ",Q6(B)]},void 0,!0,void 0,this),B&&Q&&QC("time",{dateTime:B,children:["Updated ",Q6(B)]},void 0,!0,void 0,this),$]},void 0,!0,void 0,this),w&&QC("p",{className:"text-lg text-theme-muted italic",children:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as aj2}from"preact/jsx-dev-runtime";var Vd0=Zw("px-2 py-1 rounded-full",{variants:{variant:{default:"bg-theme",muted:"bg-theme-muted"}},defaultVariants:{variant:"default"}}),TAA=({count:A,label:Q,variant:B,className:w})=>{return aj2("span",{className:s1(Vd0({variant:B}),w),children:[A," ",Q]},void 0,!0,void 0,this)};import{jsxDEV as WdB}from"preact/jsx-dev-runtime";import{jsxDEV as FdB}from"preact/jsx-dev-runtime";import{jsxDEV as qdB}from"preact/jsx-dev-runtime";import{jsxDEV as tj2}from"preact/jsx-dev-runtime";var bd0=Zw("inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium",{variants:{status:{draft:"bg-status-neutral text-status-neutral",queued:"bg-status-info text-status-info",sent:"bg-status-success text-status-success",failed:"bg-status-danger text-status-danger",published:"bg-status-success text-status-success",pending:"bg-status-warning text-status-warning",captured:"bg-status-info text-status-info",available:"bg-status-success text-status-success","early access":"bg-status-info text-status-info","coming soon":"bg-status-warning text-status-warning",planned:"bg-status-neutral text-status-neutral"}},defaultVariants:{status:"draft"}}),Lf=({status:A,className:Q,label:B})=>{return tj2("span",{className:s1(bd0({status:A}),Q),children:B??A},void 0,!1,void 0,this)};import{jsxDEV as zR}from"preact/jsx-dev-runtime";var SAA=({url:A,title:Q,date:B,description:w,series:$,featured:f})=>{return zR("li",{className:"block pb-10 border-b border-rule last:border-b-0 last:pb-0 transition-transform duration-200 hover:translate-x-1",children:zR("a",{href:A,className:"group block",children:[$&&zR("span",{className:"block font-mono text-[0.65rem] font-medium uppercase tracking-[0.18em] text-accent mb-3",children:[String($.index).padStart(3,"0")," \xB7 ",$.name]},void 0,!0,void 0,this),zR("h3",{className:s1("font-heading font-normal text-heading mb-2 leading-[1.15] tracking-[-0.01em] transition-colors group-hover:text-accent",f?"text-[clamp(1.75rem,3.2vw,2.65rem)] leading-[1.05] tracking-[-0.018em] [font-variation-settings:'opsz'_96,'SOFT'_30]":"text-[clamp(1.4rem,2.4vw,2rem)] [font-variation-settings:'opsz'_72,'SOFT'_30]"),children:Q},void 0,!1,void 0,this),zR("time",{className:"block font-mono text-[0.7rem] uppercase tracking-[0.14em] text-theme-light mb-4",children:new Date(B).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric"})},void 0,!1,void 0,this),w&&zR("p",{className:"text-[0.95rem] leading-[1.6] text-theme-muted max-w-[60ch]",children:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)};import{jsxDEV as kdB,Fragment as jdB}from"preact/jsx-dev-runtime";import{jsxDEV as v2,Fragment as RMA}from"preact/jsx-dev-runtime";var PMA="grid grid-cols-1 gap-3 md:grid-cols-[200px_minmax(0,1fr)] md:gap-14",_MA=(A,Q)=>String(Math.max(0,A)).padStart(Q,"0"),ej2=(A)=>new Date(A).toLocaleDateString("en-GB",{year:"numeric",month:"short",day:"2-digit"}),Rd0=(A)=>new Date(A).toLocaleDateString("en-GB",{month:"short",day:"2-digit"}),qR=(A)=>{let Q=new Date(A).getFullYear();return Number.isFinite(Q)?String(Q):"Undated"},Od0=(A,Q)=>{if(Q===1)return A;return`${A.endsWith("/")?A.slice(0,-1):A}/page/${Q}`},Av2=(A)=>{let Q=A.trim().toLowerCase();if(Q.endsWith("ies"))return Q.slice(0,-3)+"y";if(Q.endsWith("s"))return Q.slice(0,-1);return Q||"entry"},_d0=({series:A})=>{if(!A)return null;return v2("span",{className:"inline-block font-mono text-[0.65rem] uppercase tracking-[0.2em] text-accent",children:[v2("span",{className:"mr-1 text-theme-light",children:String(A.index).padStart(3,"0")},void 0,!1,void 0,this),A.name]},void 0,!0,void 0,this)},Qv2=({item:A})=>v2("section",{"aria-label":"Latest",className:`${PMA} mb-14 border-b border-rule pb-[4.5rem]`,children:[v2("div",{className:"flex flex-row items-baseline gap-6 pt-0.5 md:flex-col md:items-start md:gap-0",children:[v2("span",{className:"font-heading text-[clamp(3.2rem,7vw,5.4rem)] font-light leading-[0.9] tracking-[-0.03em] text-accent [font-variant-numeric:tabular-nums] [font-variation-settings:'opsz'_144,'SOFT'_30] md:mb-5",children:qR(A.date)},void 0,!1,void 0,this),v2("div",{className:"flex w-full max-w-[168px] flex-col gap-1.5 border-rule-strong pt-2 font-mono md:border-t md:pt-3",children:[v2("span",{className:"text-[0.625rem] uppercase tracking-[0.26em] text-theme-light",children:"Latest"},void 0,!1,void 0,this),v2("time",{dateTime:A.date,className:"text-xs tracking-[0.04em] text-theme-muted [font-variant-numeric:tabular-nums]",children:ej2(A.date)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),v2("div",{className:"min-w-0",children:v2("a",{href:A.url,className:"group block text-inherit no-underline",children:[A.series&&v2("div",{className:"mb-[22px]",children:v2(_d0,{series:A.series},void 0,!1,void 0,this)},void 0,!1,void 0,this),v2("h2",{className:"mb-[22px] max-w-[15ch] font-heading text-[clamp(2.4rem,5vw,3.75rem)] font-normal leading-[0.98] tracking-[-0.028em] text-heading transition-colors duration-150 [font-variation-settings:'opsz'_144,'SOFT'_30] [text-wrap:balance] group-hover:text-accent",children:A.title},void 0,!1,void 0,this),A.description&&v2("p",{className:"max-w-[50ch] font-heading text-[clamp(1.1rem,1.5vw,1.32rem)] font-normal italic leading-[1.45] text-theme-muted [font-variation-settings:'opsz'_24,'SOFT'_70]",children:A.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Bv2=({item:A})=>v2("li",{className:"group grid grid-cols-1 items-baseline gap-3 border-t border-rule py-[22px] transition-colors duration-150 hover:bg-[rgb(from_var(--color-accent)_r_g_b_/_0.025)] md:grid-cols-[200px_minmax(0,1fr)] md:gap-14",children:v2("a",{href:A.url,className:"contents text-inherit no-underline",children:[v2("div",{className:"flex flex-row items-baseline gap-3.5 pt-0.5 md:flex-col md:gap-1.5",children:[v2("span",{className:"font-heading text-[1.55rem] font-normal leading-none tracking-[-0.018em] text-theme-muted transition-colors duration-150 [font-variant-numeric:tabular-nums] [font-variation-settings:'opsz'_72,'SOFT'_50] group-hover:text-accent",children:Rd0(A.date)},void 0,!1,void 0,this),v2("time",{dateTime:A.date,className:"font-mono text-[0.62rem] uppercase tracking-[0.18em] text-theme-light [font-variant-numeric:tabular-nums]",children:qR(A.date)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),v2("div",{className:"min-w-0",children:[A.series&&v2("div",{className:"mb-2",children:v2(_d0,{series:A.series},void 0,!1,void 0,this)},void 0,!1,void 0,this),v2("h3",{className:"mb-2 font-heading text-[clamp(1.2rem,1.85vw,1.5rem)] font-medium leading-[1.2] tracking-[-0.016em] text-heading transition-colors duration-150 [font-variation-settings:'opsz'_48,'SOFT'_40] [text-wrap:balance] group-hover:text-accent",children:A.title},void 0,!1,void 0,this),A.description&&v2("p",{className:"max-w-[62ch] text-[0.90625rem] leading-[1.55] text-theme-muted",children:A.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),wv2=({year:A,count:Q,label:B,latestDate:w})=>v2("div",{className:`${PMA} relative items-baseline py-3 before:absolute before:left-0 before:right-0 before:top-3.5 before:h-px before:bg-rule-strong md:py-[18px] md:pt-14 md:before:top-6`,children:[v2("span",{className:"pt-7 font-heading text-[clamp(2.4rem,5.4vw,3.6rem)] font-light italic leading-[0.95] tracking-[-0.025em] text-accent [font-variant-numeric:tabular-nums] [font-variation-settings:'opsz'_144,'SOFT'_30] md:pt-0",children:A},void 0,!1,void 0,this),v2("span",{className:"font-mono text-[0.68rem] uppercase tracking-[0.22em] text-theme-light [font-variant-numeric:tabular-nums] md:pt-1.5",children:[Q," ",B,Q===1?"":"s"," \xB7 finished ",Rd0(w)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),$v2=({pagination:A,baseUrl:Q})=>{if(!A||A.totalPages<=1)return null;let B=Math.max(2,String(A.totalPages).length),w=A.hasPrevPage??A.currentPage>1,$=A.hasNextPage??A.currentPage<A.totalPages;return v2("nav",{"aria-label":"Pagination",className:`${PMA} mt-16 border-t border-rule pt-6 font-mono text-[0.68rem] uppercase tracking-[0.2em] text-theme-light [font-variant-numeric:tabular-nums]`,children:[v2("span",{children:[_MA(A.currentPage,B)," /"," ",_MA(A.totalPages,B)]},void 0,!0,void 0,this),v2("span",{className:"flex items-baseline justify-between gap-6",children:[w?v2("a",{href:Od0(Q,A.currentPage-1),className:"text-theme-muted no-underline transition-colors duration-150 hover:text-brand",children:"\u2190 Newer"},void 0,!1,void 0,this):v2("span",{"aria-disabled":"true",className:"opacity-30",children:"\u2190 Newer"},void 0,!1,void 0,this),$?v2("a",{href:Od0(Q,A.currentPage+1),className:"text-theme-muted no-underline transition-colors duration-150 hover:text-brand",children:"Older \u2192"},void 0,!1,void 0,this):v2("span",{"aria-disabled":"true",className:"opacity-30",children:"Older \u2192"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},dT=({label:A,items:Q,pagination:B,baseUrl:w="",emptyMessage:$})=>{let f=B?.currentPage??1,I=f===1&&Q.length>0,D=I&&Q[0]?qR(Q[0].date):void 0,H=I?Q.slice(1):Q,Y=Av2(A);return v2("section",{"aria-labelledby":"content-archive-title",children:[v2("h1",{id:"content-archive-title",className:"sr-only",children:A},void 0,!1,void 0,this),v2("div",{className:"mb-10 flex items-center gap-2.5 font-mono text-[0.7rem] font-medium uppercase tracking-[0.22em] text-accent",children:[v2("span",{className:"h-px w-[18px] bg-accent","aria-hidden":"true"},void 0,!1,void 0,this),v2("span",{children:A},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.length===0?v2("p",{className:"text-theme-muted italic",children:$??`No ${A.toLowerCase()} yet.`},void 0,!1,void 0,this):v2(RMA,{children:[I&&Q[0]&&v2(Qv2,{item:Q[0]},void 0,!1,void 0,this),H.length>0&&v2(RMA,{children:[v2("header",{className:"mb-7 flex items-baseline justify-between gap-6 font-mono text-[0.68rem] uppercase tracking-[0.24em] text-theme-light",children:[v2("span",{children:"Archive"},void 0,!1,void 0,this),v2("span",{className:"text-theme-muted",children:I?"Older entries":`Page ${_MA(f,2)}`},void 0,!1,void 0,this)]},void 0,!0,void 0,this),v2("ol",{className:"m-0 list-none p-0",children:H.map((W,G)=>{let K=qR(W.date),Z=G>0?qR(H[G-1]?.date??""):D,q=Z===void 0||K!==Z,L=H.filter((C)=>qR(C.date)===K).length;return v2(RMA,{children:[q&&v2(wv2,{year:K,count:L,label:Y,latestDate:W.date},void 0,!1,void 0,this),v2(Bv2,{item:W},void 0,!1,void 0,this)]},W.id,!0,void 0,this)})},void 0,!1,void 0,this)]},void 0,!0,void 0,this),v2($v2,{pagination:B,baseUrl:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as CR,Fragment as fv2}from"preact/jsx-dev-runtime";var mAA=({items:A,viewAllUrl:Q,viewAllLabel:B,emptyMessage:w})=>{if(A.length===0)return CR("p",{className:"text-theme-muted italic",children:w??"Nothing here yet."},void 0,!1,void 0,this);return CR(fv2,{children:[CR("ul",{className:"flex flex-col gap-10",children:A.map(($,f)=>CR(SAA,{url:$.url,title:$.title,date:$.date,description:$.description,series:$.series,featured:f===0},$.id,!1,void 0,this))},void 0,!1,void 0,this),Q&&CR("a",{href:Q,className:"mt-10 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:[B??"View All",CR("span",{"aria-hidden":"true",children:"\u2192"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as nT}from"preact/jsx-dev-runtime";var kMA=({title:A,number:Q,blurb:B,variant:w="editorial"})=>{if(w==="compact")return nT("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-8",children:A},void 0,!1,void 0,this);return nT("header",{children:[Q!==void 0&&nT("span",{className:"block font-mono text-[0.7rem] font-medium uppercase tracking-[0.22em] text-accent mb-[0.85rem]",children:Q},void 0,!1,void 0,this),nT("h2",{className:"font-heading font-normal text-heading leading-[1.05] tracking-[-0.015em] text-[clamp(1.75rem,2.6vw,2.1rem)] [font-variation-settings:'opsz'_48,'SOFT'_30]",children:A},void 0,!1,void 0,this),B!==void 0&&nT("p",{className:"font-heading italic font-light text-[0.95rem] leading-[1.5] text-theme-light mt-3 max-w-[22ch] [font-variation-settings:'opsz'_18,'SOFT'_50]",children:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as oT}from"preact/jsx-dev-runtime";var Iv2=(A)=>`/topics/${A.toLowerCase().replace(/\s+/g,"-")}`,jMA=({subjects:A,hrefFor:Q=Iv2})=>oT("ul",{className:"grid grid-cols-1 sm:grid-cols-2 sm:gap-x-10 max-w-[40rem] border-t border-rule-strong list-none p-0 mt-8",children:A.map((B,w)=>oT("li",{className:"border-b border-rule",children:oT("a",{href:Q(B),className:"flex items-baseline gap-[1.1rem] py-[0.95rem] text-theme transition-[color,padding-left] duration-200 hover:text-accent hover:pl-[0.4rem]",children:[oT("span",{className:"font-mono text-[0.66rem] font-medium tracking-[0.18em] text-theme-light min-w-[1.6rem] transition-colors",children:String(w+1).padStart(2,"0")},void 0,!1,void 0,this),oT("span",{className:"font-heading italic font-normal text-[1.05rem] tracking-[-0.005em] [font-variation-settings:'opsz'_24,'SOFT'_60]",children:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},B,!1,void 0,this))},void 0,!1,void 0,this);import{Fragment as vMA}from"preact";import{jsxDEV as sT}from"preact/jsx-dev-runtime";var Dv2=/(\*[^*]+\*)/;function uAA(A,Q){let B=A.split(`
|
|
2939
|
+
prose-img:rounded-lg prose-img:shadow-md prose-img:my-8`,Q),dangerouslySetInnerHTML:{__html:A}},void 0,!1,void 0,this)};import{jsxDEV as CrB}from"preact/jsx-dev-runtime";var nj2=Zw("",{variants:{level:{1:"text-4xl font-bold mb-8 mt-0 leading-tight tracking-tight",2:"text-3xl font-semibold mt-16 mb-6 border-b pb-4 leading-snug tracking-tight",3:"text-2xl font-semibold mt-10 mb-4 leading-snug tracking-tight"}},defaultVariants:{level:1}});import{jsxDEV as LMA}from"preact/jsx-dev-runtime";var qd0=Zw("bg-theme-subtle rounded-lg border border-theme hover:shadow-lg transition-shadow",{variants:{variant:{vertical:"flex flex-col p-6",horizontal:"flex flex-col sm:flex-row items-start gap-4 p-6",compact:"flex flex-col p-4"}},defaultVariants:{variant:"vertical"}}),UB=({href:A,variant:Q,className:B,children:w})=>{let $=s1(qd0({variant:Q}),B);if(A)return LMA("article",{className:s1($,"group"),children:LMA("a",{href:A,className:"contents",children:w},void 0,!1,void 0,this)},void 0,!1,void 0,this);return LMA("article",{className:$,children:w},void 0,!1,void 0,this)};import{jsxDEV as oj2}from"preact/jsx-dev-runtime";var Cd0=Zw("object-cover rounded-lg",{variants:{size:{small:"w-full sm:w-32 h-48 sm:h-32 flex-shrink-0",medium:"w-full sm:w-48 h-48",large:"w-full h-48"}},defaultVariants:{size:"medium"}}),EMA=({src:A,alt:Q,size:B,className:w})=>{return oj2("img",{src:A,alt:Q,loading:"lazy",decoding:"async",className:s1(Cd0({size:B}),w)},void 0,!1,void 0,this)};import{jsxDEV as Ld0}from"preact/jsx-dev-runtime";var mJ=({src:A,alt:Q,width:B,height:w,srcset:$,sizes:f,className:I})=>{return Ld0("div",{className:s1("w-full overflow-hidden",I),children:Ld0("img",{src:A,alt:Q,width:B,height:w,...$&&{srcset:$},...f&&{sizes:f},loading:"lazy",decoding:"async",style:{aspectRatio:`${B}/${w}`},className:"w-full h-auto rounded-lg"},void 0,!1,void 0,this)},void 0,!1,void 0,this)};import{jsxDEV as MMA}from"preact/jsx-dev-runtime";var f$=({href:A,children:Q,className:B})=>{let w=s1("text-2xl font-semibold mb-2 text-theme",B);if(A)return MMA("h2",{className:w,children:MMA("a",{href:A,className:"hover:text-brand",children:Q},void 0,!1,void 0,this)},void 0,!1,void 0,this);return MMA("h2",{className:w,children:Q},void 0,!1,void 0,this)};import{jsxDEV as sj2}from"preact/jsx-dev-runtime";var h$=({children:A,className:Q})=>{return sj2("div",{className:s1("mb-3",Q),children:A},void 0,!1,void 0,this)};import{jsxDEV as VMA}from"preact/jsx-dev-runtime";var SI=({message:A,description:Q,className:B})=>{return VMA("div",{className:s1("text-center py-12",B),children:[VMA("p",{className:"text-theme-muted",children:A},void 0,!1,void 0,this),Q&&VMA("p",{className:"text-sm text-theme-muted mt-2",children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as bMA}from"preact/jsx-dev-runtime";var lH=({title:A,count:Q,singularLabel:B,pluralLabel:w,description:$,className:f})=>{let I=Q!==void 0&&B?`${Q} ${Q===1?B:w??`${B}s`}`:null,D=I&&$?`${I} ${$}`:I??$;return bMA("div",{className:s1("mb-8",f),children:[bMA("h1",{className:"text-3xl font-bold mb-2 text-theme",children:A},void 0,!1,void 0,this),D&&bMA("p",{className:"text-theme-muted",children:D},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};var Q6=(A,Q={})=>{let{style:B="short",includeTime:w=!1}=Q,$=typeof A==="string"?new Date(A):A;if(w)return $.toLocaleString();switch(B){case"long":return $.toLocaleDateString(void 0,{year:"numeric",month:"long",day:"numeric"});case"full":return $.toLocaleDateString(void 0,{weekday:"long",year:"numeric",month:"long",day:"numeric"});case"short":default:return $.toLocaleDateString()}};import{jsxDEV as OMA}from"preact/jsx-dev-runtime";var rT=Zw("rounded-full",{variants:{variant:{default:"bg-theme-muted text-theme",muted:"bg-theme text-theme-muted",accent:"bg-accent/10 text-accent"},size:{xs:"text-xs px-2 py-1",sm:"text-sm px-3 py-1",md:"text-sm px-3 py-1 font-medium",lg:"text-sm px-4 py-2 font-medium"}},defaultVariants:{variant:"default",size:"xs"}}),NR=({tags:A,maxVisible:Q=5,variant:B,size:w,className:$})=>{let f=A.slice(0,Q),I=A.length-Q;return OMA("div",{className:s1("flex flex-wrap gap-2",$),children:[f.map((D)=>OMA("span",{className:s1(rT({variant:B,size:w})),children:D},D,!1,void 0,this)),I>0&&OMA("span",{className:s1(rT({size:w}),"bg-transparent text-theme-muted"),children:["+",I," more"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as Ed0}from"preact/jsx-dev-runtime";var AC=({href:A,children:Q,className:B})=>{return Ed0("nav",{className:s1("mt-8 pt-6 border-t border-theme",B),children:Ed0("a",{href:A,className:"text-brand hover:text-brand-dark text-sm",children:["\u2190 ",Q]},void 0,!0,void 0,this)},void 0,!1,void 0,this)};import{jsxDEV as QC}from"preact/jsx-dev-runtime";var Md0=Zw("",{variants:{titleSize:{"3xl":"text-3xl","4xl":"text-4xl"}},defaultVariants:{titleSize:"4xl"}}),BC=({title:A,created:Q,updated:B,summary:w,metadata:$,titleSize:f,useSemanticHeader:I=!0,className:D})=>{return QC(I?"header":"div",{className:s1("mb-8",D),children:[QC("h1",{className:s1(Md0({titleSize:f}),"font-bold mb-4 text-theme"),children:A},void 0,!1,void 0,this),(Q??B??$)&&QC("div",{className:"text-sm text-theme-muted mb-4",children:[Q&&QC("time",{dateTime:Q,children:["Created ",Q6(Q)]},void 0,!0,void 0,this),Q&&B&&" \u2022 ",B&&!Q&&QC("time",{dateTime:B,children:["Last updated ",Q6(B)]},void 0,!0,void 0,this),B&&Q&&QC("time",{dateTime:B,children:["Updated ",Q6(B)]},void 0,!0,void 0,this),$]},void 0,!0,void 0,this),w&&QC("p",{className:"text-lg text-theme-muted italic",children:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as aj2}from"preact/jsx-dev-runtime";var Vd0=Zw("px-2 py-1 rounded-full",{variants:{variant:{default:"bg-theme",muted:"bg-theme-muted"}},defaultVariants:{variant:"default"}}),TAA=({count:A,label:Q,variant:B,className:w})=>{return aj2("span",{className:s1(Vd0({variant:B}),w),children:[A," ",Q]},void 0,!0,void 0,this)};import{jsxDEV as WdB}from"preact/jsx-dev-runtime";import{jsxDEV as FdB}from"preact/jsx-dev-runtime";import{jsxDEV as qdB}from"preact/jsx-dev-runtime";import{jsxDEV as tj2}from"preact/jsx-dev-runtime";var bd0=Zw("inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium",{variants:{status:{draft:"bg-status-neutral text-status-neutral",queued:"bg-status-info text-status-info",sent:"bg-status-success text-status-success",failed:"bg-status-danger text-status-danger",published:"bg-status-success text-status-success",pending:"bg-status-warning text-status-warning",captured:"bg-status-info text-status-info",available:"bg-status-success text-status-success","early access":"bg-status-info text-status-info","coming soon":"bg-status-warning text-status-warning",planned:"bg-status-neutral text-status-neutral"}},defaultVariants:{status:"draft"}}),Lf=({status:A,className:Q,label:B})=>{return tj2("span",{className:s1(bd0({status:A}),Q),children:B??A},void 0,!1,void 0,this)};import{jsxDEV as zR}from"preact/jsx-dev-runtime";var SAA=({url:A,title:Q,date:B,description:w,series:$,featured:f})=>{return zR("li",{className:"block pb-10 border-b border-rule last:border-b-0 last:pb-0 transition-transform duration-200 hover:translate-x-1",children:zR("a",{href:A,className:"group block",children:[$&&zR("span",{className:"block font-mono text-[0.65rem] font-medium uppercase tracking-[0.18em] text-accent mb-3",children:[String($.index).padStart(3,"0")," \xB7 ",$.name]},void 0,!0,void 0,this),zR("h3",{className:s1("font-heading font-normal text-heading mb-2 leading-[1.15] tracking-[-0.01em] transition-colors group-hover:text-accent",f?"text-[clamp(1.75rem,3.2vw,2.65rem)] leading-[1.05] tracking-[-0.018em] [font-variation-settings:'opsz'_96,'SOFT'_30]":"text-[clamp(1.4rem,2.4vw,2rem)] [font-variation-settings:'opsz'_72,'SOFT'_30]"),children:Q},void 0,!1,void 0,this),zR("time",{className:"block font-mono text-[0.7rem] uppercase tracking-[0.14em] text-theme-light mb-4",children:new Date(B).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric"})},void 0,!1,void 0,this),w&&zR("p",{className:"text-[0.95rem] leading-[1.6] text-theme-muted max-w-[60ch]",children:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)};import{jsxDEV as kdB,Fragment as jdB}from"preact/jsx-dev-runtime";import{jsxDEV as v2,Fragment as RMA}from"preact/jsx-dev-runtime";var PMA="grid grid-cols-1 gap-3 md:grid-cols-[200px_minmax(0,1fr)] md:gap-14",_MA=(A,Q)=>String(Math.max(0,A)).padStart(Q,"0"),ej2=(A)=>new Date(A).toLocaleDateString("en-GB",{year:"numeric",month:"short",day:"2-digit"}),Rd0=(A)=>new Date(A).toLocaleDateString("en-GB",{month:"short",day:"2-digit"}),qR=(A)=>{let Q=new Date(A).getFullYear();return Number.isFinite(Q)?String(Q):"Undated"},Od0=(A,Q)=>{if(Q===1)return A;return`${A.endsWith("/")?A.slice(0,-1):A}/page/${Q}`},Av2=(A)=>{let Q=A.trim().toLowerCase();if(Q.endsWith("ies"))return Q.slice(0,-3)+"y";if(Q.endsWith("s"))return Q.slice(0,-1);return Q||"entry"},_d0=({series:A})=>{if(!A)return null;return v2("span",{className:"inline-block font-mono text-[0.65rem] uppercase tracking-[0.2em] text-accent",children:[v2("span",{className:"mr-1 text-theme-light",children:String(A.index).padStart(3,"0")},void 0,!1,void 0,this),A.name]},void 0,!0,void 0,this)},Qv2=({item:A})=>v2("section",{"aria-label":"Latest",className:`${PMA} mb-14 border-b border-rule pb-[4.5rem]`,children:[v2("div",{className:"flex flex-row items-baseline gap-6 pt-0.5 md:flex-col md:items-start md:gap-0",children:[v2("span",{className:"font-heading text-[clamp(3.2rem,7vw,5.4rem)] font-light leading-[0.9] tracking-[-0.03em] text-accent [font-variant-numeric:tabular-nums] [font-variation-settings:'opsz'_144,'SOFT'_30] md:mb-5",children:qR(A.date)},void 0,!1,void 0,this),v2("div",{className:"flex w-full max-w-[168px] flex-col gap-1.5 border-rule-strong pt-2 font-mono md:border-t md:pt-3",children:[v2("span",{className:"text-[0.625rem] uppercase tracking-[0.26em] text-theme-light",children:"Latest"},void 0,!1,void 0,this),v2("time",{dateTime:A.date,className:"text-xs tracking-[0.04em] text-theme-muted [font-variant-numeric:tabular-nums]",children:ej2(A.date)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),v2("div",{className:"min-w-0",children:v2("a",{href:A.url,className:"group block text-inherit no-underline",children:[A.series&&v2("div",{className:"mb-[22px]",children:v2(_d0,{series:A.series},void 0,!1,void 0,this)},void 0,!1,void 0,this),v2("h2",{className:"mb-[22px] max-w-[15ch] font-heading text-[clamp(2.4rem,5vw,3.75rem)] font-normal leading-[0.98] tracking-[-0.028em] text-heading transition-colors duration-150 [font-variation-settings:'opsz'_144,'SOFT'_30] [text-wrap:balance] group-hover:text-accent",children:A.title},void 0,!1,void 0,this),A.description&&v2("p",{className:"max-w-[50ch] font-heading text-[clamp(1.1rem,1.5vw,1.32rem)] font-normal italic leading-[1.45] text-theme-muted [font-variation-settings:'opsz'_24,'SOFT'_70]",children:A.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Bv2=({item:A})=>v2("li",{className:"group grid grid-cols-1 items-baseline gap-3 border-t border-rule py-[22px] transition-colors duration-150 hover:bg-[rgb(from_var(--color-accent)_r_g_b_/_0.025)] md:grid-cols-[200px_minmax(0,1fr)] md:gap-14",children:v2("a",{href:A.url,className:"contents text-inherit no-underline",children:[v2("div",{className:"flex flex-row items-baseline gap-3.5 pt-0.5 md:flex-col md:gap-1.5",children:[v2("span",{className:"font-heading text-[1.55rem] font-normal leading-none tracking-[-0.018em] text-theme-muted transition-colors duration-150 [font-variant-numeric:tabular-nums] [font-variation-settings:'opsz'_72,'SOFT'_50] group-hover:text-accent",children:Rd0(A.date)},void 0,!1,void 0,this),v2("time",{dateTime:A.date,className:"font-mono text-[0.62rem] uppercase tracking-[0.18em] text-theme-light [font-variant-numeric:tabular-nums]",children:qR(A.date)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),v2("div",{className:"min-w-0",children:[A.series&&v2("div",{className:"mb-2",children:v2(_d0,{series:A.series},void 0,!1,void 0,this)},void 0,!1,void 0,this),v2("h3",{className:"mb-2 font-heading text-[clamp(1.2rem,1.85vw,1.5rem)] font-medium leading-[1.2] tracking-[-0.016em] text-heading transition-colors duration-150 [font-variation-settings:'opsz'_48,'SOFT'_40] [text-wrap:balance] group-hover:text-accent",children:A.title},void 0,!1,void 0,this),A.description&&v2("p",{className:"max-w-[62ch] text-[0.90625rem] leading-[1.55] text-theme-muted",children:A.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),wv2=({year:A,count:Q,label:B,latestDate:w})=>v2("div",{className:`${PMA} relative items-baseline py-3 before:absolute before:left-0 before:right-0 before:top-3.5 before:h-px before:bg-rule-strong md:py-[18px] md:pt-14 md:before:top-6`,children:[v2("span",{className:"pt-7 font-heading text-[clamp(2.4rem,5.4vw,3.6rem)] font-light leading-[0.95] tracking-[-0.025em] text-accent [font-variant-numeric:tabular-nums] [font-variation-settings:'opsz'_144,'SOFT'_30] md:pt-0",children:A},void 0,!1,void 0,this),v2("span",{className:"font-mono text-[0.68rem] uppercase tracking-[0.22em] text-theme-light [font-variant-numeric:tabular-nums] md:pt-1.5",children:[Q," ",B,Q===1?"":"s"," \xB7 finished ",Rd0(w)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),$v2=({pagination:A,baseUrl:Q})=>{if(!A||A.totalPages<=1)return null;let B=Math.max(2,String(A.totalPages).length),w=A.hasPrevPage??A.currentPage>1,$=A.hasNextPage??A.currentPage<A.totalPages;return v2("nav",{"aria-label":"Pagination",className:`${PMA} mt-16 border-t border-rule pt-6 font-mono text-[0.68rem] uppercase tracking-[0.2em] text-theme-light [font-variant-numeric:tabular-nums]`,children:[v2("span",{children:[_MA(A.currentPage,B)," /"," ",_MA(A.totalPages,B)]},void 0,!0,void 0,this),v2("span",{className:"flex items-baseline justify-between gap-6",children:[w?v2("a",{href:Od0(Q,A.currentPage-1),className:"text-theme-muted no-underline transition-colors duration-150 hover:text-brand",children:"\u2190 Newer"},void 0,!1,void 0,this):v2("span",{"aria-disabled":"true",className:"opacity-30",children:"\u2190 Newer"},void 0,!1,void 0,this),$?v2("a",{href:Od0(Q,A.currentPage+1),className:"text-theme-muted no-underline transition-colors duration-150 hover:text-brand",children:"Older \u2192"},void 0,!1,void 0,this):v2("span",{"aria-disabled":"true",className:"opacity-30",children:"Older \u2192"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},dT=({label:A,items:Q,pagination:B,baseUrl:w="",emptyMessage:$})=>{let f=B?.currentPage??1,I=f===1&&Q.length>0,D=I&&Q[0]?qR(Q[0].date):void 0,H=I?Q.slice(1):Q,Y=Av2(A);return v2("section",{"aria-labelledby":"content-archive-title",children:[v2("h1",{id:"content-archive-title",className:"sr-only",children:A},void 0,!1,void 0,this),v2("div",{className:"mb-10 flex items-center gap-2.5 font-mono text-[0.7rem] font-medium uppercase tracking-[0.22em] text-accent",children:[v2("span",{className:"h-px w-[18px] bg-accent","aria-hidden":"true"},void 0,!1,void 0,this),v2("span",{children:A},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.length===0?v2("p",{className:"text-theme-muted italic",children:$??`No ${A.toLowerCase()} yet.`},void 0,!1,void 0,this):v2(RMA,{children:[I&&Q[0]&&v2(Qv2,{item:Q[0]},void 0,!1,void 0,this),H.length>0&&v2(RMA,{children:[v2("header",{className:"mb-7 flex items-baseline justify-between gap-6 font-mono text-[0.68rem] uppercase tracking-[0.24em] text-theme-light",children:[v2("span",{children:"Archive"},void 0,!1,void 0,this),v2("span",{className:"text-theme-muted",children:I?"Older entries":`Page ${_MA(f,2)}`},void 0,!1,void 0,this)]},void 0,!0,void 0,this),v2("ol",{className:"m-0 list-none p-0",children:H.map((W,G)=>{let K=qR(W.date),Z=G>0?qR(H[G-1]?.date??""):D,q=Z===void 0||K!==Z,L=H.filter((C)=>qR(C.date)===K).length;return v2(RMA,{children:[q&&v2(wv2,{year:K,count:L,label:Y,latestDate:W.date},void 0,!1,void 0,this),v2(Bv2,{item:W},void 0,!1,void 0,this)]},W.id,!0,void 0,this)})},void 0,!1,void 0,this)]},void 0,!0,void 0,this),v2($v2,{pagination:B,baseUrl:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as CR,Fragment as fv2}from"preact/jsx-dev-runtime";var mAA=({items:A,viewAllUrl:Q,viewAllLabel:B,emptyMessage:w})=>{if(A.length===0)return CR("p",{className:"text-theme-muted italic",children:w??"Nothing here yet."},void 0,!1,void 0,this);return CR(fv2,{children:[CR("ul",{className:"flex flex-col gap-10",children:A.map(($,f)=>CR(SAA,{url:$.url,title:$.title,date:$.date,description:$.description,series:$.series,featured:f===0},$.id,!1,void 0,this))},void 0,!1,void 0,this),Q&&CR("a",{href:Q,className:"mt-10 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:[B??"View All",CR("span",{"aria-hidden":"true",children:"\u2192"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as nT}from"preact/jsx-dev-runtime";var kMA=({title:A,number:Q,blurb:B,variant:w="editorial"})=>{if(w==="compact")return nT("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-8",children:A},void 0,!1,void 0,this);return nT("header",{children:[Q!==void 0&&nT("span",{className:"block font-mono text-[0.7rem] font-medium uppercase tracking-[0.22em] text-accent mb-[0.85rem]",children:Q},void 0,!1,void 0,this),nT("h2",{className:"font-heading font-normal text-heading leading-[1.05] tracking-[-0.015em] text-[clamp(1.75rem,2.6vw,2.1rem)] [font-variation-settings:'opsz'_48,'SOFT'_30]",children:A},void 0,!1,void 0,this),B!==void 0&&nT("p",{className:"font-heading italic font-light text-[0.95rem] leading-[1.5] text-theme-light mt-3 max-w-[22ch] [font-variation-settings:'opsz'_18,'SOFT'_50]",children:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as oT}from"preact/jsx-dev-runtime";var Iv2=(A)=>`/topics/${A.toLowerCase().replace(/\s+/g,"-")}`,jMA=({subjects:A,hrefFor:Q=Iv2})=>oT("ul",{className:"grid grid-cols-1 sm:grid-cols-2 sm:gap-x-10 max-w-[40rem] border-t border-rule-strong list-none p-0 mt-8",children:A.map((B,w)=>oT("li",{className:"border-b border-rule",children:oT("a",{href:Q(B),className:"flex items-baseline gap-[1.1rem] py-[0.95rem] text-theme transition-[color,padding-left] duration-200 hover:text-accent hover:pl-[0.4rem]",children:[oT("span",{className:"font-mono text-[0.66rem] font-medium tracking-[0.18em] text-theme-light min-w-[1.6rem] transition-colors",children:String(w+1).padStart(2,"0")},void 0,!1,void 0,this),oT("span",{className:"font-heading italic font-normal text-[1.05rem] tracking-[-0.005em] [font-variation-settings:'opsz'_24,'SOFT'_60]",children:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},B,!1,void 0,this))},void 0,!1,void 0,this);import{Fragment as vMA}from"preact";import{jsxDEV as sT}from"preact/jsx-dev-runtime";var Dv2=/(\*[^*]+\*)/;function uAA(A,Q){let B=A.split(`
|
|
2940
2940
|
`);return sT(vMA,{children:B.map((w,$)=>sT(vMA,{children:[$>0&&sT("br",{},void 0,!1,void 0,this),w.split(Dv2).map((f,I)=>{if(f.length>=3&&f.startsWith("*")&&f.endsWith("*"))return sT("span",{className:Q,children:f.slice(1,-1)},I,!1,void 0,this);return sT(vMA,{children:f},I,!1,void 0,this)})]},$,!0,void 0,this))},void 0,!1,void 0,this)}import{createContext as Hv2,h as Yv2}from"preact";import{useContext as Xv2}from"preact/hooks";var xMA=Hv2(null);function cAA({headCollector:A,children:Q}){return Yv2(xMA.Provider,{value:A},Q)}function Pd0(){return Xv2(xMA)}function XQ(A){let Q=Pd0();if(Q)Q.setHeadProps(A);return null}import{jsxDEV as Wv2}from"preact/jsx-dev-runtime";var mI=({markdown:A,className:Q})=>{let B=eq();return Wv2(CMA,{html:B(A),...Q&&{className:Q}},void 0,!1,void 0,this)};import{jsxDEV as uJ}from"preact/jsx-dev-runtime";function hMA(A,Q){if(Q===1)return A;return`${A.endsWith("/")?A.slice(0,-1):A}/page/${Q}`}function Uv2(A,Q,B){let w=[];w.push(1);let $=Math.max(2,A-B),f=Math.min(Q-1,A+B);if($>2)w.push("ellipsis");for(let I=$;I<=f;I++)w.push(I);if(f<Q-1)w.push("ellipsis");if(Q>1)w.push(Q);return w}var yMA="px-3 py-2 text-sm font-medium text-theme rounded-lg hover:text-brand hover:bg-theme-subtle transition-colors",Jv2="px-3 py-2 text-sm font-semibold text-brand bg-theme-subtle rounded-lg",kd0="px-3 py-2 text-sm font-medium text-theme-muted cursor-not-allowed",cJ=({currentPage:A,totalPages:Q,baseUrl:B,siblingCount:w=1})=>{if(Q<=1)return null;let $=Uv2(A,Q,w),f=A>1,I=A<Q;return uJ("nav",{"aria-label":"Pagination",className:"flex items-center justify-center gap-1 mt-12",children:[f?uJ("a",{href:hMA(B,A-1),className:yMA,"aria-label":"Previous page",children:"\u2190 Prev"},void 0,!1,void 0,this):uJ("span",{className:kd0,children:"\u2190 Prev"},void 0,!1,void 0,this),uJ("div",{className:"flex items-center gap-1 mx-2",children:$.map((D,H)=>D==="ellipsis"?uJ("span",{className:"px-2 py-2 text-sm text-theme-muted",children:"\u2026"},`ellipsis-${H}`,!1,void 0,this):D===A?uJ("span",{className:Jv2,"aria-current":"page",children:D},D,!1,void 0,this):uJ("a",{href:hMA(B,D),className:yMA,children:D},D,!1,void 0,this))},void 0,!1,void 0,this),I?uJ("a",{href:hMA(B,A+1),className:yMA,"aria-label":"Next page",children:"Next \u2192"},void 0,!1,void 0,this):uJ("span",{className:kd0,children:"Next \u2192"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as LR}from"preact/jsx-dev-runtime";function tX({items:A}){return LR("nav",{"aria-label":"Breadcrumb",className:"text-sm text-theme-muted mb-6",children:LR("ol",{className:"flex flex-wrap items-center gap-1",children:A.map((Q,B)=>{let w=B===A.length-1;return LR("li",{className:"flex items-center gap-1",children:[B>0&&LR("span",{className:"mx-1","aria-hidden":"true",children:"/"},void 0,!1,void 0,this),w||!Q.href?LR("span",{className:"text-heading font-medium",children:Q.label},void 0,!1,void 0,this):LR("a",{href:Q.href,className:"hover:text-brand transition-colors",children:Q.label},void 0,!1,void 0,this)]},B,!0,void 0,this)})},void 0,!1,void 0,this)},void 0,!1,void 0,this)}import{jsxDEV as q8}from"preact/jsx-dev-runtime";var pAA=Zw("newsletter-signup",{variants:{variant:{inline:"",card:"p-6 rounded-lg bg-theme-subtle",section:"py-16 text-center"}},defaultVariants:{variant:"card"}});function gMA({variant:A="card",title:Q,description:B,buttonText:w="Subscribe",showNameField:$=!1,action:f="/api/newsletter/subscribe",className:I,successMessage:D="Check your email to confirm your subscription."}){let H=Q??(A==="inline"?"Stay updated":A==="section"?"Subscribe to the Newsletter":"Subscribe"),Y=B??(A==="section"?"Get the latest essays and updates delivered to your inbox.":A==="card"?"Get updates delivered to your inbox.":void 0),W="You are already subscribed!",G=`
|
|
2941
2941
|
(function() {
|
|
2942
2942
|
var form = document.currentScript.previousElementSibling;
|
|
@@ -3229,13 +3229,13 @@ ${A.map((f)=>({url:`${Q}${f.path}`,lastmod:B,changefreq:f.path==="/"?"daily":"we
|
|
|
3229
3229
|
`+$:B,I=XW(this.outputDir,"styles","main.css");await this.cssProcessor.process(f,I,this.workingDir,this.outputDir,this.logger);let D=await u$.readFile(I,"utf-8"),H=w.length>0?w:Q;if(H.length>0){let Y=H.join(`
|
|
3230
3230
|
`)+`
|
|
3231
3231
|
|
|
3232
|
-
`+D;await u$.writeFile(I,Y,"utf-8")}this.logger.debug("CSS processed successfully with font imports")}async copyStaticAssets(){this.logger.debug("Copying static assets from public/ directory");let A=XW(process.cwd(),"public");try{await u$.access(A)}catch{this.logger.debug("No public/ directory found, skipping static assets");return}let Q=await u$.readdir(A,{withFileTypes:!0});for(let B of Q){let w=XW(A,B.name),$=XW(this.outputDir,B.name);if(B.isDirectory())await this.copyDirectory(w,$);else await u$.copyFile(w,$),this.logger.debug(`Copied static asset: ${B.name}`)}this.logger.debug("Static assets copied successfully")}async writeInlineStaticAssets(A){if(!A)return;let Q=Object.entries(A);if(Q.length===0)return;this.logger.debug(`Writing ${Q.length} inline static asset(s) from SitePackage`),await Promise.all(Q.map(async([B,w])=>{let $=B.startsWith("/")?B.slice(1):B,f=XW(this.outputDir,$);await u$.mkdir(ms2(f),{recursive:!0}),await u$.writeFile(f,w,"utf-8"),this.logger.debug(`Wrote inline static asset: ${$}`)}))}async copyDirectory(A,Q){await u$.mkdir(Q,{recursive:!0});let B=await u$.readdir(A,{withFileTypes:!0});for(let w of B){let $=XW(A,w.name),f=XW(Q,w.name);if(w.isDirectory())await this.copyDirectory($,f);else await u$.copyFile($,f)}}}function _OA(A){return new oQ1(A)}G6();GA();GA();G6();var sQ1=F.object({environment:F.enum(["preview","production"]),outputDir:F.string(),workingDir:F.string().optional(),sharedImagesDir:F.string().default("./dist/images"),enableContentGeneration:F.boolean().default(!1),cleanBeforeBuild:F.boolean().default(!0),siteConfig:BI,layouts:F.record(F.any()),themeCSS:F.string().optional()}),q1w=F.object({success:F.boolean(),outputDir:F.string(),filesGenerated:F.number(),routesBuilt:F.number(),errors:F.array(F.string()).optional(),warnings:F.array(F.string()).optional()});function aQ1(A){let Q=A.list(),B=Q.length===0?["No routes registered for site build"]:[];return{routes:Q,warnings:B}}function tQ1(A,Q,B){let w=Q.getProfile(),$=B.getNavigationItems("primary"),f=B.getNavigationItems("secondary");return{...A,...w.socialLinks!==void 0&&{socialLinks:w.socialLinks},navigation:{primary:$,secondary:f},copyright:A.copyright??"Powered by Rizom"}}G6();Bf();G6();GA();var us2=F.object({id:F.string(),entityType:F.string(),content:F.string(),metadata:F.object({slug:F.string()}).passthrough()}).passthrough(),cs2=F.object({content:F.string(),metadata:F.object({width:F.number().optional(),height:F.number().optional()}).passthrough()});async function t1A(A,Q){let B=Q.urlGenerator??I9.getInstance();if(A===null||A===void 0)return A;if(Array.isArray(A))return Promise.all(A.map((_)=>t1A(_,{...Q,urlGenerator:B})));if(typeof A!=="object")return A;let w={},$=Object.entries(A),f=await Promise.all($.map(([,_])=>t1A(_,{...Q,urlGenerator:B})));for(let _=0;_<$.length;_++){let o=$[_];if(o)w[o[0]]=f[_]}let I=us2.safeParse(A);if(!I.success)return w;let D=I.data,H=D.entityType,Y=D.metadata.slug,W=Q.pipelineContext.entityDisplay?.[H],G=W?W.label:H.charAt(0).toUpperCase()+H.slice(1),K=W?W.pluralName??W.label.toLowerCase()+"s":ef(H),Z=`/${K}`,q=K.charAt(0).toUpperCase()+K.slice(1),L=Tv(D),C=L?Q.imageBuildService?.get(L):void 0,R={};if(C)R={coverImageUrl:C.src,coverImageWidth:C.width,coverImageHeight:C.height,...C.srcset&&{coverImageSrcset:C.srcset,coverImageSizes:C.sizes}};else{let _=await ps2(L,Q.pipelineContext.services.entityService);if(_)R={coverImageUrl:_.url,..._.width&&{coverImageWidth:_.width},..._.height&&{coverImageHeight:_.height}}}return{...w,...D,url:B.generateUrl(H,Y),typeLabel:G,listUrl:Z,listLabel:q,...R}}async function ps2(A,Q){if(!A)return;let B=await Q.getEntity({entityType:"image",id:A}),w=cs2.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 eQ1(A,Q){let B=new Set;try{let w=A.getEntityTypes();for(let $ of w){if($==="image")continue;let f=await A.listEntities({entityType:$});for(let I of f){let D=Tv(I);if(D)B.add(D)}}}catch(w){Q.warn("Failed to collect image IDs for pre-resolution",{error:y0(w)})}return[...B]}async function AB1(A,Q,B,w){if(!A.template)return A.content??null;let $=A.template,f=A.dataQuery?{dataParams:A.dataQuery,fallback:A.content,publishedOnly:B}:{savedContent:{entityType:"site-content",entityId:`${Q.id}:${A.id}`},fallback:A.content},I=await w.pipelineContext.services.resolveTemplateContent($,f);if(!I)return null;return t1A(I,{pipelineContext:w.pipelineContext,imageBuildService:w.imageBuildService,urlGenerator:I9.getInstance()})}function QB1(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 AB1(B,Q,w,{pipelineContext:A.pipelineContext,imageBuildService:A.imageBuildService})},getViewTemplate:(Q)=>{return A.pipelineContext.services.getViewTemplate(Q)},layouts:A.parsedOptions.layouts,getSiteLayoutInfo:async()=>{return tQ1(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 ls2}from"path";async function BB1(A){let Q=A.parsedOptions.workingDir??ls2(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 wB1(A){await new s1A({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 $B1(A){let Q=new o1A(A.pipelineContext.services.entityService,A.pipelineContext.logger,A.sharedImagesDir),B=await eQ1(A.pipelineContext.services.entityService,A.pipelineContext.logger);if(B.length>0)await Q.resolveAll(B);return Q}async function fB1(A){let Q=A.reporter?.createSub({scale:{start:85,end:95}});await A.staticSiteBuilder.build(A.buildContext,(B)=>{Q?.report(B).catch(()=>{})})}function IB1(A){return{success:!0,outputDir:A.outputDir,filesGenerated:A.routesBuilt+1,routesBuilt:A.routesBuilt,...A.warnings.length>0&&{warnings:A.warnings}}}function DB1(A){return{success:!1,outputDir:A.outputDir,filesGenerated:0,routesBuilt:0,errors:[A.errorMessage]}}async function HB1(A){let Q=sQ1.parse(A.buildOptions),B=z$.from(A.progress),w=[];try{await B?.report({message:"Starting site build",progress:0,total:100}),await B?.report({message:"Generating dynamic routes",progress:10,total:100}),await wB1({pipelineContext:A.pipelineContext});let $=await BB1({logger:A.pipelineContext.logger,parsedOptions:Q,staticSiteBuilderFactory:A.staticSiteBuilderFactory}),f=aQ1(A.pipelineContext.routeRegistry);w.push(...f.warnings);let{routes:I}=f;await B?.report({message:`Building ${I.length} routes`,progress:20,total:100}),await B?.report({message:"Resolving images",progress:25,total:100});let D=await $B1({pipelineContext:A.pipelineContext,sharedImagesDir:Q.sharedImagesDir}),H=QB1({routes:I,parsedOptions:Q,buildOptions:A.buildOptions,pipelineContext:A.pipelineContext,imageBuildService:D,siteMetadata:Q.siteConfig});return await fB1({staticSiteBuilder:$,buildContext:H,reporter:B}),await B?.report({message:"Site build complete",progress:100,total:100}),IB1({outputDir:Q.outputDir,routesBuilt:I.length,warnings:w})}catch($){let f=Error("Site build process failed");return A.pipelineContext.logger.error("Site build failed",{error:f,originalError:$}),DB1({outputDir:Q.outputDir,errorMessage:f.message})}}class pI{static instance=null;static defaultStaticSiteBuilderFactory=_OA;pipelineContext;staticSiteBuilderFactory;static setDefaultStaticSiteBuilderFactory(A){pI.defaultStaticSiteBuilderFactory=A}static getInstance(A,Q,B,w,$=void 0){return pI.instance??=new pI(A,pI.defaultStaticSiteBuilderFactory,Q,B,w,$),pI.instance}static resetInstance(){pI.instance=null}static createFresh(A,Q,B,w,$,f=void 0){return new pI(A,$??pI.defaultStaticSiteBuilderFactory,Q,B,w,f)}constructor(A,Q,B,w,$,f){this.pipelineContext={logger:A,services:B,routeRegistry:w,profileService:$,entityDisplay:f},this.staticSiteBuilderFactory=Q,I9.getInstance().configure(f)}async build(A,Q){return HB1({buildOptions:A,progress:Q,pipelineContext:this.pipelineContext,staticSiteBuilderFactory:this.staticSiteBuilderFactory})}}GA();class POA{config;context;pluginId;logger;debounces=new Map;unsubscribeFunctions=[];constructor(A,Q,B,w){this.config=A;this.context=Q;this.pluginId=B;this.logger=w}requestBuild(A){let Q=A??(this.config.previewOutputDir?"preview":"production"),B=this.debounces.get(Q);if(!B)B=new UN(()=>{this.enqueueBuild(Q)},this.config.rebuildDebounce),this.debounces.set(Q,B);B.trigger()}setupAutoRebuild(){let A=new Set(["base"]),Q=async(w)=>{let{entityType:$}=w.payload;if(!A.has($))this.logger.debug(`Entity type ${$} will trigger rebuild`),this.requestBuild();return{success:!0}},B=["entity:created","entity:updated","entity:deleted"];for(let w of B)this.unsubscribeFunctions.push(this.context.messaging.subscribe(w,Q));this.logger.debug(`Auto-rebuild enabled (${this.config.rebuildDebounce}ms debounce), excluding types: ${[...A].join(", ")}`)}dispose(){for(let A of this.debounces.values())A.dispose();this.debounces.clear();for(let A of this.unsubscribeFunctions)A();this.unsubscribeFunctions=[]}async enqueueBuild(A){let Q=A==="production"?this.config.productionOutputDir:this.config.previewOutputDir;this.logger.debug(`Triggering ${A} site rebuild`);try{await this.context.jobs.enqueue({type:"site-build",data:{environment:A,outputDir:Q,workingDir:this.config.workingDir,enableContentGeneration:!0,metadata:{trigger:"debounced-rebuild",timestamp:new Date().toISOString()}},options:{priority:0,source:this.pluginId,metadata:{operationType:"content_operations"},deduplication:"skip"}}),this.logger.debug("Site rebuild enqueued")}catch(B){this.logger.error("Failed to enqueue site rebuild",{error:B})}}}G6();function is2(A,Q){return A.map((B)=>({...B,template:B.template.includes(":")?B.template:`${Q}:${B.template}`}))}function e1A(A,Q,B){for(let w of A)B.register({...w,pluginId:Q,sections:w.sections?is2(w.sections,Q):[]})}function YB1(A,Q,B){A.messaging.subscribe("plugin:site-builder:route:register",async(w)=>{try{let $=up.parse(w.payload),{routes:f,pluginId:I}=$;return e1A(f,I,Q),{success:!0}}catch($){return B.error("Failed to register routes",{error:$}),{success:!1,error:"Failed to register routes"}}}),A.messaging.subscribe("plugin:site-builder:route:unregister",async(w)=>{try{let $=cp.parse(w.payload),{paths:f,pluginId:I}=$;if(f)for(let D of f)Q.unregister(D);else if(I)Q.unregisterByPlugin(I);return{success:!0}}catch($){return B.error("Failed to unregister routes",{error:$}),{success:!1,error:"Failed to unregister routes"}}}),A.messaging.subscribe("plugin:site-builder:route:list",async(w)=>{try{let $=pp.parse(w.payload);return{success:!0,data:{routes:Q.list($.pluginId?$:void 0)}}}catch($){return B.error("Failed to list routes",{error:$}),{success:!1,error:"Failed to list routes"}}}),A.messaging.subscribe("plugin:site-builder:route:get",async(w)=>{try{let $=lp.parse(w.payload);return{success:!0,data:{route:Q.get($.path)}}}catch($){return B.error("Failed to get route",{error:$}),{success:!1,error:"Failed to get route"}}}),A.messaging.subscribe("site-builder:routes:list",async()=>{return{success:!0,data:Q.list()}})}import{promises as XB1}from"fs";import{join as WB1}from"path";async function rs2(A,Q,B){let w=A.siteConfig.url??"https://example.com",$=Q.list(),f=OOA(w,A.environment);await XB1.writeFile(WB1(A.outputDir,"robots.txt"),f,"utf-8"),B.info(`Generated robots.txt for ${A.environment} environment`);let I=ROA($,w);await XB1.writeFile(WB1(A.outputDir,"sitemap.xml"),I,"utf-8"),B.info(`Generated sitemap.xml with ${$.length} URLs`)}function UB1(A){let{context:Q,routeRegistry:B,logger:w}=A;Q.messaging.subscribe("site:build:completed",async($)=>{try{let f=$.payload;return w.info(`Received site:build:completed event for ${f.environment} environment - generating SEO files`),await rs2(f,B,w),{success:!0}}catch(f){return w.error("Failed to generate SEO files",f),{success:!1}}})}f0();GA();G6();var JB1=F.object({environment:F.enum(["preview","production"]).optional(),outputDir:F.string(),workingDir:F.string().optional(),enableContentGeneration:F.boolean().optional(),siteConfig:BI.optional()});G6();G6();async function fm(A,Q){try{let B=await A({type:kk,payload:void 0});if("success"in B&&B.success&&B.data){let w=BI.safeParse(B.data);if(w.success)return BI.parse({...Q,...w.data})}}catch{}return Q}class kOA extends ow{sendMessage;cfg;constructor(A,Q,B){super(A,{schema:JB1,jobTypeName:"site-build"});this.sendMessage=Q;this.cfg=B}async process(A,Q,B){let w=A.environment??"preview",$=A.enableContentGeneration??!1;try{this.logger.debug("Starting site build job",{jobId:Q,environment:w,outputDir:A.outputDir}),await B.report({progress:0,total:100,message:`Starting site build for ${w} environment`});let f=B.createSub({scale:{start:10,end:90}}),I=await fm(this.sendMessage,A.siteConfig??this.cfg.defaultSiteConfig),D=await this.cfg.siteBuilder.build({outputDir:A.outputDir,workingDir:A.workingDir,sharedImagesDir:this.cfg.sharedImagesDir,enableContentGeneration:$,environment:w,cleanBeforeBuild:!0,siteConfig:I,layouts:this.cfg.layouts,themeCSS:this.cfg.themeCSS,slots:this.cfg.slots,headScripts:this.cfg.getHeadScripts?.(),...this.cfg.staticAssets&&{staticAssets:this.cfg.staticAssets}},f.toCallback());if(await B.report({progress:100,total:100,message:`Site build completed: ${D.routesBuilt} routes built`}),this.logger.debug("Site build job completed",{jobId:Q,environment:w,routesBuilt:D.routesBuilt,success:D.success}),D.success){this.logger.info(`Emitting site:build:completed event for ${w} environment`);let H=w==="preview"?this.cfg.previewUrl??this.cfg.siteUrl:this.cfg.siteUrl;await this.sendMessage({type:"site:build:completed",payload:{outputDir:A.outputDir,environment:w,routesBuilt:D.routesBuilt,siteConfig:{...I,url:H},generateEntityUrl:(Y,W)=>I9.getInstance().generateUrl(Y,W)},broadcast:!0})}return{success:D.success,routesBuilt:D.routesBuilt,outputDir:A.outputDir,environment:w,...D.errors&&{errors:D.errors},...D.warnings&&{warnings:D.warnings}}}catch(f){throw this.logger.error("Site build job failed",f),f}}summarizeDataForLog(A){return{environment:A.environment,outputDir:A.outputDir}}}GA();G6();var ds2=F.object({slot:F.enum(GN).optional().default("primary"),limit:F.number().optional()});class jOA{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=ds2.parse(A??{});this.logger.debug("NavigationDataSource fetch called",{params:w});let $=this.routeRegistry.getNavigationItems(w.slot),f=w.limit?$.slice(0,w.limit):$,I=f.map((H)=>({label:H.label,href:H.href}));this.logger.debug("NavigationDataSource returning",{slot:w.slot,itemCount:f.length,items:I});let D={navigation:I};return Q.parse(D)}}G6();f0();GA();var ns2=F.object({environment:F.enum(["preview","production"]).optional().describe("Build environment (defaults to production, or preview if configured)")});function GB1(A,Q){return[xQ(A,"build-site","Build a static site from registered routes. Call this for every user build/rebuild request, including repeated requests like 'build it again' or 'one more build'.",ns2,async(B)=>{return Q(B.environment),{success:!0,message:`Site build requested${B.environment?` for ${B.environment}`:""} (debounced)`,data:{}}},{cli:{name:"build"}})]}GA();G6();var FB1=F.object({previewOutputDir:F.string().describe("Output directory for preview builds").default("./dist/site-preview"),productionOutputDir:F.string().describe("Output directory for production builds").default("./dist/site-production"),sharedImagesDir:F.string().describe("Shared directory for optimized images (used by both preview and production)").default("./dist/images"),workingDir:F.string().optional().describe("Working directory for builds").default("./.preact-work"),siteInfo:BI.default({title:"Brain",description:"A knowledge management system"}),themeCSS:F.string().describe("Custom CSS theme overrides to inject into builds").optional(),analyticsScript:F.string().describe("Analytics tracking script to inject into page head (e.g., Cloudflare Web Analytics)").optional(),templates:F.any().optional().describe("Template definitions to register"),routes:F.array(FN).optional().describe("Routes to register"),layouts:F.record(F.any()).optional().describe("Layout components (at least 'default' required)"),autoRebuild:F.boolean().default(!0).describe("Automatically rebuild site when content changes"),rebuildDebounce:F.number().min(100).describe("Debounce time in ms before triggering site rebuild after content changes").default(5000),entityDisplay:F.record(F.object({label:F.string().describe("Display label for entity type (e.g., 'Essay')"),pluralName:F.string().optional().describe("URL path segment (defaults to label.toLowerCase() + 's')"),layout:F.string().optional().describe("Layout name for this entity type's generated routes (defaults to 'default')"),paginate:F.boolean().optional().describe("Enable pagination for list pages"),pageSize:F.number().optional().describe("Items per page (default: 10)"),navigation:F.object({show:F.boolean().optional().describe("Show in navigation"),slot:F.enum(GN).optional().describe("Navigation slot (primary or secondary)"),priority:F.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:F.record(F.string()).optional().describe("Static files to write to the output directory at build time. Keys are output paths (e.g. '/canvases/tree.js'), values are file contents as strings. Typically supplied by a SitePackage via text imports.")});var KB1={name:"@brains/site-builder-plugin",private:!0,version:"0.2.0-alpha.70",description:"Static site generation plugin for Brain system",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint .",clean:"rm -rf dist"},dependencies:{"@brains/image":"workspace:*","@brains/plugins":"workspace:*","@brains/site-composition":"workspace:*","@brains/site-engine":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*","@tailwindcss/typography":"^0.5.19",preact:"^10.27.2","preact-render-to-string":"^6.3.1"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14",eslint:"^8.56.0",typescript:"^5.3.3"}};class vOA extends Ww{siteBuilder;pluginContext;_routeRegistry;_slotRegistry;profileService;layouts;rebuildManager;headScripts=new Map;get routeRegistry(){if(!this._routeRegistry)throw Error("RouteRegistry not initialized - plugin not registered");return this._routeRegistry}constructor(A={}){let Q=A.layouts??{};super("site-builder",KB1,{...A,layouts:Q},FB1);this.layouts=Q}async onRegister(A){if(this.pluginContext=A,this._routeRegistry=new a1A(A.logger),this._slotRegistry=new _1A,A.messaging.subscribe("plugin:site-builder:slot:register",async(B)=>{let{slotName:w,pluginId:$,render:f,priority:I}=B.payload;return this._slotRegistry?.register(w,{pluginId:$,render:f,...I!==void 0&&{priority:I}}),{success:!0}}),A.messaging.subscribe("plugin:site-builder:head-script:register",async(B)=>{let{pluginId:w,script:$}=B.payload;return this.headScripts.set(w,$),{success:!0}}),A.entities.registerDataSource(new jOA(this._routeRegistry,A.logger.child("NavigationDataSource"))),this.profileService=f7.getInstance(A.entityService,A.logger),YB1(A,this._routeRegistry,this.logger),this.config.templates)A.templates.register(this.config.templates);if(this.config.routes)e1A(this.config.routes,this.id,this.routeRegistry);let Q={entityService:A.entityService,sendMessage:A.messaging.send,resolveTemplateContent:(B,w)=>A.templates.resolve(B,w),getViewTemplate:(B)=>A.views.get(B),listViewTemplateNames:()=>A.views.list().map((B)=>B.name)};if(this.siteBuilder=pI.getInstance(A.logger.child("SiteBuilder"),Q,this.routeRegistry,this.profileService,this.config.entityDisplay),A.jobs.registerHandler("site-build",new kOA(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 POA(this.config,A,this.id,this.logger),this.config.autoRebuild)this.logger.debug("Auto-rebuild enabled"),this.rebuildManager.setupAutoRebuild();A.messaging.subscribe(jk,async()=>{let B=await this.getInstructions();if(B)A.registerInstructions(B);return{success:!0}}),UB1({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 GB1(this.id,(Q)=>A.requestBuild(Q))}async getResources(){let A=this.getContext();return[{uri:"brain://site",name:"Site Metadata",description:"Site metadata \u2014 title, description, domain, URLs",mimeType:"application/json",handler:async()=>{let Q=await fm(A.messaging.send,this.config.siteInfo);return{contents:[{uri:"brain://site",mimeType:"application/json",text:JSON.stringify({...Q,domain:A.domain,siteUrl:A.siteUrl,previewUrl:A.previewUrl},null,2)}]}}},{uri:"site://routes",name:"Site Routes",description:"All registered routes with sections and templates",mimeType:"application/json",handler:async()=>{let Q=this.routeRegistry.list();return{contents:[{uri:"site://routes",mimeType:"application/json",text:JSON.stringify(Q.map((B)=>({id:B.id,path:B.path,title:B.title,description:B.description,sections:B.sections.map((w)=>({id:w.id,template:w.template}))})),null,2)}]}}},{uri:"site://templates",name:"View Templates",description:"All registered view templates",mimeType:"application/json",handler:async()=>{let Q=A.views.list();return{contents:[{uri:"site://templates",mimeType:"application/json",text:JSON.stringify(Q.map((B)=>({name:B.name,description:B.description,hasWebRenderer:!!B.renderers.web})),null,2)}]}}}]}getSiteBuilder(){return this.siteBuilder}getSlotRegistry(){return this._slotRegistry}async getInstructions(){let A=this.getContext(),Q="## Site Builder Actions\n- When the user asks to build, rebuild, publish, or build the website/site again, call `site-builder_build-site` immediately.\n- Every repeated build request requires a fresh `site-builder_build-site` call. Do not say a build was started, queued, or requested unless this turn invoked the tool.",B=await fm(A.messaging.send,this.config.siteInfo);return`## Your Site
|
|
3232
|
+
`+D;await u$.writeFile(I,Y,"utf-8")}this.logger.debug("CSS processed successfully with font imports")}async copyStaticAssets(){this.logger.debug("Copying static assets from public/ directory");let A=XW(process.cwd(),"public");try{await u$.access(A)}catch{this.logger.debug("No public/ directory found, skipping static assets");return}let Q=await u$.readdir(A,{withFileTypes:!0});for(let B of Q){let w=XW(A,B.name),$=XW(this.outputDir,B.name);if(B.isDirectory())await this.copyDirectory(w,$);else await u$.copyFile(w,$),this.logger.debug(`Copied static asset: ${B.name}`)}this.logger.debug("Static assets copied successfully")}async writeInlineStaticAssets(A){if(!A)return;let Q=Object.entries(A);if(Q.length===0)return;this.logger.debug(`Writing ${Q.length} inline static asset(s) from SitePackage`),await Promise.all(Q.map(async([B,w])=>{let $=B.startsWith("/")?B.slice(1):B,f=XW(this.outputDir,$);await u$.mkdir(ms2(f),{recursive:!0}),await u$.writeFile(f,w,"utf-8"),this.logger.debug(`Wrote inline static asset: ${$}`)}))}async copyDirectory(A,Q){await u$.mkdir(Q,{recursive:!0});let B=await u$.readdir(A,{withFileTypes:!0});for(let w of B){let $=XW(A,w.name),f=XW(Q,w.name);if(w.isDirectory())await this.copyDirectory($,f);else await u$.copyFile($,f)}}}function _OA(A){return new oQ1(A)}G6();GA();GA();G6();var sQ1=F.object({environment:F.enum(["preview","production"]),outputDir:F.string(),workingDir:F.string().optional(),sharedImagesDir:F.string().default("./dist/images"),enableContentGeneration:F.boolean().default(!1),cleanBeforeBuild:F.boolean().default(!0),siteConfig:BI,layouts:F.record(F.any()),themeCSS:F.string().optional()}),q1w=F.object({success:F.boolean(),outputDir:F.string(),filesGenerated:F.number(),routesBuilt:F.number(),errors:F.array(F.string()).optional(),warnings:F.array(F.string()).optional()});function aQ1(A){let Q=A.list(),B=Q.length===0?["No routes registered for site build"]:[];return{routes:Q,warnings:B}}function tQ1(A,Q,B){let w=Q.getProfile(),$=B.getNavigationItems("primary"),f=B.getNavigationItems("secondary");return{...A,...w.socialLinks!==void 0&&{socialLinks:w.socialLinks},navigation:{primary:$,secondary:f},copyright:A.copyright??"Powered by Rizom"}}G6();Bf();G6();GA();var us2=F.object({id:F.string(),entityType:F.string(),content:F.string(),metadata:F.object({slug:F.string()}).passthrough()}).passthrough(),cs2=F.object({content:F.string(),metadata:F.object({width:F.number().optional(),height:F.number().optional()}).passthrough()});async function t1A(A,Q){let B=Q.urlGenerator??I9.getInstance();if(A===null||A===void 0)return A;if(Array.isArray(A))return Promise.all(A.map((_)=>t1A(_,{...Q,urlGenerator:B})));if(typeof A!=="object")return A;let w={},$=Object.entries(A),f=await Promise.all($.map(([,_])=>t1A(_,{...Q,urlGenerator:B})));for(let _=0;_<$.length;_++){let o=$[_];if(o)w[o[0]]=f[_]}let I=us2.safeParse(A);if(!I.success)return w;let D=I.data,H=D.entityType,Y=D.metadata.slug,W=Q.pipelineContext.entityDisplay?.[H],G=W?W.label:H.charAt(0).toUpperCase()+H.slice(1),K=W?W.pluralName??W.label.toLowerCase()+"s":ef(H),Z=`/${K}`,q=K.charAt(0).toUpperCase()+K.slice(1),L=Tv(D),C=L?Q.imageBuildService?.get(L):void 0,R={};if(C)R={coverImageUrl:C.src,coverImageWidth:C.width,coverImageHeight:C.height,...C.srcset&&{coverImageSrcset:C.srcset,coverImageSizes:C.sizes}};else{let _=await ps2(L,Q.pipelineContext.services.entityService);if(_)R={coverImageUrl:_.url,..._.width&&{coverImageWidth:_.width},..._.height&&{coverImageHeight:_.height}}}return{...w,...D,url:B.generateUrl(H,Y),typeLabel:G,listUrl:Z,listLabel:q,...R}}async function ps2(A,Q){if(!A)return;let B=await Q.getEntity({entityType:"image",id:A}),w=cs2.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 eQ1(A,Q){let B=new Set;try{let w=A.getEntityTypes();for(let $ of w){if($==="image")continue;let f=await A.listEntities({entityType:$});for(let I of f){let D=Tv(I);if(D)B.add(D)}}}catch(w){Q.warn("Failed to collect image IDs for pre-resolution",{error:y0(w)})}return[...B]}async function AB1(A,Q,B,w){if(!A.template)return A.content??null;let $=A.template,f=A.dataQuery?{dataParams:A.dataQuery,fallback:A.content,publishedOnly:B}:{savedContent:{entityType:"site-content",entityId:`${Q.id}:${A.id}`},fallback:A.content},I=await w.pipelineContext.services.resolveTemplateContent($,f);if(!I)return null;return t1A(I,{pipelineContext:w.pipelineContext,imageBuildService:w.imageBuildService,urlGenerator:I9.getInstance()})}function QB1(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 AB1(B,Q,w,{pipelineContext:A.pipelineContext,imageBuildService:A.imageBuildService})},getViewTemplate:(Q)=>{return A.pipelineContext.services.getViewTemplate(Q)},layouts:A.parsedOptions.layouts,getSiteLayoutInfo:async()=>{return tQ1(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 ls2}from"path";async function BB1(A){let Q=A.parsedOptions.workingDir??ls2(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 wB1(A){await new s1A({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 $B1(A){let Q=new o1A(A.pipelineContext.services.entityService,A.pipelineContext.logger,A.sharedImagesDir),B=await eQ1(A.pipelineContext.services.entityService,A.pipelineContext.logger);if(B.length>0)await Q.resolveAll(B);return Q}async function fB1(A){let Q=A.reporter?.createSub({scale:{start:85,end:95}});await A.staticSiteBuilder.build(A.buildContext,(B)=>{Q?.report(B).catch(()=>{})})}function IB1(A){return{success:!0,outputDir:A.outputDir,filesGenerated:A.routesBuilt+1,routesBuilt:A.routesBuilt,...A.warnings.length>0&&{warnings:A.warnings}}}function DB1(A){return{success:!1,outputDir:A.outputDir,filesGenerated:0,routesBuilt:0,errors:[A.errorMessage]}}async function HB1(A){let Q=sQ1.parse(A.buildOptions),B=z$.from(A.progress),w=[];try{await B?.report({message:"Starting site build",progress:0,total:100}),await B?.report({message:"Generating dynamic routes",progress:10,total:100}),await wB1({pipelineContext:A.pipelineContext});let $=await BB1({logger:A.pipelineContext.logger,parsedOptions:Q,staticSiteBuilderFactory:A.staticSiteBuilderFactory}),f=aQ1(A.pipelineContext.routeRegistry);w.push(...f.warnings);let{routes:I}=f;await B?.report({message:`Building ${I.length} routes`,progress:20,total:100}),await B?.report({message:"Resolving images",progress:25,total:100});let D=await $B1({pipelineContext:A.pipelineContext,sharedImagesDir:Q.sharedImagesDir}),H=QB1({routes:I,parsedOptions:Q,buildOptions:A.buildOptions,pipelineContext:A.pipelineContext,imageBuildService:D,siteMetadata:Q.siteConfig});return await fB1({staticSiteBuilder:$,buildContext:H,reporter:B}),await B?.report({message:"Site build complete",progress:100,total:100}),IB1({outputDir:Q.outputDir,routesBuilt:I.length,warnings:w})}catch($){let f=Error("Site build process failed");return A.pipelineContext.logger.error("Site build failed",{error:f,originalError:$}),DB1({outputDir:Q.outputDir,errorMessage:f.message})}}class pI{static instance=null;static defaultStaticSiteBuilderFactory=_OA;pipelineContext;staticSiteBuilderFactory;static setDefaultStaticSiteBuilderFactory(A){pI.defaultStaticSiteBuilderFactory=A}static getInstance(A,Q,B,w,$=void 0){return pI.instance??=new pI(A,pI.defaultStaticSiteBuilderFactory,Q,B,w,$),pI.instance}static resetInstance(){pI.instance=null}static createFresh(A,Q,B,w,$,f=void 0){return new pI(A,$??pI.defaultStaticSiteBuilderFactory,Q,B,w,f)}constructor(A,Q,B,w,$,f){this.pipelineContext={logger:A,services:B,routeRegistry:w,profileService:$,entityDisplay:f},this.staticSiteBuilderFactory=Q,I9.getInstance().configure(f)}async build(A,Q){return HB1({buildOptions:A,progress:Q,pipelineContext:this.pipelineContext,staticSiteBuilderFactory:this.staticSiteBuilderFactory})}}GA();class POA{config;context;pluginId;logger;debounces=new Map;unsubscribeFunctions=[];constructor(A,Q,B,w){this.config=A;this.context=Q;this.pluginId=B;this.logger=w}requestBuild(A){let Q=A??(this.config.previewOutputDir?"preview":"production"),B=this.debounces.get(Q);if(!B)B=new UN(()=>{this.enqueueBuild(Q)},this.config.rebuildDebounce),this.debounces.set(Q,B);B.trigger()}setupAutoRebuild(){let A=new Set(["base"]),Q=async(w)=>{let{entityType:$}=w.payload;if(!A.has($))this.logger.debug(`Entity type ${$} will trigger rebuild`),this.requestBuild();return{success:!0}},B=["entity:created","entity:updated","entity:deleted"];for(let w of B)this.unsubscribeFunctions.push(this.context.messaging.subscribe(w,Q));this.logger.debug(`Auto-rebuild enabled (${this.config.rebuildDebounce}ms debounce), excluding types: ${[...A].join(", ")}`)}dispose(){for(let A of this.debounces.values())A.dispose();this.debounces.clear();for(let A of this.unsubscribeFunctions)A();this.unsubscribeFunctions=[]}async enqueueBuild(A){let Q=A==="production"?this.config.productionOutputDir:this.config.previewOutputDir;this.logger.debug(`Triggering ${A} site rebuild`);try{await this.context.jobs.enqueue({type:"site-build",data:{environment:A,outputDir:Q,workingDir:this.config.workingDir,enableContentGeneration:!0,metadata:{trigger:"debounced-rebuild",timestamp:new Date().toISOString()}},options:{priority:0,source:this.pluginId,metadata:{operationType:"content_operations"},deduplication:"skip"}}),this.logger.debug("Site rebuild enqueued")}catch(B){this.logger.error("Failed to enqueue site rebuild",{error:B})}}}G6();function is2(A,Q){return A.map((B)=>({...B,template:B.template.includes(":")?B.template:`${Q}:${B.template}`}))}function e1A(A,Q,B){for(let w of A)B.register({...w,pluginId:Q,sections:w.sections?is2(w.sections,Q):[]})}function YB1(A,Q,B){A.messaging.subscribe("plugin:site-builder:route:register",async(w)=>{try{let $=up.parse(w.payload),{routes:f,pluginId:I}=$;return e1A(f,I,Q),{success:!0}}catch($){return B.error("Failed to register routes",{error:$}),{success:!1,error:"Failed to register routes"}}}),A.messaging.subscribe("plugin:site-builder:route:unregister",async(w)=>{try{let $=cp.parse(w.payload),{paths:f,pluginId:I}=$;if(f)for(let D of f)Q.unregister(D);else if(I)Q.unregisterByPlugin(I);return{success:!0}}catch($){return B.error("Failed to unregister routes",{error:$}),{success:!1,error:"Failed to unregister routes"}}}),A.messaging.subscribe("plugin:site-builder:route:list",async(w)=>{try{let $=pp.parse(w.payload);return{success:!0,data:{routes:Q.list($.pluginId?$:void 0)}}}catch($){return B.error("Failed to list routes",{error:$}),{success:!1,error:"Failed to list routes"}}}),A.messaging.subscribe("plugin:site-builder:route:get",async(w)=>{try{let $=lp.parse(w.payload);return{success:!0,data:{route:Q.get($.path)}}}catch($){return B.error("Failed to get route",{error:$}),{success:!1,error:"Failed to get route"}}}),A.messaging.subscribe("site-builder:routes:list",async()=>{return{success:!0,data:Q.list()}})}import{promises as XB1}from"fs";import{join as WB1}from"path";async function rs2(A,Q,B){let w=A.siteConfig.url??"https://example.com",$=Q.list(),f=OOA(w,A.environment);await XB1.writeFile(WB1(A.outputDir,"robots.txt"),f,"utf-8"),B.info(`Generated robots.txt for ${A.environment} environment`);let I=ROA($,w);await XB1.writeFile(WB1(A.outputDir,"sitemap.xml"),I,"utf-8"),B.info(`Generated sitemap.xml with ${$.length} URLs`)}function UB1(A){let{context:Q,routeRegistry:B,logger:w}=A;Q.messaging.subscribe("site:build:completed",async($)=>{try{let f=$.payload;return w.info(`Received site:build:completed event for ${f.environment} environment - generating SEO files`),await rs2(f,B,w),{success:!0}}catch(f){return w.error("Failed to generate SEO files",f),{success:!1}}})}f0();GA();G6();var JB1=F.object({environment:F.enum(["preview","production"]).optional(),outputDir:F.string(),workingDir:F.string().optional(),enableContentGeneration:F.boolean().optional(),siteConfig:BI.optional()});G6();G6();async function fm(A,Q){try{let B=await A({type:kk,payload:void 0});if("success"in B&&B.success&&B.data){let w=BI.safeParse(B.data);if(w.success)return BI.parse({...Q,...w.data})}}catch{}return Q}class kOA extends ow{sendMessage;cfg;constructor(A,Q,B){super(A,{schema:JB1,jobTypeName:"site-build"});this.sendMessage=Q;this.cfg=B}async process(A,Q,B){let w=A.environment??"preview",$=A.enableContentGeneration??!1;try{this.logger.debug("Starting site build job",{jobId:Q,environment:w,outputDir:A.outputDir}),await B.report({progress:0,total:100,message:`Starting site build for ${w} environment`});let f=B.createSub({scale:{start:10,end:90}}),I=await fm(this.sendMessage,A.siteConfig??this.cfg.defaultSiteConfig),D=await this.cfg.siteBuilder.build({outputDir:A.outputDir,workingDir:A.workingDir,sharedImagesDir:this.cfg.sharedImagesDir,enableContentGeneration:$,environment:w,cleanBeforeBuild:!0,siteConfig:I,layouts:this.cfg.layouts,themeCSS:this.cfg.themeCSS,slots:this.cfg.slots,headScripts:this.cfg.getHeadScripts?.(),...this.cfg.staticAssets&&{staticAssets:this.cfg.staticAssets}},f.toCallback());if(await B.report({progress:100,total:100,message:`Site build completed: ${D.routesBuilt} routes built`}),this.logger.debug("Site build job completed",{jobId:Q,environment:w,routesBuilt:D.routesBuilt,success:D.success}),D.success){this.logger.info(`Emitting site:build:completed event for ${w} environment`);let H=w==="preview"?this.cfg.previewUrl??this.cfg.siteUrl:this.cfg.siteUrl;await this.sendMessage({type:"site:build:completed",payload:{outputDir:A.outputDir,environment:w,routesBuilt:D.routesBuilt,siteConfig:{...I,url:H},generateEntityUrl:(Y,W)=>I9.getInstance().generateUrl(Y,W)},broadcast:!0})}return{success:D.success,routesBuilt:D.routesBuilt,outputDir:A.outputDir,environment:w,...D.errors&&{errors:D.errors},...D.warnings&&{warnings:D.warnings}}}catch(f){throw this.logger.error("Site build job failed",f),f}}summarizeDataForLog(A){return{environment:A.environment,outputDir:A.outputDir}}}GA();G6();var ds2=F.object({slot:F.enum(GN).optional().default("primary"),limit:F.number().optional()});class jOA{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=ds2.parse(A??{});this.logger.debug("NavigationDataSource fetch called",{params:w});let $=this.routeRegistry.getNavigationItems(w.slot),f=w.limit?$.slice(0,w.limit):$,I=f.map((H)=>({label:H.label,href:H.href}));this.logger.debug("NavigationDataSource returning",{slot:w.slot,itemCount:f.length,items:I});let D={navigation:I};return Q.parse(D)}}G6();f0();GA();var ns2=F.object({environment:F.enum(["preview","production"]).optional().describe("Build environment (defaults to production, or preview if configured)")});function GB1(A,Q){return[xQ(A,"build-site","Build a static site from registered routes. Call this for every user build/rebuild request, including repeated requests like 'build it again' or 'one more build'.",ns2,async(B)=>{return Q(B.environment),{success:!0,message:`Site build requested${B.environment?` for ${B.environment}`:""} (debounced)`,data:{}}},{cli:{name:"build"}})]}GA();G6();var FB1=F.object({previewOutputDir:F.string().describe("Output directory for preview builds").default("./dist/site-preview"),productionOutputDir:F.string().describe("Output directory for production builds").default("./dist/site-production"),sharedImagesDir:F.string().describe("Shared directory for optimized images (used by both preview and production)").default("./dist/images"),workingDir:F.string().optional().describe("Working directory for builds").default("./.preact-work"),siteInfo:BI.default({title:"Brain",description:"A knowledge management system"}),themeCSS:F.string().describe("Custom CSS theme overrides to inject into builds").optional(),analyticsScript:F.string().describe("Analytics tracking script to inject into page head (e.g., Cloudflare Web Analytics)").optional(),templates:F.any().optional().describe("Template definitions to register"),routes:F.array(FN).optional().describe("Routes to register"),layouts:F.record(F.any()).optional().describe("Layout components (at least 'default' required)"),autoRebuild:F.boolean().default(!0).describe("Automatically rebuild site when content changes"),rebuildDebounce:F.number().min(100).describe("Debounce time in ms before triggering site rebuild after content changes").default(5000),entityDisplay:F.record(F.object({label:F.string().describe("Display label for entity type (e.g., 'Essay')"),pluralName:F.string().optional().describe("URL path segment (defaults to label.toLowerCase() + 's')"),layout:F.string().optional().describe("Layout name for this entity type's generated routes (defaults to 'default')"),paginate:F.boolean().optional().describe("Enable pagination for list pages"),pageSize:F.number().optional().describe("Items per page (default: 10)"),navigation:F.object({show:F.boolean().optional().describe("Show in navigation"),slot:F.enum(GN).optional().describe("Navigation slot (primary or secondary)"),priority:F.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:F.record(F.string()).optional().describe("Static files to write to the output directory at build time. Keys are output paths (e.g. '/canvases/tree.js'), values are file contents as strings. Typically supplied by a SitePackage via text imports.")});var KB1={name:"@brains/site-builder-plugin",private:!0,version:"0.2.0-alpha.71",description:"Static site generation plugin for Brain system",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint .",clean:"rm -rf dist"},dependencies:{"@brains/image":"workspace:*","@brains/plugins":"workspace:*","@brains/site-composition":"workspace:*","@brains/site-engine":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*","@tailwindcss/typography":"^0.5.19",preact:"^10.27.2","preact-render-to-string":"^6.3.1"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14",eslint:"^8.56.0",typescript:"^5.3.3"}};class vOA extends Ww{siteBuilder;pluginContext;_routeRegistry;_slotRegistry;profileService;layouts;rebuildManager;headScripts=new Map;get routeRegistry(){if(!this._routeRegistry)throw Error("RouteRegistry not initialized - plugin not registered");return this._routeRegistry}constructor(A={}){let Q=A.layouts??{};super("site-builder",KB1,{...A,layouts:Q},FB1);this.layouts=Q}async onRegister(A){if(this.pluginContext=A,this._routeRegistry=new a1A(A.logger),this._slotRegistry=new _1A,A.messaging.subscribe("plugin:site-builder:slot:register",async(B)=>{let{slotName:w,pluginId:$,render:f,priority:I}=B.payload;return this._slotRegistry?.register(w,{pluginId:$,render:f,...I!==void 0&&{priority:I}}),{success:!0}}),A.messaging.subscribe("plugin:site-builder:head-script:register",async(B)=>{let{pluginId:w,script:$}=B.payload;return this.headScripts.set(w,$),{success:!0}}),A.entities.registerDataSource(new jOA(this._routeRegistry,A.logger.child("NavigationDataSource"))),this.profileService=f7.getInstance(A.entityService,A.logger),YB1(A,this._routeRegistry,this.logger),this.config.templates)A.templates.register(this.config.templates);if(this.config.routes)e1A(this.config.routes,this.id,this.routeRegistry);let Q={entityService:A.entityService,sendMessage:A.messaging.send,resolveTemplateContent:(B,w)=>A.templates.resolve(B,w),getViewTemplate:(B)=>A.views.get(B),listViewTemplateNames:()=>A.views.list().map((B)=>B.name)};if(this.siteBuilder=pI.getInstance(A.logger.child("SiteBuilder"),Q,this.routeRegistry,this.profileService,this.config.entityDisplay),A.jobs.registerHandler("site-build",new kOA(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 POA(this.config,A,this.id,this.logger),this.config.autoRebuild)this.logger.debug("Auto-rebuild enabled"),this.rebuildManager.setupAutoRebuild();A.messaging.subscribe(jk,async()=>{let B=await this.getInstructions();if(B)A.registerInstructions(B);return{success:!0}}),UB1({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 GB1(this.id,(Q)=>A.requestBuild(Q))}async getResources(){let A=this.getContext();return[{uri:"brain://site",name:"Site Metadata",description:"Site metadata \u2014 title, description, domain, URLs",mimeType:"application/json",handler:async()=>{let Q=await fm(A.messaging.send,this.config.siteInfo);return{contents:[{uri:"brain://site",mimeType:"application/json",text:JSON.stringify({...Q,domain:A.domain,siteUrl:A.siteUrl,previewUrl:A.previewUrl},null,2)}]}}},{uri:"site://routes",name:"Site Routes",description:"All registered routes with sections and templates",mimeType:"application/json",handler:async()=>{let Q=this.routeRegistry.list();return{contents:[{uri:"site://routes",mimeType:"application/json",text:JSON.stringify(Q.map((B)=>({id:B.id,path:B.path,title:B.title,description:B.description,sections:B.sections.map((w)=>({id:w.id,template:w.template}))})),null,2)}]}}},{uri:"site://templates",name:"View Templates",description:"All registered view templates",mimeType:"application/json",handler:async()=>{let Q=A.views.list();return{contents:[{uri:"site://templates",mimeType:"application/json",text:JSON.stringify(Q.map((B)=>({name:B.name,description:B.description,hasWebRenderer:!!B.renderers.web})),null,2)}]}}}]}getSiteBuilder(){return this.siteBuilder}getSlotRegistry(){return this._slotRegistry}async getInstructions(){let A=this.getContext(),Q="## Site Builder Actions\n- When the user asks to build, rebuild, publish, or build the website/site again, call `site-builder_build-site` immediately.\n- Every repeated build request requires a fresh `site-builder_build-site` call. Do not say a build was started, queued, or requested unless this turn invoked the tool.",B=await fm(A.messaging.send,this.config.siteInfo);return`## Your Site
|
|
3233
3233
|
${[`**Title:** ${B.title}`,`**Description:** ${B.description}`,A.domain&&`**Domain:** ${A.domain}`,A.siteUrl&&`**URL:** ${A.siteUrl}`].filter(Boolean).join(`
|
|
3234
3234
|
`)}
|
|
3235
3235
|
|
|
3236
3236
|
## Site Builder Actions
|
|
3237
3237
|
- When the user asks to build, rebuild, publish, or build the website/site again, call \`site-builder_build-site\` immediately.
|
|
3238
|
-
- Every repeated build request requires a fresh \`site-builder_build-site\` call. Do not say a build was started, queued, or requested unless this turn invoked the tool.`}async onShutdown(){this.logger.debug("Shutting down site-builder plugin"),this.rebuildManager?.dispose(),pI.resetInstance(),this.logger.debug("Cleaned up all event subscriptions")}}function PC(A={}){return new vOA(A)}f0();G6();GA();f0();G6();var ZB1=F.object({}),Im=B2.extend({id:F.literal("site-info"),entityType:F.literal("site-info"),metadata:ZB1}),xOA=rp,eR=BI.omit({url:!0,analyticsScript:!0});f0();class WW extends W2{constructor(){super({entityType:"site-info",schema:Im,frontmatterSchema:eR,isSingleton:!0,hasBody:!1})}createSiteInfoContent(A){let Q=eR.parse(A);return this.buildMarkdown("",Q)}parseSiteInfoBody(A){return this.parseFrontmatter(A)}fromMarkdown(A){return{content:A,entityType:"site-info"}}extractMetadata(A){return{}}generateFrontMatter(A){let Q=this.parseFrontmatter(A.content);return this.buildMarkdown("",Q)}}class UW{static instance=null;logger;entityService;adapter;defaultSiteInfo;static getDefaultSiteInfo(){return{title:"Brain",description:"A knowledge management system"}}static getInstance(A,Q,B){return UW.instance??=new UW(A,Q,B),UW.instance}static resetInstance(){UW.instance=null}static createFresh(A,Q,B){return new UW(A,Q,B)}constructor(A,Q,B){this.entityService=A,this.logger=Q.child("SiteInfoService"),this.adapter=new WW;let w=UW.getDefaultSiteInfo();this.defaultSiteInfo={...w,...B}}async initialize(){try{if(!await this.entityService.getEntity({entityType:"site-info",id:"site-info"})){if(await this.entityService.getEntity({entityType:"site-info",id:"site-info"}))return;this.logger.info("No site info found, creating default site info");let B=this.adapter.createSiteInfoContent(this.defaultSiteInfo);await this.entityService.createEntity({entity:{id:"site-info",entityType:"site-info",content:B,metadata:{}}}),this.logger.info("Default site info created successfully")}}catch(A){this.logger.error("Failed to initialize site info",{error:A})}}async getSiteInfo(){try{let A=await this.entityService.getEntity({entityType:"site-info",id:"site-info"});if(A)return this.adapter.parseSiteInfoBody(A.content)}catch(A){this.logger.debug("Site info not found, using defaults",{error:A})}return this.defaultSiteInfo}}var ss2=new WW;class A2A{logger;id="site-info:entities";name="Site Info DataSource";description="Provides site metadata (title, description, CTA) and profile social links";constructor(A){this.logger=A}async fetch(A,Q,B){let{entityService:w}=B,$;try{let D=await w.getEntity({entityType:"site-info",id:"site-info"});$=D?ss2.parseSiteInfoBody(D.content):{title:"Brain",description:"A knowledge management system"}}catch{$={title:"Brain",description:"A knowledge management system"}}let f;try{let D=await w.getEntity({entityType:"anchor-profile",id:"anchor-profile"});if(D)f=D.metadata.socialLinks}catch{}let I={...$,socialLinks:f,copyright:$.copyright??"Powered by Rizom"};return this.logger.debug("SiteInfoDataSource returning",{title:I.title,hasSocialLinks:!!I.socialLinks}),Q.parse(I)}}var NB1={name:"@brains/site-info",private:!0,version:"0.2.0-alpha.
|
|
3238
|
+
- Every repeated build request requires a fresh \`site-builder_build-site\` call. Do not say a build was started, queued, or requested unless this turn invoked the tool.`}async onShutdown(){this.logger.debug("Shutting down site-builder plugin"),this.rebuildManager?.dispose(),pI.resetInstance(),this.logger.debug("Cleaned up all event subscriptions")}}function PC(A={}){return new vOA(A)}f0();G6();GA();f0();G6();var ZB1=F.object({}),Im=B2.extend({id:F.literal("site-info"),entityType:F.literal("site-info"),metadata:ZB1}),xOA=rp,eR=BI.omit({url:!0,analyticsScript:!0});f0();class WW extends W2{constructor(){super({entityType:"site-info",schema:Im,frontmatterSchema:eR,isSingleton:!0,hasBody:!1})}createSiteInfoContent(A){let Q=eR.parse(A);return this.buildMarkdown("",Q)}parseSiteInfoBody(A){return this.parseFrontmatter(A)}fromMarkdown(A){return{content:A,entityType:"site-info"}}extractMetadata(A){return{}}generateFrontMatter(A){let Q=this.parseFrontmatter(A.content);return this.buildMarkdown("",Q)}}class UW{static instance=null;logger;entityService;adapter;defaultSiteInfo;static getDefaultSiteInfo(){return{title:"Brain",description:"A knowledge management system"}}static getInstance(A,Q,B){return UW.instance??=new UW(A,Q,B),UW.instance}static resetInstance(){UW.instance=null}static createFresh(A,Q,B){return new UW(A,Q,B)}constructor(A,Q,B){this.entityService=A,this.logger=Q.child("SiteInfoService"),this.adapter=new WW;let w=UW.getDefaultSiteInfo();this.defaultSiteInfo={...w,...B}}async initialize(){try{if(!await this.entityService.getEntity({entityType:"site-info",id:"site-info"})){if(await this.entityService.getEntity({entityType:"site-info",id:"site-info"}))return;this.logger.info("No site info found, creating default site info");let B=this.adapter.createSiteInfoContent(this.defaultSiteInfo);await this.entityService.createEntity({entity:{id:"site-info",entityType:"site-info",content:B,metadata:{}}}),this.logger.info("Default site info created successfully")}}catch(A){this.logger.error("Failed to initialize site info",{error:A})}}async getSiteInfo(){try{let A=await this.entityService.getEntity({entityType:"site-info",id:"site-info"});if(A)return this.adapter.parseSiteInfoBody(A.content)}catch(A){this.logger.debug("Site info not found, using defaults",{error:A})}return this.defaultSiteInfo}}var ss2=new WW;class A2A{logger;id="site-info:entities";name="Site Info DataSource";description="Provides site metadata (title, description, CTA) and profile social links";constructor(A){this.logger=A}async fetch(A,Q,B){let{entityService:w}=B,$;try{let D=await w.getEntity({entityType:"site-info",id:"site-info"});$=D?ss2.parseSiteInfoBody(D.content):{title:"Brain",description:"A knowledge management system"}}catch{$={title:"Brain",description:"A knowledge management system"}}let f;try{let D=await w.getEntity({entityType:"anchor-profile",id:"anchor-profile"});if(D)f=D.metadata.socialLinks}catch{}let I={...$,socialLinks:f,copyright:$.copyright??"Powered by Rizom"};return this.logger.debug("SiteInfoDataSource returning",{title:I.title,hasSocialLinks:!!I.socialLinks}),Q.parse(I)}}var NB1={name:"@brains/site-info",private:!0,version:"0.2.0-alpha.71",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 ts2=new WW;class hOA extends KQ{entityType="site-info";schema=Im;adapter=ts2;defaultSiteInfo;constructor(A){super("site-info",NB1);this.defaultSiteInfo=A?.siteInfo??{}}getEntityTypeConfig(){return{embeddable:!1}}getDataSources(){return[new A2A(this.logger.child("SiteInfoDataSource"))]}async onRegister(A){let Q=UW.createFresh(A.entityService,this.logger,this.defaultSiteInfo);A.messaging.subscribe(kk,async()=>{return{success:!0,data:await Q.getSiteInfo()}}),A.messaging.subscribe("entity:updated",async(B)=>{if(B.payload.entityType==="site-info"){let $=await Q.getSiteInfo();await A.messaging.send({type:jk,payload:$,broadcast:!0})}return{success:!0}}),A.messaging.subscribe("sync:initial:completed",async()=>{return await Q.initialize(),{success:!0}})}}function kC(A){return new hOA(A)}var es2=new WW;async function yOA(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 es2.parseSiteInfoBody(B.content)}GA();var Aa2=eR.extend({navigation:F.object({primary:F.array(F.object({label:F.string(),href:F.string(),priority:F.number()})),secondary:F.array(F.object({label:F.string(),href:F.string(),priority:F.number()}))}),copyright:F.string(),socialLinks:F.array(F.object({platform:F.enum(["github","instagram","linkedin","email","website"]).describe("Social media platform"),url:F.string().describe("Profile or contact URL"),label:F.string().optional().describe("Optional display label")})).optional().describe("Social media links from profile entity")});f0();JW();Ym();GA();var gOA=F.object({defaultPrompt:F.string().default("Write a blog post about my recent work and insights"),paginate:F.boolean().default(!0),pageSize:F.number().default(10)});f0();GA();L$();var wa2=F.object({prompt:F.string().optional(),title:F.string().optional(),content:F.string().optional(),excerpt:F.string().optional(),coverImageId:F.string().optional(),seriesName:F.string().optional(),seriesIndex:F.number().optional(),skipAi:F.boolean().optional()}),cQw=AI.extend({title:F.string().optional(),slug:F.string().optional()});class TOA extends X9{constructor(A,Q){super(A,Q,{schema:wa2,jobTypeName:"blog-generation",entityType:"post"})}async generate(A,Q){let{prompt:B,coverImageId:w,seriesName:$,seriesIndex:f,skipAi:I}=A,{title:D,content:H,excerpt:Y}=A;if(I){if(!D)this.failEarly("Title is required when skipAi is true");H=H??`## Introduction
|
|
3239
3239
|
|
|
3240
3240
|
Add your introduction here.
|
|
3241
3241
|
|
|
@@ -3280,7 +3280,7 @@ The excerpt should be clear, concise, and compelling.`});GA();Rw();JW();import{j
|
|
|
3280
3280
|
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=Va2.parse(Q);return A.ai.generate({prompt:`Title: ${B.title}
|
|
3281
3281
|
|
|
3282
3282
|
Content:
|
|
3283
|
-
${B.content}`,templateName:"blog:excerpt"})})}var _B1={name:"@brains/blog",private:!0,version:"0.2.0-alpha.
|
|
3283
|
+
${B.content}`,templateName:"blog:excerpt"})})}var _B1={name:"@brains/blog",private:!0,version:"0.2.0-alpha.71",description:"AI-powered blog post generation from existing brain content",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class pOA extends KQ{entityType=jC.entityType;schema=A_;adapter=jC;constructor(A={}){super("blog",_B1,A,gOA)}getEntityTypeConfig(){return{weight:2}}createGenerationHandler(A){return new TOA(this.logger.child("BlogGenerationJobHandler"),A)}getTemplates(){return EB1()}getDataSources(){return[new mOA(this.logger.child("BlogDataSource"))]}async onRegister(A){let{RSSDataSource:Q}=await Promise.resolve().then(() => (jB1(),kB1));A.entities.registerDataSource(new Q(this.logger.child("RSSDataSource"))),await MB1(A,this.logger),VB1(A,this.logger),OB1(A,this.logger),RB1(A),this.logger.info("Blog plugin registered (routes auto-generated at /posts/)")}}function lOA(A={}){return new pOA(A)}JW();Ym();f0();GA();GA();d5();Lw();var I4=F.object({title:F.string(),slug:F.string(),coverImageId:F.string().optional()}),vB1=I4.pick({title:!0,slug:!0}),B_=B2.extend({metadata:vB1}),w2A=B_.extend({frontmatter:I4}),$2A=w2A.extend({description:F.string().optional(),postCount:F.number(),coverImageUrl:F.string().optional(),coverImageWidth:F.number().optional(),coverImageHeight:F.number().optional()}),xB1=F.object({description:F.string().optional()});function vC(A){return new RB(xB1,{title:A,mappings:[{key:"description",label:"Description",type:"string"}]})}Lw();class iOA extends W2{constructor(){super({entityType:"series",schema:B_,frontmatterSchema:I4,supportsCoverImage:!0,bodyFormatter:vC("")})}toMarkdown(A){let Q,B={};try{Q=this.parseFrontMatter(A.content,I4).coverImageId,B=vC(A.metadata.title).parse(this.extractBody(A.content))}catch{}let w={title:A.metadata.title,slug:A.metadata.slug,...Q&&{coverImageId:Q}},f=vC(A.metadata.title).format(B);return this.buildMarkdown(f,w)}fromMarkdown(A){let Q=this.parseFrontMatter(A,I4);return{content:A,entityType:"series",metadata:{title:Q.title,slug:Q.slug}}}parseBody(A){try{let Q=this.parseFrontMatter(A,I4);return vC(Q.title).parse(this.extractBody(A))}catch{return{}}}generateFrontMatter(){return""}}var w_=new iOA;f0();GA();LD();class rOA{entityService;logger;constructor(A,Q){this.entityService=A;this.logger=Q}async syncAllSeries(){this.logger.debug("Syncing series from all entity types");let A=await this.collectSeriesNames();this.logger.debug(`Found ${A.size} unique series`);let Q=await this.entityService.listEntities({entityType:"series",options:{limit:1000}}),B=new Map(Q.map(($)=>[$.id,$])),w=new Set;for(let $ of A){let f=U2($);w.add(f);let I=B.get(f),D=I?.content??this.createSeriesContent($),H=xB(D);if(I?.contentHash===H)continue;let Y={id:f,entityType:"series",content:D,contentHash:H,created:I?.created??new Date().toISOString(),updated:new Date().toISOString(),metadata:{title:$,slug:U2($)}};await this.entityService.upsertEntity({entity:Y}),this.logger.debug(`Upserted series: ${$}`)}for(let $ of Q)if(!w.has($.id))await this.entityService.deleteEntity({entityType:"series",id:$.id}),this.logger.debug(`Deleted orphaned series: ${$.id}`)}async handleEntityChange(A,Q){let B=this.getSeriesName(A);if(B)await this.ensureSeriesExists(B);if(Q&&Q!==B)await this.cleanupOrphanedSeries(Q)}async handleEntityDeleted(){await this.syncAllSeries()}getSeriesName(A){let B=A.metadata.seriesName;return typeof B==="string"?B:void 0}async ensureSeriesExists(A){let Q=U2(A);if(await this.entityService.getEntity({entityType:"series",id:Q}))return;let w=this.createSeriesContent(A),$={id:Q,entityType:"series",content:w,contentHash:xB(w),created:new Date().toISOString(),updated:new Date().toISOString(),metadata:{title:A,slug:U2(A)}};await this.entityService.upsertEntity({entity:$}),this.logger.debug(`Created series: ${A}`)}async cleanupOrphanedSeries(A){let Q=U2(A);if(!await this.entityService.getEntity({entityType:"series",id:Q}))return;if(!await this.hasSeriesReferences(A))await this.entityService.deleteEntity({entityType:"series",id:Q}),this.logger.debug(`Deleted orphaned series: ${A}`)}async hasSeriesReferences(A){let Q=this.entityService.getEntityTypes();for(let B of Q){if(B==="series")continue;if((await this.entityService.listEntities({entityType:B,options:{filter:{metadata:{seriesName:A}},limit:1}})).length>0)return!0}return!1}async collectSeriesNames(){let A=new Set,Q=this.entityService.getEntityTypes();for(let B of Q){if(B==="series")continue;let w=await this.entityService.listEntities({entityType:B,options:{limit:1000}});for(let $ of w){let f=this.getSeriesName($);if(f)A.add(f)}}return A}createSeriesContent(A){let Q={title:A,slug:U2(A)};return H9("",Q)}}f0();GA();var Ra2=F.object({entityType:F.literal("series"),query:F.object({id:F.string().optional(),limit:F.number().optional(),page:F.number().optional(),pageSize:F.number().optional()}).passthrough()}),_a2=F.object({type:F.enum(["list","detail"]),seriesName:F.string().optional()});function Pa2(A){let Q=_a2.safeParse(A);if(Q.success)return{type:Q.data.type,seriesName:Q.data.seriesName};let B=Ra2.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 hB1(A){let Q=t2(A.content,I4);return w2A.parse({...A,frontmatter:Q.metadata})}class dOA{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=Pa2(A),$=B.entityService;if(w.type==="list")return this.fetchSeriesList(Q,$);if(w.seriesName)return this.fetchSeriesDetail(w.seriesName,Q,$);if(w.seriesSlug)return this.fetchSeriesDetailBySlug(w.seriesSlug,Q,$);throw Error("Invalid series query: must specify seriesName or slug for detail")}async fetchSeriesList(A,Q){let B=await Q.listEntities({entityType:"series",options:{limit:1000}}),w=await this.countEntitiesPerSeries(Q),$=B.map((f)=>{let I=hB1(f),D=w_.parseBody(f.content);return{...I,description:D.description,postCount:w.get(f.metadata.title)??0}});return this.logger.debug(`Found ${$.length} series entities`),A.parse({series:$})}async fetchSeriesDetail(A,Q,B,w){if(!w)w=(await B.listEntities({entityType:"series",options:{filter:{metadata:{title:A}}}}))[0];if(!w)throw Error(`Series not found: ${A}`);let $=hB1(w),f=w_.parseBody(w.content),I=await this.getSeriesMembers(A,B);return this.logger.debug(`Found ${I.length} entities in series "${A}"`),Q.parse({seriesName:A,posts:I,series:{...$,description:f.description,postCount:I.length},description:f.description})}async fetchSeriesDetailBySlug(A,Q,B){let $=(await B.listEntities({entityType:"series",options:{filter:{metadata:{slug:A}}}}))[0];if(!$)return this.logger.warn(`Series not found with slug: ${A}`),Q.parse({seriesName:A,posts:[]});return this.fetchSeriesDetail($.metadata.title,Q,B,$)}async countEntitiesPerSeries(A){let Q=new Map,B=A.getEntityTypes();for(let w of B){if(w==="series")continue;let $=await A.listEntities({entityType:w,options:{limit:1000}});for(let f of $){let I=this.getSeriesName(f);if(I)Q.set(I,(Q.get(I)??0)+1)}}return Q}async getSeriesMembers(A,Q){let B=[],w=Q.getEntityTypes();for(let $ of w){if($==="series")continue;let f=await Q.listEntities({entityType:$,options:{filter:{metadata:{seriesName:A}}}});B.push(...f)}return B.sort(($,f)=>{let I=$.metadata.seriesIndex,D=f.metadata.seriesIndex;return(typeof I==="number"?I:999)-(typeof D==="number"?D:999)}),B}getSeriesName(A){let B=A.metadata.seriesName;return typeof B==="string"?B:void 0}}f0();GA();LD();var ka2=F.object({prompt:F.string().optional(),title:F.string().optional(),seriesId:F.string().optional()});class f2A{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}
|
|
3284
3284
|
|
|
3285
3285
|
Content in this series:
|
|
3286
3286
|
${w.join(`
|
|
@@ -3292,7 +3292,7 @@ Your task is to write a series description (2-3 sentences) that:
|
|
|
3292
3292
|
3. Is engaging and makes readers want to explore the content
|
|
3293
3293
|
4. Works well as a series overview on a website
|
|
3294
3294
|
|
|
3295
|
-
Be concise and focus on what makes this series unique and valuable.`});var cB1={name:"@brains/series",private:!0,version:"0.2.0-alpha.
|
|
3295
|
+
Be concise and focus on what makes this series unique and valuable.`});var cB1={name:"@brains/series",private:!0,version:"0.2.0-alpha.71",description:"Cross-content series \u2014 auto-derived from entities with seriesName metadata",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint src test --ext .ts,.tsx","lint:fix":"eslint src test --ext .ts,.tsx --fix"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/entity-service":"workspace:*","@brains/job-queue":"workspace:*","@brains/plugins":"workspace:*","@brains/templates":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var pB1=F.discriminatedUnion("mode",[F.object({mode:F.literal("derive"),reason:F.string().optional()}),F.object({mode:F.literal("source"),entityId:F.string(),entityType:F.string(),seriesName:F.string()})]);class nOA extends KQ{entityType="series";schema=B_;adapter=w_;manager;constructor(){super("series",cB1)}getEntityTypeConfig(){return{weight:0.5}}createGenerationHandler(A){return new f2A(this.logger.child("SeriesGenerationHandler"),A)}getTemplates(){return{...mB1(),description:uB1}}getDataSources(){return[new dOA(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 rOA(A.entityService,this.logger.child("SeriesManager"))}createSeriesProjectionHandler(A){return{process:async(Q)=>{let B=pB1.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=pB1.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 f2A(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 oOA(){return new nOA}f0();GA();f0();GA();GA();f0();var ya2=F.enum(["draft","queued","published"]),lB1="publishedAt is required when deck status is published",iB1=(A)=>A.status==="published"&&!A.publishedAt,sOA=(A)=>{if(iB1(A))throw Error(lB1)},cZ=F.object({title:F.string(),slug:F.string().optional(),description:F.string().optional(),author:F.string().optional(),status:ya2,publishedAt:F.string().datetime().optional(),event:F.string().optional(),coverImageId:F.string().optional()}),ga2=cZ.pick({title:!0,description:!0,status:!0,publishedAt:!0,coverImageId:!0}).extend({slug:F.string()}).superRefine((A,Q)=>{if(!iB1(A))return;Q.addIssue({code:F.ZodIssueCode.custom,path:["publishedAt"],message:lB1})}),I2A=B2.extend({entityType:F.literal("deck"),metadata:ga2}),D2A=I2A.extend({frontmatter:cZ,body:F.string()}),Jm=D2A.extend({url:F.string().optional(),typeLabel:F.string().optional(),listUrl:F.string().optional(),listLabel:F.string().optional(),coverImageUrl:F.string().optional(),coverImageWidth:F.number().optional(),coverImageHeight:F.number().optional()});class aOA extends W2{constructor(){super({entityType:"deck",schema:I2A,frontmatterSchema:cZ,supportsCoverImage:!0})}validateSlideStructure(A){if(!/^---$/gm.test(A))throw Error("Invalid deck: markdown must contain slide separators (---) to be a valid presentation")}toMarkdown(A){let Q=this.extractBody(A.content);this.validateSlideStructure(Q);let B=this.parseFrontMatter(A.content,cZ);sOA(B);let w={...B,slug:B.slug??A.metadata.slug};return this.buildMarkdown(Q,w)}fromMarkdown(A){let Q=this.parseFrontmatter(A),B=this.extractBody(A);sOA(Q),this.validateSlideStructure(B);let w=Q.slug??U2(Q.title),$=Q.status;return{entityType:"deck",content:A,metadata:{slug:w,title:Q.title,description:Q.description,status:$,publishedAt:Q.publishedAt,coverImageId:Q.coverImageId}}}generateTitle(A){return A.metadata.title}generateSummary(A){if(A.metadata.description)return A.metadata.description;return`Presentation: ${A.metadata.title}`}generateFrontMatter(A){return this.toMarkdown(A)}}var Gm=new aOA;GA();Rw();var Ta2=F.object({markdown:F.string().describe("Markdown content with slide separators (---)")}),tOA=O1({name:"deck-detail",description:"Render a presentation deck as Reveal.js slides",schema:Ta2,dataSourceId:"decks:entities",requiredPermission:"public",layout:{component:GMA,fullscreen:!0}});Rw();GA();var eOA=F.object({decks:F.array(D2A)}),ARA=F.object({decks:F.array(Jm),pageTitle:F.string().optional(),pageLabel:F.string().optional()});import{jsxDEV as QRA}from"preact/jsx-dev-runtime";var Sa2="Presentations",BRA=({decks:A,pageLabel:Q})=>{let B=A.map(($)=>({id:$.id,url:$.url,title:$.frontmatter.title,date:$.frontmatter.publishedAt??$.created,description:$.frontmatter.description}));return QRA("div",{className:"deck-list bg-theme",children:QRA("div",{className:"container mx-auto max-w-[1100px] px-6 py-16 md:px-12 md:py-24",children:QRA(dT,{label:Q&&Q!=="Decks"?Q:Sa2,items:B},void 0,!1,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)};d5();class H2A extends RB{constructor(){super(eOA,{title:"Deck List",mappings:[{key:"decks",label:"Decks",type:"array",itemType:"object"}]})}}var wRA=O1({name:"deck-list",description:"List view of all presentation decks",schema:ARA,dataSourceId:"decks:entities",requiredPermission:"public",formatter:new H2A,layout:{component:BRA}});GA();f0();var ma2=F.object({title:F.string().max(80).describe("A short, punchy title (2-5 words) that's memorable and evocative"),content:F.string().describe("Full slide deck content in markdown format with slide separators (---). Each slide should have a header and focused content."),description:F.string().describe("A concise 1-2 sentence summary that captures the essence of the talk")}),rB1=O1({name:"decks:generation",description:"Template for AI to generate complete slide decks from prompts",schema:ma2,dataSourceId:"shell:ai-content",requiredPermission:"public",useKnowledgeContext:!0,basePrompt:`You are creating slide decks in a distinctive voice that blends philosophy, technology, and culture.
|
|
3296
3296
|
|
|
3297
3297
|
Your task is to generate a complete slide deck based on the user's prompt.
|
|
3298
3298
|
|
|
@@ -3361,7 +3361,7 @@ Add your conclusion here`,H=H??`Presentation: ${I}`,await this.reportProgress(Q,
|
|
|
3361
3361
|
Note: This presentation is for "${$}".`:""}`,R=await this.context.ai.generate({prompt:C,templateName:"decks:generation"});I=I??R.title,D=D??R.content,H=H??R.description,await this.reportProgress(Q,{progress:50,message:`Generated deck: "${I}"`})}else if(!H)await this.reportProgress(Q,{progress:30,message:"Generating description with AI"}),H=(await this.context.ai.generate({prompt:`Title: ${I}
|
|
3362
3362
|
|
|
3363
3363
|
Content:
|
|
3364
|
-
${D}`,templateName:"decks:description"})).description,await this.reportProgress(Q,{progress:50,message:"Description generated"});else await this.reportProgress(Q,{progress:50,message:"Using provided content"});if(!I||!D)this.failEarly("Title and content are required");let W={slug:U2(I),title:I,status:"draft"},G=await VU({entityType:"deck",title:I,deriveId:(q)=>q,regeneratePrompt:"Generate a different presentation deck title on the same topic.",context:this.context});if(G!==I)W.title=G,W.slug=U2(G);let K={title:W.title,status:W.status,slug:W.slug,description:H,author:w,event:$},Z=H9(D,K);return{id:G,content:Z,metadata:W,title:G,resultExtras:{title:G,slug:W.slug},createOptions:{deduplicateId:!0}}}summarizeDataForLog(A){return{prompt:A.prompt,title:A.title}}}var nB1={name:"@brains/decks",private:!0,version:"0.2.0-alpha.
|
|
3364
|
+
${D}`,templateName:"decks:description"})).description,await this.reportProgress(Q,{progress:50,message:"Description generated"});else await this.reportProgress(Q,{progress:50,message:"Using provided content"});if(!I||!D)this.failEarly("Title and content are required");let W={slug:U2(I),title:I,status:"draft"},G=await VU({entityType:"deck",title:I,deriveId:(q)=>q,regeneratePrompt:"Generate a different presentation deck title on the same topic.",context:this.context});if(G!==I)W.title=G,W.slug=U2(G);let K={title:W.title,status:W.status,slug:W.slug,description:H,author:w,event:$},Z=H9(D,K);return{id:G,content:Z,metadata:W,title:G,resultExtras:{title:G,slug:W.slug},createOptions:{deduplicateId:!0}}}summarizeDataForLog(A){return{prompt:A.prompt,title:A.title}}}var nB1={name:"@brains/decks",private:!0,version:"0.2.0-alpha.71",description:"Presentation decks plugin for creating and viewing slide presentations",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/image":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class IRA extends KQ{entityType=Gm.entityType;schema=Gm.schema;adapter=Gm;constructor(){super("decks",nB1)}createGenerationHandler(A){return new fRA(this.logger.child("DeckGenerationJobHandler"),A)}getTemplates(){return{"deck-detail":tOA,"deck-list":wRA,generation:rB1,description:dB1}}getDataSources(){return[new $RA(this.logger)]}getEntityTypeConfig(){return{weight:1.5}}async onRegister(A){await this.registerWithPublishPipeline(A),this.subscribeToPublishExecute(A),this.registerEvalHandlers(A),this.logger.info("Decks plugin registered")}async registerWithPublishPipeline(A){await A.messaging.send({type:"publish:register",payload:{entityType:"deck",provider:{name:"internal",publish:async()=>({id:"internal"})}}})}subscribeToPublishExecute(A){A.messaging.subscribe("publish:execute",async(Q)=>{let{entityType:B,entityId:w}=Q.payload;if(B!=="deck")return{success:!0};try{let $=await A.entityService.getEntity({entityType:"deck",id:w});if(!$)return await A.messaging.send({type:"publish:report:failure",payload:{entityType:B,entityId:w,error:`Deck not found: ${w}`}}),{success:!0};if($.metadata.status==="published")return{success:!0};let f=new Date().toISOString(),I={...$,metadata:{...$.metadata,status:"published",publishedAt:f}};await A.entityService.updateEntity({entity:{...I,content:this.adapter.toMarkdown(I)}}),await A.messaging.send({type:"publish:report:success",payload:{entityType:B,entityId:w,result:{id:w}}})}catch($){await A.messaging.send({type:"publish:report:failure",payload:{entityType:B,entityId:w,error:y0($)}})}return{success:!0}})}registerEvalHandlers(A){A.eval.registerHandler("generateDeck",async(Q)=>{let B=F.object({prompt:F.string(),event:F.string().optional()}).parse(Q);return A.ai.generate({prompt:`${B.prompt}${B.event?`
|
|
3365
3365
|
|
|
3366
3366
|
Note: This presentation is for "${B.event}".`:""}`,templateName:"decks:generation"})}),A.eval.registerHandler("generateDescription",async(Q)=>{let B=F.object({title:F.string(),content:F.string()}).parse(Q);return A.ai.generate({prompt:`Title: ${B.title}
|
|
3367
3367
|
|
|
@@ -3376,7 +3376,7 @@ Guidelines:
|
|
|
3376
3376
|
3. Depth: Provide enough detail to be useful as a reference, but stay focused on the topic.
|
|
3377
3377
|
4. Style: Informative and educational. Write as if explaining to yourself for future reference.
|
|
3378
3378
|
5. Length: Adjust based on topic complexity - concise for simple topics, more detailed for complex ones.
|
|
3379
|
-
6. No meta-commentary: Just provide the content directly without phrases like "Here is..." or "This note covers..."`});f0();GA();L$();var aB1=F.object({prompt:F.string(),title:F.string().optional()}),ia2=AI.extend({title:F.string().optional()});class Y2A extends X9{constructor(A,Q){super(A,Q,{schema:aB1,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:f_.createNoteContent(w,B.body),metadata:{title:w},title:w,resultExtras:{title:w}}}summarizeDataForLog(A){return{prompt:A.prompt,title:A.title}}}var tB1={name:"@brains/note",private:!0,version:"0.2.0-alpha.
|
|
3379
|
+
6. No meta-commentary: Just provide the content directly without phrases like "Here is..." or "This note covers..."`});f0();GA();L$();var aB1=F.object({prompt:F.string(),title:F.string().optional()}),ia2=AI.extend({title:F.string().optional()});class Y2A extends X9{constructor(A,Q){super(A,Q,{schema:aB1,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:f_.createNoteContent(w,B.body),metadata:{title:w},title:w,resultExtras:{title:w}}}summarizeDataForLog(A){return{prompt:A.prompt,title:A.title}}}var tB1={name:"@brains/note",private:!0,version:"0.2.0-alpha.71",description:"Personal knowledge capture with markdown-first workflow",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class XRA extends KQ{entityType=f_.entityType;schema=$_;adapter=f_;constructor(A={}){super("note",tB1,A,HRA)}createGenerationHandler(A){return new Y2A(this.logger.child("NoteGenerationJobHandler"),A)}getTemplates(){return{generation:YRA}}async onRegister(A){A.eval.registerHandler("generateNote",async(Q)=>{let B=F.object({prompt:F.string()}).parse(Q);return A.ai.generate({prompt:B.prompt,templateName:"note:generation"})})}}function xC(A={}){return new XRA(A)}f0();GA();GA();f0();var eB1=F.object({ref:F.string(),label:F.string()}),Aw1=F.enum(["pending","draft","published"]),IG=F.object({status:Aw1,title:F.string(),url:F.string().url(),description:F.string().optional(),domain:F.string(),capturedAt:F.string().datetime(),source:eB1}),Qw1=IG.pick({title:!0,status:!0}),Zm=B2.extend({entityType:F.literal("link"),metadata:Qw1}),WRA=F.object({enableSummarization:F.boolean().default(!0).describe("Generate AI summaries for captured links"),jinaApiKey:F.string().optional().describe("Jina Reader API key for higher rate limits (500 RPM vs 20 RPM without key)")});f0();class lZ extends W2{constructor(){super({entityType:"link",schema:Zm,frontmatterSchema:IG})}createLinkContent(A){let Q={status:A.status,title:A.title,url:A.url,description:A.description,domain:A.domain,capturedAt:A.capturedAt,source:A.source},B=A.summary??"";return this.buildMarkdown(B,Q)}parseLinkContent(A){return{frontmatter:this.parseFrontMatter(A,IG),summary:this.extractBody(A).trim()}}fromMarkdown(A){let{frontmatter:Q}=this.parseLinkContent(A);return{content:A,entityType:"link",metadata:{title:Q.title,status:Q.status}}}}var URA=new lZ;f0();GA();var da2=F.object({success:F.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:F.string().describe("If success is false, explain why content could not be extracted. Use an empty string when success is true."),title:F.string().max(80).describe("The page title - extract from the content or create a descriptive one. Leave empty string if success is false."),description:F.string().describe("A one-sentence description of what the page is about. Leave empty string if success is false."),summary:F.string().describe("A 1-2 paragraph summary of the main content. Leave empty string if success is false.")}),Bw1=O1({name:"link:extraction",description:"Extract structured content from webpage markdown",dataSourceId:"shell:ai-content",schema:da2,basePrompt:`You are an expert at extracting key information from webpage content.
|
|
3380
3380
|
|
|
3381
3381
|
You will receive webpage content in markdown format. Your job is to extract structured information from it.
|
|
3382
3382
|
|
|
@@ -3398,7 +3398,7 @@ Accuracy rules:
|
|
|
3398
3398
|
|
|
3399
3399
|
`))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 aa2}from"crypto";class hC{static URL_PATTERN=/https?:\/\/[^\s<>"{}|\\^`[\]]+?(?=[,;:\s]|$)/gi;static extractUrls(A){let Q=A.match(hC.URL_PATTERN)??[];return[...new Set(Q)]}static normalizeUrl(A){try{let Q=new URL(A),B=Q.pathname.replace(/\/$/,"")||"/";return`${Q.protocol}//${Q.host}${B}`}catch{return A}}static generateEntityId(A){let Q=this.normalizeUrl(A),B=aa2("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}}}f0();GA();L$();var ta2=F.object({url:F.string().url(),metadata:F.object({interfaceId:F.string().optional(),userId:F.string().optional(),channelId:F.string().optional(),channelName:F.string().optional(),timestamp:F.string().optional()}).optional()}),e5w=F.object({success:F.boolean(),entityId:F.string().optional(),title:F.string().optional(),url:F.string().optional(),status:F.enum(["pending","draft","published"]).optional(),error:F.string().optional()});class W2A extends ow{context;linkAdapter;urlFetcher;constructor(A,Q,B){super(A,{schema:ta2,jobTypeName:"link-capture"});this.context=Q,this.linkAdapter=new lZ,this.urlFetcher=new I_(B?.jinaApiKey?{jinaApiKey:B.jinaApiKey}:void 0)}async process(A,Q,B){let{url:w,metadata:$}=A;try{await B.report({progress:vQ.START,total:100,message:"Starting link capture"});let f=hC.generateEntityId(w);await B.report({progress:vQ.INIT,total:100,message:"Checking for existing link"});let I=await this.context.entityService.getEntity({entityType:"link",id:f});if(I){this.logger.info("Link already captured, returning existing",{url:w,entityId:f});let{frontmatter:Z}=this.linkAdapter.parseLinkContent(I.content);return{success:!0,entityId:I.id,title:Z.title,url:w,status:I.metadata.status}}await B.report({progress:vQ.FETCH,total:100,message:"Fetching webpage content"});let D=await this.urlFetcher.fetch(w);if(!D.success){if(D.errorType==="url_not_found"||D.errorType==="url_unreachable")return this.logger.warn("Link URL not accessible",{url:w,errorType:D.errorType,error:D.error}),{success:!1,error:`Could not capture link: ${D.error}`}}await B.report({progress:vQ.PROCESS,total:100,message:"Extracting content with AI"});let H=await this.context.ai.generate({templateName:"link:extraction",prompt:D.success?`Extract structured information from this webpage content:
|
|
3400
3400
|
|
|
3401
|
-
${D.content}`:`The URL ${w} could not be fetched. Return success: false with error: "${D.error}"`,data:{url:w,hasContent:D.success},interfacePermissionGrant:"public"});this.logger.debug("AI extraction result",{result:H}),await B.report({progress:vQ.EXTRACT,total:100,message:"Processing extraction results"});let Y=this.resolveSource($),W=new Date().toISOString();if(H.success===!1||!H.title||!H.description||!H.summary){let Z=H.title||new URL(w).hostname;this.logger.info("Incomplete extraction, saving as pending",{url:w}),await B.report({progress:vQ.SAVE,total:100,message:"Saving link as pending"});let q=this.linkAdapter.createLinkContent({status:"pending",title:Z,url:w,description:H.description,summary:H.summary,domain:new URL(w).hostname,capturedAt:W,source:Y}),L=await this.context.entityService.createEntity({entity:{id:f,entityType:"link",content:q,metadata:{status:"pending",title:Z}}});return await B.report({progress:vQ.COMPLETE,total:100,message:"Link saved (pending)"}),{success:!0,entityId:L.entityId,title:Z,url:w,status:"pending"}}await B.report({progress:vQ.SAVE,total:100,message:`Saving link: "${H.title}"`});let G=this.linkAdapter.createLinkContent({status:"draft",title:H.title,url:w,description:H.description,summary:H.summary,domain:new URL(w).hostname,capturedAt:W,source:Y}),K=await this.context.entityService.createEntity({entity:{id:f,entityType:"link",content:G,metadata:{status:"draft",title:H.title}}});return await B.report({progress:vQ.COMPLETE,total:100,message:`Link captured: "${H.title}"`}),{success:!0,entityId:K.entityId,title:H.title,url:w,status:"draft"}}catch(f){return this.logger.error("Link capture job failed",{error:f,jobId:Q,data:A}),C$.failure(f)}}resolveSource(A){let Q=A?.channelId,B=A?.channelName;if(Q)return{ref:`matrix:${Q}`,label:B??Q};let w=A?.interfaceId??"cli";return{ref:`${w}:local`,label:w.toUpperCase()}}summarizeDataForLog(A){return{url:A.url,interfaceId:A.metadata?.interfaceId}}}var fw1={name:"@brains/link",private:!0,version:"0.2.0-alpha.
|
|
3401
|
+
${D.content}`:`The URL ${w} could not be fetched. Return success: false with error: "${D.error}"`,data:{url:w,hasContent:D.success},interfacePermissionGrant:"public"});this.logger.debug("AI extraction result",{result:H}),await B.report({progress:vQ.EXTRACT,total:100,message:"Processing extraction results"});let Y=this.resolveSource($),W=new Date().toISOString();if(H.success===!1||!H.title||!H.description||!H.summary){let Z=H.title||new URL(w).hostname;this.logger.info("Incomplete extraction, saving as pending",{url:w}),await B.report({progress:vQ.SAVE,total:100,message:"Saving link as pending"});let q=this.linkAdapter.createLinkContent({status:"pending",title:Z,url:w,description:H.description,summary:H.summary,domain:new URL(w).hostname,capturedAt:W,source:Y}),L=await this.context.entityService.createEntity({entity:{id:f,entityType:"link",content:q,metadata:{status:"pending",title:Z}}});return await B.report({progress:vQ.COMPLETE,total:100,message:"Link saved (pending)"}),{success:!0,entityId:L.entityId,title:Z,url:w,status:"pending"}}await B.report({progress:vQ.SAVE,total:100,message:`Saving link: "${H.title}"`});let G=this.linkAdapter.createLinkContent({status:"draft",title:H.title,url:w,description:H.description,summary:H.summary,domain:new URL(w).hostname,capturedAt:W,source:Y}),K=await this.context.entityService.createEntity({entity:{id:f,entityType:"link",content:G,metadata:{status:"draft",title:H.title}}});return await B.report({progress:vQ.COMPLETE,total:100,message:`Link captured: "${H.title}"`}),{success:!0,entityId:K.entityId,title:H.title,url:w,status:"draft"}}catch(f){return this.logger.error("Link capture job failed",{error:f,jobId:Q,data:A}),C$.failure(f)}}resolveSource(A){let Q=A?.channelId,B=A?.channelName;if(Q)return{ref:`matrix:${Q}`,label:B??Q};let w=A?.interfaceId??"cli";return{ref:`${w}:local`,label:w.toUpperCase()}}summarizeDataForLog(A){return{url:A.url,interfaceId:A.metadata?.interfaceId}}}var fw1={name:"@brains/link",private:!0,version:"0.2.0-alpha.71",description:"Web content capture plugin with AI-powered extraction and structured storage",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class NRA extends KQ{entityType=URA.entityType;schema=Zm;adapter=URA;shell;constructor(A={}){super("link",fw1,A,WRA)}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 W2A(this.logger.child("LinkCaptureJobHandler"),this.context,this.config.jinaApiKey?{jinaApiKey:this.config.jinaApiKey}:void 0),this.id),Q}async interceptCreate(A,Q,B){if(A.content)try{let f=this.adapter.fromMarkdown(A.content).metadata,I=typeof f?.title==="string"?f.title:void 0,D=typeof f?.status==="string"?f.status:void 0,H=this.extractFirstUrl(A.content);if(I&&D&&H){let Y=U2(H)||U2(I)||`${A.entityType}-${Date.now()}`,W=new Date().toISOString();return{kind:"handled",result:{success:!0,data:{entityId:(await B.entityService.createEntity({entity:{id:Y,entityType:A.entityType,content:A.content,metadata:{title:I,status:D},created:W,updated:W}})).entityId,status:"created"}}}}}catch{}let w=A.url??this.extractFirstUrl(A.content,A.prompt,A.title);if(w){if(!this.shell)throw Error("LinkPlugin shell was not initialized during register()");try{return{kind:"handled",result:{success:!0,data:{status:"generating",jobId:await this.shell.getJobQueueService().enqueue({type:"link-capture",data:{url:w,metadata:{interfaceId:Q.interfaceType,userId:Q.userId,...Q.channelId?{channelId:Q.channelId}:{},...Q.channelName?{channelName:Q.channelName}:{},timestamp:new Date().toISOString()}},options:{source:this.id,metadata:{operationType:"data_processing",pluginId:this.id,interfaceType:Q.interfaceType,...Q.channelId?{channelId:Q.channelId}:{}}}})}}}}catch($){return{kind:"handled",result:{success:!1,error:$ instanceof Error?$.message:"Failed to queue link capture job"}}}}if(A.content)return{kind:"handled",result:{success:!1,error:"Direct link creation requires full link markdown/frontmatter, or provide a URL to capture."}};if(A.prompt)return{kind:"handled",result:{success:!1,error:"Link creation requires a URL in the prompt, content, or title, or full link markdown content for direct creation."}};return{kind:"continue",input:A}}createGenerationHandler(A){return new W2A(this.logger.child("LinkCaptureJobHandler"),A,this.config.jinaApiKey?{jinaApiKey:this.config.jinaApiKey}:void 0)}getTemplates(){return{extraction:Bw1,"link-list":ww1,"link-detail":$w1}}getDataSources(){return[new ZRA(this.logger.child("LinksDataSource"))]}async onRegister(A){A.eval.registerHandler("extractContent",async(Q)=>{let{url:B}=F.object({url:F.string().url()}).parse(Q),$=await new I_(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:
|
|
3402
3402
|
|
|
3403
3403
|
${$.content}`,data:{url:B,hasContent:!0},interfacePermissionGrant:"public"})})}extractFirstUrl(...A){for(let Q of A){if(!Q)continue;let[B]=hC.extractUrls(Q);if(B)return B}return}}function Iw1(A={}){return new NRA(A)}var yC=Iw1;GA();var z$w=F.object({id:F.string().optional(),metadata:F.object({conversationId:F.string().optional(),interfaceId:F.string().optional(),userId:F.string().optional(),messageId:F.string().optional(),timestamp:F.string().optional()}).optional()});f0();GA();Rw();GA();f0();var Dw1=F.enum(["draft","published"]),D4=F.object({title:F.string(),slug:F.string().optional(),status:Dw1,publishedAt:F.string().datetime().optional(),description:F.string(),year:F.number(),coverImageId:F.string().optional(),url:F.string().url().optional()}),Hw1=D4.pick({title:!0,status:!0,publishedAt:!0,year:!0}).extend({slug:F.string()}),D_=B2.extend({entityType:F.literal("project"),metadata:Hw1}),U2A=F.object({context:F.string(),problem:F.string(),solution:F.string(),outcome:F.string()}),zm=D_.extend({frontmatter:D4,body:F.string(),structuredContent:U2A.optional(),coverImageUrl:F.string().optional()}),H_=zm.extend({url:F.string().optional(),typeLabel:F.string().optional(),coverImageUrl:F.string().optional(),coverImageWidth:F.number().optional(),coverImageHeight:F.number().optional()}),At2=zm.extend({url:F.string(),typeLabel:F.string(),coverImageUrl:F.string().optional(),coverImageWidth:F.number().optional(),coverImageHeight:F.number().optional()});f0();GA();d5();class zRA extends RB{constructor(){super(U2A,{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 qRA=new zRA;class CRA extends W2{constructor(){super({entityType:"project",schema:D_,frontmatterSchema:D4,supportsCoverImage:!0,bodyFormatter:qRA})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,D4),w={...B,slug:B.slug??A.metadata.slug};return this.buildMarkdown(Q,w)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,D4),B=Q.slug??U2(Q.title);return{content:A,entityType:"project",metadata:{title:Q.title,slug:B,status:Q.status,publishedAt:Q.publishedAt,year:Q.year}}}parseProjectFrontmatter(A){return this.parseFrontMatter(A.content,D4)}parseStructuredContent(A){return qRA.parse(this.extractBody(A.content))}createProjectContent(A,Q){let B=qRA.format(Q);return this.buildMarkdown(B,A)}}var iZ=new CRA;GA();var LRA=F.object({});import{jsxDEV as iI,Fragment as Bt2}from"preact/jsx-dev-runtime";var Qt2=({project:A})=>{let{frontmatter:Q,url:B,coverImageUrl:w}=A;return iI(UB,{href:B,children:[w&&iI("img",{src:w,alt:Q.title,className:"w-full h-56 object-cover rounded-md mb-4"},void 0,!1,void 0,this),iI(f$,{children:Q.title},void 0,!1,void 0,this),iI("p",{className:"text-theme leading-relaxed",children:Q.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},ERA=({projects:A,pageTitle:Q,pagination:B,baseUrl:w="/projects"})=>{let $=Q??"Projects",f=B?.totalItems??A.length,I=`Browse all ${f} ${f===1?"project":"projects"}`;return iI(Bt2,{children:[iI(XQ,{title:$,description:I},void 0,!1,void 0,this),iI("div",{className:"project-list bg-theme",children:iI("div",{className:"container mx-auto px-6 md:px-12 max-w-5xl py-16 md:py-24",children:[iI("h1",{className:"text-4xl font-bold text-heading mb-12",children:$},void 0,!1,void 0,this),iI("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-8",children:A.map((D)=>iI(Qt2,{project:D},D.id,!1,void 0,this))},void 0,!1,void 0,this),B&&B.totalPages>1&&iI("div",{className:"mt-12",children:iI(cJ,{currentPage:B.currentPage,totalPages:B.totalPages,baseUrl:w},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as uB,Fragment as Yw1}from"preact/jsx-dev-runtime";var wt2=({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(UB,{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(UB,{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)},J2A=({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(mI,{markdown:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},MRA=({project:A,prevProject:Q,nextProject:B})=>{let{frontmatter:w,structuredContent:$,metadata:f,coverImageUrl:I}=A;return uB(Yw1,{children:[uB(XQ,{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(mJ,{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:f.year},void 0,!1,void 0,this),w.url&&uB(Yw1,{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(J2A,{title:"Context",content:$.context},void 0,!1,void 0,this),uB(J2A,{title:"Problem",content:$.problem},void 0,!1,void 0,this),uB(J2A,{title:"Solution",content:$.solution},void 0,!1,void 0,this),uB(J2A,{title:"Outcome",content:$.outcome},void 0,!1,void 0,this)]},void 0,!0,void 0,this),uB(wt2,{prevProject:Q,nextProject:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};GA();f0();var $t2=F.object({title:F.string().max(80).describe("A clear, compelling project title (3-8 words). Should capture the essence of the project."),description:F.string().describe("A 1-2 sentence summary of the project for portfolio cards. Focus on the core value delivered."),context:F.string().describe("Background information: Who was the client/user? What was the situation? What constraints existed? (2-4 paragraphs)"),problem:F.string().describe("The challenge: What specific problem needed solving? What were the pain points? (2-3 paragraphs)"),solution:F.string().describe("The approach: What was built? What technologies/methods were used? How did it work? (3-5 paragraphs)"),outcome:F.string().describe("The results: What impact did this have? What metrics improved? What was learned? (2-3 paragraphs)")}),VRA=O1({name:"portfolio:generation",description:"Template for AI to generate portfolio project case studies",schema:$t2,dataSourceId:"shell:ai-content",requiredPermission:"public",useKnowledgeContext:!0,basePrompt:`You are helping to create a professional portfolio case study based on REAL project information.
|
|
3404
3404
|
|
|
@@ -3422,7 +3422,7 @@ ${A.prompt}
|
|
|
3422
3422
|
|
|
3423
3423
|
Project year: ${A.year}
|
|
3424
3424
|
|
|
3425
|
-
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 G2A extends X9{constructor(A,Q){super(A,Q,{schema:ft2,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:bRA(A),templateName:"portfolio:generation"}),$=A.title??w.title,f=U2($);await this.reportProgress(Q,{progress:50,message:`Generated project: "${$}"`});let I={title:$,slug:f,status:"draft",description:w.description,year:B},D={context:w.context,problem:w.problem,solution:w.solution,outcome:w.outcome};return{id:f,content:iZ.createProjectContent(I,D),metadata:{title:$,slug:f,status:"draft",year:B},title:$,resultExtras:{title:$}}}summarizeDataForLog(A){return{prompt:A.prompt.substring(0,100),year:A.year,title:A.title}}}f0();f0();function It2(A){let Q=t2(A.content,D4),B=iZ.parseStructuredContent(A);return zm.parse({...A,frontmatter:Q.metadata,body:Q.content,structuredContent:B})}class F2A extends r6{id="portfolio:entities";name="Portfolio Project DataSource";description="Fetches and transforms project entities for rendering";config={entityType:"project",defaultSort:[{field:"year",direction:"desc"},{field:"title",direction:"asc"}],defaultLimit:10,enableNavigation:!0};constructor(A){super(A);this.logger.debug("ProjectDataSource initialized")}transformEntity(A){return It2(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 Xw1={name:"@brains/portfolio",private:!0,version:"0.2.0-alpha.
|
|
3425
|
+
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 G2A extends X9{constructor(A,Q){super(A,Q,{schema:ft2,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:bRA(A),templateName:"portfolio:generation"}),$=A.title??w.title,f=U2($);await this.reportProgress(Q,{progress:50,message:`Generated project: "${$}"`});let I={title:$,slug:f,status:"draft",description:w.description,year:B},D={context:w.context,problem:w.problem,solution:w.solution,outcome:w.outcome};return{id:f,content:iZ.createProjectContent(I,D),metadata:{title:$,slug:f,status:"draft",year:B},title:$,resultExtras:{title:$}}}summarizeDataForLog(A){return{prompt:A.prompt.substring(0,100),year:A.year,title:A.title}}}f0();f0();function It2(A){let Q=t2(A.content,D4),B=iZ.parseStructuredContent(A);return zm.parse({...A,frontmatter:Q.metadata,body:Q.content,structuredContent:B})}class F2A extends r6{id="portfolio:entities";name="Portfolio Project DataSource";description="Fetches and transforms project entities for rendering";config={entityType:"project",defaultSort:[{field:"year",direction:"desc"},{field:"title",direction:"asc"}],defaultLimit:10,enableNavigation:!0};constructor(A){super(A);this.logger.debug("ProjectDataSource initialized")}transformEntity(A){return It2(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 Xw1={name:"@brains/portfolio",private:!0,version:"0.2.0-alpha.71",description:"Portfolio showcase for projects and case studies",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/templates":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest",typescript:"^5.3.3"}};var Ht2=F.object({projects:F.array(H_),pageTitle:F.string().optional(),pagination:Y9.nullable(),baseUrl:F.string().optional()});function Yt2(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 ORA extends KQ{entityType=iZ.entityType;schema=D_;adapter=iZ;constructor(A={}){super("portfolio",Xw1,A,LRA)}async interceptCreate(A,Q,B){if(!A.prompt||A.content)return{kind:"continue",input:A};let w=Yt2(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 G2A(this.logger.child("ProjectGenerationJobHandler"),A)}getTemplates(){return{"project-list":O1({name:"project-list",description:"Portfolio project list page template",schema:Ht2,dataSourceId:"portfolio:entities",requiredPermission:"public",layout:{component:ERA}}),"project-detail":O1({name:"project-detail",description:"Individual project case study template",schema:F.object({project:H_,prevProject:H_.nullable(),nextProject:H_.nullable()}),dataSourceId:"portfolio:entities",requiredPermission:"public",layout:{component:MRA}}),generation:VRA}}getDataSources(){return[new F2A(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=F.object({prompt:F.string(),year:F.number()}).parse(Q);return A.ai.generate({prompt:bRA(B),templateName:"portfolio:generation"})})}async registerWithPublishPipeline(A){let Q={name:"internal",publish:async()=>({id:"internal"})};await A.messaging.send({type:"publish:register",payload:{entityType:"project",provider:Q}})}subscribeToPublishExecute(A){A.messaging.subscribe("publish:execute",async(Q)=>{let{entityType:B,entityId:w}=Q.payload;if(B!=="project")return{success:!0};try{let $=await A.entityService.getEntity({entityType:"project",id:w});if(!$)return await A.messaging.send({type:"publish:report:failure",payload:{entityType:B,entityId:w,error:`Project not found: ${w}`}}),{success:!0};if($.metadata.status==="published")return{success:!0};let f=t2($.content,D4),I=new Date().toISOString(),D=H9(f.content,{...f.metadata,status:"published",publishedAt:I});await A.entityService.updateEntity({entity:{...$,content:D,metadata:{...$.metadata,status:"published",publishedAt:I}}}),await A.messaging.send({type:"publish:report:success",payload:{entityType:B,entityId:w,publishedAt:I}})}catch($){await A.messaging.send({type:"publish:report:failure",payload:{entityType:B,entityId:w,error:y0($)}})}return{success:!0}})}}function RRA(A={}){return new ORA(A)}f0();GA();var Ww1=F.object({includeEntityTypes:F.array(F.string()).default([]),minRelevanceScore:F.number().min(0).max(1).default(0.5),mergeSimilarityThreshold:F.number().min(0).max(1).default(0.85),autoMerge:F.boolean().default(!0),extractableStatuses:F.array(F.string()).default(["published"]),enableAutoExtraction:F.boolean().default(!0),sourceChangeBatchDelayMs:F.number().int().min(0).default(1000)});f0();GA();f0();var Xt2=F.object({}),K2A=B2.extend({entityType:F.literal("topic"),metadata:Xt2}),x9w=F.object({content:F.string()}),Uw1=F.object({title:F.string().describe("Topic title")});var gC="topics",cB="topic",_RA="topics-projection",Jw1="topic:project",Z2A="topics-plugin",Gw1="topics:batch-completed",Fw1="topics-source-batch";class DG extends W2{constructor(){super({entityType:cB,schema:K2A,frontmatterSchema:Uw1})}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:cB}}extractMetadata(A){return{}}generateFrontMatter(A){let Q=this.parseTopicBody(A.content),w=this.buildMarkdown("",this.buildFrontmatter(Q.title)).match(/^---\n[\s\S]*?\n---/);return w?w[0]:""}parseTopicBody(A){if(A.startsWith("---"))try{let Q=this.parseFrontmatter(A);return{content:this.extractBody(A).replace(/\n*## Sources[\s\S]*$/,"").trim(),formatted:A,title:Q.title}}catch{return{content:A,formatted:A,title:"Unknown Topic"}}return{content:A,formatted:A,title:"Unknown Topic"}}createTopicBody(A){return this.buildMarkdown(A.content,this.buildFrontmatter(A.title))}}f0();GA();GA();var Wt2=F.object({title:F.string().max(100),content:F.string(),relevanceScore:F.number().min(0).max(1)}),Kw1=F.array(Wt2);var Ut2=F.object({topics:Kw1}),Zw1=O1({name:"topics:extraction",description:"Extract topics from conversation text",dataSourceId:"shell:ai-content",schema:Ut2,basePrompt:`You are an expert at analyzing content and extracting key topics.
|
|
3426
3426
|
|
|
3427
3427
|
Analyze the provided content and extract meaningful topics discussed.
|
|
3428
3428
|
|
|
@@ -3525,13 +3525,13 @@ ${A.incomingTopic.content}`})}}function Et2(A){if(A.length===0)return"";return A
|
|
|
3525
3525
|
|
|
3526
3526
|
${Q.content}`}).join(`
|
|
3527
3527
|
|
|
3528
|
-
`)}async function TC(A,Q,B,w={}){if(A.length===0)return{created:0,merged:0,skipped:0,batches:0};let $=w.minRelevanceScore??0,f=w.autoMerge??!1,I=w.mergeSimilarityThreshold??0.85,D=Rw1(A),H=new $Y(Q.entityService,B),Y=w.topicMergeSynthesizer??new hRA(Q,B),W=await L2A(Q.entityService),G=new Map,K=0,Z=0,q=0;for(let C of D){B.info(`Processing batch of ${C.length} entities`);let R=Et2(C),k=E2A({entityTitle:`Batch of ${C.length} entities`,entityType:"batch",content:R,existingTopicTitles:W});try{let o=(await Q.ai.generate({prompt:k,templateName:"topics:extraction"})).topics.filter((r)=>r.relevanceScore>=$);for(let r of o)try{if(f){let y=await H.findMergeCandidate({incoming:r,threshold:I,additionalCandidates:Array.from(G.values())});if(y){let g=await Y.synthesize({existingTopic:y.topic,incomingTopic:r}),AA=await H.applySynthesizedMerge({existingId:y.topic.id,synthesized:{...g,title:y.title}});if(!AA)throw Error(`Failed to merge topic: ${r.title}`);G.set(AA.id,AA),Z++;continue}}let S=SY(r.title);if(G.has(S)){q++;continue}let x=await H.createTopicOptimistic({title:r.title,content:r.content});if(x.topic)G.set(x.topic.id,x.topic);if(x.created)K++;else q++}catch(S){B.error("Topic batch item failed",{title:r.title,error:y0(S)})}}catch(_){B.error("Batch topic extraction failed",{batchSize:C.length,promptChars:k.length,error:y0(_)})}}let L={created:K,merged:Z,skipped:q,batches:D.length};if(K>0||Z>0)await Q.messaging.send({type:Gw1,payload:L,broadcast:!0});return L}GA();var Mt2=F.discriminatedUnion("mode",[F.object({mode:F.literal("derive"),reason:F.string().optional()}),F.object({mode:F.literal("rebuild"),reason:F.string().optional()}),F.object({mode:F.literal("source-batch"),minRelevanceScore:F.number().min(0).max(1).optional()})]);class yRA{refs=new Map;add(A){this.refs.set(`${A.entityType}:${A.entityId}`,A)}drain(){let A=Array.from(this.refs.values());return this.refs.clear(),A}}function xw1(A){let{context:Q,logger:B,config:w}=A;return{process:async($)=>{if($.mode==="derive")return await A.extractAllTopics(),{success:!0};if($.mode==="rebuild")return await A.rebuildAllTopics(),{success:!0};return Vt2({context:Q,logger:B,config:w,sourceBatch:A.sourceBatch,isEntityPublished:A.isEntityPublished,minRelevanceScore:$.minRelevanceScore??w.minRelevanceScore})},validateAndParse:($)=>{let f=Mt2.safeParse($??{});return f.success?f.data:null}}}async function Vt2(A){let Q=A.sourceBatch.drain(),B=await Promise.all(Q.map(async(H)=>({ref:H,entity:await A.context.entityService.getEntity({entityType:H.entityType,id:H.entityId})}))),w=0,$=0,f=0,I=[];for(let{ref:H,entity:Y}of B){if(!Y){$++;continue}if(Y.contentHash!==H.contentHash){w++;continue}if(!A.isEntityPublished(Y)){f++;continue}I.push(Y)}if(I.length===0)return{success:!0,sources:Q.length,created:0,merged:0,skipped:0,batches:0,stale:w,missing:$,unpublished:f};let D=await TC(I,A.context,A.logger,{minRelevanceScore:A.minRelevanceScore,autoMerge:A.config.autoMerge,mergeSimilarityThreshold:A.config.mergeSimilarityThreshold});return{success:!0,sources:Q.length,...D,stale:w,missing:$,unpublished:f}}function hw1(){return{priority:5,source:Z2A,deduplication:"coalesce",deduplicationKey:"topics-initial-derivation",metadata:{operationType:"data_processing",operationTarget:"topics-initial-derivation",pluginId:gC}}}async function yw1(A){let Q=await Tw1(A);if(Q.length===0){A.logger.info("No entities to extract topics from");return}A.logger.info(`Batch topic extraction: ${Q.length} entities`);let B=await TC(Q,A.context,A.logger,{minRelevanceScore:A.config.minRelevanceScore,autoMerge:A.config.autoMerge,mergeSimilarityThreshold:A.config.mergeSimilarityThreshold});A.logger.info("Batch topic extraction complete",B)}async function gw1(A){let Q=await Tw1(A),B=await gRA(Q,A.context,A.logger,A.config);A.logger.info("Topic rebuild complete",B)}async function gRA(A,Q,B,w){let $=new $Y(Q.entityService,B),f=await $.listTopics();for(let D of f)await $.deleteTopic(D.id);if(A.length===0)return{deleted:f.length,created:0,merged:0,skipped:0,batches:0};let I=await TC(A,Q,B,{minRelevanceScore:w.minRelevanceScore,autoMerge:w.autoMerge,mergeSimilarityThreshold:w.mergeSimilarityThreshold});return{deleted:f.length,...I}}async function Tw1(A){let Q=bt2(A),B=[];for(let w of Q){let $=await A.context.entityService.listEntities({entityType:w});for(let f of $){if(!A.isEntityPublished(f))continue;B.push(f)}}return B}function bt2(A){return A.context.entityService.getEntityTypes().filter((B)=>A.shouldProcessEntityType(B))}var W_=F.object({entityType:F.string(),content:F.string(),metadata:F.record(F.unknown()).optional()}),Ot2=W_.extend({minRelevanceScore:F.number().optional()}),Rt2=F.object({contentA:W_,contentB:W_,minRelevanceScore:F.number().optional(),threshold:F.number().min(0).max(1).optional()}),Em=F.object({title:F.string(),content:F.string()}),_t2=F.object({existingTopics:F.array(Em),incomingTopic:Em,threshold:F.number().optional()}),Pt2=F.object({existingTopics:F.array(Em).default([]),incomingTopic:Em.extend({relevanceScore:F.number().min(0).max(1).optional()}),threshold:F.number().optional()}),kt2=F.object({entities:F.array(W_).min(1),minRelevanceScore:F.number().optional()}),jt2=F.object({existingTopics:F.array(Em).optional(),entities:F.array(W_)}),vt2=F.object({entities:F.array(W_)});function X_(A,Q=""){return{id:`eval${Q}-${Date.now()}`,entityType:A.entityType,content:A.content,contentHash:xB(A.content),metadata:A.metadata??{},created:new Date().toISOString(),updated:new Date().toISOString()}}function Sw1(A){return{title:A.title,relevanceScore:A.relevanceScore}}function xt2(A){let Q=A.metadata.title;return typeof Q==="string"?Q:A.id}function ht2(A,Q){return{...A,sources:[{id:Q.id,type:Q.entityType,title:xt2(Q)}]}}async function SC(A){let Q=await A.entityService.listEntities({entityType:cB});await Promise.all(Q.map((B)=>A.entityService.deleteEntity({entityType:cB,id:B.id})))}async function yt2(A){for(;;){if((await A.jobs.getActiveJobs(["shell:embedding"])).length===0)return;await new Promise((B)=>setTimeout(B,100))}}function mw1(A){let{context:Q,logger:B,config:w}=A,$=new xRA(Q,B),f=async(I,D,H="")=>{let Y=X_(I,H);return $.extractFromEntity(Y,D)};Q.eval.registerHandler("extractFromEntity",async(I)=>{await SC(Q);let D=Ot2.parse(I),H=D.minRelevanceScore??w.minRelevanceScore,Y=X_(D);return(await $.extractFromEntity(Y,H)).map((G)=>ht2(G,Y))}),Q.eval.registerHandler("checkMergeSimilarity",async(I)=>{await SC(Q);let D=Rt2.parse(I),H=D.minRelevanceScore??w.minRelevanceScore,Y=D.threshold??w.mergeSimilarityThreshold,[W,G]=await Promise.all([f(D.contentA,H,"-a"),f(D.contentB,H,"-b")]),K=new $Y(Q.entityService,B),Z=[];for(let C of W){let R=await K.createTopic(C);if(R)Z.push(R)}let q=(await Promise.all(G.map(async(C)=>{let R=await K.findMergeCandidate({incoming:C,threshold:Y,additionalCandidates:Z});if(!R)return null;return{incomingTitle:C.title,candidateTitle:R.title,candidateScore:R.score}}))).filter((C)=>C!==null),L=q.map((C)=>C.candidateTitle);return{topicsA:W.map(Sw1),topicsB:G.map(Sw1),matchingTitles:L,mergeCandidates:q,wouldMerge:q.length>0}}),Q.eval.registerHandler("detectMergeCandidate",async(I)=>{await SC(Q);let D=_t2.parse(I),H=D.threshold??w.mergeSimilarityThreshold,Y=new $Y(Q.entityService,B),W=[];for(let K of D.existingTopics){let Z=await Y.createTopic(K);if(Z)W.push(Z)}let G=await Y.findMergeCandidate({incoming:{title:D.incomingTopic.title},threshold:H,additionalCandidates:W});return{found:G!==null,candidateTitle:G?.title,candidateScore:G?.score}}),Q.eval.registerHandler("processTopicWithAutoMerge",async(I)=>{await SC(Q);let D=Pt2.parse(I),H=new $Y(Q.entityService,B);for(let K of D.existingTopics)await H.createTopic({title:K.title,content:K.content});await yt2(Q);let Y=X_({entityType:"post",content:D.incomingTopic.content,metadata:{title:D.incomingTopic.title}},"-source"),W=await TC([Y],Q,B,{minRelevanceScore:0,autoMerge:!0,mergeSimilarityThreshold:D.threshold??w.mergeSimilarityThreshold}),G=await Q.entityService.listEntities({entityType:cB});return{...W,topicCount:G.length,topics:G.map(jRA)}}),Q.eval.registerHandler("rebuildTopics",async(I)=>{await SC(Q);let D=jt2.parse(I),H=new $Y(Q.entityService,B);for(let K of D.existingTopics??[])await H.createTopic(K);let Y=D.entities.map((K,Z)=>X_(K,`-rebuild-${Z}`)),W=await gRA(Y,Q,B,w),G=await Q.entityService.listEntities({entityType:cB});return{...W,topicCount:G.length,topics:G.map(jRA)}}),Q.eval.registerHandler("extractSequentially",async(I)=>{await SC(Q);let D=kt2.parse(I),H=D.minRelevanceScore??w.minRelevanceScore,Y=new $Y(Q.entityService,B),W=[];for(let[K,Z]of D.entities.entries()){let q=X_(Z,`-sequential-${K}`),L=await $.extractFromEntity(q,H);for(let C of L)await Y.createTopic({title:C.title,content:C.content});W.push({extractedTitles:L.map((C)=>C.title)})}let G=await Q.entityService.listEntities({entityType:cB});return{totalTopics:G.length,perEntity:W,topics:G.map(Y_)}}),Q.eval.registerHandler("batchExtract",async(I)=>{await SC(Q);let H=vt2.parse(I).entities.map((G,K)=>X_(G,`-batch-${K}`)),Y=await TC(H,Q,B,{minRelevanceScore:w.minRelevanceScore}),W=await Q.entityService.listEntities({entityType:cB});return{...Y,topics:W.map(Y_)}})}var uw1={name:"@brains/topics",private:!0,version:"0.2.0-alpha.70",description:"Extract and manage topics from conversations",type:"module",main:"./src/index.ts",types:"./src/index.ts",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/plugins":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","@types/node":"^20.0.0",typescript:"^5.3.3"}};var Tt2=new DG;class cw1 extends KQ{entityType=cB;schema=K2A;adapter=Tt2;sourceBatch=new yRA;constructor(A={}){super(gC,uw1,A,Ww1)}getEntityTypeConfig(){return{weight:0.5,projectionSource:!1}}getTemplates(){return{extraction:Zw1,"merge-synthesis":Nw1,"topic-list":zw1,"topic-detail":qw1}}getDataSources(){return[new vRA(this.logger.child("TopicsDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableAutoExtraction)return[];return[{id:_RA,targetType:cB,job:{type:Jw1,handler:xw1({context:A,logger:this.logger,config:this.config,extractAllTopics:()=>this.extractAllTopics(A),rebuildAllTopics:()=>this.rebuildAllTopics(A),sourceBatch:this.sourceBatch,isEntityPublished:(Q)=>this.isEntityPublished(Q)})},initialSync:{shouldEnqueue:async()=>!await qN(A,cB),jobData:{mode:"derive",reason:"initial-sync"},jobOptions:hw1()},sourceChange:{sourceTypes:this.config.includeEntityTypes,requireInitialSync:!0,jobData:(Q)=>{let B=Q.entity;if(!B)return null;if(!this.shouldProcessEntityType(B.entityType,A.entityService))return null;if(!this.isEntityPublished(B))return null;return this.sourceBatch.add({entityId:B.id,entityType:B.entityType,contentHash:B.contentHash}),{mode:"source-batch"}},jobOptions:()=>({priority:5,source:Z2A,delayMs:this.config.sourceChangeBatchDelayMs,deduplication:"skip",deduplicationKey:Fw1,metadata:{operationType:"data_processing",operationTarget:"topic-source-batch",pluginId:gC}})}}]}async onRegister(A){A.insights.register("topic-distribution",Ew1()),Mw1({context:A,pluginId:this.id}),mw1({context:A,logger:this.logger,config:this.config})}hasRunInitialDerivation(){return this.getDerivedEntityProjectionController(_RA)?.hasQueuedInitialSync()??!1}shouldProcessEntityType(A,Q){if(A===cB)return!1;if(!this.config.includeEntityTypes.includes(A))return!1;return Q.getEntityTypeConfig(A).projectionSource!==!1}isEntityPublished(A){let B=A.metadata.status;if(B===void 0||B===null)return!0;if(typeof B!=="string")return!1;return this.config.extractableStatuses.includes(B)}async extractAllTopics(A){await yw1({context:A,logger:this.logger,config:this.config,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q,A.entityService),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}async rebuildAllTopics(A){await gw1({context:A,logger:this.logger,config:this.config,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q,A.entityService),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}}function M2A(A){return new cw1(A)}f0();GA();f0();var pw1=F.enum(["linkedin"]),lw1=F.enum(["draft","queued","published","failed"]),iw1=F.enum(["post","deck"]),H4=F.object({title:F.string().describe("Short descriptive title (3-6 words) for file naming"),platform:pw1.describe("Target platform"),status:lw1,coverImageId:F.string().optional().describe("Image entity ID for post image"),publishedAt:F.string().datetime().optional(),platformPostId:F.string().optional().describe("ID from platform after publishing"),sourceEntityId:F.string().optional().describe("Source entity ID if auto-generated"),sourceEntityType:iw1.optional().describe("Source entity type (post, deck)")}),rw1=H4.pick({title:!0,platform:!0,status:!0,publishedAt:!0,platformPostId:!0}).extend({slug:F.string().describe("URL-friendly identifier: {platform}-{title}")}),U_=B2.extend({entityType:F.literal("social-post"),metadata:rw1}),V2A=U_.extend({frontmatter:H4,body:F.string()}),b2A=V2A.extend({url:F.string().optional(),listUrl:F.string().optional(),listLabel:F.string().optional(),typeLabel:F.string().optional(),coverImageUrl:F.string().optional(),coverImageWidth:F.number().optional(),coverImageHeight:F.number().optional()});f0();GA();class TRA extends W2{constructor(){super({entityType:"social-post",schema:U_,frontmatterSchema:H4,supportsCoverImage:!0})}toMarkdown(A){let Q="",B={};try{B=this.parseFrontMatter(A.content,H4),Q=this.extractBody(A.content)}catch{Q=A.content}let w={...B,title:A.metadata.title,platform:A.metadata.platform,status:A.metadata.status,...A.metadata.publishedAt!==void 0&&{publishedAt:A.metadata.publishedAt},...A.metadata.platformPostId!==void 0&&{platformPostId:A.metadata.platformPostId}};return this.buildMarkdown(Q,w)}fromMarkdown(A){let Q=this.parseFrontMatter(A,H4),B=`${Q.platform}-${U2(Q.title)}`;return{content:A,entityType:"social-post",metadata:{title:Q.title,slug:B,platform:Q.platform,status:Q.status,publishedAt:Q.publishedAt,platformPostId:Q.platformPostId}}}parsePostFrontmatter(A){return this.parseFrontMatter(A.content,H4)}getPostContent(A){return this.extractBody(A.content)}createPostContent(A,Q){return this.buildMarkdown(Q,A)}}var Vf=new TRA;f0();f0();GA();var St2=tY.extend({platform:F.enum(["linkedin"]).optional(),status:F.enum(["draft","queued","published","failed"]).optional(),sortByQueue:F.boolean().optional(),nextInQueue:F.boolean().optional()}),mt2=eY.extend({query:St2.optional()});function dw1(A){let Q=t2(A.content,H4);return V2A.parse({...A,frontmatter:Q.metadata,body:Q.content})}class O2A extends r6{id="social-media:posts";name="Social Post DataSource";description="Fetches and transforms social post entities for queue management and publishing";config={entityType:"social-post",defaultSort:[{field:"publishedAt",direction:"desc",nullsFirst:!0},{field:"created",direction:"desc"}],defaultLimit:100};constructor(A){super(A);this.logger.debug("SocialPostDataSource initialized")}parseQuery(A){let Q=mt2.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}transformEntity(A){return dw1(A)}buildDetailResult(A,Q){return{post:A}}buildListResult(A,Q,B){return{posts:A,totalCount:Q?.totalItems??A.length,pagination:Q,baseUrl:B.baseUrl}}async fetch(A,Q,B){let{query:w}=this.parseQuery(A),$=B.entityService;if(w.nextInQueue)return this.fetchNextInQueue(Q,$);if(w.id){let{item:W}=await this.fetchDetail(w.id,$);return Q.parse(this.buildDetailResult(W,null))}let f={};if(w.platform)f.platform=w.platform;if(w.status)f.status=w.status;let I=Object.keys(f).length>0,D=w.sortByQueue?[{field:"queueOrder",direction:"asc"}]:this.config.defaultSort,{items:H,pagination:Y}=await this.fetchList(w,$,{...I&&{filter:{metadata:f}},sortFields:D});return Q.parse(this.buildListResult(H,Y,w))}async fetchNextInQueue(A,Q){let w=(await Q.listEntities({entityType:this.config.entityType,options:{filter:{metadata:{status:"queued"}},sortFields:[{field:"queueOrder",direction:"asc"}],limit:1}}))[0],$=w?dw1(w):null;return A.parse({post:$})}}GA();var nw1=F.object({accessToken:F.string().optional(),refreshToken:F.string().optional(),organizationId:F.string().optional()}),SRA=F.object({linkedin:nw1.optional(),publishInterval:F.number().default(3600000),enabled:F.boolean().default(!0),defaultPrompt:F.string().default("Create an engaging social media post that drives engagement"),maxRetries:F.number().default(3),autoGenerateOnBlogPublish:F.boolean().default(!1)});f0();GA();L$();uRA();import{jsxDEV as b6,Fragment as pt2}from"preact/jsx-dev-runtime";function ut2(A,Q){if(A.length<=Q)return A;return A.slice(0,Q).trim()+"..."}function ct2(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"})}var _2A=({posts:A,pageTitle:Q,pagination:B,baseUrl:w="/social-posts"})=>{let $=Q??"Social Posts",f=B?.totalItems??A.length,I=`Browse all ${f} social ${f===1?"post":"posts"}`;return b6(pt2,{children:[b6(XQ,{title:$,description:I},void 0,!1,void 0,this),b6("div",{className:"social-post-list bg-theme",children:b6("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[b6("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:$},void 0,!1,void 0,this),A.length===0?b6("p",{className:"text-theme-muted italic",children:"No social posts yet."},void 0,!1,void 0,this):b6("ul",{className:"space-y-6",children:A.map((D)=>b6("li",{children:b6(UB,{href:D.url,variant:"horizontal",children:b6("div",{className:"flex flex-col sm:flex-row gap-4",children:[D.coverImageUrl&&b6("img",{src:D.coverImageUrl,alt:D.frontmatter.title,className:"w-full sm:w-24 h-48 sm:h-24 object-cover rounded-lg shrink-0"},void 0,!1,void 0,this),b6("div",{className:"flex-1 min-w-0",children:[b6("div",{className:"flex items-start justify-between gap-4 mb-2",children:[b6("h2",{className:"text-lg font-semibold text-heading",children:D.frontmatter.title},void 0,!1,void 0,this),b6("time",{className:"text-sm text-theme-muted shrink-0",children:ct2(D.frontmatter.publishedAt??D.created)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),b6("div",{className:"flex items-center gap-2 mb-3",children:[b6(Lf,{status:D.frontmatter.status},void 0,!1,void 0,this),b6("span",{className:"text-xs text-theme-muted uppercase",children:D.frontmatter.platform},void 0,!1,void 0,this),b6("span",{className:"text-xs text-theme-muted font-mono",children:D.id},void 0,!1,void 0,this)]},void 0,!0,void 0,this),b6("p",{className:"text-theme leading-relaxed",children:ut2(D.body,200)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},D.id,!1,void 0,this))},void 0,!1,void 0,this),B&&B.totalPages>1&&b6(cJ,{currentPage:B.currentPage,totalPages:B.totalPages,baseUrl:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as O6,Fragment as lt2}from"preact/jsx-dev-runtime";function ow1(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric",hour:"numeric",minute:"2-digit"})}var P2A=({post:A})=>{let Q=`Social Post - ${A.frontmatter.platform}`,B=A.body.slice(0,160),w=[{label:"Home",href:"/"},{label:A.listLabel??"Social Posts",href:A.listUrl??"/social-posts"},{label:A.frontmatter.platform}];return O6(lt2,{children:[O6(XQ,{title:Q,description:B},void 0,!1,void 0,this),O6("section",{className:"social-post-detail",children:O6("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:O6("div",{className:"max-w-3xl mx-auto",children:[O6(tX,{items:w},void 0,!1,void 0,this),O6("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-4",children:A.frontmatter.title},void 0,!1,void 0,this),O6("div",{className:"flex flex-wrap items-center gap-3 mb-6",children:[O6(Lf,{status:A.frontmatter.status},void 0,!1,void 0,this),O6("span",{className:"text-sm text-theme-muted uppercase",children:A.frontmatter.platform},void 0,!1,void 0,this),O6("span",{className:"text-sm text-theme-muted font-mono",children:A.id},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.coverImageUrl&&A.coverImageWidth&&A.coverImageHeight&&O6(mJ,{src:A.coverImageUrl,alt:A.frontmatter.title,width:A.coverImageWidth,height:A.coverImageHeight,className:"mb-8"},void 0,!1,void 0,this),O6(UB,{className:"p-8 mb-8",children:O6("p",{className:"text-lg text-theme leading-relaxed whitespace-pre-wrap",children:A.body},void 0,!1,void 0,this)},void 0,!1,void 0,this),O6("div",{className:"space-y-4 text-sm text-theme-muted",children:[O6("div",{children:[O6("span",{className:"font-medium",children:"Created:"},void 0,!1,void 0,this)," ",ow1(A.created)]},void 0,!0,void 0,this),A.frontmatter.publishedAt&&O6("div",{children:[O6("span",{className:"font-medium",children:"Published:"},void 0,!1,void 0,this)," ",ow1(A.frontmatter.publishedAt)]},void 0,!0,void 0,this),A.frontmatter.platformPostId&&O6("div",{children:O6("a",{href:`https://www.linkedin.com/feed/update/${A.frontmatter.platformPostId}`,target:"_blank",rel:"noopener noreferrer",className:"text-brand hover:underline",children:"View on LinkedIn \u2192"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};function Mm(A){return`social-media:${A}`}var it2=F.union([F.boolean(),F.object({generate:F.boolean().optional(),prompt:F.string().optional()})]),cRA=F.object({prompt:F.string().optional(),platform:F.enum(["linkedin"]).optional(),sourceEntityType:F.enum(["post","deck"]).optional(),sourceEntityId:F.string().optional(),title:F.string().optional().describe("Required when content is provided directly"),content:F.string().optional(),addToQueue:F.boolean().optional(),generateImage:F.boolean().optional().describe("Auto-generate cover image for post"),coverImage:it2.optional().describe("Generic cover image generation request")}),rt2=AI.extend({slug:F.string().optional()});class mC extends X9{constructor(A,Q){super(A,Q,{schema:cRA,jobTypeName:"social-post-generation",entityType:"social-post"})}async generate(A,Q){let B=A.platform??"linkedin",w=A.addToQueue??!1,{prompt:$,sourceEntityType:f,sourceEntityId:I}=A,{content:D,title:H}=A;if(D&&H)await this.reportProgress(Q,{progress:50,message:"Using provided content"});else if(D&&!H){await this.reportProgress(Q,{progress:10,message:"Shaping content with AI"});let C=await this.context.ai.generate({prompt:D,templateName:Mm(B)});H=C.title,D=C.content,await this.reportProgress(Q,{progress:50,message:"Social post shaped from content"})}else if(I&&f){await this.reportProgress(Q,{progress:10,message:`Fetching source ${f}`});let C=await this.context.entityService.getEntity({entityType:f,id:I});if(!C)this.failEarly(`Source entity not found: ${f}/${I}`);await this.reportProgress(Q,{progress:30,message:"Generating social post from source content"});let k=F.object({slug:F.string()}).safeParse(C.metadata),_=k.success?k.data.slug:I,o=await this.context.ai.generate({prompt:`Create an engaging ${B} post to promote this ${f}:
|
|
3528
|
+
`)}async function TC(A,Q,B,w={}){if(A.length===0)return{created:0,merged:0,skipped:0,batches:0};let $=w.minRelevanceScore??0,f=w.autoMerge??!1,I=w.mergeSimilarityThreshold??0.85,D=Rw1(A),H=new $Y(Q.entityService,B),Y=w.topicMergeSynthesizer??new hRA(Q,B),W=await L2A(Q.entityService),G=new Map,K=0,Z=0,q=0;for(let C of D){B.info(`Processing batch of ${C.length} entities`);let R=Et2(C),k=E2A({entityTitle:`Batch of ${C.length} entities`,entityType:"batch",content:R,existingTopicTitles:W});try{let o=(await Q.ai.generate({prompt:k,templateName:"topics:extraction"})).topics.filter((r)=>r.relevanceScore>=$);for(let r of o)try{if(f){let y=await H.findMergeCandidate({incoming:r,threshold:I,additionalCandidates:Array.from(G.values())});if(y){let g=await Y.synthesize({existingTopic:y.topic,incomingTopic:r}),AA=await H.applySynthesizedMerge({existingId:y.topic.id,synthesized:{...g,title:y.title}});if(!AA)throw Error(`Failed to merge topic: ${r.title}`);G.set(AA.id,AA),Z++;continue}}let S=SY(r.title);if(G.has(S)){q++;continue}let x=await H.createTopicOptimistic({title:r.title,content:r.content});if(x.topic)G.set(x.topic.id,x.topic);if(x.created)K++;else q++}catch(S){B.error("Topic batch item failed",{title:r.title,error:y0(S)})}}catch(_){B.error("Batch topic extraction failed",{batchSize:C.length,promptChars:k.length,error:y0(_)})}}let L={created:K,merged:Z,skipped:q,batches:D.length};if(K>0||Z>0)await Q.messaging.send({type:Gw1,payload:L,broadcast:!0});return L}GA();var Mt2=F.discriminatedUnion("mode",[F.object({mode:F.literal("derive"),reason:F.string().optional()}),F.object({mode:F.literal("rebuild"),reason:F.string().optional()}),F.object({mode:F.literal("source-batch"),minRelevanceScore:F.number().min(0).max(1).optional()})]);class yRA{refs=new Map;add(A){this.refs.set(`${A.entityType}:${A.entityId}`,A)}drain(){let A=Array.from(this.refs.values());return this.refs.clear(),A}}function xw1(A){let{context:Q,logger:B,config:w}=A;return{process:async($)=>{if($.mode==="derive")return await A.extractAllTopics(),{success:!0};if($.mode==="rebuild")return await A.rebuildAllTopics(),{success:!0};return Vt2({context:Q,logger:B,config:w,sourceBatch:A.sourceBatch,isEntityPublished:A.isEntityPublished,minRelevanceScore:$.minRelevanceScore??w.minRelevanceScore})},validateAndParse:($)=>{let f=Mt2.safeParse($??{});return f.success?f.data:null}}}async function Vt2(A){let Q=A.sourceBatch.drain(),B=await Promise.all(Q.map(async(H)=>({ref:H,entity:await A.context.entityService.getEntity({entityType:H.entityType,id:H.entityId})}))),w=0,$=0,f=0,I=[];for(let{ref:H,entity:Y}of B){if(!Y){$++;continue}if(Y.contentHash!==H.contentHash){w++;continue}if(!A.isEntityPublished(Y)){f++;continue}I.push(Y)}if(I.length===0)return{success:!0,sources:Q.length,created:0,merged:0,skipped:0,batches:0,stale:w,missing:$,unpublished:f};let D=await TC(I,A.context,A.logger,{minRelevanceScore:A.minRelevanceScore,autoMerge:A.config.autoMerge,mergeSimilarityThreshold:A.config.mergeSimilarityThreshold});return{success:!0,sources:Q.length,...D,stale:w,missing:$,unpublished:f}}function hw1(){return{priority:5,source:Z2A,deduplication:"coalesce",deduplicationKey:"topics-initial-derivation",metadata:{operationType:"data_processing",operationTarget:"topics-initial-derivation",pluginId:gC}}}async function yw1(A){let Q=await Tw1(A);if(Q.length===0){A.logger.info("No entities to extract topics from");return}A.logger.info(`Batch topic extraction: ${Q.length} entities`);let B=await TC(Q,A.context,A.logger,{minRelevanceScore:A.config.minRelevanceScore,autoMerge:A.config.autoMerge,mergeSimilarityThreshold:A.config.mergeSimilarityThreshold});A.logger.info("Batch topic extraction complete",B)}async function gw1(A){let Q=await Tw1(A),B=await gRA(Q,A.context,A.logger,A.config);A.logger.info("Topic rebuild complete",B)}async function gRA(A,Q,B,w){let $=new $Y(Q.entityService,B),f=await $.listTopics();for(let D of f)await $.deleteTopic(D.id);if(A.length===0)return{deleted:f.length,created:0,merged:0,skipped:0,batches:0};let I=await TC(A,Q,B,{minRelevanceScore:w.minRelevanceScore,autoMerge:w.autoMerge,mergeSimilarityThreshold:w.mergeSimilarityThreshold});return{deleted:f.length,...I}}async function Tw1(A){let Q=bt2(A),B=[];for(let w of Q){let $=await A.context.entityService.listEntities({entityType:w});for(let f of $){if(!A.isEntityPublished(f))continue;B.push(f)}}return B}function bt2(A){return A.context.entityService.getEntityTypes().filter((B)=>A.shouldProcessEntityType(B))}var W_=F.object({entityType:F.string(),content:F.string(),metadata:F.record(F.unknown()).optional()}),Ot2=W_.extend({minRelevanceScore:F.number().optional()}),Rt2=F.object({contentA:W_,contentB:W_,minRelevanceScore:F.number().optional(),threshold:F.number().min(0).max(1).optional()}),Em=F.object({title:F.string(),content:F.string()}),_t2=F.object({existingTopics:F.array(Em),incomingTopic:Em,threshold:F.number().optional()}),Pt2=F.object({existingTopics:F.array(Em).default([]),incomingTopic:Em.extend({relevanceScore:F.number().min(0).max(1).optional()}),threshold:F.number().optional()}),kt2=F.object({entities:F.array(W_).min(1),minRelevanceScore:F.number().optional()}),jt2=F.object({existingTopics:F.array(Em).optional(),entities:F.array(W_)}),vt2=F.object({entities:F.array(W_)});function X_(A,Q=""){return{id:`eval${Q}-${Date.now()}`,entityType:A.entityType,content:A.content,contentHash:xB(A.content),metadata:A.metadata??{},created:new Date().toISOString(),updated:new Date().toISOString()}}function Sw1(A){return{title:A.title,relevanceScore:A.relevanceScore}}function xt2(A){let Q=A.metadata.title;return typeof Q==="string"?Q:A.id}function ht2(A,Q){return{...A,sources:[{id:Q.id,type:Q.entityType,title:xt2(Q)}]}}async function SC(A){let Q=await A.entityService.listEntities({entityType:cB});await Promise.all(Q.map((B)=>A.entityService.deleteEntity({entityType:cB,id:B.id})))}async function yt2(A){for(;;){if((await A.jobs.getActiveJobs(["shell:embedding"])).length===0)return;await new Promise((B)=>setTimeout(B,100))}}function mw1(A){let{context:Q,logger:B,config:w}=A,$=new xRA(Q,B),f=async(I,D,H="")=>{let Y=X_(I,H);return $.extractFromEntity(Y,D)};Q.eval.registerHandler("extractFromEntity",async(I)=>{await SC(Q);let D=Ot2.parse(I),H=D.minRelevanceScore??w.minRelevanceScore,Y=X_(D);return(await $.extractFromEntity(Y,H)).map((G)=>ht2(G,Y))}),Q.eval.registerHandler("checkMergeSimilarity",async(I)=>{await SC(Q);let D=Rt2.parse(I),H=D.minRelevanceScore??w.minRelevanceScore,Y=D.threshold??w.mergeSimilarityThreshold,[W,G]=await Promise.all([f(D.contentA,H,"-a"),f(D.contentB,H,"-b")]),K=new $Y(Q.entityService,B),Z=[];for(let C of W){let R=await K.createTopic(C);if(R)Z.push(R)}let q=(await Promise.all(G.map(async(C)=>{let R=await K.findMergeCandidate({incoming:C,threshold:Y,additionalCandidates:Z});if(!R)return null;return{incomingTitle:C.title,candidateTitle:R.title,candidateScore:R.score}}))).filter((C)=>C!==null),L=q.map((C)=>C.candidateTitle);return{topicsA:W.map(Sw1),topicsB:G.map(Sw1),matchingTitles:L,mergeCandidates:q,wouldMerge:q.length>0}}),Q.eval.registerHandler("detectMergeCandidate",async(I)=>{await SC(Q);let D=_t2.parse(I),H=D.threshold??w.mergeSimilarityThreshold,Y=new $Y(Q.entityService,B),W=[];for(let K of D.existingTopics){let Z=await Y.createTopic(K);if(Z)W.push(Z)}let G=await Y.findMergeCandidate({incoming:{title:D.incomingTopic.title},threshold:H,additionalCandidates:W});return{found:G!==null,candidateTitle:G?.title,candidateScore:G?.score}}),Q.eval.registerHandler("processTopicWithAutoMerge",async(I)=>{await SC(Q);let D=Pt2.parse(I),H=new $Y(Q.entityService,B);for(let K of D.existingTopics)await H.createTopic({title:K.title,content:K.content});await yt2(Q);let Y=X_({entityType:"post",content:D.incomingTopic.content,metadata:{title:D.incomingTopic.title}},"-source"),W=await TC([Y],Q,B,{minRelevanceScore:0,autoMerge:!0,mergeSimilarityThreshold:D.threshold??w.mergeSimilarityThreshold}),G=await Q.entityService.listEntities({entityType:cB});return{...W,topicCount:G.length,topics:G.map(jRA)}}),Q.eval.registerHandler("rebuildTopics",async(I)=>{await SC(Q);let D=jt2.parse(I),H=new $Y(Q.entityService,B);for(let K of D.existingTopics??[])await H.createTopic(K);let Y=D.entities.map((K,Z)=>X_(K,`-rebuild-${Z}`)),W=await gRA(Y,Q,B,w),G=await Q.entityService.listEntities({entityType:cB});return{...W,topicCount:G.length,topics:G.map(jRA)}}),Q.eval.registerHandler("extractSequentially",async(I)=>{await SC(Q);let D=kt2.parse(I),H=D.minRelevanceScore??w.minRelevanceScore,Y=new $Y(Q.entityService,B),W=[];for(let[K,Z]of D.entities.entries()){let q=X_(Z,`-sequential-${K}`),L=await $.extractFromEntity(q,H);for(let C of L)await Y.createTopic({title:C.title,content:C.content});W.push({extractedTitles:L.map((C)=>C.title)})}let G=await Q.entityService.listEntities({entityType:cB});return{totalTopics:G.length,perEntity:W,topics:G.map(Y_)}}),Q.eval.registerHandler("batchExtract",async(I)=>{await SC(Q);let H=vt2.parse(I).entities.map((G,K)=>X_(G,`-batch-${K}`)),Y=await TC(H,Q,B,{minRelevanceScore:w.minRelevanceScore}),W=await Q.entityService.listEntities({entityType:cB});return{...Y,topics:W.map(Y_)}})}var uw1={name:"@brains/topics",private:!0,version:"0.2.0-alpha.71",description:"Extract and manage topics from conversations",type:"module",main:"./src/index.ts",types:"./src/index.ts",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/plugins":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","@types/node":"^20.0.0",typescript:"^5.3.3"}};var Tt2=new DG;class cw1 extends KQ{entityType=cB;schema=K2A;adapter=Tt2;sourceBatch=new yRA;constructor(A={}){super(gC,uw1,A,Ww1)}getEntityTypeConfig(){return{weight:0.5,projectionSource:!1}}getTemplates(){return{extraction:Zw1,"merge-synthesis":Nw1,"topic-list":zw1,"topic-detail":qw1}}getDataSources(){return[new vRA(this.logger.child("TopicsDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableAutoExtraction)return[];return[{id:_RA,targetType:cB,job:{type:Jw1,handler:xw1({context:A,logger:this.logger,config:this.config,extractAllTopics:()=>this.extractAllTopics(A),rebuildAllTopics:()=>this.rebuildAllTopics(A),sourceBatch:this.sourceBatch,isEntityPublished:(Q)=>this.isEntityPublished(Q)})},initialSync:{shouldEnqueue:async()=>!await qN(A,cB),jobData:{mode:"derive",reason:"initial-sync"},jobOptions:hw1()},sourceChange:{sourceTypes:this.config.includeEntityTypes,requireInitialSync:!0,jobData:(Q)=>{let B=Q.entity;if(!B)return null;if(!this.shouldProcessEntityType(B.entityType,A.entityService))return null;if(!this.isEntityPublished(B))return null;return this.sourceBatch.add({entityId:B.id,entityType:B.entityType,contentHash:B.contentHash}),{mode:"source-batch"}},jobOptions:()=>({priority:5,source:Z2A,delayMs:this.config.sourceChangeBatchDelayMs,deduplication:"skip",deduplicationKey:Fw1,metadata:{operationType:"data_processing",operationTarget:"topic-source-batch",pluginId:gC}})}}]}async onRegister(A){A.insights.register("topic-distribution",Ew1()),Mw1({context:A,pluginId:this.id}),mw1({context:A,logger:this.logger,config:this.config})}hasRunInitialDerivation(){return this.getDerivedEntityProjectionController(_RA)?.hasQueuedInitialSync()??!1}shouldProcessEntityType(A,Q){if(A===cB)return!1;if(!this.config.includeEntityTypes.includes(A))return!1;return Q.getEntityTypeConfig(A).projectionSource!==!1}isEntityPublished(A){let B=A.metadata.status;if(B===void 0||B===null)return!0;if(typeof B!=="string")return!1;return this.config.extractableStatuses.includes(B)}async extractAllTopics(A){await yw1({context:A,logger:this.logger,config:this.config,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q,A.entityService),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}async rebuildAllTopics(A){await gw1({context:A,logger:this.logger,config:this.config,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q,A.entityService),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}}function M2A(A){return new cw1(A)}f0();GA();f0();var pw1=F.enum(["linkedin"]),lw1=F.enum(["draft","queued","published","failed"]),iw1=F.enum(["post","deck"]),H4=F.object({title:F.string().describe("Short descriptive title (3-6 words) for file naming"),platform:pw1.describe("Target platform"),status:lw1,coverImageId:F.string().optional().describe("Image entity ID for post image"),publishedAt:F.string().datetime().optional(),platformPostId:F.string().optional().describe("ID from platform after publishing"),sourceEntityId:F.string().optional().describe("Source entity ID if auto-generated"),sourceEntityType:iw1.optional().describe("Source entity type (post, deck)")}),rw1=H4.pick({title:!0,platform:!0,status:!0,publishedAt:!0,platformPostId:!0}).extend({slug:F.string().describe("URL-friendly identifier: {platform}-{title}")}),U_=B2.extend({entityType:F.literal("social-post"),metadata:rw1}),V2A=U_.extend({frontmatter:H4,body:F.string()}),b2A=V2A.extend({url:F.string().optional(),listUrl:F.string().optional(),listLabel:F.string().optional(),typeLabel:F.string().optional(),coverImageUrl:F.string().optional(),coverImageWidth:F.number().optional(),coverImageHeight:F.number().optional()});f0();GA();class TRA extends W2{constructor(){super({entityType:"social-post",schema:U_,frontmatterSchema:H4,supportsCoverImage:!0})}toMarkdown(A){let Q="",B={};try{B=this.parseFrontMatter(A.content,H4),Q=this.extractBody(A.content)}catch{Q=A.content}let w={...B,title:A.metadata.title,platform:A.metadata.platform,status:A.metadata.status,...A.metadata.publishedAt!==void 0&&{publishedAt:A.metadata.publishedAt},...A.metadata.platformPostId!==void 0&&{platformPostId:A.metadata.platformPostId}};return this.buildMarkdown(Q,w)}fromMarkdown(A){let Q=this.parseFrontMatter(A,H4),B=`${Q.platform}-${U2(Q.title)}`;return{content:A,entityType:"social-post",metadata:{title:Q.title,slug:B,platform:Q.platform,status:Q.status,publishedAt:Q.publishedAt,platformPostId:Q.platformPostId}}}parsePostFrontmatter(A){return this.parseFrontMatter(A.content,H4)}getPostContent(A){return this.extractBody(A.content)}createPostContent(A,Q){return this.buildMarkdown(Q,A)}}var Vf=new TRA;f0();f0();GA();var St2=tY.extend({platform:F.enum(["linkedin"]).optional(),status:F.enum(["draft","queued","published","failed"]).optional(),sortByQueue:F.boolean().optional(),nextInQueue:F.boolean().optional()}),mt2=eY.extend({query:St2.optional()});function dw1(A){let Q=t2(A.content,H4);return V2A.parse({...A,frontmatter:Q.metadata,body:Q.content})}class O2A extends r6{id="social-media:posts";name="Social Post DataSource";description="Fetches and transforms social post entities for queue management and publishing";config={entityType:"social-post",defaultSort:[{field:"publishedAt",direction:"desc",nullsFirst:!0},{field:"created",direction:"desc"}],defaultLimit:100};constructor(A){super(A);this.logger.debug("SocialPostDataSource initialized")}parseQuery(A){let Q=mt2.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}transformEntity(A){return dw1(A)}buildDetailResult(A,Q){return{post:A}}buildListResult(A,Q,B){return{posts:A,totalCount:Q?.totalItems??A.length,pagination:Q,baseUrl:B.baseUrl}}async fetch(A,Q,B){let{query:w}=this.parseQuery(A),$=B.entityService;if(w.nextInQueue)return this.fetchNextInQueue(Q,$);if(w.id){let{item:W}=await this.fetchDetail(w.id,$);return Q.parse(this.buildDetailResult(W,null))}let f={};if(w.platform)f.platform=w.platform;if(w.status)f.status=w.status;let I=Object.keys(f).length>0,D=w.sortByQueue?[{field:"queueOrder",direction:"asc"}]:this.config.defaultSort,{items:H,pagination:Y}=await this.fetchList(w,$,{...I&&{filter:{metadata:f}},sortFields:D});return Q.parse(this.buildListResult(H,Y,w))}async fetchNextInQueue(A,Q){let w=(await Q.listEntities({entityType:this.config.entityType,options:{filter:{metadata:{status:"queued"}},sortFields:[{field:"queueOrder",direction:"asc"}],limit:1}}))[0],$=w?dw1(w):null;return A.parse({post:$})}}GA();var nw1=F.object({accessToken:F.string().optional(),refreshToken:F.string().optional(),organizationId:F.string().optional()}),SRA=F.object({linkedin:nw1.optional(),publishInterval:F.number().default(3600000),enabled:F.boolean().default(!0),defaultPrompt:F.string().default("Create an engaging social media post that drives engagement"),maxRetries:F.number().default(3),autoGenerateOnBlogPublish:F.boolean().default(!1)});f0();GA();L$();uRA();import{jsxDEV as b6,Fragment as pt2}from"preact/jsx-dev-runtime";function ut2(A,Q){if(A.length<=Q)return A;return A.slice(0,Q).trim()+"..."}function ct2(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"})}var _2A=({posts:A,pageTitle:Q,pagination:B,baseUrl:w="/social-posts"})=>{let $=Q??"Social Posts",f=B?.totalItems??A.length,I=`Browse all ${f} social ${f===1?"post":"posts"}`;return b6(pt2,{children:[b6(XQ,{title:$,description:I},void 0,!1,void 0,this),b6("div",{className:"social-post-list bg-theme",children:b6("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[b6("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:$},void 0,!1,void 0,this),A.length===0?b6("p",{className:"text-theme-muted italic",children:"No social posts yet."},void 0,!1,void 0,this):b6("ul",{className:"space-y-6",children:A.map((D)=>b6("li",{children:b6(UB,{href:D.url,variant:"horizontal",children:b6("div",{className:"flex flex-col sm:flex-row gap-4",children:[D.coverImageUrl&&b6("img",{src:D.coverImageUrl,alt:D.frontmatter.title,className:"w-full sm:w-24 h-48 sm:h-24 object-cover rounded-lg shrink-0"},void 0,!1,void 0,this),b6("div",{className:"flex-1 min-w-0",children:[b6("div",{className:"flex items-start justify-between gap-4 mb-2",children:[b6("h2",{className:"text-lg font-semibold text-heading",children:D.frontmatter.title},void 0,!1,void 0,this),b6("time",{className:"text-sm text-theme-muted shrink-0",children:ct2(D.frontmatter.publishedAt??D.created)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),b6("div",{className:"flex items-center gap-2 mb-3",children:[b6(Lf,{status:D.frontmatter.status},void 0,!1,void 0,this),b6("span",{className:"text-xs text-theme-muted uppercase",children:D.frontmatter.platform},void 0,!1,void 0,this),b6("span",{className:"text-xs text-theme-muted font-mono",children:D.id},void 0,!1,void 0,this)]},void 0,!0,void 0,this),b6("p",{className:"text-theme leading-relaxed",children:ut2(D.body,200)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},D.id,!1,void 0,this))},void 0,!1,void 0,this),B&&B.totalPages>1&&b6(cJ,{currentPage:B.currentPage,totalPages:B.totalPages,baseUrl:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as O6,Fragment as lt2}from"preact/jsx-dev-runtime";function ow1(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric",hour:"numeric",minute:"2-digit"})}var P2A=({post:A})=>{let Q=`Social Post - ${A.frontmatter.platform}`,B=A.body.slice(0,160),w=[{label:"Home",href:"/"},{label:A.listLabel??"Social Posts",href:A.listUrl??"/social-posts"},{label:A.frontmatter.platform}];return O6(lt2,{children:[O6(XQ,{title:Q,description:B},void 0,!1,void 0,this),O6("section",{className:"social-post-detail",children:O6("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:O6("div",{className:"max-w-3xl mx-auto",children:[O6(tX,{items:w},void 0,!1,void 0,this),O6("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-4",children:A.frontmatter.title},void 0,!1,void 0,this),O6("div",{className:"flex flex-wrap items-center gap-3 mb-6",children:[O6(Lf,{status:A.frontmatter.status},void 0,!1,void 0,this),O6("span",{className:"text-sm text-theme-muted uppercase",children:A.frontmatter.platform},void 0,!1,void 0,this),O6("span",{className:"text-sm text-theme-muted font-mono",children:A.id},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.coverImageUrl&&A.coverImageWidth&&A.coverImageHeight&&O6(mJ,{src:A.coverImageUrl,alt:A.frontmatter.title,width:A.coverImageWidth,height:A.coverImageHeight,className:"mb-8"},void 0,!1,void 0,this),O6(UB,{className:"p-8 mb-8",children:O6("p",{className:"text-lg text-theme leading-relaxed whitespace-pre-wrap",children:A.body},void 0,!1,void 0,this)},void 0,!1,void 0,this),O6("div",{className:"space-y-4 text-sm text-theme-muted",children:[O6("div",{children:[O6("span",{className:"font-medium",children:"Created:"},void 0,!1,void 0,this)," ",ow1(A.created)]},void 0,!0,void 0,this),A.frontmatter.publishedAt&&O6("div",{children:[O6("span",{className:"font-medium",children:"Published:"},void 0,!1,void 0,this)," ",ow1(A.frontmatter.publishedAt)]},void 0,!0,void 0,this),A.frontmatter.platformPostId&&O6("div",{children:O6("a",{href:`https://www.linkedin.com/feed/update/${A.frontmatter.platformPostId}`,target:"_blank",rel:"noopener noreferrer",className:"text-brand hover:underline",children:"View on LinkedIn \u2192"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};function Mm(A){return`social-media:${A}`}var it2=F.union([F.boolean(),F.object({generate:F.boolean().optional(),prompt:F.string().optional()})]),cRA=F.object({prompt:F.string().optional(),platform:F.enum(["linkedin"]).optional(),sourceEntityType:F.enum(["post","deck"]).optional(),sourceEntityId:F.string().optional(),title:F.string().optional().describe("Required when content is provided directly"),content:F.string().optional(),addToQueue:F.boolean().optional(),generateImage:F.boolean().optional().describe("Auto-generate cover image for post"),coverImage:it2.optional().describe("Generic cover image generation request")}),rt2=AI.extend({slug:F.string().optional()});class mC extends X9{constructor(A,Q){super(A,Q,{schema:cRA,jobTypeName:"social-post-generation",entityType:"social-post"})}async generate(A,Q){let B=A.platform??"linkedin",w=A.addToQueue??!1,{prompt:$,sourceEntityType:f,sourceEntityId:I}=A,{content:D,title:H}=A;if(D&&H)await this.reportProgress(Q,{progress:50,message:"Using provided content"});else if(D&&!H){await this.reportProgress(Q,{progress:10,message:"Shaping content with AI"});let C=await this.context.ai.generate({prompt:D,templateName:Mm(B)});H=C.title,D=C.content,await this.reportProgress(Q,{progress:50,message:"Social post shaped from content"})}else if(I&&f){await this.reportProgress(Q,{progress:10,message:`Fetching source ${f}`});let C=await this.context.entityService.getEntity({entityType:f,id:I});if(!C)this.failEarly(`Source entity not found: ${f}/${I}`);await this.reportProgress(Q,{progress:30,message:"Generating social post from source content"});let k=F.object({slug:F.string()}).safeParse(C.metadata),_=k.success?k.data.slug:I,o=await this.context.ai.generate({prompt:`Create an engaging ${B} post to promote this ${f}:
|
|
3529
3529
|
|
|
3530
3530
|
Source: ${f}/${_}
|
|
3531
3531
|
|
|
3532
3532
|
${C.content}`,templateName:Mm(B)});H=o.title,D=o.content,await this.reportProgress(Q,{progress:50,message:"Social post generated from source"})}else if($){await this.reportProgress(Q,{progress:10,message:"Generating social post with AI"});let C=await this.context.ai.generate({prompt:$,templateName:Mm(B)});H=C.title,D=C.content,await this.reportProgress(Q,{progress:50,message:"Social post generated"})}else this.failEarly("No content source provided (prompt, sourceEntityId, or content)");if(!D||!H)this.failEarly("Content or title was not generated");let W={title:H,platform:B,status:w?"queued":"draft",...I&&{sourceEntityId:I},...f&&{sourceEntityType:f}},G=Vf.createPostContent(W,D),Z=Vf.fromMarkdown(G).metadata;if(!Z)this.failEarly("Failed to parse social post metadata");let q=await VU({entityType:"social-post",title:H,deriveId:(C)=>`${B}-${U2(C)}`,regeneratePrompt:"Generate a different social media post title on the same topic.",context:this.context}),L=G;if(q!==H){Z.title=q,Z.slug=`${B}-${U2(q)}`;let C={...W,title:q};L=Vf.createPostContent(C,D)}return{id:Z.slug,content:L,metadata:Z,title:q,resultExtras:{slug:Z.slug},createOptions:{deduplicateId:!0}}}async onGenerationFailure(A,Q){await this.context.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:Q}})}async afterCreate(A,Q,B,w){if(A.generateImage){await this.reportProgress(B,{progress:90,message:"Queueing image generation"});let $=w.title??"Social Post";await this.context.jobs.enqueue({type:"image:image-generate",data:{prompt:`Social media graphic for: ${$}`,title:`${$} Image`,aspectRatio:"16:9",targetEntityType:"social-post",targetEntityId:Q},toolContext:{interfaceType:"job",userId:"system"}})}await this.context.messaging.send({type:"generate:report:success",payload:{entityType:"social-post",entityId:Q}})}summarizeDataForLog(A){return{platform:A.platform??"linkedin",hasPrompt:!!A.prompt,sourceEntityType:A.sourceEntityType,addToQueue:A.addToQueue??!1,generateImage:A.generateImage??!1,coverImage:!!A.coverImage}}}class pRA{config;logger;name="linkedin";apiBaseUrl="https://api.linkedin.com/v2";cachedUserId=null;constructor(A,Q){this.config=A;this.logger=Q}async publish(A,Q,B){if(!this.config.accessToken)throw Error("LinkedIn access token not configured");let w=await this.getAuthor(),$=null;if(B)$=await this.uploadImage(w,B);let f={shareCommentary:{text:A},shareMediaCategory:$?"IMAGE":"NONE",...$&&{media:[{status:"READY",media:$}]}},I=await fetch(`${this.apiBaseUrl}/ugcPosts`,{method:"POST",headers:{Authorization:`Bearer ${this.config.accessToken}`,"Content-Type":"application/json","X-Restli-Protocol-Version":"2.0.0"},body:JSON.stringify({author:w,lifecycleState:"PUBLISHED",specificContent:{"com.linkedin.ugc.ShareContent":f},visibility:{"com.linkedin.ugc.MemberNetworkVisibility":"PUBLIC"}})});if(!I.ok){let Y=await I.text();throw this.logger.error("LinkedIn API error",{status:I.status,error:Y}),Error(`LinkedIn API error: ${I.status} - ${Y}`)}let D=I.headers.get("X-RestLi-Id")??"";this.logger.info("LinkedIn post created",{postId:D,hasImage:!!$});let H={id:D};if(D)H.url=`https://www.linkedin.com/feed/update/${D}`;return H}async uploadImage(A,Q){try{let B=await fetch(`${this.apiBaseUrl}/assets?action=registerUpload`,{method:"POST",headers:{Authorization:`Bearer ${this.config.accessToken}`,"Content-Type":"application/json","X-Restli-Protocol-Version":"2.0.0"},body:JSON.stringify({registerUploadRequest:{recipes:["urn:li:digitalmediaRecipe:feedshare-image"],owner:A,serviceRelationships:[{relationshipType:"OWNER",identifier:"urn:li:userGeneratedContent"}]}})});if(!B.ok){let D=await B.text();return this.logger.warn("LinkedIn image upload registration failed",{status:B.status,error:D}),null}let w=await B.json(),$=w.value.uploadMechanism["com.linkedin.digitalmedia.uploading.MediaUploadHttpRequest"].uploadUrl,f=w.value.asset,I=await fetch($,{method:"PUT",headers:{Authorization:`Bearer ${this.config.accessToken}`,"Content-Type":Q.mimeType},body:new Uint8Array(Q.data)});if(!I.ok)return this.logger.warn("LinkedIn image binary upload failed",{status:I.status}),null;return this.logger.info("LinkedIn image uploaded",{assetUrn:f}),f}catch(B){return this.logger.warn("LinkedIn image upload error",{error:B}),null}}async validateCredentials(){if(!this.config.accessToken)return!1;try{if(this.config.organizationId)return(await fetch(`${this.apiBaseUrl}/organizations/${this.config.organizationId}`,{headers:{Authorization:`Bearer ${this.config.accessToken}`}})).ok;return await this.getUserId(),!0}catch{return!1}}async getAuthor(){if(this.config.organizationId)return`urn:li:organization:${this.config.organizationId}`;return this.getUserId()}async getUserId(){if(this.cachedUserId)return this.cachedUserId;if(!this.config.accessToken)throw Error("LinkedIn access token not configured");try{let B=await fetch("https://api.linkedin.com/v2/userinfo",{headers:{Authorization:`Bearer ${this.config.accessToken}`}});if(B.ok){let w=await B.json();return this.cachedUserId=`urn:li:person:${w.sub}`,this.cachedUserId}}catch{}let A=await fetch("https://api.linkedin.com/v2/me",{headers:{Authorization:`Bearer ${this.config.accessToken}`}});if(!A.ok){let B=await A.text();throw Error(`Failed to get LinkedIn user ID: ${A.status} - ${B}`)}let Q=await A.json();return this.cachedUserId=`urn:li:person:${Q.id}`,this.cachedUserId}}function lRA(A,Q){return new pRA(A,Q)}f0();GA();Rw();uRA();var dt2=F.object({posts:F.array(b2A),totalCount:F.number().optional(),pagination:Y9.nullable(),baseUrl:F.string().optional()}),nt2=F.object({post:b2A});function sw1(){return{linkedin:R2A,"social-post-list":O1({name:"social-post-list",description:"Social post list page template",schema:dt2,dataSourceId:"social-media:posts",requiredPermission:"public",layout:{component:_2A}}),"social-post-detail":O1({name:"social-post-detail",description:"Individual social post template",schema:nt2,dataSourceId:"social-media:posts",requiredPermission:"public",layout:{component:P2A}})}}GA();var ot2=F.object({prompt:F.string().optional(),content:F.string().optional(),platform:F.enum(["linkedin"]).default("linkedin")}),st2=F.object({prompt:F.string().optional(),content:F.string().optional(),title:F.string().optional(),platform:F.enum(["linkedin"]).optional()});function aw1(A){A.eval.registerHandler("generation",async(Q)=>{let B=ot2.parse(Q),w=B.content?`Create an engaging LinkedIn post to share this content:
|
|
3533
3533
|
|
|
3534
|
-
${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=st2.parse(Q),w=[],$=z$.from(async(Y)=>{let W={progress:Y.progress};if(Y.message!==void 0)W.message=Y.message;w.push(W)});if(!$)throw Error("Failed to create progress reporter");let I=await new mC(A.logger,A).process(B,`eval-${Date.now()}`,$),D=!1,H;if(I.success&&I.entityId){let Y=await A.entityService.getEntity({entityType:"social-post",id:I.entityId});D=!!Y,H=Y?.content.slice(0,300)}return{...I,entityExists:D,entityPreview:H,progressSteps:w}})}GA();f0();class Vm{sendMessage;logger;entityService;providers;constructor(A){this.sendMessage=A.sendMessage,this.logger=A.logger,this.entityService=A.entityService,this.providers=A.providers}async handle(A){let{entityType:Q,entityId:B}=A;if(Q!=="social-post")return;this.logger.debug("Handling publish:execute",{entityId:B});try{let w=await this.entityService.getEntity({entityType:"social-post",id:B});if(!w){await this.reportFailure(Q,B,`Post not found: ${B}`);return}if(w.metadata.status==="published"){this.logger.debug("Post already published, skipping",{entityId:B});return}let $=w.metadata.platform,f=this.providers.get($);if(!f){await this.reportFailure(Q,B,`No provider configured for platform: ${$}`);return}let I=t2(w.content,H4),D;if(I.metadata.coverImageId)D=await this.fetchImageData(I.metadata.coverImageId);try{let H=await f.publish(I.content,w.metadata,D),Y=new Date().toISOString(),W=H.id||void 0,G={...I.metadata,status:"published",publishedAt:Y,...W&&{platformPostId:W}},K=Vf.createPostContent(G,I.content);await this.entityService.updateEntity({entity:{...w,content:K,metadata:{...w.metadata,status:"published",publishedAt:Y,platformPostId:W}}}),await this.reportSuccess(Q,B,H.id),this.logger.info(`Post published successfully: ${B}`,{platform:$,platformPostId:W})}catch(H){let Y=H instanceof Error?H.message:String(H),W={...I.metadata,status:"failed"},G=Vf.createPostContent(W,I.content);await this.entityService.updateEntity({entity:{...w,content:G,metadata:{...w.metadata,status:"failed"}}}),await this.reportFailure(Q,B,Y),this.logger.error(`Post publish failed: ${B}`,{platform:$,error:Y})}}catch(w){let $=y0(w);this.logger.error("Unexpected error in publish handler",{entityId:B,error:$}),await this.reportFailure(Q,B,$)}}async reportSuccess(A,Q,B){await this.sendMessage({type:"publish:report:success",payload:{entityType:A,entityId:Q,result:{id:B}}})}async reportFailure(A,Q,B){await this.sendMessage({type:"publish:report:failure",payload:{entityType:A,entityId:Q,error:B}})}async fetchImageData(A){try{let Q=await this.entityService.getEntity({entityType:"image",id:A});if(!Q){this.logger.warn("Cover image not found",{imageId:A});return}let w=Q.content.match(/^data:([^;]+);base64,(.+)$/);if(!w?.[1]||!w[2]){this.logger.warn("Invalid image data URL format",{imageId:A});return}let $=w[1],f=w[2];return{data:Buffer.from(f,"base64"),mimeType:$}}catch(Q){this.logger.warn("Failed to fetch cover image",{imageId:A,error:Q});return}}}function tw1(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 ew1(A,Q,B){let w=new Vm({sendMessage:A.messaging.send,logger:B.child("PublishExecuteHandler"),entityService:A.entityService,providers:Q});A.messaging.subscribe("publish:execute",async($)=>{return await w.handle($.payload),{success:!0}}),B.debug("Subscribed to publish:execute messages")}GA();function A81(A,Q){A.messaging.subscribe("entity:updated",async(B)=>{let{entityType:w,entityId:$,entity:f}=B.payload;if(w!=="post")return{success:!0};if(f.metadata?.status!=="queued")return{success:!0};try{if((await A.entityService.listEntities({entityType:"social-post",options:{filter:{metadata:{sourceEntityType:"post",sourceEntityId:$}},limit:1}})).length>0)return Q.debug(`Social post already exists for ${$}, skipping auto-generate`),{success:!0};return await A.messaging.send({type:"social:auto-generate",payload:{sourceEntityType:w,sourceEntityId:$,platform:"linkedin"}}),Q.info(`Auto-generate social post triggered for queued post ${$}`),{success:!0}}catch(D){let H=y0(D);return Q.error(`Failed to trigger auto-generate for ${$}:`,{error:H}),{success:!0}}}),Q.debug("Subscribed to entity:updated for auto-generation")}function Q81(A,Q){A.messaging.subscribe("social:auto-generate",async(B)=>{let{sourceEntityType:w,sourceEntityId:$,platform:f}=B.payload;try{let I=await A.jobs.enqueue({type:`${Vf.entityType}:generation`,data:{sourceEntityType:w,sourceEntityId:$,platform:f,addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}});return Q.info(`Social post generation job enqueued for ${w}/${$}`,{jobId:I}),{success:!0,jobId:I}}catch(I){let D=y0(I);return Q.error(`Failed to enqueue social post generation for ${$}:`,{error:D}),{success:!1}}}),Q.debug("Subscribed to social:auto-generate messages")}function B81(A,Q){A.messaging.subscribe("generate:execute",async(B)=>{let{entityType:w}=B.payload;if(w!=="social-post")return{success:!0};Q.info("Received generate:execute for social-post");try{let $=await A.entityService.listEntities({entityType:"post",options:{filter:{metadata:{status:"published"}},limit:5}});if($.length===0)return Q.info("No published posts found for social post generation"),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:"No published posts available for social post generation"}}),{success:!0};let f=null;for(let D of $)if((await A.entityService.listEntities({entityType:"social-post",options:{filter:{metadata:{sourceEntityType:"post",sourceEntityId:D.id}},limit:1}})).length===0){f=D;break}if(!f)return Q.info("All recent posts already have social posts"),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:"All recent posts already have social posts generated"}}),{success:!0};let I=await A.jobs.enqueue({type:`${Vf.entityType}:generation`,data:{sourceEntityType:"post",sourceEntityId:f.id,platform:"linkedin",addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}});return Q.info("Social post generation job queued",{jobId:I,sourcePostId:f.id}),{success:!0}}catch($){let f=y0($);return Q.error("Failed to handle generate:execute:",{error:f}),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:f}}),{success:!0}}}),Q.debug("Subscribed to generate:execute messages")}var w81={name:"@brains/social-media",private:!0,version:"0.2.0-alpha.70",description:"Multi-provider social media posting with queue-based publishing",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class iRA extends KQ{entityType=Vf.entityType;schema=U_;adapter=Vf;providers=new Map;constructor(A){super("social-media",w81,A,SRA)}createGenerationHandler(A){return new mC(this.logger.child("GenerationJobHandler"),A)}getTemplates(){return sw1()}getDataSources(){return[new O2A(this.logger.child("SocialPostDataSource"))]}async onRegister(A){if(this.initializeProviders(),tw1(A,this.providers,this.logger),ew1(A,this.providers,this.logger),this.config.autoGenerateOnBlogPublish)A81(A,this.logger),Q81(A,this.logger),this.logger.info("Auto-generate on blog publish enabled");B81(A,this.logger),aw1(A),this.logger.info("Social media plugin registered successfully")}initializeProviders(){if(this.config.linkedin?.accessToken){let A=lRA(this.config.linkedin,this.logger.child("LinkedInClient"));this.providers.set("linkedin",A),this.logger.info("LinkedIn provider initialized")}}}function bm(A){return new iRA(A)}GA();var tt2=F.enum(["draft","queued","published","failed"]),KDw=F.object({status:tt2.default("draft"),queueOrder:F.number().optional().describe("Position in publish queue (lower = sooner)"),publishedAt:F.string().datetime().optional()});class rRA{name="internal";async publish(A,Q){return{id:"internal"}}}var k9={REGISTER:"publish:register",QUEUE:"publish:queue",DIRECT:"publish:direct",REMOVE:"publish:remove",REORDER:"publish:reorder",LIST:"publish:list",REPORT_SUCCESS:"publish:report:success",REPORT_FAILURE:"publish:report:failure",EXECUTE:"publish:execute",QUEUED:"publish:queued",COMPLETED:"publish:completed",FAILED:"publish:failed",LIST_RESPONSE:"publish:list:response"},rZ={REGISTER:"generate:register",REPORT_SUCCESS:"generate:report:success",REPORT_FAILURE:"generate:report:failure",EXECUTE:"generate:execute",COMPLETED:"generate:completed",FAILED:"generate:failed",SKIPPED:"generate:skipped"};GA();var et2=F.object({skipIfDraftExists:F.boolean().optional(),minSourceEntities:F.number().optional(),maxUnpublishedDrafts:F.number().optional(),sourceEntityType:F.string().optional()}),$81=F.object({entitySchedules:F.record(F.string(),F.string()).optional(),generationSchedules:F.record(F.string(),F.string()).optional(),generationConditions:F.record(F.string(),et2).optional(),maxRetries:F.number().optional().default(3),retryBaseDelayMs:F.number().optional().default(5000)});class FW{static instance=null;queues=new Map;static getInstance(){return FW.instance??=new FW,FW.instance}static resetInstance(){FW.instance=null}static createFresh(){return new FW}constructor(){}async add(A,Q){let B=this.getOrCreateQueue(A),w=B.find((I)=>I.entityId===Q);if(w)return{position:w.position};let $=B.length+1,f={entityId:Q,entityType:A,position:$,queuedAt:new Date().toISOString()};return B.push(f),{position:$}}async remove(A,Q){let B=this.queues.get(A);if(!B)return;let w=B.findIndex(($)=>$.entityId===Q);if(w===-1)return;B.splice(w,1),this.recalculatePositions(B)}async reorder(A,Q,B){let w=this.queues.get(A);if(!w)return;let $=w.findIndex((D)=>D.entityId===Q);if($===-1)return;let[f]=w.splice($,1);if(!f)return;let I=Math.max(0,Math.min(B-1,w.length));w.splice(I,0,f),this.recalculatePositions(w)}async list(A){let Q=this.queues.get(A);if(!Q)return[];return[...Q]}async getNext(A){let Q=this.queues.get(A);if(!Q||Q.length===0)return null;return Q[0]??null}async getNextAcrossTypes(){let A=null;for(let Q of this.queues.values()){let B=Q[0];if(!B)continue;if(!A||B.queuedAt<A.queuedAt)A=B}return A}async popNext(A){let Q=this.queues.get(A);if(!Q||Q.length===0)return null;let B=Q.shift()??null;if(B)this.recalculatePositions(Q);return B}getRegisteredTypes(){return Array.from(this.queues.keys())}async getQueuedEntityTypes(){let A=[];for(let[Q,B]of this.queues.entries())if(B.length>0)A.push(Q);return A}getOrCreateQueue(A){let Q=this.queues.get(A);if(!Q)Q=[],this.queues.set(A,Q);return Q}recalculatePositions(A){A.forEach((Q,B)=>{Q.position=B+1})}}class KW{static instance=null;providers=new Map;defaultProvider=new rRA;static getInstance(){return KW.instance??=new KW,KW.instance}static resetInstance(){KW.instance=null}static createFresh(){return new KW}constructor(){}register(A,Q){this.providers.set(A,Q)}get(A){return this.providers.get(A)??this.defaultProvider}has(A){return this.providers.has(A)}unregister(A){this.providers.delete(A)}getRegisteredTypes(){return Array.from(this.providers.keys())}}GA();GA();async function f81(A,Q){let B={entityType:A.entityType,entityId:A.entityId};if(Q.messageBus)await Q.messageBus.send({type:k9.EXECUTE,payload:B,sender:"publish-service"});Q.onExecute?.(B)}async function I81(A,Q){let B=Q.providerRegistry.get(A.entityType);if(!Q.entityService){Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:"EntityService not available for provider mode",retryCount:0,willRetry:!1});return}let w=await Q.entityService.getEntity({entityType:A.entityType,id:A.entityId});if(!w){Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:`Entity not found: ${A.entityType}/${A.entityId}`,retryCount:0,willRetry:!1});return}try{let $=await B.publish(w.content,w.metadata);Q.retryTracker.clearRetries(A.entityId),Q.onPublish?.({entityType:A.entityType,entityId:A.entityId,result:$})}catch($){let f=y0($);Q.retryTracker.recordFailure(A.entityId,f);let I=Q.retryTracker.getRetryInfo(A.entityId);Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:f,retryCount:I?.retryCount??1,willRetry:I?.willRetry??!1})}}function D81(A,Q,B,w){if(w.retryTracker.clearRetries(Q),w.messageBus)w.messageBus.send({type:k9.COMPLETED,payload:{entityType:A,entityId:Q,result:B},sender:"publish-service"});w.onPublish?.({entityType:A,entityId:Q,result:B})}function H81(A,Q,B,w){w.retryTracker.recordFailure(Q,B);let $=w.retryTracker.getRetryInfo(Q),f={entityType:A,entityId:Q,error:B,retryCount:$?.retryCount??1,willRetry:$?.willRetry??!1};if(w.messageBus)w.messageBus.send({type:k9.FAILED,payload:f,sender:"publish-service"});w.onFailed?.(f)}async function Y81(A,Q){let B=Q.generationConditions[A];if(B&&Q.onCheckGenerationConditions){let $=await Q.onCheckGenerationConditions(A,B);if(!$.shouldGenerate){if(Q.messageBus)Q.messageBus.send({type:rZ.SKIPPED,payload:{entityType:A,reason:$.reason??"Conditions not met"},sender:"content-pipeline"});return}}let w={entityType:A};if(Q.messageBus)await Q.messageBus.send({type:rZ.EXECUTE,payload:w,sender:"content-pipeline"});Q.onGenerate?.(w)}function X81(A,Q,B){if(B)B.send({type:rZ.COMPLETED,payload:{entityType:A,entityId:Q},sender:"content-pipeline"})}function W81(A,Q,B){if(B)B.send({type:rZ.FAILED,payload:{entityType:A,error:Q},sender:"content-pipeline"})}var Ae2=1000;class dRA{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(Ae2,()=>this.processUnscheduledTypes())}stop(){if(Qe2(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 f81(A,this.deps.getPublishDeps());else await I81(A,this.deps.getPublishDeps())}get entitySchedules(){return this.deps.config.entitySchedules}}function Qe2(A){for(let Q of A.values())Q.stop();A.clear()}class nRA{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(){Be2(this.generationJobs)}async handleTriggerGeneration(A){if(!this.deps.isRunning())return;try{await Y81(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 Be2(A){for(let Q of A.values())Q.stop();A.clear()}class fY{static instance=null;config;publishRunner;generationRunner;running=!1;static getInstance(A){return fY.instance??=new fY(A),fY.instance}static resetInstance(){if(fY.instance)fY.instance.stop();fY.instance=null}static createFresh(A){return new fY(A)}constructor(A){this.config={...A,entitySchedules:A.entitySchedules??{},generationSchedules:A.generationSchedules??{},generationConditions:A.generationConditions??{}},this.validateCronExpressions(),this.publishRunner=new dRA({config:this.config,getPublishDeps:()=>this.publishDeps,isRunning:()=>this.running}),this.generationRunner=new nRA({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){D81(A,Q,B,this.publishDeps)}failPublish(A,Q,B){H81(A,Q,B,this.publishDeps)}async publishDirect(A,Q,B,w){return this.config.providerRegistry.get(A).publish(B,w)}completeGeneration(A,Q){X81(A,Q,this.config.messageBus)}failGeneration(A,Q){W81(A,Q,this.config.messageBus)}get entitySchedules(){return this.config.entitySchedules}get generationSchedules(){return this.config.generationSchedules}get publishDeps(){return{providerRegistry:this.config.providerRegistry,retryTracker:this.config.retryTracker,messageBus:this.config.messageBus,entityService:this.config.entityService,onExecute:this.config.onExecute,onPublish:this.config.onPublish,onFailed:this.config.onFailed}}get generationDeps(){return{logger:this.config.logger,messageBus:this.config.messageBus,generationConditions:this.config.generationConditions,onCheckGenerationConditions:this.config.onCheckGenerationConditions,onGenerate:this.config.onGenerate}}validateCronExpressions(){for(let[A,Q]of Object.entries(this.entitySchedules))this.validateCronExpression(A,Q,"publish");for(let[A,Q]of Object.entries(this.generationSchedules))this.validateCronExpression(A,Q,"generation")}validateCronExpression(A,Q,B){try{this.config.backend.validateCron(Q)}catch(w){throw Error(`Invalid ${B} cron expression for ${A}: "${Q}" - ${y0(w)}`)}}}var U81={maxRetries:3,baseDelayMs:5000};class ZW{static instance=null;retries=new Map;config;static getInstance(A){return ZW.instance??=new ZW(A??U81),ZW.instance}static resetInstance(){ZW.instance=null}static createFresh(A){return new ZW(A??U81)}constructor(A){this.config=A}recordFailure(A,Q){let w=(this.retries.get(A)?.retryCount??0)+1,$=this.config.baseDelayMs*Math.pow(2,w-1),f=Date.now()+$;this.retries.set(A,{entityId:A,retryCount:w,lastError:Q,nextRetryAt:f})}shouldRetry(A){let Q=this.retries.get(A);if(!Q)return!1;return Q.retryCount<this.config.maxRetries}isReadyForRetry(A){let Q=this.retries.get(A);if(!Q)return!1;return Date.now()>=Q.nextRetryAt}clearRetries(A){this.retries.delete(A)}getRetryInfo(A){let Q=this.retries.get(A);if(!Q)return null;return{entityId:Q.entityId,retryCount:Q.retryCount,lastError:Q.lastError,nextRetryAt:Q.nextRetryAt,willRetry:Q.retryCount<this.config.maxRetries}}}function j9(A,Q,B,w,$,f,I,D){return j9.fromTZ(j9.tp(A,Q,B,w,$,f,I),D)}j9.fromTZISO=(A,Q,B)=>j9.fromTZ(we2(A,Q),B);j9.fromTZ=function(A,Q){let B=new Date(Date.UTC(A.y,A.m-1,A.d,A.h,A.i,A.s)),w=oRA(A.tz,B),$=new Date(B.getTime()-w),f=oRA(A.tz,$);if(f-w===0)return $;{let I=new Date(B.getTime()-f),D=oRA(A.tz,I);if(D-f===0)return I;if(!Q&&D-f>0)return I;if(Q)throw Error("Invalid date passed to fromTZ()");return $}};j9.toTZ=function(A,Q){let B=A.toLocaleString("en-US",{timeZone:Q}).replace(/[\u202f]/," "),w=new Date(B);return{y:w.getFullYear(),m:w.getMonth()+1,d:w.getDate(),h:w.getHours(),i:w.getMinutes(),s:w.getSeconds(),tz:Q}};j9.tp=(A,Q,B,w,$,f,I)=>({y:A,m:Q,d:B,h:w,i:$,s:f,tz:I});function oRA(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 we2(A,Q){let B=new Date(Date.parse(A));if(isNaN(B))throw Error("minitz: Invalid ISO8601 passed to parser.");let w=A.substring(9);return A.includes("Z")||w.includes("-")||w.includes("+")?j9.tp(B.getUTCFullYear(),B.getUTCMonth()+1,B.getUTCDate(),B.getUTCHours(),B.getUTCMinutes(),B.getUTCSeconds(),"Etc/UTC"):j9.tp(B.getFullYear(),B.getMonth()+1,B.getDate(),B.getHours(),B.getMinutes(),B.getSeconds(),Q)}j9.minitz=j9;var sRA=32,Rm=31|sRA,K81=[1,2,4,8,16],J81=class{pattern;timezone;second;minute;hour;day;month;dayOfWeek;lastDayOfMonth;starDOM;starDOW;constructor(A,Q){this.pattern=A,this.timezone=Q,this.second=Array(60).fill(0),this.minute=Array(60).fill(0),this.hour=Array(24).fill(0),this.day=Array(31).fill(0),this.month=Array(12).fill(0),this.dayOfWeek=Array(7).fill(0),this.lastDayOfMonth=!1,this.starDOM=!1,this.starDOW=!1,this.parse()}parse(){if(!(typeof this.pattern=="string"||this.pattern instanceof String))throw TypeError("CronPattern: Pattern has to be of type string.");this.pattern.indexOf("@")>=0&&(this.pattern=this.handleNicknames(this.pattern).trim());let A=this.pattern.replace(/\s+/g," ").split(" ");if(A.length<5||A.length>6)throw TypeError("CronPattern: invalid configuration format ('"+this.pattern+"'), exactly five or six space separated parts are required.");if(A.length===5&&A.unshift("0"),A[3].indexOf("L")>=0&&(A[3]=A[3].replace("L",""),this.lastDayOfMonth=!0),A[3]=="*"&&(this.starDOM=!0),A[4].length>=3&&(A[4]=this.replaceAlphaMonths(A[4])),A[5].length>=3&&(A[5]=this.replaceAlphaDays(A[5])),A[5]=="*"&&(this.starDOW=!0),this.pattern.indexOf("?")>=0){let Q=new Y4(new Date,this.timezone).getDate(!0);A[0]=A[0].replace("?",Q.getSeconds().toString()),A[1]=A[1].replace("?",Q.getMinutes().toString()),A[2]=A[2].replace("?",Q.getHours().toString()),this.starDOM||(A[3]=A[3].replace("?",Q.getDate().toString())),A[4]=A[4].replace("?",(Q.getMonth()+1).toString()),this.starDOW||(A[5]=A[5].replace("?",Q.getDay().toString()))}this.throwAtIllegalCharacters(A),this.partToArray("second",A[0],0,1),this.partToArray("minute",A[1],0,1),this.partToArray("hour",A[2],0,1),this.partToArray("day",A[3],-1,1),this.partToArray("month",A[4],-1,1),this.partToArray("dayOfWeek",A[5],0,Rm),this.dayOfWeek[7]&&(this.dayOfWeek[0]=this.dayOfWeek[7])}partToArray(A,Q,B,w){let $=this[A],f=A==="day"&&this.lastDayOfMonth;if(Q===""&&!f)throw TypeError("CronPattern: configuration entry "+A+" ("+Q+") is empty, check for trailing spaces.");if(Q==="*")return $.fill(w);let I=Q.split(",");if(I.length>1)for(let D=0;D<I.length;D++)this.partToArray(A,I[D],B,w);else Q.indexOf("-")!==-1&&Q.indexOf("/")!==-1?this.handleRangeWithStepping(Q,A,B,w):Q.indexOf("-")!==-1?this.handleRange(Q,A,B,w):Q.indexOf("/")!==-1?this.handleStepping(Q,A,B,w):Q!==""&&this.handleNumber(Q,A,B,w)}throwAtIllegalCharacters(A){for(let Q=0;Q<A.length;Q++)if((Q===5?/[^/*0-9,\-#L]+/:/[^/*0-9,-]+/).test(A[Q]))throw TypeError("CronPattern: configuration entry "+Q+" ("+A[Q]+") contains illegal characters.")}handleNumber(A,Q,B,w){let $=this.extractNth(A,Q),f=parseInt($[0],10)+B;if(isNaN(f))throw TypeError("CronPattern: "+Q+" is not a number: '"+A+"'");this.setPart(Q,f,$[1]||w)}setPart(A,Q,B){if(!Object.prototype.hasOwnProperty.call(this,A))throw TypeError("CronPattern: Invalid part specified: "+A);if(A==="dayOfWeek"){if(Q===7&&(Q=0),Q<0||Q>6)throw RangeError("CronPattern: Invalid value for dayOfWeek: "+Q);this.setNthWeekdayOfMonth(Q,B);return}if(A==="second"||A==="minute"){if(Q<0||Q>=60)throw RangeError("CronPattern: Invalid value for "+A+": "+Q)}else if(A==="hour"){if(Q<0||Q>=24)throw RangeError("CronPattern: Invalid value for "+A+": "+Q)}else if(A==="day"){if(Q<0||Q>=31)throw RangeError("CronPattern: Invalid value for "+A+": "+Q)}else if(A==="month"&&(Q<0||Q>=12))throw RangeError("CronPattern: Invalid value for "+A+": "+Q);this[A][Q]=B}handleRangeWithStepping(A,Q,B,w){let $=this.extractNth(A,Q),f=$[0].match(/^(\d+)-(\d+)\/(\d+)$/);if(f===null)throw TypeError("CronPattern: Syntax error, illegal range with stepping: '"+A+"'");let[,I,D,H]=f,Y=parseInt(I,10)+B,W=parseInt(D,10)+B,G=parseInt(H,10);if(isNaN(Y))throw TypeError("CronPattern: Syntax error, illegal lower range (NaN)");if(isNaN(W))throw TypeError("CronPattern: Syntax error, illegal upper range (NaN)");if(isNaN(G))throw TypeError("CronPattern: Syntax error, illegal stepping: (NaN)");if(G===0)throw TypeError("CronPattern: Syntax error, illegal stepping: 0");if(G>this[Q].length)throw TypeError("CronPattern: Syntax error, steps cannot be greater than maximum value of part ("+this[Q].length+")");if(Y>W)throw TypeError("CronPattern: From value is larger than to value: '"+A+"'");for(let K=Y;K<=W;K+=G)this.setPart(Q,K,$[1]||w)}extractNth(A,Q){let B=A,w;if(B.includes("#")){if(Q!=="dayOfWeek")throw Error("CronPattern: nth (#) only allowed in day-of-week field");w=B.split("#")[1],B=B.split("#")[0]}return[B,w]}handleRange(A,Q,B,w){let $=this.extractNth(A,Q),f=$[0].split("-");if(f.length!==2)throw TypeError("CronPattern: Syntax error, illegal range: '"+A+"'");let I=parseInt(f[0],10)+B,D=parseInt(f[1],10)+B;if(isNaN(I))throw TypeError("CronPattern: Syntax error, illegal lower range (NaN)");if(isNaN(D))throw TypeError("CronPattern: Syntax error, illegal upper range (NaN)");if(I>D)throw TypeError("CronPattern: From value is larger than to value: '"+A+"'");for(let H=I;H<=D;H++)this.setPart(Q,H,$[1]||w)}handleStepping(A,Q,B,w){let $=this.extractNth(A,Q),f=$[0].split("/");if(f.length!==2)throw TypeError("CronPattern: Syntax error, illegal stepping: '"+A+"'");f[0]===""&&(f[0]="*");let I=0;f[0]!=="*"&&(I=parseInt(f[0],10)+B);let D=parseInt(f[1],10);if(isNaN(D))throw TypeError("CronPattern: Syntax error, illegal stepping: (NaN)");if(D===0)throw TypeError("CronPattern: Syntax error, illegal stepping: 0");if(D>this[Q].length)throw TypeError("CronPattern: Syntax error, max steps for part is ("+this[Q].length+")");for(let H=I;H<this[Q].length;H+=D)this.setPart(Q,H,$[1]||w)}replaceAlphaDays(A){return A.replace(/-sun/gi,"-7").replace(/sun/gi,"0").replace(/mon/gi,"1").replace(/tue/gi,"2").replace(/wed/gi,"3").replace(/thu/gi,"4").replace(/fri/gi,"5").replace(/sat/gi,"6")}replaceAlphaMonths(A){return A.replace(/jan/gi,"1").replace(/feb/gi,"2").replace(/mar/gi,"3").replace(/apr/gi,"4").replace(/may/gi,"5").replace(/jun/gi,"6").replace(/jul/gi,"7").replace(/aug/gi,"8").replace(/sep/gi,"9").replace(/oct/gi,"10").replace(/nov/gi,"11").replace(/dec/gi,"12")}handleNicknames(A){let Q=A.trim().toLowerCase();return Q==="@yearly"||Q==="@annually"?"0 0 1 1 *":Q==="@monthly"?"0 0 1 * *":Q==="@weekly"?"0 0 * * 0":Q==="@daily"?"0 0 * * *":Q==="@hourly"?"0 * * * *":A}setNthWeekdayOfMonth(A,Q){if(typeof Q!="number"&&Q==="L")this.dayOfWeek[A]=this.dayOfWeek[A]|sRA;else if(Q===Rm)this.dayOfWeek[A]=Rm;else if(Q<6&&Q>0)this.dayOfWeek[A]=this.dayOfWeek[A]|K81[Q-1];else throw TypeError(`CronPattern: nth weekday out of range, should be 1-5 or L. Value: ${Q}, Type: ${typeof Q}`)}},G81=[31,28,31,30,31,30,31,31,30,31,30,31],HG=[["month","year",0],["day","month",-1],["hour","day",0],["minute","hour",0],["second","minute",0]],Y4=class A{tz;ms;second;minute;hour;day;month;year;constructor(Q,B){if(this.tz=B,Q&&Q instanceof Date)if(!isNaN(Q))this.fromDate(Q);else throw TypeError("CronDate: Invalid date passed to CronDate constructor");else if(Q===void 0)this.fromDate(new Date);else if(Q&&typeof Q=="string")this.fromString(Q);else if(Q instanceof A)this.fromCronDate(Q);else throw TypeError("CronDate: Invalid type ("+typeof Q+") passed to CronDate constructor")}isNthWeekdayOfMonth(Q,B,w,$){let f=new Date(Date.UTC(Q,B,w)).getUTCDay(),I=0;for(let D=1;D<=w;D++)new Date(Date.UTC(Q,B,D)).getUTCDay()===f&&I++;if($&Rm&&K81[I-1]&$)return!0;if($&sRA){let D=new Date(Date.UTC(Q,B+1,0)).getUTCDate();for(let H=w+1;H<=D;H++)if(new Date(Date.UTC(Q,B,H)).getUTCDay()===f)return!1;return!0}return!1}fromDate(Q){if(this.tz!==void 0)if(typeof this.tz=="number")this.ms=Q.getUTCMilliseconds(),this.second=Q.getUTCSeconds(),this.minute=Q.getUTCMinutes()+this.tz,this.hour=Q.getUTCHours(),this.day=Q.getUTCDate(),this.month=Q.getUTCMonth(),this.year=Q.getUTCFullYear(),this.apply();else{let B=j9.toTZ(Q,this.tz);this.ms=Q.getMilliseconds(),this.second=B.s,this.minute=B.i,this.hour=B.h,this.day=B.d,this.month=B.m-1,this.year=B.y}else this.ms=Q.getMilliseconds(),this.second=Q.getSeconds(),this.minute=Q.getMinutes(),this.hour=Q.getHours(),this.day=Q.getDate(),this.month=Q.getMonth(),this.year=Q.getFullYear()}fromCronDate(Q){this.tz=Q.tz,this.year=Q.year,this.month=Q.month,this.day=Q.day,this.hour=Q.hour,this.minute=Q.minute,this.second=Q.second,this.ms=Q.ms}apply(){if(this.month>11||this.day>G81[this.month]||this.hour>59||this.minute>59||this.second>59||this.hour<0||this.minute<0||this.second<0){let Q=new Date(Date.UTC(this.year,this.month,this.day,this.hour,this.minute,this.second,this.ms));return this.ms=Q.getUTCMilliseconds(),this.second=Q.getUTCSeconds(),this.minute=Q.getUTCMinutes(),this.hour=Q.getUTCHours(),this.day=Q.getUTCDate(),this.month=Q.getUTCMonth(),this.year=Q.getUTCFullYear(),!0}else return!1}fromString(Q){if(typeof this.tz=="number"){let B=j9.fromTZISO(Q);this.ms=B.getUTCMilliseconds(),this.second=B.getUTCSeconds(),this.minute=B.getUTCMinutes(),this.hour=B.getUTCHours(),this.day=B.getUTCDate(),this.month=B.getUTCMonth(),this.year=B.getUTCFullYear(),this.apply()}else return this.fromDate(j9.fromTZISO(Q,this.tz))}findNext(Q,B,w,$){let f=this[B],I;w.lastDayOfMonth&&(this.month!==1?I=G81[this.month]:I=new Date(Date.UTC(this.year,this.month+1,0,0,0,0,0)).getUTCDate());let D=!w.starDOW&&B=="day"?new Date(Date.UTC(this.year,this.month,1,0,0,0,0)).getUTCDay():void 0;for(let H=this[B]+$;H<w[B].length;H++){let Y=w[B][H];if(B==="day"&&w.lastDayOfMonth&&H-$==I&&(Y=1),B==="day"&&!w.starDOW){let W=w.dayOfWeek[(D+(H-$-1))%7];if(W&&W&Rm)W=this.isNthWeekdayOfMonth(this.year,this.month,H-$,W)?1:0;else if(W)throw Error(`CronDate: Invalid value for dayOfWeek encountered. ${W}`);Q.legacyMode&&!w.starDOM?Y=Y||W:Y=Y&&W}if(Y)return this[B]=H-$,f!==this[B]?2:1}return 3}recurse(Q,B,w){let $=this.findNext(B,HG[w][0],Q,HG[w][2]);if($>1){let f=w+1;for(;f<HG.length;)this[HG[f][0]]=-HG[f][2],f++;if($===3)return this[HG[w][1]]++,this[HG[w][0]]=-HG[w][2],this.apply(),this.recurse(Q,B,0);if(this.apply())return this.recurse(Q,B,w-1)}return w+=1,w>=HG.length?this:this.year>=3000?null:this.recurse(Q,B,w)}increment(Q,B,w){return this.second+=B.interval!==void 0&&B.interval>1&&w?B.interval:1,this.ms=0,this.apply(),this.recurse(Q,B,0)}getDate(Q){return Q||this.tz===void 0?new Date(this.year,this.month,this.day,this.hour,this.minute,this.second,this.ms):typeof this.tz=="number"?new Date(Date.UTC(this.year,this.month,this.day,this.hour,this.minute-this.tz,this.second,this.ms)):j9.fromTZ(j9.tp(this.year,this.month+1,this.day,this.hour,this.minute,this.second,this.tz),!1)}getTime(){return this.getDate(!1).getTime()}};function $e2(A){if(A===void 0&&(A={}),delete A.name,A.legacyMode=A.legacyMode===void 0?!0:A.legacyMode,A.paused=A.paused===void 0?!1:A.paused,A.maxRuns=A.maxRuns===void 0?1/0:A.maxRuns,A.catch=A.catch===void 0?!1:A.catch,A.interval=A.interval===void 0?0:parseInt(A.interval.toString(),10),A.utcOffset=A.utcOffset===void 0?void 0:parseInt(A.utcOffset.toString(),10),A.unref=A.unref===void 0?!1:A.unref,A.startAt&&(A.startAt=new Y4(A.startAt,A.timezone)),A.stopAt&&(A.stopAt=new Y4(A.stopAt,A.timezone)),A.interval!==null){if(isNaN(A.interval))throw Error("CronOptions: Supplied value for interval is not a number");if(A.interval<0)throw Error("CronOptions: Supplied value for interval can not be negative")}if(A.utcOffset!==void 0){if(isNaN(A.utcOffset))throw Error("CronOptions: Invalid value passed for utcOffset, should be number representing minutes offset from UTC.");if(A.utcOffset<-870||A.utcOffset>870)throw Error("CronOptions: utcOffset out of bounds.");if(A.utcOffset!==void 0&&A.timezone)throw Error("CronOptions: Combining 'utcOffset' with 'timezone' is not allowed.")}if(A.unref!==!0&&A.unref!==!1)throw Error("CronOptions: Unref should be either true, false or undefined(false).");return A}function Om(A){return Object.prototype.toString.call(A)==="[object Function]"||typeof A=="function"||A instanceof Function}function fe2(A){return Om(A)}function Ie2(A){typeof Deno<"u"&&typeof Deno.unrefTimer<"u"?Deno.unrefTimer(A):A&&typeof A.unref<"u"&&A.unref()}var F81=30000,k2A=[],aRA=class{name;options;_states;fn;constructor(A,Q,B){let w,$;if(Om(Q))$=Q;else if(typeof Q=="object")w=Q;else if(Q!==void 0)throw Error("Cron: Invalid argument passed for optionsIn. Should be one of function, or object (options).");if(Om(B))$=B;else if(typeof B=="object")w=B;else if(B!==void 0)throw Error("Cron: Invalid argument passed for funcIn. Should be one of function, or object (options).");if(this.name=w?.name,this.options=$e2(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 J81("* * * * *")},A&&(A instanceof Date||typeof A=="string"&&A.indexOf(":")>0)?this._states.once=new Y4(A,this.options.timezone||this.options.utcOffset):this._states.pattern=new J81(A,this.options.timezone),this.name){if(k2A.find((f)=>f.name===this.name))throw Error("Cron: Tried to initialize new named job '"+this.name+"', but name already taken.");k2A.push(this)}return $!==void 0&&fe2($)&&(this.fn=$,this.schedule()),this}nextRun(A){let Q=this._next(A);return Q?Q.getDate(!1):null}nextRuns(A,Q){this._states.maxRuns!==void 0&&A>this._states.maxRuns&&(A=this._states.maxRuns);let B=[],w=Q||this._states.currentRun||void 0;for(;A--&&(w=this.nextRun(w));)B.push(w);return B}getPattern(){return this._states.pattern?this._states.pattern.pattern:void 0}isRunning(){let A=this.nextRun(this._states.currentRun),Q=!this._states.paused,B=this.fn!==void 0,w=!this._states.kill;return Q&&B&&w&&A!==null}isStopped(){return this._states.kill}isBusy(){return this._states.blocking}currentRun(){return this._states.currentRun?this._states.currentRun.getDate():null}previousRun(){return this._states.previousRun?this._states.previousRun.getDate():null}msToNext(A){let Q=this._next(A);return Q?A instanceof Y4||A instanceof Date?Q.getTime()-A.getTime():Q.getTime()-new Y4(A).getTime():null}stop(){this._states.kill=!0,this._states.currentTimeout&&clearTimeout(this._states.currentTimeout);let A=k2A.indexOf(this);A>=0&&k2A.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>F81&&(Q=F81),this._states.currentTimeout=setTimeout(()=>this._checkTrigger(B),Q),this._states.currentTimeout&&this.options.unref&&Ie2(this._states.currentTimeout),this)}async _trigger(A){if(this._states.blocking=!0,this._states.currentRun=new Y4(void 0,this.options.timezone||this.options.utcOffset),this.options.catch)try{this.fn!==void 0&&await this.fn(this,this.options.context)}catch(Q){Om(this.options.catch)&&this.options.catch(Q,this)}else this.fn!==void 0&&await this.fn(this,this.options.context);this._states.previousRun=new Y4(A,this.options.timezone||this.options.utcOffset),this._states.blocking=!1}async trigger(){await this._trigger()}runsLeft(){return this._states.maxRuns}_checkTrigger(A){let Q=new Date,B=!this._states.paused&&Q.getTime()>=A.getTime(),w=this._states.blocking&&this.options.protect;B&&!w?(this._states.maxRuns!==void 0&&this._states.maxRuns--,this._trigger()):B&&w&&Om(this.options.protect)&&setTimeout(()=>this.options.protect(this),0),this.schedule()}_next(A){let Q=!!(A||this._states.currentRun),B=!1;!A&&this.options.startAt&&this.options.interval&&([A,Q]=this._calculatePreviousRun(A,Q),B=!A),A=new Y4(A,this.options.timezone||this.options.utcOffset),this.options.startAt&&A&&A.getTime()<this.options.startAt.getTime()&&(A=this.options.startAt);let w=this._states.once||new Y4(A,this.options.timezone||this.options.utcOffset);return!B&&w!==this._states.once&&(w=w.increment(this._states.pattern,this.options,Q)),this._states.once&&this._states.once.getTime()<=A.getTime()||w===null||this._states.maxRuns!==void 0&&this._states.maxRuns<=0||this._states.kill||this.options.stopAt&&w.getTime()>=this.options.stopAt.getTime()?null:w}_calculatePreviousRun(A,Q){let B=new Y4(void 0,this.options.timezone||this.options.utcOffset),w=A;if(this.options.startAt.getTime()<=B.getTime()){w=this.options.startAt;let $=w.getTime()+this.options.interval*1000;for(;$<=B.getTime();)w=new Y4(w,this.options.timezone||this.options.utcOffset).increment(this._states.pattern,this.options,!0),$=w.getTime()+this.options.interval*1000;Q=!0}return w===null&&(w=void 0),[w,Q]}};class j2A{scheduleCron(A,Q){let B=new aRA(A,()=>{Q()});return{stop:()=>B.stop()}}scheduleInterval(A,Q){let B=setInterval(()=>{Q()},A);return{stop:()=>clearInterval(B)}}validateCron(A){new aRA(A).stop()}}f0();GA();var tRA=F.object({action:F.enum(["list","add","remove","reorder"]).describe("Queue action to perform"),entityType:F.string().optional().describe("Entity type (required for add/remove/reorder, optional for list)"),entityId:F.string().optional().describe("Entity ID (required for add/remove/reorder)"),position:F.number().optional().describe("New position for reorder action (1-based)")}),eRA=F.object({position:F.number(),entityType:F.string(),entityId:F.string(),queuedAt:F.string()}),De2=F.object({success:F.literal(!0),message:F.string().optional(),data:F.object({queue:F.array(eRA).optional(),entityType:F.string().optional(),entityId:F.string().optional(),position:F.number().optional()}).optional()}),He2=F.object({success:F.literal(!1),error:F.string(),code:F.string().optional()}),A_A=F.union([De2,He2]);function v2A(A,Q,B){return{...xQ(Q,"queue","Manage the publish queue for all entity types (list, add, remove, reorder)",tRA,async($)=>{let{action:f,entityType:I,entityId:D,position:H}=$;switch(f){case"list":return Ye2(B,I);case"add":return Xe2(B,I,D);case"remove":return We2(B,I,D);case"reorder":return Ue2(B,I,D,H);default:return{success:!1,error:`Unknown action: ${f}`}}}),outputSchema:A_A}}async function Ye2(A,Q){let B=[];if(Q)B=await A.list(Q);else{let $=A.getRegisteredTypes();for(let f of $){let I=await A.list(f);B.push(...I)}B.sort((f,I)=>new Date(f.queuedAt).getTime()-new Date(I.queuedAt).getTime())}if(B.length===0)return{success:!0,data:{queue:[]},message:"No items in queue"};return{success:!0,data:{queue:B.map(($,f)=>({position:f+1,entityType:$.entityType,entityId:$.entityId,queuedAt:$.queuedAt}))},message:`${B.length} items in queue`}}async function Xe2(A,Q,B){let w=Q_A("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 We2(A,Q,B){let w=Q_A("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 Ue2(A,Q,B,w){let $=Q_A("reorder",Q,B);if(!$.success)return $.error;let f=Je2(w);if(!f.success)return f.error;return await A.reorder($.entityType,$.entityId,f.position),{success:!0,data:{entityType:$.entityType,entityId:$.entityId,position:f.position},message:`Moved to position ${f.position}`}}function Q_A(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 Je2(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}}f0();GA();f0();GA();async function Z81(A,Q){let{bodyContent:B,coverImageId:w}=Ge2(Q.content),$=w?await Fe2(A,w):void 0,f={bodyContent:B};if($)f.imageData=$;return f}function Ge2(A){try{let Q=t2(A,F.record(F.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 Fe2(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 B_A=F.object({entityType:F.string().describe("Entity type to publish (e.g., social-post, post, deck)"),id:F.string().optional().describe("Entity ID to publish"),slug:F.string().optional().describe("Entity slug to publish")}),Ke2=F.object({success:F.literal(!0),message:F.string().optional(),data:F.object({entityType:F.string().optional(),entityId:F.string().optional(),platformId:F.string().optional(),url:F.string().optional()}).optional()}),Ze2=F.object({success:F.literal(!1),error:F.string(),code:F.string().optional()}),w_A=F.union([Ke2,Ze2]);function x2A(A,Q,B){return{...xQ(Q,"publish","Publish an entity directly to its platform. Works with any registered entity type (social-post, post, deck, etc.)",B_A,async($)=>{let{entityType:f,id:I,slug:D}=$;if(!I&&!D)return{success:!1,error:"Either 'id' or 'slug' must be provided"};let H=await Ne2(A,f,I,D);if(!H)return{success:!1,error:`Entity not found: ${f}:${I??D}`};if(H.metadata.status==="published")return{success:!1,error:"Entity is already published"};if(!B.has(f))return{success:!1,error:`No publish provider registered for ${f}. Check that the required credentials are configured.`};let Y=B.get(f),{bodyContent:W,imageData:G}=await Z81(A,H),K=await Y.publish(W,H.metadata,G);return await A.entityService.updateEntity({entity:{...H,metadata:{...H.metadata,status:"published",publishedAt:new Date().toISOString(),platformId:K.id}}}),{success:!0,data:{entityType:f,entityId:H.id,platformId:K.id,url:K.url},message:`Published ${f}:${H.id}`}}),outputSchema:w_A}}async function Ne2(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}f0();GA();function N81(A,Q){ze2(A,Q),qe2(A,Q)}function ze2(A,Q){A.messaging.subscribe(k9.REGISTER,async(B)=>Ce2(Q,B.payload)),A.messaging.subscribe(k9.QUEUE,async(B)=>Le2(A,Q,B.payload)),A.messaging.subscribe(k9.DIRECT,async(B)=>Ee2(A,Q,B.payload)),A.messaging.subscribe(k9.REMOVE,async(B)=>Me2(Q,B.payload)),A.messaging.subscribe(k9.REORDER,async(B)=>Ve2(Q,B.payload)),A.messaging.subscribe(k9.LIST,async(B)=>be2(A,Q,B.payload)),A.messaging.subscribe(k9.REPORT_SUCCESS,async(B)=>Oe2(Q,B.payload)),A.messaging.subscribe(k9.REPORT_FAILURE,async(B)=>Re2(Q,B.payload)),Q.logger.debug("Subscribed to publish messages")}function qe2(A,Q){A.messaging.subscribe(rZ.REPORT_SUCCESS,async(B)=>_e2(Q,B.payload)),A.messaging.subscribe(rZ.REPORT_FAILURE,async(B)=>Pe2(Q,B.payload)),Q.logger.debug("Subscribed to generation messages")}async function Ce2(A,Q){let{entityType:B,provider:w}=Q;try{if(w)A.providerRegistry.register(B,w),A.logger.info(`Registered provider for entity type: ${B}`,{providerName:w.name});return{success:!0}}catch($){let f=y0($);return A.logger.error(`Failed to register provider: ${f}`),{success:!1}}}async function Le2(A,Q,B){let{entityType:w,entityId:$}=B;try{let f=await Q.queueManager.add(w,$);return await A.messaging.send({type:k9.QUEUED,payload:{entityType:w,entityId:$,position:f.position}}),Q.logger.debug(`Entity queued: ${$}`,{entityType:w,position:f.position}),{success:!0}}catch(f){let I=y0(f);return Q.logger.error(`Failed to queue entity: ${I}`),{success:!1}}}async function Ee2(A,Q,B){let{entityType:w,entityId:$}=B;return await A.messaging.send({type:k9.EXECUTE,payload:{entityType:w,entityId:$}}),Q.logger.debug(`Direct publish requested: ${$}`,{entityType:w}),{success:!0}}async function Me2(A,Q){let{entityType:B,entityId:w}=Q;try{return await A.queueManager.remove(B,w),A.logger.debug(`Entity removed from queue: ${w}`,{entityType:B}),{success:!0}}catch($){let f=y0($);return A.logger.error(`Failed to remove entity: ${f}`),{success:!1}}}async function Ve2(A,Q){let{entityType:B,entityId:w,position:$}=Q;try{return await A.queueManager.reorder(B,w,$),A.logger.debug(`Entity reordered: ${w}`,{entityType:B,newPosition:$}),{success:!0}}catch(f){let I=y0(f);return A.logger.error(`Failed to reorder entity: ${I}`),{success:!1}}}async function be2(A,Q,B){let{entityType:w}=B;try{let $=await Q.queueManager.list(w);return await A.messaging.send({type:k9.LIST_RESPONSE,payload:{entityType:w,queue:$.map((f)=>({entityId:f.entityId,position:f.position,queuedAt:f.queuedAt}))}}),{success:!0}}catch($){let f=y0($);return Q.logger.error(`Failed to list queue: ${f}`),{success:!1}}}async function Oe2(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 Re2(A,Q){let{entityType:B,entityId:w,error:$}=Q;A.scheduler.failPublish(B,w,$);let f=A.retryTracker.getRetryInfo(w);return A.logger.info(`Publish reported failure: ${w}`,{entityType:B,error:$,retryCount:f?.retryCount,willRetry:f?.willRetry}),{success:!0}}async function _e2(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 Pe2(A,Q){let{entityType:B,error:w}=Q;return A.scheduler.failGeneration(B,w),A.logger.warn("Generation failed",{entityType:B,error:w}),{success:!0}}GA();async function z81(A,Q,B,w){try{if(w.skipIfDraftExists!==!1){if((await A.listEntities({entityType:B,options:{filter:{metadata:{status:"draft"}},limit:1}})).length>0)return{shouldGenerate:!1,reason:"Draft already exists"}}if(w.maxUnpublishedDrafts!==void 0){let $=await A.listEntities({entityType:B,options:{filter:{metadata:{status:"draft"}},limit:w.maxUnpublishedDrafts+1}});if($.length>=w.maxUnpublishedDrafts)return{shouldGenerate:!1,reason:`Max unpublished drafts reached (${$.length}/${w.maxUnpublishedDrafts})`}}if(w.minSourceEntities!==void 0&&w.sourceEntityType){let $=await A.listEntities({entityType:w.sourceEntityType,options:{publishedOnly:!0,limit:w.minSourceEntities}});if($.length<w.minSourceEntities)return{shouldGenerate:!1,reason:`Not enough source entities (${$.length}/${w.minSourceEntities} ${w.sourceEntityType})`}}return{shouldGenerate:!0}}catch($){return Q.error("Failed to check generation conditions",{entityType:B,error:y0($)}),{shouldGenerate:!1,reason:`Condition check failed: ${y0($)}`}}}function q81(A){let{context:Q,config:B,queueManager:w,providerRegistry:$,retryTracker:f,logger:I}=A,D=ke2(Q);return fY.createFresh({queueManager:w,providerRegistry:$,retryTracker:f,logger:I,backend:new j2A,...B.entitySchedules&&{entitySchedules:B.entitySchedules},...B.generationSchedules&&{generationSchedules:B.generationSchedules},...B.generationConditions&&{generationConditions:B.generationConditions},messageBus:D,entityService:Q.entityService,onCheckGenerationConditions:(H,Y)=>z81(Q.entityService,I,H,Y)})}function ke2(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 C81(A,Q,B){let w=A.getEntityTypes();for(let f of w){let I=await A.listEntities({entityType:f,options:{filter:{metadata:{status:"queued"}}}});for(let D of I)await Q.add(D.entityType,D.id)}let $=0;for(let f of w){let I=await Q.list(f);$+=I.length}if($>0)B.info(`Rebuilt queue with ${$} queued entities`)}var je2=["draft","queued","published","failed"];async function L81(A,Q){await A.messaging.send({type:"dashboard:register-widget",payload:{id:"publication-pipeline",pluginId:Q,title:"Publication Pipeline",section:"secondary",priority:100,rendererName:"PipelineWidget",visibility:"anchor",dataProvider:()=>ve2(A)}})}async function ve2(A){let Q=A.entityService.getEntityTypes(),B=[],w={draft:0,queued:0,published:0,failed:0};for(let $ of Q){let f=await A.entityService.listEntities({entityType:$});for(let I of f){let D=xe2(I.metadata.status);if(!D)continue;w[D]++,B.push({id:I.id,title:he2(I.id,I.metadata.title),type:$,status:D})}}return{summary:w,items:B}}function xe2(A){return je2.find((Q)=>Q===A)}function he2(A,Q){return typeof Q==="string"?Q:A}var E81={name:"@brains/content-pipeline",private:!0,version:"0.2.0-alpha.70",description:"Content pipeline plugin for managing entity publishing queues, scheduling, and generation",type:"module",main:"src/index.ts",types:"src/index.ts",scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*",croner:"^9.1.0"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14",typescript:"^5.3.3"},exports:{".":{types:"./src/index.ts",default:"./src/index.ts"}},files:["src"]};class $_A extends Ww{pluginContext;queueManager;providerRegistry;retryTracker;scheduler;constructor(A){super("content-pipeline",E81,A??{},$81)}async onRegister(A){this.pluginContext=A,this.queueManager=FW.createFresh(),this.providerRegistry=KW.createFresh(),this.retryTracker=ZW.createFresh({maxRetries:this.config.maxRetries,baseDelayMs:this.config.retryBaseDelayMs}),this.scheduler=q81({context:A,config:this.config,queueManager:this.queueManager,providerRegistry:this.providerRegistry,retryTracker:this.retryTracker,logger:this.logger}),N81(A,{queueManager:this.queueManager,providerRegistry:this.providerRegistry,retryTracker:this.retryTracker,scheduler:this.scheduler,logger:this.logger})}async onReady(A){await C81(A.entityService,this.queueManager,this.logger),await L81(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[v2A(this.pluginContext,this.id,this.queueManager),x2A(this.pluginContext,this.id,this.providerRegistry)]}async getInstructions(){return'## Publishing\n- Use `content-pipeline_queue` to manage the publish queue \u2014 list queued items, add entities to the queue, remove them, or reorder.\n- Use `content-pipeline_publish` to publish an entity directly to its platform (e.g. LinkedIn, Buttondown).\n- When users ask about their "publish queue", "publishing queue", or "what\'s queued", use `content-pipeline_queue`.'}getQueueManager(){return this.queueManager}getProviderRegistry(){return this.providerRegistry}getRetryTracker(){return this.retryTracker}getScheduler(){return this.scheduler}async onShutdown(){await this.scheduler.stop(),FW.resetInstance(),KW.resetInstance(),ZW.resetInstance()}}function f_A(A){return new $_A(A)}f0();GA();var M81=F.object({accountId:F.string().describe("Cloudflare account ID"),apiToken:F.string().describe("Cloudflare API token with Analytics:Read permission"),siteTag:F.string().describe("Cloudflare Web Analytics site tag")}),I_A=F.object({cloudflare:M81.optional()});f0();GA();var ge2=F.object({date:F.string().describe("Single date in YYYY-MM-DD format").optional(),days:F.number().min(1).max(365).describe("Number of days back from yesterday (e.g., 7 for last week)").optional(),startDate:F.string().describe("Start date in YYYY-MM-DD format (use with endDate)").optional(),endDate:F.string().describe("End date in YYYY-MM-DD format (use with startDate)").optional(),limit:F.number().min(1).max(100).default(20).describe("Maximum items for breakdowns (pages, referrers, countries)")});function Te2(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 V81(A,Q,B){let w=[];if(!B)return w;return w.push(xQ(A,"query",`Query website analytics from Cloudflare.
|
|
3534
|
+
${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=st2.parse(Q),w=[],$=z$.from(async(Y)=>{let W={progress:Y.progress};if(Y.message!==void 0)W.message=Y.message;w.push(W)});if(!$)throw Error("Failed to create progress reporter");let I=await new mC(A.logger,A).process(B,`eval-${Date.now()}`,$),D=!1,H;if(I.success&&I.entityId){let Y=await A.entityService.getEntity({entityType:"social-post",id:I.entityId});D=!!Y,H=Y?.content.slice(0,300)}return{...I,entityExists:D,entityPreview:H,progressSteps:w}})}GA();f0();class Vm{sendMessage;logger;entityService;providers;constructor(A){this.sendMessage=A.sendMessage,this.logger=A.logger,this.entityService=A.entityService,this.providers=A.providers}async handle(A){let{entityType:Q,entityId:B}=A;if(Q!=="social-post")return;this.logger.debug("Handling publish:execute",{entityId:B});try{let w=await this.entityService.getEntity({entityType:"social-post",id:B});if(!w){await this.reportFailure(Q,B,`Post not found: ${B}`);return}if(w.metadata.status==="published"){this.logger.debug("Post already published, skipping",{entityId:B});return}let $=w.metadata.platform,f=this.providers.get($);if(!f){await this.reportFailure(Q,B,`No provider configured for platform: ${$}`);return}let I=t2(w.content,H4),D;if(I.metadata.coverImageId)D=await this.fetchImageData(I.metadata.coverImageId);try{let H=await f.publish(I.content,w.metadata,D),Y=new Date().toISOString(),W=H.id||void 0,G={...I.metadata,status:"published",publishedAt:Y,...W&&{platformPostId:W}},K=Vf.createPostContent(G,I.content);await this.entityService.updateEntity({entity:{...w,content:K,metadata:{...w.metadata,status:"published",publishedAt:Y,platformPostId:W}}}),await this.reportSuccess(Q,B,H.id),this.logger.info(`Post published successfully: ${B}`,{platform:$,platformPostId:W})}catch(H){let Y=H instanceof Error?H.message:String(H),W={...I.metadata,status:"failed"},G=Vf.createPostContent(W,I.content);await this.entityService.updateEntity({entity:{...w,content:G,metadata:{...w.metadata,status:"failed"}}}),await this.reportFailure(Q,B,Y),this.logger.error(`Post publish failed: ${B}`,{platform:$,error:Y})}}catch(w){let $=y0(w);this.logger.error("Unexpected error in publish handler",{entityId:B,error:$}),await this.reportFailure(Q,B,$)}}async reportSuccess(A,Q,B){await this.sendMessage({type:"publish:report:success",payload:{entityType:A,entityId:Q,result:{id:B}}})}async reportFailure(A,Q,B){await this.sendMessage({type:"publish:report:failure",payload:{entityType:A,entityId:Q,error:B}})}async fetchImageData(A){try{let Q=await this.entityService.getEntity({entityType:"image",id:A});if(!Q){this.logger.warn("Cover image not found",{imageId:A});return}let w=Q.content.match(/^data:([^;]+);base64,(.+)$/);if(!w?.[1]||!w[2]){this.logger.warn("Invalid image data URL format",{imageId:A});return}let $=w[1],f=w[2];return{data:Buffer.from(f,"base64"),mimeType:$}}catch(Q){this.logger.warn("Failed to fetch cover image",{imageId:A,error:Q});return}}}function tw1(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 ew1(A,Q,B){let w=new Vm({sendMessage:A.messaging.send,logger:B.child("PublishExecuteHandler"),entityService:A.entityService,providers:Q});A.messaging.subscribe("publish:execute",async($)=>{return await w.handle($.payload),{success:!0}}),B.debug("Subscribed to publish:execute messages")}GA();function A81(A,Q){A.messaging.subscribe("entity:updated",async(B)=>{let{entityType:w,entityId:$,entity:f}=B.payload;if(w!=="post")return{success:!0};if(f.metadata?.status!=="queued")return{success:!0};try{if((await A.entityService.listEntities({entityType:"social-post",options:{filter:{metadata:{sourceEntityType:"post",sourceEntityId:$}},limit:1}})).length>0)return Q.debug(`Social post already exists for ${$}, skipping auto-generate`),{success:!0};return await A.messaging.send({type:"social:auto-generate",payload:{sourceEntityType:w,sourceEntityId:$,platform:"linkedin"}}),Q.info(`Auto-generate social post triggered for queued post ${$}`),{success:!0}}catch(D){let H=y0(D);return Q.error(`Failed to trigger auto-generate for ${$}:`,{error:H}),{success:!0}}}),Q.debug("Subscribed to entity:updated for auto-generation")}function Q81(A,Q){A.messaging.subscribe("social:auto-generate",async(B)=>{let{sourceEntityType:w,sourceEntityId:$,platform:f}=B.payload;try{let I=await A.jobs.enqueue({type:`${Vf.entityType}:generation`,data:{sourceEntityType:w,sourceEntityId:$,platform:f,addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}});return Q.info(`Social post generation job enqueued for ${w}/${$}`,{jobId:I}),{success:!0,jobId:I}}catch(I){let D=y0(I);return Q.error(`Failed to enqueue social post generation for ${$}:`,{error:D}),{success:!1}}}),Q.debug("Subscribed to social:auto-generate messages")}function B81(A,Q){A.messaging.subscribe("generate:execute",async(B)=>{let{entityType:w}=B.payload;if(w!=="social-post")return{success:!0};Q.info("Received generate:execute for social-post");try{let $=await A.entityService.listEntities({entityType:"post",options:{filter:{metadata:{status:"published"}},limit:5}});if($.length===0)return Q.info("No published posts found for social post generation"),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:"No published posts available for social post generation"}}),{success:!0};let f=null;for(let D of $)if((await A.entityService.listEntities({entityType:"social-post",options:{filter:{metadata:{sourceEntityType:"post",sourceEntityId:D.id}},limit:1}})).length===0){f=D;break}if(!f)return Q.info("All recent posts already have social posts"),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:"All recent posts already have social posts generated"}}),{success:!0};let I=await A.jobs.enqueue({type:`${Vf.entityType}:generation`,data:{sourceEntityType:"post",sourceEntityId:f.id,platform:"linkedin",addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}});return Q.info("Social post generation job queued",{jobId:I,sourcePostId:f.id}),{success:!0}}catch($){let f=y0($);return Q.error("Failed to handle generate:execute:",{error:f}),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:f}}),{success:!0}}}),Q.debug("Subscribed to generate:execute messages")}var w81={name:"@brains/social-media",private:!0,version:"0.2.0-alpha.71",description:"Multi-provider social media posting with queue-based publishing",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class iRA extends KQ{entityType=Vf.entityType;schema=U_;adapter=Vf;providers=new Map;constructor(A){super("social-media",w81,A,SRA)}createGenerationHandler(A){return new mC(this.logger.child("GenerationJobHandler"),A)}getTemplates(){return sw1()}getDataSources(){return[new O2A(this.logger.child("SocialPostDataSource"))]}async onRegister(A){if(this.initializeProviders(),tw1(A,this.providers,this.logger),ew1(A,this.providers,this.logger),this.config.autoGenerateOnBlogPublish)A81(A,this.logger),Q81(A,this.logger),this.logger.info("Auto-generate on blog publish enabled");B81(A,this.logger),aw1(A),this.logger.info("Social media plugin registered successfully")}initializeProviders(){if(this.config.linkedin?.accessToken){let A=lRA(this.config.linkedin,this.logger.child("LinkedInClient"));this.providers.set("linkedin",A),this.logger.info("LinkedIn provider initialized")}}}function bm(A){return new iRA(A)}GA();var tt2=F.enum(["draft","queued","published","failed"]),KDw=F.object({status:tt2.default("draft"),queueOrder:F.number().optional().describe("Position in publish queue (lower = sooner)"),publishedAt:F.string().datetime().optional()});class rRA{name="internal";async publish(A,Q){return{id:"internal"}}}var k9={REGISTER:"publish:register",QUEUE:"publish:queue",DIRECT:"publish:direct",REMOVE:"publish:remove",REORDER:"publish:reorder",LIST:"publish:list",REPORT_SUCCESS:"publish:report:success",REPORT_FAILURE:"publish:report:failure",EXECUTE:"publish:execute",QUEUED:"publish:queued",COMPLETED:"publish:completed",FAILED:"publish:failed",LIST_RESPONSE:"publish:list:response"},rZ={REGISTER:"generate:register",REPORT_SUCCESS:"generate:report:success",REPORT_FAILURE:"generate:report:failure",EXECUTE:"generate:execute",COMPLETED:"generate:completed",FAILED:"generate:failed",SKIPPED:"generate:skipped"};GA();var et2=F.object({skipIfDraftExists:F.boolean().optional(),minSourceEntities:F.number().optional(),maxUnpublishedDrafts:F.number().optional(),sourceEntityType:F.string().optional()}),$81=F.object({entitySchedules:F.record(F.string(),F.string()).optional(),generationSchedules:F.record(F.string(),F.string()).optional(),generationConditions:F.record(F.string(),et2).optional(),maxRetries:F.number().optional().default(3),retryBaseDelayMs:F.number().optional().default(5000)});class FW{static instance=null;queues=new Map;static getInstance(){return FW.instance??=new FW,FW.instance}static resetInstance(){FW.instance=null}static createFresh(){return new FW}constructor(){}async add(A,Q){let B=this.getOrCreateQueue(A),w=B.find((I)=>I.entityId===Q);if(w)return{position:w.position};let $=B.length+1,f={entityId:Q,entityType:A,position:$,queuedAt:new Date().toISOString()};return B.push(f),{position:$}}async remove(A,Q){let B=this.queues.get(A);if(!B)return;let w=B.findIndex(($)=>$.entityId===Q);if(w===-1)return;B.splice(w,1),this.recalculatePositions(B)}async reorder(A,Q,B){let w=this.queues.get(A);if(!w)return;let $=w.findIndex((D)=>D.entityId===Q);if($===-1)return;let[f]=w.splice($,1);if(!f)return;let I=Math.max(0,Math.min(B-1,w.length));w.splice(I,0,f),this.recalculatePositions(w)}async list(A){let Q=this.queues.get(A);if(!Q)return[];return[...Q]}async getNext(A){let Q=this.queues.get(A);if(!Q||Q.length===0)return null;return Q[0]??null}async getNextAcrossTypes(){let A=null;for(let Q of this.queues.values()){let B=Q[0];if(!B)continue;if(!A||B.queuedAt<A.queuedAt)A=B}return A}async popNext(A){let Q=this.queues.get(A);if(!Q||Q.length===0)return null;let B=Q.shift()??null;if(B)this.recalculatePositions(Q);return B}getRegisteredTypes(){return Array.from(this.queues.keys())}async getQueuedEntityTypes(){let A=[];for(let[Q,B]of this.queues.entries())if(B.length>0)A.push(Q);return A}getOrCreateQueue(A){let Q=this.queues.get(A);if(!Q)Q=[],this.queues.set(A,Q);return Q}recalculatePositions(A){A.forEach((Q,B)=>{Q.position=B+1})}}class KW{static instance=null;providers=new Map;defaultProvider=new rRA;static getInstance(){return KW.instance??=new KW,KW.instance}static resetInstance(){KW.instance=null}static createFresh(){return new KW}constructor(){}register(A,Q){this.providers.set(A,Q)}get(A){return this.providers.get(A)??this.defaultProvider}has(A){return this.providers.has(A)}unregister(A){this.providers.delete(A)}getRegisteredTypes(){return Array.from(this.providers.keys())}}GA();GA();async function f81(A,Q){let B={entityType:A.entityType,entityId:A.entityId};if(Q.messageBus)await Q.messageBus.send({type:k9.EXECUTE,payload:B,sender:"publish-service"});Q.onExecute?.(B)}async function I81(A,Q){let B=Q.providerRegistry.get(A.entityType);if(!Q.entityService){Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:"EntityService not available for provider mode",retryCount:0,willRetry:!1});return}let w=await Q.entityService.getEntity({entityType:A.entityType,id:A.entityId});if(!w){Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:`Entity not found: ${A.entityType}/${A.entityId}`,retryCount:0,willRetry:!1});return}try{let $=await B.publish(w.content,w.metadata);Q.retryTracker.clearRetries(A.entityId),Q.onPublish?.({entityType:A.entityType,entityId:A.entityId,result:$})}catch($){let f=y0($);Q.retryTracker.recordFailure(A.entityId,f);let I=Q.retryTracker.getRetryInfo(A.entityId);Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:f,retryCount:I?.retryCount??1,willRetry:I?.willRetry??!1})}}function D81(A,Q,B,w){if(w.retryTracker.clearRetries(Q),w.messageBus)w.messageBus.send({type:k9.COMPLETED,payload:{entityType:A,entityId:Q,result:B},sender:"publish-service"});w.onPublish?.({entityType:A,entityId:Q,result:B})}function H81(A,Q,B,w){w.retryTracker.recordFailure(Q,B);let $=w.retryTracker.getRetryInfo(Q),f={entityType:A,entityId:Q,error:B,retryCount:$?.retryCount??1,willRetry:$?.willRetry??!1};if(w.messageBus)w.messageBus.send({type:k9.FAILED,payload:f,sender:"publish-service"});w.onFailed?.(f)}async function Y81(A,Q){let B=Q.generationConditions[A];if(B&&Q.onCheckGenerationConditions){let $=await Q.onCheckGenerationConditions(A,B);if(!$.shouldGenerate){if(Q.messageBus)Q.messageBus.send({type:rZ.SKIPPED,payload:{entityType:A,reason:$.reason??"Conditions not met"},sender:"content-pipeline"});return}}let w={entityType:A};if(Q.messageBus)await Q.messageBus.send({type:rZ.EXECUTE,payload:w,sender:"content-pipeline"});Q.onGenerate?.(w)}function X81(A,Q,B){if(B)B.send({type:rZ.COMPLETED,payload:{entityType:A,entityId:Q},sender:"content-pipeline"})}function W81(A,Q,B){if(B)B.send({type:rZ.FAILED,payload:{entityType:A,error:Q},sender:"content-pipeline"})}var Ae2=1000;class dRA{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(Ae2,()=>this.processUnscheduledTypes())}stop(){if(Qe2(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 f81(A,this.deps.getPublishDeps());else await I81(A,this.deps.getPublishDeps())}get entitySchedules(){return this.deps.config.entitySchedules}}function Qe2(A){for(let Q of A.values())Q.stop();A.clear()}class nRA{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(){Be2(this.generationJobs)}async handleTriggerGeneration(A){if(!this.deps.isRunning())return;try{await Y81(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 Be2(A){for(let Q of A.values())Q.stop();A.clear()}class fY{static instance=null;config;publishRunner;generationRunner;running=!1;static getInstance(A){return fY.instance??=new fY(A),fY.instance}static resetInstance(){if(fY.instance)fY.instance.stop();fY.instance=null}static createFresh(A){return new fY(A)}constructor(A){this.config={...A,entitySchedules:A.entitySchedules??{},generationSchedules:A.generationSchedules??{},generationConditions:A.generationConditions??{}},this.validateCronExpressions(),this.publishRunner=new dRA({config:this.config,getPublishDeps:()=>this.publishDeps,isRunning:()=>this.running}),this.generationRunner=new nRA({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){D81(A,Q,B,this.publishDeps)}failPublish(A,Q,B){H81(A,Q,B,this.publishDeps)}async publishDirect(A,Q,B,w){return this.config.providerRegistry.get(A).publish(B,w)}completeGeneration(A,Q){X81(A,Q,this.config.messageBus)}failGeneration(A,Q){W81(A,Q,this.config.messageBus)}get entitySchedules(){return this.config.entitySchedules}get generationSchedules(){return this.config.generationSchedules}get publishDeps(){return{providerRegistry:this.config.providerRegistry,retryTracker:this.config.retryTracker,messageBus:this.config.messageBus,entityService:this.config.entityService,onExecute:this.config.onExecute,onPublish:this.config.onPublish,onFailed:this.config.onFailed}}get generationDeps(){return{logger:this.config.logger,messageBus:this.config.messageBus,generationConditions:this.config.generationConditions,onCheckGenerationConditions:this.config.onCheckGenerationConditions,onGenerate:this.config.onGenerate}}validateCronExpressions(){for(let[A,Q]of Object.entries(this.entitySchedules))this.validateCronExpression(A,Q,"publish");for(let[A,Q]of Object.entries(this.generationSchedules))this.validateCronExpression(A,Q,"generation")}validateCronExpression(A,Q,B){try{this.config.backend.validateCron(Q)}catch(w){throw Error(`Invalid ${B} cron expression for ${A}: "${Q}" - ${y0(w)}`)}}}var U81={maxRetries:3,baseDelayMs:5000};class ZW{static instance=null;retries=new Map;config;static getInstance(A){return ZW.instance??=new ZW(A??U81),ZW.instance}static resetInstance(){ZW.instance=null}static createFresh(A){return new ZW(A??U81)}constructor(A){this.config=A}recordFailure(A,Q){let w=(this.retries.get(A)?.retryCount??0)+1,$=this.config.baseDelayMs*Math.pow(2,w-1),f=Date.now()+$;this.retries.set(A,{entityId:A,retryCount:w,lastError:Q,nextRetryAt:f})}shouldRetry(A){let Q=this.retries.get(A);if(!Q)return!1;return Q.retryCount<this.config.maxRetries}isReadyForRetry(A){let Q=this.retries.get(A);if(!Q)return!1;return Date.now()>=Q.nextRetryAt}clearRetries(A){this.retries.delete(A)}getRetryInfo(A){let Q=this.retries.get(A);if(!Q)return null;return{entityId:Q.entityId,retryCount:Q.retryCount,lastError:Q.lastError,nextRetryAt:Q.nextRetryAt,willRetry:Q.retryCount<this.config.maxRetries}}}function j9(A,Q,B,w,$,f,I,D){return j9.fromTZ(j9.tp(A,Q,B,w,$,f,I),D)}j9.fromTZISO=(A,Q,B)=>j9.fromTZ(we2(A,Q),B);j9.fromTZ=function(A,Q){let B=new Date(Date.UTC(A.y,A.m-1,A.d,A.h,A.i,A.s)),w=oRA(A.tz,B),$=new Date(B.getTime()-w),f=oRA(A.tz,$);if(f-w===0)return $;{let I=new Date(B.getTime()-f),D=oRA(A.tz,I);if(D-f===0)return I;if(!Q&&D-f>0)return I;if(Q)throw Error("Invalid date passed to fromTZ()");return $}};j9.toTZ=function(A,Q){let B=A.toLocaleString("en-US",{timeZone:Q}).replace(/[\u202f]/," "),w=new Date(B);return{y:w.getFullYear(),m:w.getMonth()+1,d:w.getDate(),h:w.getHours(),i:w.getMinutes(),s:w.getSeconds(),tz:Q}};j9.tp=(A,Q,B,w,$,f,I)=>({y:A,m:Q,d:B,h:w,i:$,s:f,tz:I});function oRA(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 we2(A,Q){let B=new Date(Date.parse(A));if(isNaN(B))throw Error("minitz: Invalid ISO8601 passed to parser.");let w=A.substring(9);return A.includes("Z")||w.includes("-")||w.includes("+")?j9.tp(B.getUTCFullYear(),B.getUTCMonth()+1,B.getUTCDate(),B.getUTCHours(),B.getUTCMinutes(),B.getUTCSeconds(),"Etc/UTC"):j9.tp(B.getFullYear(),B.getMonth()+1,B.getDate(),B.getHours(),B.getMinutes(),B.getSeconds(),Q)}j9.minitz=j9;var sRA=32,Rm=31|sRA,K81=[1,2,4,8,16],J81=class{pattern;timezone;second;minute;hour;day;month;dayOfWeek;lastDayOfMonth;starDOM;starDOW;constructor(A,Q){this.pattern=A,this.timezone=Q,this.second=Array(60).fill(0),this.minute=Array(60).fill(0),this.hour=Array(24).fill(0),this.day=Array(31).fill(0),this.month=Array(12).fill(0),this.dayOfWeek=Array(7).fill(0),this.lastDayOfMonth=!1,this.starDOM=!1,this.starDOW=!1,this.parse()}parse(){if(!(typeof this.pattern=="string"||this.pattern instanceof String))throw TypeError("CronPattern: Pattern has to be of type string.");this.pattern.indexOf("@")>=0&&(this.pattern=this.handleNicknames(this.pattern).trim());let A=this.pattern.replace(/\s+/g," ").split(" ");if(A.length<5||A.length>6)throw TypeError("CronPattern: invalid configuration format ('"+this.pattern+"'), exactly five or six space separated parts are required.");if(A.length===5&&A.unshift("0"),A[3].indexOf("L")>=0&&(A[3]=A[3].replace("L",""),this.lastDayOfMonth=!0),A[3]=="*"&&(this.starDOM=!0),A[4].length>=3&&(A[4]=this.replaceAlphaMonths(A[4])),A[5].length>=3&&(A[5]=this.replaceAlphaDays(A[5])),A[5]=="*"&&(this.starDOW=!0),this.pattern.indexOf("?")>=0){let Q=new Y4(new Date,this.timezone).getDate(!0);A[0]=A[0].replace("?",Q.getSeconds().toString()),A[1]=A[1].replace("?",Q.getMinutes().toString()),A[2]=A[2].replace("?",Q.getHours().toString()),this.starDOM||(A[3]=A[3].replace("?",Q.getDate().toString())),A[4]=A[4].replace("?",(Q.getMonth()+1).toString()),this.starDOW||(A[5]=A[5].replace("?",Q.getDay().toString()))}this.throwAtIllegalCharacters(A),this.partToArray("second",A[0],0,1),this.partToArray("minute",A[1],0,1),this.partToArray("hour",A[2],0,1),this.partToArray("day",A[3],-1,1),this.partToArray("month",A[4],-1,1),this.partToArray("dayOfWeek",A[5],0,Rm),this.dayOfWeek[7]&&(this.dayOfWeek[0]=this.dayOfWeek[7])}partToArray(A,Q,B,w){let $=this[A],f=A==="day"&&this.lastDayOfMonth;if(Q===""&&!f)throw TypeError("CronPattern: configuration entry "+A+" ("+Q+") is empty, check for trailing spaces.");if(Q==="*")return $.fill(w);let I=Q.split(",");if(I.length>1)for(let D=0;D<I.length;D++)this.partToArray(A,I[D],B,w);else Q.indexOf("-")!==-1&&Q.indexOf("/")!==-1?this.handleRangeWithStepping(Q,A,B,w):Q.indexOf("-")!==-1?this.handleRange(Q,A,B,w):Q.indexOf("/")!==-1?this.handleStepping(Q,A,B,w):Q!==""&&this.handleNumber(Q,A,B,w)}throwAtIllegalCharacters(A){for(let Q=0;Q<A.length;Q++)if((Q===5?/[^/*0-9,\-#L]+/:/[^/*0-9,-]+/).test(A[Q]))throw TypeError("CronPattern: configuration entry "+Q+" ("+A[Q]+") contains illegal characters.")}handleNumber(A,Q,B,w){let $=this.extractNth(A,Q),f=parseInt($[0],10)+B;if(isNaN(f))throw TypeError("CronPattern: "+Q+" is not a number: '"+A+"'");this.setPart(Q,f,$[1]||w)}setPart(A,Q,B){if(!Object.prototype.hasOwnProperty.call(this,A))throw TypeError("CronPattern: Invalid part specified: "+A);if(A==="dayOfWeek"){if(Q===7&&(Q=0),Q<0||Q>6)throw RangeError("CronPattern: Invalid value for dayOfWeek: "+Q);this.setNthWeekdayOfMonth(Q,B);return}if(A==="second"||A==="minute"){if(Q<0||Q>=60)throw RangeError("CronPattern: Invalid value for "+A+": "+Q)}else if(A==="hour"){if(Q<0||Q>=24)throw RangeError("CronPattern: Invalid value for "+A+": "+Q)}else if(A==="day"){if(Q<0||Q>=31)throw RangeError("CronPattern: Invalid value for "+A+": "+Q)}else if(A==="month"&&(Q<0||Q>=12))throw RangeError("CronPattern: Invalid value for "+A+": "+Q);this[A][Q]=B}handleRangeWithStepping(A,Q,B,w){let $=this.extractNth(A,Q),f=$[0].match(/^(\d+)-(\d+)\/(\d+)$/);if(f===null)throw TypeError("CronPattern: Syntax error, illegal range with stepping: '"+A+"'");let[,I,D,H]=f,Y=parseInt(I,10)+B,W=parseInt(D,10)+B,G=parseInt(H,10);if(isNaN(Y))throw TypeError("CronPattern: Syntax error, illegal lower range (NaN)");if(isNaN(W))throw TypeError("CronPattern: Syntax error, illegal upper range (NaN)");if(isNaN(G))throw TypeError("CronPattern: Syntax error, illegal stepping: (NaN)");if(G===0)throw TypeError("CronPattern: Syntax error, illegal stepping: 0");if(G>this[Q].length)throw TypeError("CronPattern: Syntax error, steps cannot be greater than maximum value of part ("+this[Q].length+")");if(Y>W)throw TypeError("CronPattern: From value is larger than to value: '"+A+"'");for(let K=Y;K<=W;K+=G)this.setPart(Q,K,$[1]||w)}extractNth(A,Q){let B=A,w;if(B.includes("#")){if(Q!=="dayOfWeek")throw Error("CronPattern: nth (#) only allowed in day-of-week field");w=B.split("#")[1],B=B.split("#")[0]}return[B,w]}handleRange(A,Q,B,w){let $=this.extractNth(A,Q),f=$[0].split("-");if(f.length!==2)throw TypeError("CronPattern: Syntax error, illegal range: '"+A+"'");let I=parseInt(f[0],10)+B,D=parseInt(f[1],10)+B;if(isNaN(I))throw TypeError("CronPattern: Syntax error, illegal lower range (NaN)");if(isNaN(D))throw TypeError("CronPattern: Syntax error, illegal upper range (NaN)");if(I>D)throw TypeError("CronPattern: From value is larger than to value: '"+A+"'");for(let H=I;H<=D;H++)this.setPart(Q,H,$[1]||w)}handleStepping(A,Q,B,w){let $=this.extractNth(A,Q),f=$[0].split("/");if(f.length!==2)throw TypeError("CronPattern: Syntax error, illegal stepping: '"+A+"'");f[0]===""&&(f[0]="*");let I=0;f[0]!=="*"&&(I=parseInt(f[0],10)+B);let D=parseInt(f[1],10);if(isNaN(D))throw TypeError("CronPattern: Syntax error, illegal stepping: (NaN)");if(D===0)throw TypeError("CronPattern: Syntax error, illegal stepping: 0");if(D>this[Q].length)throw TypeError("CronPattern: Syntax error, max steps for part is ("+this[Q].length+")");for(let H=I;H<this[Q].length;H+=D)this.setPart(Q,H,$[1]||w)}replaceAlphaDays(A){return A.replace(/-sun/gi,"-7").replace(/sun/gi,"0").replace(/mon/gi,"1").replace(/tue/gi,"2").replace(/wed/gi,"3").replace(/thu/gi,"4").replace(/fri/gi,"5").replace(/sat/gi,"6")}replaceAlphaMonths(A){return A.replace(/jan/gi,"1").replace(/feb/gi,"2").replace(/mar/gi,"3").replace(/apr/gi,"4").replace(/may/gi,"5").replace(/jun/gi,"6").replace(/jul/gi,"7").replace(/aug/gi,"8").replace(/sep/gi,"9").replace(/oct/gi,"10").replace(/nov/gi,"11").replace(/dec/gi,"12")}handleNicknames(A){let Q=A.trim().toLowerCase();return Q==="@yearly"||Q==="@annually"?"0 0 1 1 *":Q==="@monthly"?"0 0 1 * *":Q==="@weekly"?"0 0 * * 0":Q==="@daily"?"0 0 * * *":Q==="@hourly"?"0 * * * *":A}setNthWeekdayOfMonth(A,Q){if(typeof Q!="number"&&Q==="L")this.dayOfWeek[A]=this.dayOfWeek[A]|sRA;else if(Q===Rm)this.dayOfWeek[A]=Rm;else if(Q<6&&Q>0)this.dayOfWeek[A]=this.dayOfWeek[A]|K81[Q-1];else throw TypeError(`CronPattern: nth weekday out of range, should be 1-5 or L. Value: ${Q}, Type: ${typeof Q}`)}},G81=[31,28,31,30,31,30,31,31,30,31,30,31],HG=[["month","year",0],["day","month",-1],["hour","day",0],["minute","hour",0],["second","minute",0]],Y4=class A{tz;ms;second;minute;hour;day;month;year;constructor(Q,B){if(this.tz=B,Q&&Q instanceof Date)if(!isNaN(Q))this.fromDate(Q);else throw TypeError("CronDate: Invalid date passed to CronDate constructor");else if(Q===void 0)this.fromDate(new Date);else if(Q&&typeof Q=="string")this.fromString(Q);else if(Q instanceof A)this.fromCronDate(Q);else throw TypeError("CronDate: Invalid type ("+typeof Q+") passed to CronDate constructor")}isNthWeekdayOfMonth(Q,B,w,$){let f=new Date(Date.UTC(Q,B,w)).getUTCDay(),I=0;for(let D=1;D<=w;D++)new Date(Date.UTC(Q,B,D)).getUTCDay()===f&&I++;if($&Rm&&K81[I-1]&$)return!0;if($&sRA){let D=new Date(Date.UTC(Q,B+1,0)).getUTCDate();for(let H=w+1;H<=D;H++)if(new Date(Date.UTC(Q,B,H)).getUTCDay()===f)return!1;return!0}return!1}fromDate(Q){if(this.tz!==void 0)if(typeof this.tz=="number")this.ms=Q.getUTCMilliseconds(),this.second=Q.getUTCSeconds(),this.minute=Q.getUTCMinutes()+this.tz,this.hour=Q.getUTCHours(),this.day=Q.getUTCDate(),this.month=Q.getUTCMonth(),this.year=Q.getUTCFullYear(),this.apply();else{let B=j9.toTZ(Q,this.tz);this.ms=Q.getMilliseconds(),this.second=B.s,this.minute=B.i,this.hour=B.h,this.day=B.d,this.month=B.m-1,this.year=B.y}else this.ms=Q.getMilliseconds(),this.second=Q.getSeconds(),this.minute=Q.getMinutes(),this.hour=Q.getHours(),this.day=Q.getDate(),this.month=Q.getMonth(),this.year=Q.getFullYear()}fromCronDate(Q){this.tz=Q.tz,this.year=Q.year,this.month=Q.month,this.day=Q.day,this.hour=Q.hour,this.minute=Q.minute,this.second=Q.second,this.ms=Q.ms}apply(){if(this.month>11||this.day>G81[this.month]||this.hour>59||this.minute>59||this.second>59||this.hour<0||this.minute<0||this.second<0){let Q=new Date(Date.UTC(this.year,this.month,this.day,this.hour,this.minute,this.second,this.ms));return this.ms=Q.getUTCMilliseconds(),this.second=Q.getUTCSeconds(),this.minute=Q.getUTCMinutes(),this.hour=Q.getUTCHours(),this.day=Q.getUTCDate(),this.month=Q.getUTCMonth(),this.year=Q.getUTCFullYear(),!0}else return!1}fromString(Q){if(typeof this.tz=="number"){let B=j9.fromTZISO(Q);this.ms=B.getUTCMilliseconds(),this.second=B.getUTCSeconds(),this.minute=B.getUTCMinutes(),this.hour=B.getUTCHours(),this.day=B.getUTCDate(),this.month=B.getUTCMonth(),this.year=B.getUTCFullYear(),this.apply()}else return this.fromDate(j9.fromTZISO(Q,this.tz))}findNext(Q,B,w,$){let f=this[B],I;w.lastDayOfMonth&&(this.month!==1?I=G81[this.month]:I=new Date(Date.UTC(this.year,this.month+1,0,0,0,0,0)).getUTCDate());let D=!w.starDOW&&B=="day"?new Date(Date.UTC(this.year,this.month,1,0,0,0,0)).getUTCDay():void 0;for(let H=this[B]+$;H<w[B].length;H++){let Y=w[B][H];if(B==="day"&&w.lastDayOfMonth&&H-$==I&&(Y=1),B==="day"&&!w.starDOW){let W=w.dayOfWeek[(D+(H-$-1))%7];if(W&&W&Rm)W=this.isNthWeekdayOfMonth(this.year,this.month,H-$,W)?1:0;else if(W)throw Error(`CronDate: Invalid value for dayOfWeek encountered. ${W}`);Q.legacyMode&&!w.starDOM?Y=Y||W:Y=Y&&W}if(Y)return this[B]=H-$,f!==this[B]?2:1}return 3}recurse(Q,B,w){let $=this.findNext(B,HG[w][0],Q,HG[w][2]);if($>1){let f=w+1;for(;f<HG.length;)this[HG[f][0]]=-HG[f][2],f++;if($===3)return this[HG[w][1]]++,this[HG[w][0]]=-HG[w][2],this.apply(),this.recurse(Q,B,0);if(this.apply())return this.recurse(Q,B,w-1)}return w+=1,w>=HG.length?this:this.year>=3000?null:this.recurse(Q,B,w)}increment(Q,B,w){return this.second+=B.interval!==void 0&&B.interval>1&&w?B.interval:1,this.ms=0,this.apply(),this.recurse(Q,B,0)}getDate(Q){return Q||this.tz===void 0?new Date(this.year,this.month,this.day,this.hour,this.minute,this.second,this.ms):typeof this.tz=="number"?new Date(Date.UTC(this.year,this.month,this.day,this.hour,this.minute-this.tz,this.second,this.ms)):j9.fromTZ(j9.tp(this.year,this.month+1,this.day,this.hour,this.minute,this.second,this.tz),!1)}getTime(){return this.getDate(!1).getTime()}};function $e2(A){if(A===void 0&&(A={}),delete A.name,A.legacyMode=A.legacyMode===void 0?!0:A.legacyMode,A.paused=A.paused===void 0?!1:A.paused,A.maxRuns=A.maxRuns===void 0?1/0:A.maxRuns,A.catch=A.catch===void 0?!1:A.catch,A.interval=A.interval===void 0?0:parseInt(A.interval.toString(),10),A.utcOffset=A.utcOffset===void 0?void 0:parseInt(A.utcOffset.toString(),10),A.unref=A.unref===void 0?!1:A.unref,A.startAt&&(A.startAt=new Y4(A.startAt,A.timezone)),A.stopAt&&(A.stopAt=new Y4(A.stopAt,A.timezone)),A.interval!==null){if(isNaN(A.interval))throw Error("CronOptions: Supplied value for interval is not a number");if(A.interval<0)throw Error("CronOptions: Supplied value for interval can not be negative")}if(A.utcOffset!==void 0){if(isNaN(A.utcOffset))throw Error("CronOptions: Invalid value passed for utcOffset, should be number representing minutes offset from UTC.");if(A.utcOffset<-870||A.utcOffset>870)throw Error("CronOptions: utcOffset out of bounds.");if(A.utcOffset!==void 0&&A.timezone)throw Error("CronOptions: Combining 'utcOffset' with 'timezone' is not allowed.")}if(A.unref!==!0&&A.unref!==!1)throw Error("CronOptions: Unref should be either true, false or undefined(false).");return A}function Om(A){return Object.prototype.toString.call(A)==="[object Function]"||typeof A=="function"||A instanceof Function}function fe2(A){return Om(A)}function Ie2(A){typeof Deno<"u"&&typeof Deno.unrefTimer<"u"?Deno.unrefTimer(A):A&&typeof A.unref<"u"&&A.unref()}var F81=30000,k2A=[],aRA=class{name;options;_states;fn;constructor(A,Q,B){let w,$;if(Om(Q))$=Q;else if(typeof Q=="object")w=Q;else if(Q!==void 0)throw Error("Cron: Invalid argument passed for optionsIn. Should be one of function, or object (options).");if(Om(B))$=B;else if(typeof B=="object")w=B;else if(B!==void 0)throw Error("Cron: Invalid argument passed for funcIn. Should be one of function, or object (options).");if(this.name=w?.name,this.options=$e2(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 J81("* * * * *")},A&&(A instanceof Date||typeof A=="string"&&A.indexOf(":")>0)?this._states.once=new Y4(A,this.options.timezone||this.options.utcOffset):this._states.pattern=new J81(A,this.options.timezone),this.name){if(k2A.find((f)=>f.name===this.name))throw Error("Cron: Tried to initialize new named job '"+this.name+"', but name already taken.");k2A.push(this)}return $!==void 0&&fe2($)&&(this.fn=$,this.schedule()),this}nextRun(A){let Q=this._next(A);return Q?Q.getDate(!1):null}nextRuns(A,Q){this._states.maxRuns!==void 0&&A>this._states.maxRuns&&(A=this._states.maxRuns);let B=[],w=Q||this._states.currentRun||void 0;for(;A--&&(w=this.nextRun(w));)B.push(w);return B}getPattern(){return this._states.pattern?this._states.pattern.pattern:void 0}isRunning(){let A=this.nextRun(this._states.currentRun),Q=!this._states.paused,B=this.fn!==void 0,w=!this._states.kill;return Q&&B&&w&&A!==null}isStopped(){return this._states.kill}isBusy(){return this._states.blocking}currentRun(){return this._states.currentRun?this._states.currentRun.getDate():null}previousRun(){return this._states.previousRun?this._states.previousRun.getDate():null}msToNext(A){let Q=this._next(A);return Q?A instanceof Y4||A instanceof Date?Q.getTime()-A.getTime():Q.getTime()-new Y4(A).getTime():null}stop(){this._states.kill=!0,this._states.currentTimeout&&clearTimeout(this._states.currentTimeout);let A=k2A.indexOf(this);A>=0&&k2A.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>F81&&(Q=F81),this._states.currentTimeout=setTimeout(()=>this._checkTrigger(B),Q),this._states.currentTimeout&&this.options.unref&&Ie2(this._states.currentTimeout),this)}async _trigger(A){if(this._states.blocking=!0,this._states.currentRun=new Y4(void 0,this.options.timezone||this.options.utcOffset),this.options.catch)try{this.fn!==void 0&&await this.fn(this,this.options.context)}catch(Q){Om(this.options.catch)&&this.options.catch(Q,this)}else this.fn!==void 0&&await this.fn(this,this.options.context);this._states.previousRun=new Y4(A,this.options.timezone||this.options.utcOffset),this._states.blocking=!1}async trigger(){await this._trigger()}runsLeft(){return this._states.maxRuns}_checkTrigger(A){let Q=new Date,B=!this._states.paused&&Q.getTime()>=A.getTime(),w=this._states.blocking&&this.options.protect;B&&!w?(this._states.maxRuns!==void 0&&this._states.maxRuns--,this._trigger()):B&&w&&Om(this.options.protect)&&setTimeout(()=>this.options.protect(this),0),this.schedule()}_next(A){let Q=!!(A||this._states.currentRun),B=!1;!A&&this.options.startAt&&this.options.interval&&([A,Q]=this._calculatePreviousRun(A,Q),B=!A),A=new Y4(A,this.options.timezone||this.options.utcOffset),this.options.startAt&&A&&A.getTime()<this.options.startAt.getTime()&&(A=this.options.startAt);let w=this._states.once||new Y4(A,this.options.timezone||this.options.utcOffset);return!B&&w!==this._states.once&&(w=w.increment(this._states.pattern,this.options,Q)),this._states.once&&this._states.once.getTime()<=A.getTime()||w===null||this._states.maxRuns!==void 0&&this._states.maxRuns<=0||this._states.kill||this.options.stopAt&&w.getTime()>=this.options.stopAt.getTime()?null:w}_calculatePreviousRun(A,Q){let B=new Y4(void 0,this.options.timezone||this.options.utcOffset),w=A;if(this.options.startAt.getTime()<=B.getTime()){w=this.options.startAt;let $=w.getTime()+this.options.interval*1000;for(;$<=B.getTime();)w=new Y4(w,this.options.timezone||this.options.utcOffset).increment(this._states.pattern,this.options,!0),$=w.getTime()+this.options.interval*1000;Q=!0}return w===null&&(w=void 0),[w,Q]}};class j2A{scheduleCron(A,Q){let B=new aRA(A,()=>{Q()});return{stop:()=>B.stop()}}scheduleInterval(A,Q){let B=setInterval(()=>{Q()},A);return{stop:()=>clearInterval(B)}}validateCron(A){new aRA(A).stop()}}f0();GA();var tRA=F.object({action:F.enum(["list","add","remove","reorder"]).describe("Queue action to perform"),entityType:F.string().optional().describe("Entity type (required for add/remove/reorder, optional for list)"),entityId:F.string().optional().describe("Entity ID (required for add/remove/reorder)"),position:F.number().optional().describe("New position for reorder action (1-based)")}),eRA=F.object({position:F.number(),entityType:F.string(),entityId:F.string(),queuedAt:F.string()}),De2=F.object({success:F.literal(!0),message:F.string().optional(),data:F.object({queue:F.array(eRA).optional(),entityType:F.string().optional(),entityId:F.string().optional(),position:F.number().optional()}).optional()}),He2=F.object({success:F.literal(!1),error:F.string(),code:F.string().optional()}),A_A=F.union([De2,He2]);function v2A(A,Q,B){return{...xQ(Q,"queue","Manage the publish queue for all entity types (list, add, remove, reorder)",tRA,async($)=>{let{action:f,entityType:I,entityId:D,position:H}=$;switch(f){case"list":return Ye2(B,I);case"add":return Xe2(B,I,D);case"remove":return We2(B,I,D);case"reorder":return Ue2(B,I,D,H);default:return{success:!1,error:`Unknown action: ${f}`}}}),outputSchema:A_A}}async function Ye2(A,Q){let B=[];if(Q)B=await A.list(Q);else{let $=A.getRegisteredTypes();for(let f of $){let I=await A.list(f);B.push(...I)}B.sort((f,I)=>new Date(f.queuedAt).getTime()-new Date(I.queuedAt).getTime())}if(B.length===0)return{success:!0,data:{queue:[]},message:"No items in queue"};return{success:!0,data:{queue:B.map(($,f)=>({position:f+1,entityType:$.entityType,entityId:$.entityId,queuedAt:$.queuedAt}))},message:`${B.length} items in queue`}}async function Xe2(A,Q,B){let w=Q_A("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 We2(A,Q,B){let w=Q_A("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 Ue2(A,Q,B,w){let $=Q_A("reorder",Q,B);if(!$.success)return $.error;let f=Je2(w);if(!f.success)return f.error;return await A.reorder($.entityType,$.entityId,f.position),{success:!0,data:{entityType:$.entityType,entityId:$.entityId,position:f.position},message:`Moved to position ${f.position}`}}function Q_A(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 Je2(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}}f0();GA();f0();GA();async function Z81(A,Q){let{bodyContent:B,coverImageId:w}=Ge2(Q.content),$=w?await Fe2(A,w):void 0,f={bodyContent:B};if($)f.imageData=$;return f}function Ge2(A){try{let Q=t2(A,F.record(F.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 Fe2(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 B_A=F.object({entityType:F.string().describe("Entity type to publish (e.g., social-post, post, deck)"),id:F.string().optional().describe("Entity ID to publish"),slug:F.string().optional().describe("Entity slug to publish")}),Ke2=F.object({success:F.literal(!0),message:F.string().optional(),data:F.object({entityType:F.string().optional(),entityId:F.string().optional(),platformId:F.string().optional(),url:F.string().optional()}).optional()}),Ze2=F.object({success:F.literal(!1),error:F.string(),code:F.string().optional()}),w_A=F.union([Ke2,Ze2]);function x2A(A,Q,B){return{...xQ(Q,"publish","Publish an entity directly to its platform. Works with any registered entity type (social-post, post, deck, etc.)",B_A,async($)=>{let{entityType:f,id:I,slug:D}=$;if(!I&&!D)return{success:!1,error:"Either 'id' or 'slug' must be provided"};let H=await Ne2(A,f,I,D);if(!H)return{success:!1,error:`Entity not found: ${f}:${I??D}`};if(H.metadata.status==="published")return{success:!1,error:"Entity is already published"};if(!B.has(f))return{success:!1,error:`No publish provider registered for ${f}. Check that the required credentials are configured.`};let Y=B.get(f),{bodyContent:W,imageData:G}=await Z81(A,H),K=await Y.publish(W,H.metadata,G);return await A.entityService.updateEntity({entity:{...H,metadata:{...H.metadata,status:"published",publishedAt:new Date().toISOString(),platformId:K.id}}}),{success:!0,data:{entityType:f,entityId:H.id,platformId:K.id,url:K.url},message:`Published ${f}:${H.id}`}}),outputSchema:w_A}}async function Ne2(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}f0();GA();function N81(A,Q){ze2(A,Q),qe2(A,Q)}function ze2(A,Q){A.messaging.subscribe(k9.REGISTER,async(B)=>Ce2(Q,B.payload)),A.messaging.subscribe(k9.QUEUE,async(B)=>Le2(A,Q,B.payload)),A.messaging.subscribe(k9.DIRECT,async(B)=>Ee2(A,Q,B.payload)),A.messaging.subscribe(k9.REMOVE,async(B)=>Me2(Q,B.payload)),A.messaging.subscribe(k9.REORDER,async(B)=>Ve2(Q,B.payload)),A.messaging.subscribe(k9.LIST,async(B)=>be2(A,Q,B.payload)),A.messaging.subscribe(k9.REPORT_SUCCESS,async(B)=>Oe2(Q,B.payload)),A.messaging.subscribe(k9.REPORT_FAILURE,async(B)=>Re2(Q,B.payload)),Q.logger.debug("Subscribed to publish messages")}function qe2(A,Q){A.messaging.subscribe(rZ.REPORT_SUCCESS,async(B)=>_e2(Q,B.payload)),A.messaging.subscribe(rZ.REPORT_FAILURE,async(B)=>Pe2(Q,B.payload)),Q.logger.debug("Subscribed to generation messages")}async function Ce2(A,Q){let{entityType:B,provider:w}=Q;try{if(w)A.providerRegistry.register(B,w),A.logger.info(`Registered provider for entity type: ${B}`,{providerName:w.name});return{success:!0}}catch($){let f=y0($);return A.logger.error(`Failed to register provider: ${f}`),{success:!1}}}async function Le2(A,Q,B){let{entityType:w,entityId:$}=B;try{let f=await Q.queueManager.add(w,$);return await A.messaging.send({type:k9.QUEUED,payload:{entityType:w,entityId:$,position:f.position}}),Q.logger.debug(`Entity queued: ${$}`,{entityType:w,position:f.position}),{success:!0}}catch(f){let I=y0(f);return Q.logger.error(`Failed to queue entity: ${I}`),{success:!1}}}async function Ee2(A,Q,B){let{entityType:w,entityId:$}=B;return await A.messaging.send({type:k9.EXECUTE,payload:{entityType:w,entityId:$}}),Q.logger.debug(`Direct publish requested: ${$}`,{entityType:w}),{success:!0}}async function Me2(A,Q){let{entityType:B,entityId:w}=Q;try{return await A.queueManager.remove(B,w),A.logger.debug(`Entity removed from queue: ${w}`,{entityType:B}),{success:!0}}catch($){let f=y0($);return A.logger.error(`Failed to remove entity: ${f}`),{success:!1}}}async function Ve2(A,Q){let{entityType:B,entityId:w,position:$}=Q;try{return await A.queueManager.reorder(B,w,$),A.logger.debug(`Entity reordered: ${w}`,{entityType:B,newPosition:$}),{success:!0}}catch(f){let I=y0(f);return A.logger.error(`Failed to reorder entity: ${I}`),{success:!1}}}async function be2(A,Q,B){let{entityType:w}=B;try{let $=await Q.queueManager.list(w);return await A.messaging.send({type:k9.LIST_RESPONSE,payload:{entityType:w,queue:$.map((f)=>({entityId:f.entityId,position:f.position,queuedAt:f.queuedAt}))}}),{success:!0}}catch($){let f=y0($);return Q.logger.error(`Failed to list queue: ${f}`),{success:!1}}}async function Oe2(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 Re2(A,Q){let{entityType:B,entityId:w,error:$}=Q;A.scheduler.failPublish(B,w,$);let f=A.retryTracker.getRetryInfo(w);return A.logger.info(`Publish reported failure: ${w}`,{entityType:B,error:$,retryCount:f?.retryCount,willRetry:f?.willRetry}),{success:!0}}async function _e2(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 Pe2(A,Q){let{entityType:B,error:w}=Q;return A.scheduler.failGeneration(B,w),A.logger.warn("Generation failed",{entityType:B,error:w}),{success:!0}}GA();async function z81(A,Q,B,w){try{if(w.skipIfDraftExists!==!1){if((await A.listEntities({entityType:B,options:{filter:{metadata:{status:"draft"}},limit:1}})).length>0)return{shouldGenerate:!1,reason:"Draft already exists"}}if(w.maxUnpublishedDrafts!==void 0){let $=await A.listEntities({entityType:B,options:{filter:{metadata:{status:"draft"}},limit:w.maxUnpublishedDrafts+1}});if($.length>=w.maxUnpublishedDrafts)return{shouldGenerate:!1,reason:`Max unpublished drafts reached (${$.length}/${w.maxUnpublishedDrafts})`}}if(w.minSourceEntities!==void 0&&w.sourceEntityType){let $=await A.listEntities({entityType:w.sourceEntityType,options:{publishedOnly:!0,limit:w.minSourceEntities}});if($.length<w.minSourceEntities)return{shouldGenerate:!1,reason:`Not enough source entities (${$.length}/${w.minSourceEntities} ${w.sourceEntityType})`}}return{shouldGenerate:!0}}catch($){return Q.error("Failed to check generation conditions",{entityType:B,error:y0($)}),{shouldGenerate:!1,reason:`Condition check failed: ${y0($)}`}}}function q81(A){let{context:Q,config:B,queueManager:w,providerRegistry:$,retryTracker:f,logger:I}=A,D=ke2(Q);return fY.createFresh({queueManager:w,providerRegistry:$,retryTracker:f,logger:I,backend:new j2A,...B.entitySchedules&&{entitySchedules:B.entitySchedules},...B.generationSchedules&&{generationSchedules:B.generationSchedules},...B.generationConditions&&{generationConditions:B.generationConditions},messageBus:D,entityService:Q.entityService,onCheckGenerationConditions:(H,Y)=>z81(Q.entityService,I,H,Y)})}function ke2(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 C81(A,Q,B){let w=A.getEntityTypes();for(let f of w){let I=await A.listEntities({entityType:f,options:{filter:{metadata:{status:"queued"}}}});for(let D of I)await Q.add(D.entityType,D.id)}let $=0;for(let f of w){let I=await Q.list(f);$+=I.length}if($>0)B.info(`Rebuilt queue with ${$} queued entities`)}var je2=["draft","queued","published","failed"];async function L81(A,Q){await A.messaging.send({type:"dashboard:register-widget",payload:{id:"publication-pipeline",pluginId:Q,title:"Publication Pipeline",section:"secondary",priority:100,rendererName:"PipelineWidget",visibility:"anchor",dataProvider:()=>ve2(A)}})}async function ve2(A){let Q=A.entityService.getEntityTypes(),B=[],w={draft:0,queued:0,published:0,failed:0};for(let $ of Q){let f=await A.entityService.listEntities({entityType:$});for(let I of f){let D=xe2(I.metadata.status);if(!D)continue;w[D]++,B.push({id:I.id,title:he2(I.id,I.metadata.title),type:$,status:D})}}return{summary:w,items:B}}function xe2(A){return je2.find((Q)=>Q===A)}function he2(A,Q){return typeof Q==="string"?Q:A}var E81={name:"@brains/content-pipeline",private:!0,version:"0.2.0-alpha.71",description:"Content pipeline plugin for managing entity publishing queues, scheduling, and generation",type:"module",main:"src/index.ts",types:"src/index.ts",scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*",croner:"^9.1.0"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14",typescript:"^5.3.3"},exports:{".":{types:"./src/index.ts",default:"./src/index.ts"}},files:["src"]};class $_A extends Ww{pluginContext;queueManager;providerRegistry;retryTracker;scheduler;constructor(A){super("content-pipeline",E81,A??{},$81)}async onRegister(A){this.pluginContext=A,this.queueManager=FW.createFresh(),this.providerRegistry=KW.createFresh(),this.retryTracker=ZW.createFresh({maxRetries:this.config.maxRetries,baseDelayMs:this.config.retryBaseDelayMs}),this.scheduler=q81({context:A,config:this.config,queueManager:this.queueManager,providerRegistry:this.providerRegistry,retryTracker:this.retryTracker,logger:this.logger}),N81(A,{queueManager:this.queueManager,providerRegistry:this.providerRegistry,retryTracker:this.retryTracker,scheduler:this.scheduler,logger:this.logger})}async onReady(A){await C81(A.entityService,this.queueManager,this.logger),await L81(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[v2A(this.pluginContext,this.id,this.queueManager),x2A(this.pluginContext,this.id,this.providerRegistry)]}async getInstructions(){return'## Publishing\n- Use `content-pipeline_queue` to manage the publish queue \u2014 list queued items, add entities to the queue, remove them, or reorder.\n- Use `content-pipeline_publish` to publish an entity directly to its platform (e.g. LinkedIn, Buttondown).\n- When users ask about their "publish queue", "publishing queue", or "what\'s queued", use `content-pipeline_queue`.'}getQueueManager(){return this.queueManager}getProviderRegistry(){return this.providerRegistry}getRetryTracker(){return this.retryTracker}getScheduler(){return this.scheduler}async onShutdown(){await this.scheduler.stop(),FW.resetInstance(),KW.resetInstance(),ZW.resetInstance()}}function f_A(A){return new $_A(A)}f0();GA();var M81=F.object({accountId:F.string().describe("Cloudflare account ID"),apiToken:F.string().describe("Cloudflare API token with Analytics:Read permission"),siteTag:F.string().describe("Cloudflare Web Analytics site tag")}),I_A=F.object({cloudflare:M81.optional()});f0();GA();var ge2=F.object({date:F.string().describe("Single date in YYYY-MM-DD format").optional(),days:F.number().min(1).max(365).describe("Number of days back from yesterday (e.g., 7 for last week)").optional(),startDate:F.string().describe("Start date in YYYY-MM-DD format (use with endDate)").optional(),endDate:F.string().describe("End date in YYYY-MM-DD format (use with startDate)").optional(),limit:F.number().min(1).max(100).default(20).describe("Maximum items for breakdowns (pages, referrers, countries)")});function Te2(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 V81(A,Q,B){let w=[];if(!B)return w;return w.push(xQ(A,"query",`Query website analytics from Cloudflare.
|
|
3535
3535
|
|
|
3536
3536
|
Date range options (use only one):
|
|
3537
3537
|
- No params: yesterday only
|
|
@@ -3669,7 +3669,7 @@ Returns pageviews, visitors, top pages, referrers, devices, and countries.`,ge2,
|
|
|
3669
3669
|
}
|
|
3670
3670
|
}
|
|
3671
3671
|
}
|
|
3672
|
-
`,variables:B})});if(!w.ok){let I=await w.text();throw Error(`Cloudflare API error: ${w.status} - ${I}`)}let $=await w.json();if($.errors&&$.errors.length>0)throw Error(`Cloudflare GraphQL error: ${$.errors.map((I)=>I.message).join(", ")}`);return($.data.viewer.accounts[0]?.rumPageloadEventsAdaptiveGroups??[]).map((I)=>({country:I.dimensions.countryName,visits:I.sum.visits}))}}GA();var H_A=7,Se2=10;function O81(A){return async()=>{if(!A)return{unavailable:!0,reason:"Cloudflare analytics not configured"};let Q=ZE(),B=Rp(H_A),w=NF(B),$=NF(Q);try{let[f,I]=await Promise.all([A.getWebsiteStats({startDate:w,endDate:$}),A.getTopPages({startDate:w,endDate:$,limit:Se2})]);return{days:H_A,startDate:w,endDate:$,pageviews:f.pageviews,visitors:f.visitors,topPages:I}}catch(f){return{error:f instanceof Error?f.message:"Failed to fetch analytics",days:H_A}}}}var R81={name:"@brains/analytics",private:!0,version:"0.2.0-alpha.
|
|
3672
|
+
`,variables:B})});if(!w.ok){let I=await w.text();throw Error(`Cloudflare API error: ${w.status} - ${I}`)}let $=await w.json();if($.errors&&$.errors.length>0)throw Error(`Cloudflare GraphQL error: ${$.errors.map((I)=>I.message).join(", ")}`);return($.data.viewer.accounts[0]?.rumPageloadEventsAdaptiveGroups??[]).map((I)=>({country:I.dimensions.countryName,visits:I.sum.visits}))}}GA();var H_A=7,Se2=10;function O81(A){return async()=>{if(!A)return{unavailable:!0,reason:"Cloudflare analytics not configured"};let Q=ZE(),B=Rp(H_A),w=NF(B),$=NF(Q);try{let[f,I]=await Promise.all([A.getWebsiteStats({startDate:w,endDate:$}),A.getTopPages({startDate:w,endDate:$,limit:Se2})]);return{days:H_A,startDate:w,endDate:$,pageviews:f.pageviews,visitors:f.visitors,topPages:I}}catch(f){return{error:f instanceof Error?f.message:"Failed to fetch analytics",days:H_A}}}}var R81={name:"@brains/analytics",private:!0,version:"0.2.0-alpha.71",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 _81 extends Ww{cloudflareClient;constructor(A={}){super("analytics",R81,A,I_A)}async onRegister(A){this.cloudflareClient=this.config.cloudflare?new D_A(this.config.cloudflare):void 0,A.insights.register("traffic-overview",O81(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:b81(Q)}})}async getTools(){return V81(this.id,this.getContext(),this.cloudflareClient)}}function ue2(A={}){return new _81(A)}var h2A=ue2;f0();GA();Lw();var ce2=new Set(["description","excerpt","summary","tagline","story"]);function pe2(A){if(A.endsWith("s"))return A;return ef(A)}function Y_A(A,Q=!1,B){let w=A._def.typeName;if(w==="ZodOptional"||w==="ZodNullable")return Y_A(A._def.innerType,!0,B);if(w==="ZodDefault")return Y_A(A._def.innerType,Q,A._def.defaultValue());return{inner:A,isOptional:Q,defaultValue:B}}function X_A(A,Q){let{inner:B,isOptional:w,defaultValue:$}=Y_A(Q),f=B._def.typeName,I={name:A,label:mY(A),widget:"string",...w&&{required:!1},...$!==void 0&&{default:$}};switch(f){case"ZodString":{if((B._def.checks??[]).some((H)=>H.kind==="datetime"))return{...I,widget:"datetime"};if(ce2.has(A))return{...I,widget:"text"};return{...I,widget:"string"}}case"ZodNumber":return{...I,widget:"number"};case"ZodBoolean":return{...I,widget:"boolean"};case"ZodEnum":{let D=B._def.values;return{...I,widget:"select",options:D}}case"ZodArray":{let D=B._def.type,H=X_A("item",D);if(H.widget==="object"&&H.fields)return{...I,widget:"list",fields:H.fields};return{...I,widget:"list",field:{name:A,label:mY(A),widget:H.widget}}}case"ZodObject":{let D=B.shape,H=Object.entries(D).map(([Y,W])=>X_A(Y,W));return{...I,widget:"object",fields:H}}default:return{...I,widget:"string"}}}function P81(A,Q){let B=Object.entries(A.shape).map(([w,$])=>X_A(w,$));if(Q)B.push({name:"body",label:"Body",widget:"markdown"});return B}function k81(A){let Q=[],B=[];for(let w of A.entityTypes){let $=A.getFrontmatterSchema(w);if(!$)continue;let f=A.getAdapter(w),I=f?.hasBody!==!1,D=A.entityDisplay?.[w],H=w===Pl?"Note":mY(w),Y=D?.label??H,W=D?.pluralName??pe2(Y);if(f?.isSingleton){B.push({name:w,label:Y,file:`${w}/${w}.md`,fields:P81($,I)});continue}if(w===Pl){Q.push({name:w,label:W,folder:".",create:!0,extension:"md",format:"frontmatter",fields:[{name:"body",label:"Body",widget:"markdown"}]});continue}Q.push({name:w,label:W,folder:w,create:!0,extension:"md",format:"frontmatter",fields:P81($,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 W_A(A){return`<!doctype html>
|
|
3673
3673
|
<html>
|
|
3674
3674
|
<head>
|
|
3675
3675
|
<meta charset="utf-8" />
|
|
@@ -3680,7 +3680,7 @@ Returns pageviews, visitors, top pages, referrers, devices, and countries.`,ge2,
|
|
|
3680
3680
|
</head>
|
|
3681
3681
|
<body></body>
|
|
3682
3682
|
</html>
|
|
3683
|
-
`}GA();var j81={name:"@brains/cms",private:!0,version:"0.2.0-alpha.
|
|
3683
|
+
`}GA();var j81={name:"@brains/cms",private:!0,version:"0.2.0-alpha.71",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 ie2=F.object({label:F.string().optional(),pluralName:F.string().optional()}).passthrough(),re2=F.object({entityDisplay:F.record(ie2).optional(),routePath:F.string().default("/cms")});function de2(A){return`${A.endsWith("/")?A:`${A}/`}config.yml`}function ne2(A,Q){let B=A.entityDisplay??Q?.entityDisplay;return B?{entityDisplay:B}:{}}async function oe2(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 se2(A,Q={}){let{repo:B,branch:w}=await oe2(A);return k81({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 v81(A,Q={}){return TY(await se2(A,Q))}class U_A extends Ww{constructor(A={}){super("cms",j81,A,re2)}async onRegister(A){await super.onRegister(A),A.endpoints.register({label:"CMS",url:this.config.routePath,priority:40,visibility:"anchor"}),A.interactions.register({id:"cms",label:"CMS",description:"Edit and manage content through the browser CMS.",href:this.config.routePath,kind:"admin",priority:40,visibility:"anchor"})}getWebRoutes(){let A=de2(this.config.routePath);return[{path:this.config.routePath,method:"GET",public:!0,handler:async()=>{return new Response(W_A({cmsConfigPath:A}),{headers:{"Content-Type":"text/html; charset=utf-8"}})}},{path:A,method:"GET",public:!0,handler:async()=>{try{let Q=await v81(this.getContext(),ne2(this.config,this.getContext()));return new Response(Q,{headers:{"Content-Type":"application/yaml; charset=utf-8"}})}catch(Q){return new Response(Q instanceof Error?Q.message:"CMS unavailable",{status:503,headers:{"Content-Type":"text/plain; charset=utf-8"}})}}}]}}function uC(A){return new U_A(A)}f0();GA();f0();GA();var y2A=["StatsWidget","ListWidget","CustomWidget","PipelineWidget","IdentityWidget","ProfileWidget","SystemWidget"],ae2=new Set(y2A);function J_A(A){return ae2.has(A)}var x81=F.object({id:F.string(),pluginId:F.string(),title:F.string(),description:F.string().optional(),priority:F.number().default(50),section:F.enum(["primary","secondary","sidebar"]).default("primary"),rendererName:F.string(),visibility:A7.default("public")});class g2A{widgets=new Map;logger;constructor(A){this.logger=A.child("DashboardWidgetRegistry")}register(A){let Q={...A,...x81.parse(A)},B=`${Q.pluginId}:${Q.id}`;this.widgets.set(B,Q),this.logger.debug("Dashboard widget registered",{key:B,title:Q.title,rendererName:Q.rendererName})}unregister(A,Q){if(Q){this.widgets.delete(`${A}:${Q}`);return}for(let B of this.widgets.keys())if(B.startsWith(`${A}:`))this.widgets.delete(B)}get(A,Q){return this.widgets.get(`${A}:${Q}`)}list(A={}){let Q=typeof A==="string"?{section:A}:A,B=Q.permissionLevel??"public";return Array.from(this.widgets.values()).filter((w)=>!Q.section||w.section===Q.section).filter((w)=>Q7.hasPermission(B,w.visibility)).sort((w,$)=>w.priority-$.priority)}get size(){return this.widgets.size}}GA();class T2A{id="dashboard:dashboard";name="Dashboard DataSource";description="Aggregates dashboard widgets from all plugins";registry;logger;constructor(A,Q){this.registry=A,this.logger=Q.child("DashboardDataSource")}async getDashboardData(A={}){let Q={},B=A.widgets??this.registry.list({...A.permissionLevel!==void 0&&{permissionLevel:A.permissionLevel}}),w=await Promise.allSettled(B.map(async($)=>{let f=await $.dataProvider(),{dataProvider:I,component:D,clientScript:H,visibility:Y="public",...W}=$;return{key:`${$.pluginId}:${$.id}`,widget:{...W,visibility:Y},data:f}}));for(let $=0;$<w.length;$++){let f=w[$],I=B[$];if(!f||!I)continue;if(f.status==="fulfilled")Q[f.value.key]={widget:f.value.widget,data:f.value.data};else this.logger.error("Widget data provider failed",{widgetId:I.id,pluginId:I.pluginId,error:y0(f.reason)})}return{widgets:Q}}async fetch(A,Q,B){return await this.getDashboardData()}}import{render as bAQ}from"preact-render-to-string";var h81=`
|
|
3684
3684
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
3685
3685
|
html, body { min-height: 100%; max-width: 100%; }
|
|
3686
3686
|
body {
|
|
@@ -4920,7 +4920,7 @@ ${h81}`;import{jsxDEV as IY,Fragment as T81}from"preact/jsx-dev-runtime";functio
|
|
|
4920
4920
|
}
|
|
4921
4921
|
});
|
|
4922
4922
|
})();`;function kAQ({input:A}){let Q=A.appInfo.entities,B=A.appInfo.entityCounts,w=RAQ(A.widgets),$=Boolean(A.character.role)||Boolean(A.character.purpose)||A.character.values.length>0,f=A.appInfo.interactions,I=`layout${$?" has-identity":""}`,D=A.operatorAccess&&!A.operatorAccess.isOperator&&A.operatorAccess.hiddenWidgetCount>0,H=new Date;return oQ("html",{lang:"en","data-theme":"dark",children:[oQ("head",{children:[oQ("meta",{charSet:"utf-8"},void 0,!1,void 0,this),oQ("meta",{name:"viewport",content:"width=device-width, initial-scale=1.0"},void 0,!1,void 0,this),oQ("title",{children:A.title},void 0,!1,void 0,this),oQ("link",{rel:"preconnect",href:"https://fonts.googleapis.com"},void 0,!1,void 0,this),oQ("link",{rel:"preconnect",href:"https://fonts.gstatic.com",crossOrigin:"anonymous"},void 0,!1,void 0,this),oQ("link",{href:OAQ,rel:"stylesheet"},void 0,!1,void 0,this),A.themeCSS!==void 0&&oQ("style",{"data-dashboard-theme":!0,dangerouslySetInnerHTML:{__html:A.themeCSS}},void 0,!1,void 0,this),oQ("style",{"data-dashboard-styles":!0,dangerouslySetInnerHTML:{__html:g81}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),oQ("body",{children:[oQ("main",{class:"console","data-component":"dashboard:dashboard",children:[oQ(S81,{title:A.title,tagline:A.profile.description,operatorAccess:A.operatorAccess},void 0,!1,void 0,this),oQ("section",{class:I,children:[$&&oQ("div",{class:"identity-column",children:[oQ(u81,{character:A.character},void 0,!1,void 0,this),oQ(G_A,{interactions:f,baseUrl:A.baseUrl},void 0,!1,void 0,this),D&&A.operatorAccess&&oQ(n81,{hiddenWidgetCount:A.operatorAccess.hiddenWidgetCount,loginUrl:A.operatorAccess.loginUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this),oQ("div",{class:"main-column",children:[oQ(m81,{total:Q,entityCounts:B},void 0,!1,void 0,this),!$&&D&&A.operatorAccess&&oQ(n81,{hiddenWidgetCount:A.operatorAccess.hiddenWidgetCount,loginUrl:A.operatorAccess.loginUrl},void 0,!1,void 0,this),w.primary.map((Y)=>oQ(S2A,{widget:Y},`${Y.widget.pluginId}:${Y.widget.id}`,!1,void 0,this)),w.secondary.map((Y)=>oQ(S2A,{widget:Y},`${Y.widget.pluginId}:${Y.widget.id}`,!1,void 0,this))]},void 0,!0,void 0,this),oQ("div",{class:"sidebar-column",children:[!$&&oQ(G_A,{interactions:f,baseUrl:A.baseUrl},void 0,!1,void 0,this),w.sidebar.map((Y)=>oQ(S2A,{widget:Y},`${Y.widget.pluginId}:${Y.widget.id}`,!1,void 0,this)),oQ(c81,{endpoints:A.appInfo.endpoints,baseUrl:A.baseUrl},void 0,!1,void 0,this),oQ(r81,{appInfo:A.appInfo,now:H},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),oQ(d81,{title:A.title,appInfo:A.appInfo,baseUrl:A.baseUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this),oQ("script",{dangerouslySetInnerHTML:{__html:_AQ}},void 0,!1,void 0,this),oQ("script",{dangerouslySetInnerHTML:{__html:PAQ}},void 0,!1,void 0,this),A.widgetScripts.map((Y,W)=>oQ("script",{dangerouslySetInnerHTML:{__html:Y}},`widget-script:${W}`,!1,void 0,this))]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}function o81(A){return`<!doctype html>
|
|
4923
|
-
${bAQ(oQ(kAQ,{input:A},void 0,!1,void 0,this))}`}function s81(A,Q){let B={},w=new Set;for(let[$,f]of Object.entries(A)){let I=Q?.get(f.widget.pluginId,f.widget.id);if(B[$]={...f,...I?.component?{component:I.component}:{}},I?.clientScript)w.add(I.clientScript)}return{widgets:B,widgetScripts:Array.from(w)}}var a81={name:"@brains/dashboard",private:!0,version:"0.2.0-alpha.
|
|
4923
|
+
${bAQ(oQ(kAQ,{input:A},void 0,!1,void 0,this))}`}function s81(A,Q){let B={},w=new Set;for(let[$,f]of Object.entries(A)){let I=Q?.get(f.widget.pluginId,f.widget.id);if(B[$]={...f,...I?.component?{component:I.component}:{}},I?.clientScript)w.add(I.clientScript)}return{widgets:B,widgetScripts:Array.from(w)}}var a81={name:"@brains/dashboard",private:!0,version:"0.2.0-alpha.71",description:"Dashboard plugin with extensible widget system",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts,.tsx","lint:fix":"eslint . --ext .ts,.tsx --fix"},dependencies:{"@brains/auth-service":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2","preact-render-to-string":"^6.3.1"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var vAQ=F.object({version:F.string().default("1.0.0"),routePath:F.string().default("/dashboard"),themeCSS:F.string().optional()}),xAQ=F.object({id:F.string(),pluginId:F.string(),title:F.string(),description:F.string().optional(),priority:F.number().default(50),section:F.enum(["primary","secondary","sidebar"]).default("primary"),rendererName:F.string(),visibility:A7.default("public"),component:F.custom().optional(),clientScript:F.string().optional(),dataProvider:F.function().returns(F.promise(F.unknown()))}).superRefine((A,Q)=>{if(!J_A(A.rendererName)&&!A.component)Q.addIssue({code:F.ZodIssueCode.custom,message:"Custom dashboard widgets must register a Preact component.",path:["component"]})}),hAQ=F.object({pluginId:F.string(),widgetId:F.string().optional()});function yAQ(A){return{id:A.id,pluginId:A.pluginId,title:A.title,...A.description?{description:A.description}:{},priority:A.priority,section:A.section,rendererName:A.rendererName,visibility:A.visibility,...A.component?{component:A.component}:{},...A.clientScript?{clientScript:A.clientScript}:{},dataProvider:A.dataProvider}}class K_A extends Ww{widgetRegistry=null;datasource=null;siteUrl;ctx;constructor(A){super("dashboard",a81,A??{},vAQ)}async onRegister(A){this.siteUrl=A.siteUrl,this.ctx=A,this.widgetRegistry=new g2A(this.logger),this.datasource=new T2A(this.widgetRegistry,this.logger),A.entities.registerDataSource(this.datasource),A.endpoints.register({label:"Dashboard",url:this.config.routePath,priority:30,visibility:"public"}),A.interactions.register({id:"dashboard",label:"Dashboard",description:"Inspect runtime status, endpoints, and dashboard widgets.",href:this.config.routePath,kind:"admin",priority:30,visibility:"public"}),A.messaging.subscribe("dashboard:register-widget",async(Q)=>{try{let B=xAQ.parse(Q.payload),w=yAQ(B);return this.widgetRegistry?.register(w),this.logger.debug("Widget registered via messaging",{widgetId:B.id,pluginId:B.pluginId,rendererName:B.rendererName,builtIn:y2A.includes(B.rendererName)}),{success:!0}}catch(B){return this.logger.error("Failed to register widget",{error:y0(B),payload:Q.payload}),{success:!1,error:"Widget registration failed"}}}),A.messaging.subscribe("dashboard:unregister-widget",async(Q)=>{let B=hAQ.parse(Q.payload);return this.widgetRegistry?.unregister(B.pluginId,B.widgetId),this.logger.debug("Widget unregistered via messaging",{pluginId:B.pluginId,widgetId:B.widgetId}),{success:!0}}),this.logger.info("Dashboard plugin registered")}getWebRoutes(){return[{path:this.config.routePath,method:"GET",public:!0,handler:async(A)=>{if(!this.datasource||!this.ctx)return new Response("Dashboard unavailable",{status:503,headers:{"Content-Type":"text/plain; charset=utf-8"}});let Q=this.ctx,B=await nb()?.getOperatorSession(A),w=Boolean(B),$=w?"anchor":"public",f=this.widgetRegistry?.list({permissionLevel:"anchor"})??[],I=f.filter((o)=>Q7.hasPermission($,o.visibility)),D=f.length-I.length,[H,Y]=await Promise.all([this.datasource.getDashboardData({permissionLevel:$,widgets:I}),Q.appInfo()]),W=Q.identity.get(),G=Q.identity.getProfile(),K=this.siteUrl??(()=>{try{return new URL(A.url).origin}catch{return}})(),Z={...Y,endpoints:Y.endpoints.filter((o)=>Q7.hasPermission($,o.visibility)),interactions:Y.interactions.filter((o)=>Q7.hasPermission($,o.visibility))},q=G.name||Y.model||"Brain Dashboard",L=new URL(A.url),C=`${L.pathname}${L.search}`,R=encodeURIComponent(C),k=s81(H.widgets,this.widgetRegistry),_={title:q,baseUrl:K,widgets:k.widgets,widgetScripts:k.widgetScripts,character:W,profile:G,appInfo:Z,...this.config.themeCSS!==void 0&&{themeCSS:this.config.themeCSS},operatorAccess:{isOperator:w,hiddenWidgetCount:D,loginUrl:`/login?return_to=${R}`,logoutUrl:`/logout?return_to=${R}`}};return new Response(o81(_),{headers:{"Content-Type":"text/html; charset=utf-8"}})}}]}async getTools(){return[]}getWidgetRegistry(){return this.widgetRegistry}}function nZ(A){return new K_A(A)}f0();GA();var gAQ=F.object({id:F.string(),pluginId:F.string(),title:F.string(),description:F.string().optional(),priority:F.number(),section:F.enum(["primary","secondary","sidebar"]),rendererName:F.string(),visibility:A7,component:F.custom().optional()}),TAQ=F.object({widget:gAQ,data:F.unknown()}),SAQ=F.object({widgets:F.record(TAQ)});GA();f0();GA();import{h as eAQ}from"preact";GA();LD();f0();var J_=F.enum(["draft","queued","published","failed"]),Pm=F.object({subject:F.string(),status:J_,entityIds:F.array(F.string()).optional(),scheduledFor:F.string().datetime().optional(),sentAt:F.string().datetime().optional(),buttondownId:F.string().optional(),sourceEntityType:F.string().optional()}),t81=Pm.pick({subject:!0,status:!0,entityIds:!0,scheduledFor:!0,sentAt:!0,buttondownId:!0,sourceEntityType:!0}),km=B2.extend({entityType:F.literal("newsletter"),metadata:t81});f0();class e81 extends W2{constructor(){super({entityType:"newsletter",schema:km,frontmatterSchema:Pm})}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 A61=new e81;f0();f0();GA();var mAQ=tY.extend({status:F.enum(["draft","queued","published","failed"]).optional()}),uAQ=eY.extend({query:mAQ.optional()});function Q61(A){try{let{content:Q}=t2(A.content,Pm);return Q}catch{return A.content}}class Z_A extends r6{id="newsletter:entities";name="Newsletter Entity DataSource";description="Fetches and transforms newsletter entities for rendering";config={entityType:"newsletter",defaultSort:[{field:"created",direction:"desc"}],defaultLimit:10,lookupField:"id",enableNavigation:!0};constructor(A){super(A);this.logger.debug("NewsletterDataSource initialized")}parseQuery(A){let Q=uAQ.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}transformEntity(A){let Q=Q61(A),B={id:A.id,subject:A.metadata.subject,status:A.metadata.status,excerpt:cY(Q,150),created:A.created,url:`/newsletters/${A.id}`};if(A.metadata.sentAt)B.sentAt=A.metadata.sentAt;return B}buildListResult(A,Q,B){return{newsletters:A,totalCount:Q?.totalItems??A.length,pagination:Q}}async fetch(A,Q,B){let{query:w}=this.parseQuery(A),$=B.entityService;if(w.id)return this.fetchSingleNewsletter(w.id,Q,$);let f=w.status,I=f?{filter:{metadata:{status:f}}}:void 0,{items:D,pagination:H}=await this.fetchList(w,$,I);return Q.parse(this.buildListResult(D,H,w))}async fetchSingleNewsletter(A,Q,B){let w=await B.getEntity({entityType:this.config.entityType,id:A});if(!w)throw Error(`Newsletter not found: ${A}`);let $=await this.resolveNavigation(w,B),f=[];if(w.metadata.entityIds?.length){let H=w.metadata.sourceEntityType??"post";f=(await Promise.all(w.metadata.entityIds.map(async(W)=>{let G=await B.getEntity({entityType:H,id:W});if(G){let K=G.metadata;return{id:W,title:K.title??W,url:`/${H}s/${K.slug??W}`}}return null}))).filter((W)=>W!==null)}let I=Q61(w),D={id:w.id,subject:w.metadata.subject,status:w.metadata.status,content:I,created:w.created,updated:w.updated,sentAt:w.metadata.sentAt,scheduledFor:w.metadata.scheduledFor,newsletter:w,prevNewsletter:$.prev?{id:$.prev.id,subject:$.prev.subject,url:$.prev.url}:null,nextNewsletter:$.next?{id:$.next.id,subject:$.next.subject,url:$.next.url}:null,sourceEntities:f.length>0?f:void 0};return Q.parse(D)}}f0();GA();var cAQ=F.object({prompt:F.string().optional().describe("AI generation prompt"),sourceEntityIds:F.array(F.string()).optional().describe("Entity IDs to include in newsletter (e.g., blog posts)"),sourceEntityType:F.enum(["post"]).optional().describe("Type of source entities"),content:F.string().optional().describe("Direct content (skip AI)"),subject:F.string().optional().describe("Newsletter subject (AI-generated if not provided)"),addToQueue:F.boolean().optional().describe("Create as queued (true) or draft (false)")});class N_A extends X9{constructor(A,Q){super(A,Q,{schema:cAQ,jobTypeName:"newsletter:generation",entityType:"newsletter"})}async generate(A,Q){let B=A.addToQueue??!1,{prompt:w,sourceEntityIds:$,sourceEntityType:f}=A,{content:I,subject:D}=A;if(I){if(!D)this.failEarly("Subject is required when providing content directly");await this.reportProgress(Q,{progress:50,message:"Using provided content"})}else if($&&$.length>0){let K=f??"post";await this.reportProgress(Q,{progress:10,message:`Fetching ${$.length} source entities`});let q=(await Promise.all($.map((_)=>this.context.entityService.getEntity({entityType:K,id:_})))).filter((_)=>_!=null);if(q.length===0)this.failEarly(`No source entities found for IDs: ${$.join(", ")}`);await this.reportProgress(Q,{progress:30,message:`Generating newsletter from ${q.length} posts`});let C=`Create an engaging newsletter that highlights these blog posts:
|
|
4924
4924
|
|
|
4925
4925
|
${q.map((_)=>`## ${_.metadata.title}
|
|
4926
4926
|
|
|
@@ -4989,14 +4989,14 @@ Newsletter-specific guidelines:
|
|
|
4989
4989
|
- "Reply and let me know..."
|
|
4990
4990
|
- "Until next time..."
|
|
4991
4991
|
|
|
4992
|
-
The goal is to build a relationship with readers through valuable, authentic content.`});GA();f0();import{jsxDEV as j7,Fragment as dAQ}from"preact/jsx-dev-runtime";var lAQ=F.object({id:F.string(),subject:F.string(),status:J_,excerpt:F.string(),created:F.string(),sentAt:F.string().optional(),url:F.string()}),iAQ=F.object({newsletters:F.array(lAQ),totalCount:F.number(),pagination:Y9.nullable()}),rAQ=({newsletters:A,totalCount:Q,pageTitle:B,pagination:w,baseUrl:$="/newsletters"})=>{let f=B??"Newsletters",I=`Browse all ${Q} ${Q===1?"newsletter":"newsletters"}`;return j7(dAQ,{children:[j7(XQ,{title:f,description:I},void 0,!1,void 0,this),j7("div",{className:"newsletter-list bg-theme",children:j7("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[j7("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:f},void 0,!1,void 0,this),A.length===0?j7("p",{className:"text-theme-muted italic",children:"No newsletters yet."},void 0,!1,void 0,this):j7("div",{className:"space-y-4",children:A.map((D)=>j7(UB,{href:D.url,children:[j7(f$,{className:"text-lg",children:D.subject},void 0,!1,void 0,this),j7(h$,{children:j7("div",{className:"flex items-center gap-3",children:[j7(Lf,{status:D.status},void 0,!1,void 0,this),j7("span",{className:"text-sm text-theme-muted",children:Q6(D.sentAt??D.created,{style:"long"})},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),D.excerpt&&j7("p",{className:"text-theme-muted line-clamp-2",children:D.excerpt},void 0,!1,void 0,this)]},D.id,!0,void 0,this))},void 0,!1,void 0,this),w&&w.totalPages>1&&j7(cJ,{currentPage:w.currentPage,totalPages:w.totalPages,baseUrl:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},w61=O1({name:"newsletter-list",description:"Newsletter list page template",schema:iAQ,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:rAQ}});GA();f0();import{jsxDEV as gw,Fragment as aAQ}from"preact/jsx-dev-runtime";var nAQ=F.object({id:F.string(),title:F.string(),url:F.string()}),$61=F.object({id:F.string(),subject:F.string(),url:F.string()}),oAQ=F.object({id:F.string(),subject:F.string(),status:J_,content:F.string(),created:F.string(),updated:F.string(),sentAt:F.string().optional(),scheduledFor:F.string().optional(),sourceEntities:F.array(nAQ).optional(),prevNewsletter:$61.nullable().optional(),nextNewsletter:$61.nullable().optional()}),sAQ=({subject:A,status:Q,content:B,created:w,sentAt:$,scheduledFor:f,sourceEntities:I,prevNewsletter:D,nextNewsletter:H})=>{let Y=[{label:"Home",href:"/"},{label:"Newsletters",href:"/newsletters"},{label:A}],W=$??w,G=$?"Sent":"Created";return gw(aAQ,{children:[gw(XQ,{title:A,description:`Newsletter: ${A}`},void 0,!1,void 0,this),gw("section",{className:"newsletter-detail-section",children:gw("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:gw("div",{className:"max-w-3xl mx-auto",children:[gw(tX,{items:Y},void 0,!1,void 0,this),gw("h1",{className:"text-3xl md:text-4xl font-bold text-heading leading-tight tracking-tight mb-4",children:A},void 0,!1,void 0,this),gw("div",{className:"flex flex-wrap items-center gap-3 mb-8 text-sm text-theme-muted",children:[gw(Lf,{status:Q},void 0,!1,void 0,this),gw("span",{children:[G,": ",Q6(W,{style:"long"})]},void 0,!0,void 0,this),f&&Q==="queued"&&gw("span",{children:["Scheduled for: ",Q6(f,{style:"long"})]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),I&&I.length>0&&gw(UB,{variant:"compact",className:"mb-8",children:[gw("h3",{className:"text-sm font-medium text-heading mb-2",children:"Related Content"},void 0,!1,void 0,this),gw("ul",{className:"space-y-1",children:I.map((K)=>gw("li",{children:gw("a",{href:K.url,className:"text-sm text-brand hover:text-brand-dark transition-colors",children:K.title},void 0,!1,void 0,this)},K.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),gw(mI,{markdown:B},void 0,!1,void 0,this),(D??H)&&gw("nav",{className:"mt-12 pt-8 border-t border-theme",children:gw("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[D?gw(UB,{href:D.url,variant:"compact",children:[gw("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Newer"},void 0,!1,void 0,this),gw("span",{className:"block mt-1 font-medium text-heading group-hover:text-brand transition-colors truncate",children:D.subject},void 0,!1,void 0,this)]},void 0,!0,void 0,this):gw("div",{},void 0,!1,void 0,this),H&&gw(UB,{href:H.url,variant:"compact",className:"md:text-right",children:[gw("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Older"},void 0,!1,void 0,this),gw("span",{className:"block mt-1 font-medium text-heading group-hover:text-brand transition-colors truncate",children:H.subject},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},f61=O1({name:"newsletter-detail",description:"Individual newsletter detail template",schema:oAQ,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:sAQ}});var I61={name:"@brains/newsletter-entity",private:!0,version:"0.2.0-alpha.
|
|
4992
|
+
The goal is to build a relationship with readers through valuable, authentic content.`});GA();f0();import{jsxDEV as j7,Fragment as dAQ}from"preact/jsx-dev-runtime";var lAQ=F.object({id:F.string(),subject:F.string(),status:J_,excerpt:F.string(),created:F.string(),sentAt:F.string().optional(),url:F.string()}),iAQ=F.object({newsletters:F.array(lAQ),totalCount:F.number(),pagination:Y9.nullable()}),rAQ=({newsletters:A,totalCount:Q,pageTitle:B,pagination:w,baseUrl:$="/newsletters"})=>{let f=B??"Newsletters",I=`Browse all ${Q} ${Q===1?"newsletter":"newsletters"}`;return j7(dAQ,{children:[j7(XQ,{title:f,description:I},void 0,!1,void 0,this),j7("div",{className:"newsletter-list bg-theme",children:j7("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[j7("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:f},void 0,!1,void 0,this),A.length===0?j7("p",{className:"text-theme-muted italic",children:"No newsletters yet."},void 0,!1,void 0,this):j7("div",{className:"space-y-4",children:A.map((D)=>j7(UB,{href:D.url,children:[j7(f$,{className:"text-lg",children:D.subject},void 0,!1,void 0,this),j7(h$,{children:j7("div",{className:"flex items-center gap-3",children:[j7(Lf,{status:D.status},void 0,!1,void 0,this),j7("span",{className:"text-sm text-theme-muted",children:Q6(D.sentAt??D.created,{style:"long"})},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),D.excerpt&&j7("p",{className:"text-theme-muted line-clamp-2",children:D.excerpt},void 0,!1,void 0,this)]},D.id,!0,void 0,this))},void 0,!1,void 0,this),w&&w.totalPages>1&&j7(cJ,{currentPage:w.currentPage,totalPages:w.totalPages,baseUrl:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},w61=O1({name:"newsletter-list",description:"Newsletter list page template",schema:iAQ,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:rAQ}});GA();f0();import{jsxDEV as gw,Fragment as aAQ}from"preact/jsx-dev-runtime";var nAQ=F.object({id:F.string(),title:F.string(),url:F.string()}),$61=F.object({id:F.string(),subject:F.string(),url:F.string()}),oAQ=F.object({id:F.string(),subject:F.string(),status:J_,content:F.string(),created:F.string(),updated:F.string(),sentAt:F.string().optional(),scheduledFor:F.string().optional(),sourceEntities:F.array(nAQ).optional(),prevNewsletter:$61.nullable().optional(),nextNewsletter:$61.nullable().optional()}),sAQ=({subject:A,status:Q,content:B,created:w,sentAt:$,scheduledFor:f,sourceEntities:I,prevNewsletter:D,nextNewsletter:H})=>{let Y=[{label:"Home",href:"/"},{label:"Newsletters",href:"/newsletters"},{label:A}],W=$??w,G=$?"Sent":"Created";return gw(aAQ,{children:[gw(XQ,{title:A,description:`Newsletter: ${A}`},void 0,!1,void 0,this),gw("section",{className:"newsletter-detail-section",children:gw("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:gw("div",{className:"max-w-3xl mx-auto",children:[gw(tX,{items:Y},void 0,!1,void 0,this),gw("h1",{className:"text-3xl md:text-4xl font-bold text-heading leading-tight tracking-tight mb-4",children:A},void 0,!1,void 0,this),gw("div",{className:"flex flex-wrap items-center gap-3 mb-8 text-sm text-theme-muted",children:[gw(Lf,{status:Q},void 0,!1,void 0,this),gw("span",{children:[G,": ",Q6(W,{style:"long"})]},void 0,!0,void 0,this),f&&Q==="queued"&&gw("span",{children:["Scheduled for: ",Q6(f,{style:"long"})]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),I&&I.length>0&&gw(UB,{variant:"compact",className:"mb-8",children:[gw("h3",{className:"text-sm font-medium text-heading mb-2",children:"Related Content"},void 0,!1,void 0,this),gw("ul",{className:"space-y-1",children:I.map((K)=>gw("li",{children:gw("a",{href:K.url,className:"text-sm text-brand hover:text-brand-dark transition-colors",children:K.title},void 0,!1,void 0,this)},K.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),gw(mI,{markdown:B},void 0,!1,void 0,this),(D??H)&&gw("nav",{className:"mt-12 pt-8 border-t border-theme",children:gw("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[D?gw(UB,{href:D.url,variant:"compact",children:[gw("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Newer"},void 0,!1,void 0,this),gw("span",{className:"block mt-1 font-medium text-heading group-hover:text-brand transition-colors truncate",children:D.subject},void 0,!1,void 0,this)]},void 0,!0,void 0,this):gw("div",{},void 0,!1,void 0,this),H&&gw(UB,{href:H.url,variant:"compact",className:"md:text-right",children:[gw("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Older"},void 0,!1,void 0,this),gw("span",{className:"block mt-1 font-medium text-heading group-hover:text-brand transition-colors truncate",children:H.subject},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},f61=O1({name:"newsletter-detail",description:"Individual newsletter detail template",schema:oAQ,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:sAQ}});var I61={name:"@brains/newsletter-entity",private:!0,version:"0.2.0-alpha.71",description:"Newsletter entity type with AI generation and publish pipeline",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint src test --ext .ts,.tsx","lint:fix":"eslint src test --ext .ts,.tsx --fix"},dependencies:{"@brains/contracts":"workspace:*","@brains/entity-service":"workspace:*","@brains/plugins":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var A0Q=F.object({});class z_A extends KQ{entityType="newsletter";schema=km;adapter=A61;constructor(A={}){super("newsletter",I61,A,A0Q)}createGenerationHandler(A){return new N_A(this.logger,A)}getTemplates(){return{generation:B61,"newsletter-list":w61,"newsletter-detail":f61}}getDataSources(){return[new Z_A(this.logger.child("NewsletterDataSource"))]}async onRegister(A){this.deferPublishRegistration(A),this.subscribeToPublishExecute(A),this.subscribeToGenerateExecute(A),this.registerEvalHandlers(A),A.messaging.subscribe("system:plugins:ready",async()=>{let Q=await A.messaging.send({type:"buttondown:is-configured",payload:{}});if(!("noop"in Q)&&Q.success)await A.messaging.send({type:"plugin:site-builder:slot:register",payload:{pluginId:this.id,slotName:"footer-top",render:()=>eAQ(gMA,{variant:"inline"})}});return{success:!0}}),this.logger.debug("Newsletter plugin registered")}deferPublishRegistration(A){let Q={name:"internal",publish:async()=>({id:"internal"})};A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"publish:register",payload:{entityType:"newsletter",provider:Q}}),{success:!0}})}subscribeToPublishExecute(A){A.messaging.subscribe("publish:execute",async(Q)=>{let{entityType:B,entityId:w}=Q.payload;if(B!=="newsletter")return{success:!0};try{let $=await A.entityService.getEntity({entityType:"newsletter",id:w});if(!$)return await A.messaging.send({type:"publish:report:failure",payload:{entityType:B,entityId:w,error:`Newsletter not found: ${w}`}}),{success:!0};if($.metadata.status==="published")return{success:!0};let f=await A.messaging.send({type:"buttondown:send",payload:{entityId:w,subject:$.metadata.subject,content:$.content}}),I=new Date().toISOString(),D=!("noop"in f)&&f.data?f.data.emailId:void 0;return await A.entityService.updateEntity({entity:{...$,metadata:{...$.metadata,status:"published",sentAt:I,buttondownId:D}}}),await A.messaging.send({type:"publish:report:success",payload:{entityType:B,entityId:w,sentAt:I}}),this.logger.info(`Published newsletter: ${w}`),{success:!0}}catch($){let f=y0($);return await A.messaging.send({type:"publish:report:failure",payload:{entityType:B,entityId:w,error:f}}),{success:!0}}})}subscribeToGenerateExecute(A){A.messaging.subscribe("generate:execute",async(Q)=>{if(Q.payload.entityType!=="newsletter")return{success:!0};try{let B=await A.entityService.listEntities({entityType:"post",options:{filter:{metadata:{status:"published"}},limit:10}});if(B.length===0)return await A.messaging.send({type:"generate:report:failure",payload:{entityType:"newsletter",error:"No published posts available for newsletter"}}),{success:!0};return await A.jobs.enqueue({type:"newsletter:generation",data:{sourceEntityIds:B.map((w)=>w.id),sourceEntityType:"post",addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}}),{success:!0}}catch(B){return await A.messaging.send({type:"generate:report:failure",payload:{entityType:"newsletter",error:y0(B)}}),{success:!0}}})}registerEvalHandlers(A){let Q=F.object({prompt:F.string().optional(),content:F.string().optional()});A.eval.registerHandler("generation",async(B)=>{let w=Q.parse(B),$=w.content?`Create an engaging newsletter based on this content:
|
|
4993
4993
|
|
|
4994
|
-
${w.content}`:w.prompt??"Write an engaging newsletter";return A.ai.generate({prompt:$,templateName:"newsletter:generation"})})}}function q_A(A={}){return new z_A(A)}f0();GA();class G_{config;logger;constructor(A,Q){this.config=A;this.logger=Q}async request(A,Q={}){let B=`https://api.buttondown.email/v1${A}`;this.logger.debug("Buttondown API request",{endpoint:A,method:Q.method??"GET"});let w=await fetch(B,{...Q,headers:{Authorization:`Token ${this.config.apiKey}`,"Content-Type":"application/json",...Q.headers}});if(!w.ok){let $=await w.json().catch(()=>({})),f=$.detail??$.message??`HTTP ${w.status}`;throw this.logger.error("Buttondown API error",{endpoint:A,status:w.status,error:f}),Error(`Buttondown API error: ${f}`)}return w.json()}async createSubscriber(A){let Q={email_address:A.email,type:this.config.doubleOptIn?"unactivated":"regular"};if(A.name)Q.metadata={name:A.name};if(A.tags&&A.tags.length>0)Q.tags=A.tags;this.logger.info("Creating subscriber",{email:A.email});try{return await this.request("/subscribers",{method:"POST",body:JSON.stringify(Q)})}catch(B){if(B instanceof Error&&B.message.includes("already subscribed")){let w=B.message.match(/id=([a-f0-9-]+)/);return this.logger.info("Subscriber already exists",{email:A.email}),{id:w?.[1]??"existing",email:A.email,subscriber_type:"already_subscribed"}}throw B}}async unsubscribe(A){this.logger.info("Unsubscribing",{email:A}),await this.request(`/subscribers/${encodeURIComponent(A)}`,{method:"DELETE"})}async listSubscribers(A){let Q=new URLSearchParams;if(A?.type)Q.set("type",A.type);if(A?.limit)Q.set("page_size",String(A.limit));let B=Q.toString(),w=B?`/subscribers?${B}`:"/subscribers";return this.request(w)}async createEmail(A){let Q={subject:A.subject,body:A.body,status:A.status??"draft"};if(A.publish_date)Q.publish_date=A.publish_date;return this.logger.info("Creating email",{subject:A.subject,status:A.status??"draft"}),this.request("/emails",{method:"POST",body:JSON.stringify(Q)})}async getEmail(A){return this.request(`/emails/${A}`)}async validateCredentials(){try{return await this.request("/subscribers?page_size=1"),!0}catch{return!1}}}f0();GA();var Q0Q=F.object({email:F.string().email().describe("Email address to subscribe"),name:F.string().optional().describe("Subscriber name (optional)"),tags:F.array(F.string()).optional().describe("Tags to apply to subscriber (optional)")}),B0Q=F.object({email:F.string().email().describe("Email address to unsubscribe")}),w0Q=F.object({type:F.enum(["unactivated","regular","unsubscribed"]).optional().describe("Filter by subscriber status"),limit:F.number().optional().describe("Maximum number of results")});function D61(A,Q,B){let w=new G_(Q,B);return[xQ(A,"subscribe","Subscribe an email address to the newsletter. Uses double opt-in by default.",Q0Q,async($)=>{try{let f=await w.createSubscriber({email:$.email,...$.name&&{name:$.name},...$.tags&&{tags:$.tags}}),I=f.subscriber_type==="already_subscribed";return P8({subscriberId:f.id,email:f.email,status:f.subscriber_type,message:I?"already_subscribed":"subscribed"},I?`${$.email} is already subscribed`:`Subscribed ${$.email} successfully`)}catch(f){return E$(y0(f))}}),xQ(A,"unsubscribe","Unsubscribe an email address from the newsletter.",B0Q,async($)=>{try{return await w.unsubscribe($.email),P8({email:$.email},`Unsubscribed ${$.email} successfully`)}catch(f){return E$(y0(f))}}),xQ(A,"list_subscribers","List newsletter subscribers with optional filtering by status.",w0Q,async($)=>{try{let f=await w.listSubscribers({...$.type&&{type:$.type},...$.limit&&{limit:$.limit}});return P8({subscribers:f.results.map((I)=>({id:I.id,email:I.email,status:I.subscriber_type})),count:f.count},`Found ${f.count} subscribers`)}catch(f){return E$(y0(f))}})]}GA();async function H61(A,Q,B,w){if(A.entityType!=="post")return{success:!0,skipped:!0,reason:"Only post entity types trigger auto-send"};let $=await B.getEntity({entityType:"post",id:A.entityId});if(!$)return{success:!1,error:`Post ${A.entityId} not found`};w.info("Auto-sending newsletter for published post",{postId:$.id,title:$.metadata.title});try{let f=await Q.createEmail({subject:$.metadata.title,body:$.content,status:"about_to_send"});return w.info("Newsletter sent for post",{postId:$.id,emailId:f.id}),{success:!0,emailId:f.id}}catch(f){let I=y0(f);return w.error("Failed to send newsletter for post",{postId:$.id,error:I}),{success:!1,error:I}}}var Y61={name:"@brains/buttondown",private:!0,version:"0.2.0-alpha.
|
|
4994
|
+
${w.content}`:w.prompt??"Write an engaging newsletter";return A.ai.generate({prompt:$,templateName:"newsletter:generation"})})}}function q_A(A={}){return new z_A(A)}f0();GA();class G_{config;logger;constructor(A,Q){this.config=A;this.logger=Q}async request(A,Q={}){let B=`https://api.buttondown.email/v1${A}`;this.logger.debug("Buttondown API request",{endpoint:A,method:Q.method??"GET"});let w=await fetch(B,{...Q,headers:{Authorization:`Token ${this.config.apiKey}`,"Content-Type":"application/json",...Q.headers}});if(!w.ok){let $=await w.json().catch(()=>({})),f=$.detail??$.message??`HTTP ${w.status}`;throw this.logger.error("Buttondown API error",{endpoint:A,status:w.status,error:f}),Error(`Buttondown API error: ${f}`)}return w.json()}async createSubscriber(A){let Q={email_address:A.email,type:this.config.doubleOptIn?"unactivated":"regular"};if(A.name)Q.metadata={name:A.name};if(A.tags&&A.tags.length>0)Q.tags=A.tags;this.logger.info("Creating subscriber",{email:A.email});try{return await this.request("/subscribers",{method:"POST",body:JSON.stringify(Q)})}catch(B){if(B instanceof Error&&B.message.includes("already subscribed")){let w=B.message.match(/id=([a-f0-9-]+)/);return this.logger.info("Subscriber already exists",{email:A.email}),{id:w?.[1]??"existing",email:A.email,subscriber_type:"already_subscribed"}}throw B}}async unsubscribe(A){this.logger.info("Unsubscribing",{email:A}),await this.request(`/subscribers/${encodeURIComponent(A)}`,{method:"DELETE"})}async listSubscribers(A){let Q=new URLSearchParams;if(A?.type)Q.set("type",A.type);if(A?.limit)Q.set("page_size",String(A.limit));let B=Q.toString(),w=B?`/subscribers?${B}`:"/subscribers";return this.request(w)}async createEmail(A){let Q={subject:A.subject,body:A.body,status:A.status??"draft"};if(A.publish_date)Q.publish_date=A.publish_date;return this.logger.info("Creating email",{subject:A.subject,status:A.status??"draft"}),this.request("/emails",{method:"POST",body:JSON.stringify(Q)})}async getEmail(A){return this.request(`/emails/${A}`)}async validateCredentials(){try{return await this.request("/subscribers?page_size=1"),!0}catch{return!1}}}f0();GA();var Q0Q=F.object({email:F.string().email().describe("Email address to subscribe"),name:F.string().optional().describe("Subscriber name (optional)"),tags:F.array(F.string()).optional().describe("Tags to apply to subscriber (optional)")}),B0Q=F.object({email:F.string().email().describe("Email address to unsubscribe")}),w0Q=F.object({type:F.enum(["unactivated","regular","unsubscribed"]).optional().describe("Filter by subscriber status"),limit:F.number().optional().describe("Maximum number of results")});function D61(A,Q,B){let w=new G_(Q,B);return[xQ(A,"subscribe","Subscribe an email address to the newsletter. Uses double opt-in by default.",Q0Q,async($)=>{try{let f=await w.createSubscriber({email:$.email,...$.name&&{name:$.name},...$.tags&&{tags:$.tags}}),I=f.subscriber_type==="already_subscribed";return P8({subscriberId:f.id,email:f.email,status:f.subscriber_type,message:I?"already_subscribed":"subscribed"},I?`${$.email} is already subscribed`:`Subscribed ${$.email} successfully`)}catch(f){return E$(y0(f))}}),xQ(A,"unsubscribe","Unsubscribe an email address from the newsletter.",B0Q,async($)=>{try{return await w.unsubscribe($.email),P8({email:$.email},`Unsubscribed ${$.email} successfully`)}catch(f){return E$(y0(f))}}),xQ(A,"list_subscribers","List newsletter subscribers with optional filtering by status.",w0Q,async($)=>{try{let f=await w.listSubscribers({...$.type&&{type:$.type},...$.limit&&{limit:$.limit}});return P8({subscribers:f.results.map((I)=>({id:I.id,email:I.email,status:I.subscriber_type})),count:f.count},`Found ${f.count} subscribers`)}catch(f){return E$(y0(f))}})]}GA();async function H61(A,Q,B,w){if(A.entityType!=="post")return{success:!0,skipped:!0,reason:"Only post entity types trigger auto-send"};let $=await B.getEntity({entityType:"post",id:A.entityId});if(!$)return{success:!1,error:`Post ${A.entityId} not found`};w.info("Auto-sending newsletter for published post",{postId:$.id,title:$.metadata.title});try{let f=await Q.createEmail({subject:$.metadata.title,body:$.content,status:"about_to_send"});return w.info("Newsletter sent for post",{postId:$.id,emailId:f.id}),{success:!0,emailId:f.id}}catch(f){let I=y0(f);return w.error("Failed to send newsletter for post",{postId:$.id,error:I}),{success:!1,error:I}}}var Y61={name:"@brains/buttondown",private:!0,version:"0.2.0-alpha.71",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 f0Q=F.object({apiKey:F.string().optional().describe("Buttondown API key"),doubleOptIn:F.boolean().default(!0).describe("Require email confirmation for new subscribers"),autoSendOnPublish:F.boolean().default(!1).describe("Automatically send newsletter when a blog post is published")});class C_A extends Ww{constructor(A={}){super("buttondown",Y61,A,f0Q)}async onRegister(A){if(A.messaging.subscribe("buttondown:is-configured",async()=>{return{success:!!this.config.apiKey}}),this.config.apiKey){let Q=new G_({apiKey:this.config.apiKey,doubleOptIn:this.config.doubleOptIn},this.logger);if(A.messaging.subscribe("buttondown:send",async(B)=>{try{return{success:!0,data:{emailId:(await Q.createEmail({subject:B.payload.subject,body:B.payload.content,status:"about_to_send"})).id}}}catch(w){return this.logger.error("Buttondown send failed",{error:y0(w)}),{success:!1}}}),this.config.autoSendOnPublish)A.messaging.subscribe("publish:completed",async(B)=>{return await H61(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 D61(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 L_A(A={}){return new C_A(A)}var I0Q=F.object({apiKey:F.string().optional().describe("Buttondown API key"),doubleOptIn:F.boolean().optional().describe("Require email confirmation for new subscribers"),autoSendOnPublish:F.boolean().optional().describe("Automatically send newsletter when a blog post is published")});function X61(A={}){let Q=I0Q.parse(A);return[q_A({}),L_A({...Q.apiKey!==void 0&&{apiKey:Q.apiKey},...Q.doubleOptIn!==void 0&&{doubleOptIn:Q.doubleOptIn},...Q.autoSendOnPublish!==void 0&&{autoSendOnPublish:Q.autoSendOnPublish}})]}f0();GA();import{existsSync as N0Q,mkdirSync as z0Q,writeFileSync as q0Q}from"fs";import{join as XG}from"path";GA();var E_A=F.object({baseFolder:F.string().default("_obsidian")});GA();function D0Q(A){let Q=A,B=!0,w=void 0,$=!1,f=!0;while(f){if(f=!1,Q instanceof F.ZodOptional)B=!1,Q=Q._def.innerType,f=!0;if(Q instanceof F.ZodDefault)B=!1,$=!0,w=Q._def.defaultValue(),Q=Q._def.innerType,f=!0;if(Q instanceof F.ZodNullable)B=!1,Q=Q._def.innerType,f=!0}let I={inner:Q,required:B};if($)I.defaultValue=w;return I}function H0Q(A){if(A instanceof F.ZodEnum)return{type:"enum",enumValues:A._def.values};if(A instanceof F.ZodLiteral)return{type:"string",defaultValue:A._def.value};if(A instanceof F.ZodString)return{type:"string"};if(A instanceof F.ZodNumber)return{type:"number"};if(A instanceof F.ZodBoolean)return{type:"boolean"};if(A instanceof F.ZodArray)return{type:"array"};if(A instanceof F.ZodDate)return{type:"date"};if(A instanceof F.ZodPipeline){if(A._def.out instanceof F.ZodDate)return{type:"date"}}return{type:"unknown"}}function W61(A){let Q=A.shape,B=[];for(let[w,$]of Object.entries(Q)){let{inner:f,required:I,defaultValue:D}=D0Q($),H=H0Q(f),Y={name:w,type:H.type,required:I},W=D!==void 0?D:H.defaultValue;if(W!==void 0)Y.defaultValue=W;if(H.enumValues)Y.enumValues=H.enumValues;B.push(Y)}return B}function Y0Q(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 U61(A,Q,B=""){let w=["---"];for(let $ of Q){let f=Y0Q($,A);if(f==="")w.push(`${$.name}:`);else w.push(`${$.name}: ${f}`)}if(w.push("---"),w.push(""),B)w.push(B);else w.push("<!-- Write your content here -->"),w.push("");return w.join(`
|
|
4995
4995
|
`)}GA();var X0Q={string:"Input",number:"Number",boolean:"Boolean",date:"Date",enum:"Select",array:"Multi",unknown:"Input"};function W0Q(A){let Q={name:A.name,id:A.name,type:X0Q[A.type]};if(A.type==="enum"&&A.enumValues){let B={};A.enumValues.forEach((w,$)=>{B[String($)]=w}),Q.options=B}return Q}function J61(A,Q){let B={filesPaths:A,fields:Q.map(W0Q)};return`---
|
|
4996
4996
|
${TY(B)}---
|
|
4997
|
-
`}GA();var U0Q=new Set(["entityType"]),J0Q={base:"Notes"},G0Q=new Set(["base"]);function F0Q(A){let Q=["file.name"];for(let B of A)if(!U0Q.has(B.name))Q.push(B.name);return Q}function K0Q(A){return A.some((Q)=>Q.name==="status"&&Q.type==="enum")}function G61(A,Q){let B=J0Q[A]??bp(A),w=K0Q(Q),$=F0Q(Q),f=[{type:"table",name:`All ${B}`,order:$}];if(w)f.push({type:"table",name:"By Status",groupBy:{property:"status",direction:"ASC"},order:$});let D={filters:{and:[G0Q.has(A)?'file.folder == "/"':`file.inFolder("${A}")`]},views:f};return{filename:`${B}.base`,content:TY(D),hasStatus:w}}function F61(A){if(A.length===0)return null;let Q=A.map((w)=>`file.inFolder("${w}")`),B={filters:{and:[Q.length===1?Q[0]:{or:Q}]},views:[{type:"table",name:"Settings",order:["file.name","file.folder"]}]};return TY(B)}function K61(A){if(A.length===0)return null;let Q=A.map((w)=>`file.inFolder("${w.entityType}")`),B={filters:{and:[Q.length===1?Q[0]:{or:Q},'status != "published"']},views:[{type:"table",name:"Pipeline",groupBy:{property:"status",direction:"ASC"},order:["file.name","file.folder","status"]}]};return TY(B)}var Z61={name:"@brains/obsidian-vault",private:!0,version:"0.2.0-alpha.70",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 C0Q={mkdir:z0Q,writeFile:q0Q,existsFile:N0Q},L0Q=F.object({entityTypes:F.array(F.string()).optional().describe("Entity types to generate templates for (default: all)")});class M_A extends Ww{deps;constructor(A={},Q={}){super("obsidian-vault",Z61,A,E_A);this.deps={...C0Q,...Q}}async onReady(A){this.logger.info("Auto-syncing Obsidian templates, fileClasses, and bases"),await this.sync(A)}async getTools(){let A=this.getContext();return[xQ(this.id,"sync-templates","Generate Obsidian templates, Metadata Menu fileClass definitions, and Bases views for all registered entity types.",L0Q,async(Q)=>{return this.sync(A,Q.entityTypes)})]}async sync(A,Q){try{let B=A.entityService.getEntityTypes(),w=Q?B.filter((C)=>Q.includes(C)):B,$=XG(A.dataDir,this.config.baseFolder),f=XG($,"templates"),I=XG($,"fileClasses"),D=XG($,"bases");this.deps.mkdir(f,{recursive:!0}),this.deps.mkdir(I,{recursive:!0}),this.deps.mkdir(D,{recursive:!0});let H=[],Y=[],W=[],G=[],K=[],Z=[];for(let C of w){let R=A.entities.getEffectiveFrontmatterSchema(C);if(!R){this.logger.debug(`Skipping ${C}: no frontmatter schema`),Y.push(C);continue}let k=W61(R),_=A.entities.getAdapter(C),o=_?.isSingleton===!0,r=J61(C,k);if(this.deps.writeFile(XG(I,`${C}.md`),r),W.push(C),o){K.push(C),this.logger.debug(`Generated fileClass (singleton): ${C}`);continue}let S=_?.getBodyTemplate()??"",x=U61(C,k,S);this.deps.writeFile(XG(f,`${C}.md`),x),H.push(C);let y=G61(C,k),g=XG(D,y.filename);if(!this.deps.existsFile(g))this.deps.writeFile(g,y.content),G.push(C),this.logger.debug(`Generated base: ${y.filename}`);if(y.hasStatus)Z.push({entityType:C,fields:k});this.logger.debug(`Generated template + fileClass: ${C}`)}let q=F61(K);if(q){let C=XG(D,"Settings.base");if(!this.deps.existsFile(C))this.deps.writeFile(C,q),G.push("Settings"),this.logger.debug("Generated Settings.base")}let L=K61(Z);if(L){let C=XG(D,"Pipeline.base");if(!this.deps.existsFile(C))this.deps.writeFile(C,L),G.push("Pipeline"),this.logger.debug("Generated Pipeline.base")}return this.logger.info(`Synced ${H.length} templates, ${W.length} fileClasses, ${G.length} bases (${Y.length} skipped)`),P8({generated:H,skipped:Y,fileClasses:W,bases:G})}catch(B){return this.logger.error("Failed to sync",{error:B}),E$(B instanceof Error?B.message:"Unknown error")}}}function V_A(A,Q){return new M_A(A,Q)}f0();GA();f0();var b_A=F.enum(["new","planned","in-progress","done","declined"]),O_A=F.enum(["low","medium","high","critical"]),jm=F.object({title:F.string(),status:b_A,priority:O_A.default("medium"),requested:F.number().int().default(1),declinedReason:F.string().optional()}),N61=F.object({title:F.string(),status:b_A,priority:O_A,requested:F.number().int(),slug:F.string()}),vm=B2.extend({entityType:F.literal("wish"),metadata:N61}),R_A=F.object({});f0();GA();class xm extends W2{constructor(){super({entityType:"wish",schema:vm,frontmatterSchema:jm})}createWishContent(A,Q){return this.buildMarkdown(Q,A)}parseWishContent(A){let Q=this.parseFrontMatter(A,jm);return{frontmatter:jm.parse(Q),description:this.extractBody(A).trim()}}fromMarkdown(A){let{frontmatter:Q}=this.parseWishContent(A),B=U2(Q.title);return{content:A,entityType:"wish",metadata:{title:Q.title,status:Q.status,priority:Q.priority,requested:Q.requested,slug:B}}}}var __A=new xm;GA();GA();async function z61(A,Q){let B=`${Q.title}: ${Q.description}`,$=(await A.search({query:B,options:{types:["wish"],limit:1}}))[0];if($&&$.score>=A.similarityThreshold)return $.entity;let f=U2(Q.title);return A.getEntity({entityType:"wish",id:f})}class m2A{logger;context;adapter=new xm;constructor(A,Q){this.logger=A;this.context=Q}async process(A,Q,B){let w=A.title??A.prompt??"Untitled wish",$=A.content??A.prompt??"",f=await z61({search:(Y)=>this.context.entityService.search(Y),getEntity:(Y)=>this.context.entityService.getEntity(Y),similarityThreshold:0.85},{title:w,description:$});if(f){let{frontmatter:Y,description:W}=this.adapter.parseWishContent(f.content),G=Y.requested+1,K=this.adapter.createWishContent({...Y,requested:G},W);return await this.context.entityService.updateEntity({entity:{...f,content:K,metadata:{...f.metadata,requested:G}}}),this.logger.info("Incremented wish request count",{id:f.id,requested:G}),{success:!0,entityId:f.id,existed:!0,requested:G}}let I=U2(w),D=A.options?.priority??"medium",H=this.adapter.createWishContent({title:w,status:"new",priority:D,requested:1},$);return await this.context.entityService.createEntity({entity:{id:I,entityType:"wish",content:H,metadata:{title:w,status:"new",priority:D,requested:1,slug:I}}}),this.logger.info("Created new wish",{id:I,title:w}),{success:!0,entityId:I,existed:!1,requested:1}}}var q61={critical:0,high:1,medium:2,low:3};function C61(A){A.sort((Q,B)=>{let w=B.metadata.requested-Q.metadata.requested;if(w!==0)return w;return q61[Q.metadata.priority]-q61[B.metadata.priority]})}var L61={name:"@brains/wishlist",private:!0,version:"0.2.0-alpha.70",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 E61 extends KQ{entityType=__A.entityType;schema=vm;adapter=__A;constructor(A={}){super("wishlist",L61,A,R_A)}async interceptCreate(A,Q,B){let w=await new m2A(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 C61(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 m2A(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 M0Q(A={}){return new E61(A)}var u2A=M0Q;f0();GA();f0();var hm=F.object({title:F.string(),target:F.string()}),M61=F.object({title:F.string(),target:F.string(),slug:F.string().optional()}),ym=B2.extend({entityType:F.literal("prompt"),metadata:M61});f0();GA();class P_A extends W2{constructor(){super({entityType:"prompt",schema:ym,frontmatterSchema:hm})}toMarkdown(A){let Q=this.extractBody(A.content),B=this.parseFrontMatter(A.content,hm);return this.buildMarkdown(Q,B)}fromMarkdown(A){let Q=this.parseFrontMatter(A,hm),B=U2(Q.target.replace(/:/g,"-"));return{content:A,entityType:"prompt",metadata:{title:Q.title,target:Q.target,slug:B}}}}var c2A=new P_A;var V61={name:"@brains/prompt",private:!0,version:"0.2.0-alpha.70",description:"Prompt entity type \u2014 AI prompts as editable markdown entities",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","bun-types":"latest",typescript:"^5.3.3"}};class k_A extends KQ{entityType=c2A.entityType;schema=ym;adapter=c2A;constructor(){super("prompt",V61,{},void 0)}getEntityTypeConfig(){return{embeddable:!1}}}function cC(){return new k_A}f0();GA();class p2A{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(b0Q),total:$.total,totalPages:$.total_pages,page:Q.page}}async triggerDownload(A){try{await this.fetchFn(A,{headers:{Authorization:`Client-ID ${this.apiKey}`}})}catch{}}}function b0Q(A){return{id:A.id,description:A.description,altDescription:A.alt_description,thumbnailUrl:A.urls.thumb,imageUrl:A.urls.regular,photographerName:A.user.name,photographerUrl:A.user.links.html,sourceUrl:A.links.html,downloadLocation:A.links.download_location,width:A.width,height:A.height}}GA();Bf();var b61={query:F.string().describe("Search terms for stock photos"),perPage:F.number().min(1).max(30).default(10).describe("Results per page (1-30)"),page:F.number().min(1).default(1).describe("Page number")},O61={photoId:F.string().describe("Photo ID from search results"),downloadLocation:F.string().url().describe("Download tracking URL (required by provider ToS)"),photographerName:F.string().describe("Photographer name for attribution"),photographerUrl:F.string().url().describe("Photographer profile URL for attribution"),sourceUrl:F.string().url().describe("Photo page URL on provider"),imageUrl:F.string().url().describe("Image URL to download"),title:F.string().optional().describe("Image entity title"),alt:F.string().optional().describe("Alt text for the image"),targetEntityType:F.string().optional().describe("Entity type to set cover image on"),targetEntityId:F.string().optional().describe("Entity ID to set cover image on")};function _61(A,Q){return[O0Q(A,Q),R0Q(A,Q)]}function O0Q(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:b61,handler:async(B)=>{let w=F.object(b61).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 R0Q(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:O61,handler:async(B)=>{let w=F.object(O61).safeParse(B);if(!w.success)return{success:!1,error:`Invalid input: ${w.error.message}`};let{photoId:$,downloadLocation:f,photographerName:I,photographerUrl:D,sourceUrl:H,imageUrl:Y,title:W,alt:G,targetEntityType:K,targetEntityId:Z}=w.data,q={photographerName:I,photographerUrl:D,sourceUrl:H},L=await Q.entityService.listEntities({entityType:"image",options:{limit:1,filter:{metadata:{sourceUrl:Y}}}});if(L[0]){let S={imageEntityId:L[0].id,alreadyExisted:!0,attribution:q};if(K&&Z)await R61(Q.entityService,K,Z,L[0].id),S.coverSet=!0;return{success:!0,data:S}}Q.provider.triggerDownload(f).catch(()=>{});let C;try{C=await Q.fetchImage(Y)}catch(S){return{success:!1,error:S instanceof Error?S.message:"Image download failed"}}let R=W??`Stock photo ${$}`,k=pF.createImageEntity({dataUrl:C,title:R,alt:G??R}),_={id:$,...k,metadata:{...k.metadata,sourceUrl:Y}},{entityId:o}=await Q.entityService.createEntity({entity:_}),r={imageEntityId:o,alreadyExisted:!1,attribution:q};if(K&&Z)await R61(Q.entityService,K,Z,o),r.coverSet=!0;return{success:!0,data:r}}}}async function R61(A,Q,B,w){let $=await A.getEntity({entityType:Q,id:B});if(!$)return;await A.updateEntity({entity:{...$,metadata:{...$.metadata,coverImageId:w}}})}Bf();var P61={name:"@brains/stock-photo",private:!0,version:"0.2.0-alpha.70",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 P0Q=F.object({provider:F.enum(["unsplash"]).default("unsplash"),apiKey:F.string().optional().describe("Stock photo provider API key")});class j_A extends Ww{deps;cachedTools=null;constructor(A={},Q={}){super("stock-photo",P61,A,P0Q);this.deps=Q}async getTools(){if(!this.config.apiKey)return[];if(this.cachedTools)return this.cachedTools;let A=this.getContext(),Q=new p2A(this.config.apiKey,this.deps.fetch??globalThis.fetch);return this.cachedTools=_61(this.id,{provider:Q,entityService:A.entityService,fetchImage:this.deps.fetchImage??WH}),this.cachedTools}}function v_A(A={},Q={}){return new j_A(A,Q)}f0();GA();f0();f0();GA();var k61=F.enum(["ai","foundation","work"]),j61=F.object({suffix:k61,title:F.string(),body:F.string(),linkLabel:F.string(),linkHref:F.string()}),gm=F.object({eyebrow:F.string(),headline:F.string(),cards:F.array(j61).min(1)}),l2A=F.object({title:F.string(),slug:F.string(),status:F.enum(["draft","published"])}),Tm=B2.extend({entityType:F.literal("ecosystem-section"),metadata:l2A});class v61 extends W2{constructor(){super({entityType:"ecosystem-section",schema:Tm,frontmatterSchema:l2A})}fromMarkdown(A){return{content:A,entityType:"ecosystem-section",metadata:this.parseFrontmatter(A)}}}var x_A=new v61;GA();function k0Q(A){return A.replace(/^---\n[\s\S]*?\n---\n?/,"")}function h_A(A,Q){return new RegExp(`(?:^|\\n)## ${Q}\\s*\\n([\\s\\S]*?)(?=\\n## |$)`).exec(A)?.[1]?.trim()??""}function Sm(A,Q){return new RegExp(`(?:^|\\n)#### ${Q}\\s*\\n([\\s\\S]*?)(?=\\n#### |\\n### |$)`).exec(A)?.[1]?.trim()??""}function i2A(A){let Q=k0Q(A),w=h_A(Q,"Cards").split(/^### Card \d+\s*$/m).map(($)=>$.trim()).filter(Boolean);return gm.parse({eyebrow:h_A(Q,"Eyebrow"),headline:h_A(Q,"Headline"),cards:w.map(($)=>({suffix:Sm($,"Suffix"),title:Sm($,"Title"),body:Sm($,"Body"),linkLabel:Sm($,"Link Label"),linkHref:Sm($,"Link Href")}))})}function x61(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(`
|
|
4997
|
+
`}GA();var U0Q=new Set(["entityType"]),J0Q={base:"Notes"},G0Q=new Set(["base"]);function F0Q(A){let Q=["file.name"];for(let B of A)if(!U0Q.has(B.name))Q.push(B.name);return Q}function K0Q(A){return A.some((Q)=>Q.name==="status"&&Q.type==="enum")}function G61(A,Q){let B=J0Q[A]??bp(A),w=K0Q(Q),$=F0Q(Q),f=[{type:"table",name:`All ${B}`,order:$}];if(w)f.push({type:"table",name:"By Status",groupBy:{property:"status",direction:"ASC"},order:$});let D={filters:{and:[G0Q.has(A)?'file.folder == "/"':`file.inFolder("${A}")`]},views:f};return{filename:`${B}.base`,content:TY(D),hasStatus:w}}function F61(A){if(A.length===0)return null;let Q=A.map((w)=>`file.inFolder("${w}")`),B={filters:{and:[Q.length===1?Q[0]:{or:Q}]},views:[{type:"table",name:"Settings",order:["file.name","file.folder"]}]};return TY(B)}function K61(A){if(A.length===0)return null;let Q=A.map((w)=>`file.inFolder("${w.entityType}")`),B={filters:{and:[Q.length===1?Q[0]:{or:Q},'status != "published"']},views:[{type:"table",name:"Pipeline",groupBy:{property:"status",direction:"ASC"},order:["file.name","file.folder","status"]}]};return TY(B)}var Z61={name:"@brains/obsidian-vault",private:!0,version:"0.2.0-alpha.71",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 C0Q={mkdir:z0Q,writeFile:q0Q,existsFile:N0Q},L0Q=F.object({entityTypes:F.array(F.string()).optional().describe("Entity types to generate templates for (default: all)")});class M_A extends Ww{deps;constructor(A={},Q={}){super("obsidian-vault",Z61,A,E_A);this.deps={...C0Q,...Q}}async onReady(A){this.logger.info("Auto-syncing Obsidian templates, fileClasses, and bases"),await this.sync(A)}async getTools(){let A=this.getContext();return[xQ(this.id,"sync-templates","Generate Obsidian templates, Metadata Menu fileClass definitions, and Bases views for all registered entity types.",L0Q,async(Q)=>{return this.sync(A,Q.entityTypes)})]}async sync(A,Q){try{let B=A.entityService.getEntityTypes(),w=Q?B.filter((C)=>Q.includes(C)):B,$=XG(A.dataDir,this.config.baseFolder),f=XG($,"templates"),I=XG($,"fileClasses"),D=XG($,"bases");this.deps.mkdir(f,{recursive:!0}),this.deps.mkdir(I,{recursive:!0}),this.deps.mkdir(D,{recursive:!0});let H=[],Y=[],W=[],G=[],K=[],Z=[];for(let C of w){let R=A.entities.getEffectiveFrontmatterSchema(C);if(!R){this.logger.debug(`Skipping ${C}: no frontmatter schema`),Y.push(C);continue}let k=W61(R),_=A.entities.getAdapter(C),o=_?.isSingleton===!0,r=J61(C,k);if(this.deps.writeFile(XG(I,`${C}.md`),r),W.push(C),o){K.push(C),this.logger.debug(`Generated fileClass (singleton): ${C}`);continue}let S=_?.getBodyTemplate()??"",x=U61(C,k,S);this.deps.writeFile(XG(f,`${C}.md`),x),H.push(C);let y=G61(C,k),g=XG(D,y.filename);if(!this.deps.existsFile(g))this.deps.writeFile(g,y.content),G.push(C),this.logger.debug(`Generated base: ${y.filename}`);if(y.hasStatus)Z.push({entityType:C,fields:k});this.logger.debug(`Generated template + fileClass: ${C}`)}let q=F61(K);if(q){let C=XG(D,"Settings.base");if(!this.deps.existsFile(C))this.deps.writeFile(C,q),G.push("Settings"),this.logger.debug("Generated Settings.base")}let L=K61(Z);if(L){let C=XG(D,"Pipeline.base");if(!this.deps.existsFile(C))this.deps.writeFile(C,L),G.push("Pipeline"),this.logger.debug("Generated Pipeline.base")}return this.logger.info(`Synced ${H.length} templates, ${W.length} fileClasses, ${G.length} bases (${Y.length} skipped)`),P8({generated:H,skipped:Y,fileClasses:W,bases:G})}catch(B){return this.logger.error("Failed to sync",{error:B}),E$(B instanceof Error?B.message:"Unknown error")}}}function V_A(A,Q){return new M_A(A,Q)}f0();GA();f0();var b_A=F.enum(["new","planned","in-progress","done","declined"]),O_A=F.enum(["low","medium","high","critical"]),jm=F.object({title:F.string(),status:b_A,priority:O_A.default("medium"),requested:F.number().int().default(1),declinedReason:F.string().optional()}),N61=F.object({title:F.string(),status:b_A,priority:O_A,requested:F.number().int(),slug:F.string()}),vm=B2.extend({entityType:F.literal("wish"),metadata:N61}),R_A=F.object({});f0();GA();class xm extends W2{constructor(){super({entityType:"wish",schema:vm,frontmatterSchema:jm})}createWishContent(A,Q){return this.buildMarkdown(Q,A)}parseWishContent(A){let Q=this.parseFrontMatter(A,jm);return{frontmatter:jm.parse(Q),description:this.extractBody(A).trim()}}fromMarkdown(A){let{frontmatter:Q}=this.parseWishContent(A),B=U2(Q.title);return{content:A,entityType:"wish",metadata:{title:Q.title,status:Q.status,priority:Q.priority,requested:Q.requested,slug:B}}}}var __A=new xm;GA();GA();async function z61(A,Q){let B=`${Q.title}: ${Q.description}`,$=(await A.search({query:B,options:{types:["wish"],limit:1}}))[0];if($&&$.score>=A.similarityThreshold)return $.entity;let f=U2(Q.title);return A.getEntity({entityType:"wish",id:f})}class m2A{logger;context;adapter=new xm;constructor(A,Q){this.logger=A;this.context=Q}async process(A,Q,B){let w=A.title??A.prompt??"Untitled wish",$=A.content??A.prompt??"",f=await z61({search:(Y)=>this.context.entityService.search(Y),getEntity:(Y)=>this.context.entityService.getEntity(Y),similarityThreshold:0.85},{title:w,description:$});if(f){let{frontmatter:Y,description:W}=this.adapter.parseWishContent(f.content),G=Y.requested+1,K=this.adapter.createWishContent({...Y,requested:G},W);return await this.context.entityService.updateEntity({entity:{...f,content:K,metadata:{...f.metadata,requested:G}}}),this.logger.info("Incremented wish request count",{id:f.id,requested:G}),{success:!0,entityId:f.id,existed:!0,requested:G}}let I=U2(w),D=A.options?.priority??"medium",H=this.adapter.createWishContent({title:w,status:"new",priority:D,requested:1},$);return await this.context.entityService.createEntity({entity:{id:I,entityType:"wish",content:H,metadata:{title:w,status:"new",priority:D,requested:1,slug:I}}}),this.logger.info("Created new wish",{id:I,title:w}),{success:!0,entityId:I,existed:!1,requested:1}}}var q61={critical:0,high:1,medium:2,low:3};function C61(A){A.sort((Q,B)=>{let w=B.metadata.requested-Q.metadata.requested;if(w!==0)return w;return q61[Q.metadata.priority]-q61[B.metadata.priority]})}var L61={name:"@brains/wishlist",private:!0,version:"0.2.0-alpha.71",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 E61 extends KQ{entityType=__A.entityType;schema=vm;adapter=__A;constructor(A={}){super("wishlist",L61,A,R_A)}async interceptCreate(A,Q,B){let w=await new m2A(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 C61(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 m2A(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 M0Q(A={}){return new E61(A)}var u2A=M0Q;f0();GA();f0();var hm=F.object({title:F.string(),target:F.string()}),M61=F.object({title:F.string(),target:F.string(),slug:F.string().optional()}),ym=B2.extend({entityType:F.literal("prompt"),metadata:M61});f0();GA();class P_A extends W2{constructor(){super({entityType:"prompt",schema:ym,frontmatterSchema:hm})}toMarkdown(A){let Q=this.extractBody(A.content),B=this.parseFrontMatter(A.content,hm);return this.buildMarkdown(Q,B)}fromMarkdown(A){let Q=this.parseFrontMatter(A,hm),B=U2(Q.target.replace(/:/g,"-"));return{content:A,entityType:"prompt",metadata:{title:Q.title,target:Q.target,slug:B}}}}var c2A=new P_A;var V61={name:"@brains/prompt",private:!0,version:"0.2.0-alpha.71",description:"Prompt entity type \u2014 AI prompts as editable markdown entities",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","bun-types":"latest",typescript:"^5.3.3"}};class k_A extends KQ{entityType=c2A.entityType;schema=ym;adapter=c2A;constructor(){super("prompt",V61,{},void 0)}getEntityTypeConfig(){return{embeddable:!1}}}function cC(){return new k_A}f0();GA();class p2A{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(b0Q),total:$.total,totalPages:$.total_pages,page:Q.page}}async triggerDownload(A){try{await this.fetchFn(A,{headers:{Authorization:`Client-ID ${this.apiKey}`}})}catch{}}}function b0Q(A){return{id:A.id,description:A.description,altDescription:A.alt_description,thumbnailUrl:A.urls.thumb,imageUrl:A.urls.regular,photographerName:A.user.name,photographerUrl:A.user.links.html,sourceUrl:A.links.html,downloadLocation:A.links.download_location,width:A.width,height:A.height}}GA();Bf();var b61={query:F.string().describe("Search terms for stock photos"),perPage:F.number().min(1).max(30).default(10).describe("Results per page (1-30)"),page:F.number().min(1).default(1).describe("Page number")},O61={photoId:F.string().describe("Photo ID from search results"),downloadLocation:F.string().url().describe("Download tracking URL (required by provider ToS)"),photographerName:F.string().describe("Photographer name for attribution"),photographerUrl:F.string().url().describe("Photographer profile URL for attribution"),sourceUrl:F.string().url().describe("Photo page URL on provider"),imageUrl:F.string().url().describe("Image URL to download"),title:F.string().optional().describe("Image entity title"),alt:F.string().optional().describe("Alt text for the image"),targetEntityType:F.string().optional().describe("Entity type to set cover image on"),targetEntityId:F.string().optional().describe("Entity ID to set cover image on")};function _61(A,Q){return[O0Q(A,Q),R0Q(A,Q)]}function O0Q(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:b61,handler:async(B)=>{let w=F.object(b61).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 R0Q(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:O61,handler:async(B)=>{let w=F.object(O61).safeParse(B);if(!w.success)return{success:!1,error:`Invalid input: ${w.error.message}`};let{photoId:$,downloadLocation:f,photographerName:I,photographerUrl:D,sourceUrl:H,imageUrl:Y,title:W,alt:G,targetEntityType:K,targetEntityId:Z}=w.data,q={photographerName:I,photographerUrl:D,sourceUrl:H},L=await Q.entityService.listEntities({entityType:"image",options:{limit:1,filter:{metadata:{sourceUrl:Y}}}});if(L[0]){let S={imageEntityId:L[0].id,alreadyExisted:!0,attribution:q};if(K&&Z)await R61(Q.entityService,K,Z,L[0].id),S.coverSet=!0;return{success:!0,data:S}}Q.provider.triggerDownload(f).catch(()=>{});let C;try{C=await Q.fetchImage(Y)}catch(S){return{success:!1,error:S instanceof Error?S.message:"Image download failed"}}let R=W??`Stock photo ${$}`,k=pF.createImageEntity({dataUrl:C,title:R,alt:G??R}),_={id:$,...k,metadata:{...k.metadata,sourceUrl:Y}},{entityId:o}=await Q.entityService.createEntity({entity:_}),r={imageEntityId:o,alreadyExisted:!1,attribution:q};if(K&&Z)await R61(Q.entityService,K,Z,o),r.coverSet=!0;return{success:!0,data:r}}}}async function R61(A,Q,B,w){let $=await A.getEntity({entityType:Q,id:B});if(!$)return;await A.updateEntity({entity:{...$,metadata:{...$.metadata,coverImageId:w}}})}Bf();var P61={name:"@brains/stock-photo",private:!0,version:"0.2.0-alpha.71",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 P0Q=F.object({provider:F.enum(["unsplash"]).default("unsplash"),apiKey:F.string().optional().describe("Stock photo provider API key")});class j_A extends Ww{deps;cachedTools=null;constructor(A={},Q={}){super("stock-photo",P61,A,P0Q);this.deps=Q}async getTools(){if(!this.config.apiKey)return[];if(this.cachedTools)return this.cachedTools;let A=this.getContext(),Q=new p2A(this.config.apiKey,this.deps.fetch??globalThis.fetch);return this.cachedTools=_61(this.id,{provider:Q,entityService:A.entityService,fetchImage:this.deps.fetchImage??WH}),this.cachedTools}}function v_A(A={},Q={}){return new j_A(A,Q)}f0();GA();f0();f0();GA();var k61=F.enum(["ai","foundation","work"]),j61=F.object({suffix:k61,title:F.string(),body:F.string(),linkLabel:F.string(),linkHref:F.string()}),gm=F.object({eyebrow:F.string(),headline:F.string(),cards:F.array(j61).min(1)}),l2A=F.object({title:F.string(),slug:F.string(),status:F.enum(["draft","published"])}),Tm=B2.extend({entityType:F.literal("ecosystem-section"),metadata:l2A});class v61 extends W2{constructor(){super({entityType:"ecosystem-section",schema:Tm,frontmatterSchema:l2A})}fromMarkdown(A){return{content:A,entityType:"ecosystem-section",metadata:this.parseFrontmatter(A)}}}var x_A=new v61;GA();function k0Q(A){return A.replace(/^---\n[\s\S]*?\n---\n?/,"")}function h_A(A,Q){return new RegExp(`(?:^|\\n)## ${Q}\\s*\\n([\\s\\S]*?)(?=\\n## |$)`).exec(A)?.[1]?.trim()??""}function Sm(A,Q){return new RegExp(`(?:^|\\n)#### ${Q}\\s*\\n([\\s\\S]*?)(?=\\n#### |\\n### |$)`).exec(A)?.[1]?.trim()??""}function i2A(A){let Q=k0Q(A),w=h_A(Q,"Cards").split(/^### Card \d+\s*$/m).map(($)=>$.trim()).filter(Boolean);return gm.parse({eyebrow:h_A(Q,"Eyebrow"),headline:h_A(Q,"Headline"),cards:w.map(($)=>({suffix:Sm($,"Suffix"),title:Sm($,"Title"),body:Sm($,"Body"),linkLabel:Sm($,"Link Label"),linkHref:Sm($,"Link Href")}))})}function x61(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(`
|
|
4998
4998
|
`)}var j0Q=F.object({query:F.object({id:F.string().optional()}).optional()}).passthrough();class r2A{id="rizom-ecosystem:entities";name="Rizom Ecosystem";description="Fetches an ecosystem-section entity for rendering";async fetch(A,Q,B){let $=j0Q.parse(A??{}).query?.id??"rizom-ecosystem",f=await B.entityService.getEntity({entityType:"ecosystem-section",id:$});if(!f)throw Error(`Ecosystem section not found: ${$}`);return Q.parse(i2A(f.content))}}f0();var v0Q=xAA({extend:{classGroups:{"font-size":[{text:["display-2xl","display-xl","display-lg","display-md","display-sm","heading-lg","heading-md","heading-sm","body-xl","body-lg","body-md","body-sm","body-xs","label-md","label-sm","label-xs"]}]}}});function NW(...A){return v0Q(JR(A))}import{jsxDEV as vUw}from"preact/jsx-dev-runtime";import{jsxDEV as gUw}from"preact/jsx-dev-runtime";import{jsxDEV as uUw}from"preact/jsx-dev-runtime";import{jsxDEV as h0Q}from"preact/jsx-dev-runtime";var y_A="px-6 md:px-10 xl:px-20",x0Q=`${y_A} relative z-[1]`,g_A=({id:A,className:Q,children:B})=>h0Q("section",{id:A,className:NW(x0Q,Q),children:B},void 0,!1,void 0,this);import{jsxDEV as d2A}from"preact/jsx-dev-runtime";var y0Q={work:"text-accent",foundation:"text-secondary",ai:"text-accent-bright"},mm=({name:A="rizom",brandSuffix:Q,className:B,dotClassName:w,suffixClassName:$})=>{let f=y0Q[Q];return d2A("span",{className:NW("inline-flex items-baseline gap-0 font-display font-medium tracking-[-0.015em] [font-variation-settings:'opsz'_24]",B),children:[d2A("span",{className:"text-theme",children:A},void 0,!1,void 0,this),d2A("span",{className:NW(f??"text-accent",w),children:"."},void 0,!1,void 0,this),d2A("span",{className:NW("italic font-normal text-theme-muted",$),children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as eUw}from"preact/jsx-dev-runtime";import{jsxDEV as wJw}from"preact/jsx-dev-runtime";import{jsxDEV as DJw,Fragment as IJw}from"preact/jsx-dev-runtime";import{jsxDEV as XJw}from"preact/jsx-dev-runtime";import{Fragment as T_A}from"preact";import{jsxDEV as um}from"preact/jsx-dev-runtime";var g0Q=/(\*[^*]+\*)/;function S_A(A,Q){let B=A.split(`
|
|
4999
|
-
`);return um(T_A,{children:B.map((w,$)=>um(T_A,{children:[$>0&&um("br",{},void 0,!1,void 0,this),w.split(g0Q).map((f,I)=>{if(f.length>=3&&f.startsWith("*")&&f.endsWith("*"))return um("span",{className:Q,children:f.slice(1,-1)},I,!1,void 0,this);return um(T_A,{children:f},I,!1,void 0,this)})]},$,!0,void 0,this))},void 0,!1,void 0,this)}import{jsxDEV as Of,Fragment as n0Q}from"preact/jsx-dev-runtime";var T0Q="italic text-accent font-normal",S0Q="You are here",m0Q={work:"text-accent",foundation:"text-secondary",ai:"text-accent-bright"},u0Q={work:"border-t-accent/60",foundation:"border-t-secondary/60",ai:"border-t-accent-bright/60"},c0Q={work:"hover:border-t-accent",foundation:"hover:border-t-secondary",ai:"hover:border-t-accent-bright"},p0Q="font-label text-[10.5px] uppercase tracking-[0.26em] mt-1",l0Q="font-body text-[15px] leading-[1.6] text-theme-muted mt-2",i0Q="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",r0Q="font-label text-[10.5px] uppercase tracking-[0.22em] text-accent self-start mt-[18px] pb-1",d0Q=({card:A})=>{let Q=A.linkLabel===S0Q,B=A.linkHref.trim().length===0,w=Of(n0Q,{children:[Of(mm,{brandSuffix:A.suffix,className:"text-[clamp(28px,3vw,40px)] [font-variation-settings:'opsz'_96]"},void 0,!1,void 0,this),Of("span",{className:`${p0Q} ${m0Q[A.suffix]}`,children:A.title},void 0,!1,void 0,this),Of("p",{className:l0Q,children:A.body},void 0,!1,void 0,this),Q?Of("span",{className:r0Q,children:A.linkLabel},void 0,!1,void 0,this):Of("span",{className:i0Q,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?u0Q[A.suffix]:"border-white/10"}`;return Q||B?Of("div",{className:$,children:w},void 0,!1,void 0,this):Of("a",{href:A.linkHref,className:`${$} text-inherit no-underline transition-colors ${c0Q[A.suffix]}`,children:w},void 0,!1,void 0,this)},m_A=({eyebrow:A,headline:Q,cards:B})=>Of(g_A,{id:"ecosystem",className:"pt-[112px] pb-[144px] border-t border-white/5",children:[Of("div",{className:"mx-auto mb-[88px] max-w-[1180px] text-center",children:[Of("span",{className:"font-label text-[11px] font-semibold uppercase tracking-[0.24em] text-accent",children:A},void 0,!1,void 0,this),Of("h2",{className:"mt-5 font-display text-[clamp(34px,4.4vw,60px)] font-[380] leading-[1.04] tracking-[-0.02em] text-heading [font-variation-settings:'opsz'_96]",children:S_A(Q,T0Q)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Of("div",{className:"mx-auto grid max-w-[1180px] grid-cols-3 gap-16 max-[768px]:grid-cols-1 max-[768px]:gap-7",children:B.map((w)=>Of(d0Q,{card:w},w.suffix,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this);var o0Q=[{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 h61(A){return{eyebrow:"The Ecosystem",headline:"One practice. *Three faces.*",cards:o0Q.map((Q)=>Q.suffix===A?{...Q,linkLabel:"You are here",linkHref:""}:Q)}}var s0Q=h61();var u_A=O1({name:"ecosystem",description:"Rizom ecosystem sibling-site section",schema:gm,formatter:{parse:i2A,format:x61},dataSourceId:"rizom-ecosystem:entities",requiredPermission:"public",layout:{component:m_A}});var y61={name:"@brains/rizom-ecosystem",private:!0,version:"0.2.0-alpha.
|
|
4999
|
+
`);return um(T_A,{children:B.map((w,$)=>um(T_A,{children:[$>0&&um("br",{},void 0,!1,void 0,this),w.split(g0Q).map((f,I)=>{if(f.length>=3&&f.startsWith("*")&&f.endsWith("*"))return um("span",{className:Q,children:f.slice(1,-1)},I,!1,void 0,this);return um(T_A,{children:f},I,!1,void 0,this)})]},$,!0,void 0,this))},void 0,!1,void 0,this)}import{jsxDEV as Of,Fragment as n0Q}from"preact/jsx-dev-runtime";var T0Q="italic text-accent font-normal",S0Q="You are here",m0Q={work:"text-accent",foundation:"text-secondary",ai:"text-accent-bright"},u0Q={work:"border-t-accent/60",foundation:"border-t-secondary/60",ai:"border-t-accent-bright/60"},c0Q={work:"hover:border-t-accent",foundation:"hover:border-t-secondary",ai:"hover:border-t-accent-bright"},p0Q="font-label text-[10.5px] uppercase tracking-[0.26em] mt-1",l0Q="font-body text-[15px] leading-[1.6] text-theme-muted mt-2",i0Q="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",r0Q="font-label text-[10.5px] uppercase tracking-[0.22em] text-accent self-start mt-[18px] pb-1",d0Q=({card:A})=>{let Q=A.linkLabel===S0Q,B=A.linkHref.trim().length===0,w=Of(n0Q,{children:[Of(mm,{brandSuffix:A.suffix,className:"text-[clamp(28px,3vw,40px)] [font-variation-settings:'opsz'_96]"},void 0,!1,void 0,this),Of("span",{className:`${p0Q} ${m0Q[A.suffix]}`,children:A.title},void 0,!1,void 0,this),Of("p",{className:l0Q,children:A.body},void 0,!1,void 0,this),Q?Of("span",{className:r0Q,children:A.linkLabel},void 0,!1,void 0,this):Of("span",{className:i0Q,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?u0Q[A.suffix]:"border-white/10"}`;return Q||B?Of("div",{className:$,children:w},void 0,!1,void 0,this):Of("a",{href:A.linkHref,className:`${$} text-inherit no-underline transition-colors ${c0Q[A.suffix]}`,children:w},void 0,!1,void 0,this)},m_A=({eyebrow:A,headline:Q,cards:B})=>Of(g_A,{id:"ecosystem",className:"pt-[112px] pb-[144px] border-t border-white/5",children:[Of("div",{className:"mx-auto mb-[88px] max-w-[1180px] text-center",children:[Of("span",{className:"font-label text-[11px] font-semibold uppercase tracking-[0.24em] text-accent",children:A},void 0,!1,void 0,this),Of("h2",{className:"mt-5 font-display text-[clamp(34px,4.4vw,60px)] font-[380] leading-[1.04] tracking-[-0.02em] text-heading [font-variation-settings:'opsz'_96]",children:S_A(Q,T0Q)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Of("div",{className:"mx-auto grid max-w-[1180px] grid-cols-3 gap-16 max-[768px]:grid-cols-1 max-[768px]:gap-7",children:B.map((w)=>Of(d0Q,{card:w},w.suffix,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this);var o0Q=[{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 h61(A){return{eyebrow:"The Ecosystem",headline:"One practice. *Three faces.*",cards:o0Q.map((Q)=>Q.suffix===A?{...Q,linkLabel:"You are here",linkHref:""}:Q)}}var s0Q=h61();var u_A=O1({name:"ecosystem",description:"Rizom ecosystem sibling-site section",schema:gm,formatter:{parse:i2A,format:x61},dataSourceId:"rizom-ecosystem:entities",requiredPermission:"public",layout:{component:m_A}});var y61={name:"@brains/rizom-ecosystem",private:!0,version:"0.2.0-alpha.71",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 c_A extends KQ{entityType="ecosystem-section";schema=Tm;adapter=x_A;constructor(A={}){super("rizom-ecosystem",y61,A,F.object({}).default({}))}getTemplates(){return{ecosystem:u_A}}getDataSources(){return[new r2A]}}function pC(A={}){return new c_A(A)}GA();f0();f0();GA();d5();GA();f0();var c$="agent",g61="agent-discovery",T61="agent:generation",S61="agent-network",m61="AgentNetworkWidget",cm="agent-discovery:entities",p_A="agent-list",l_A="agent-detail",w6="skill",u61="skill",n2A="skill-derivation",c61="skill:project",p61="skill-derivation",l61="skill:skill-derivation",i61="skills";var F_=F.object({name:F.string(),description:F.string(),tags:F.array(F.string())}),X4=F.enum(["discovered","approved"]).describe("Discovered for review or approved for calling"),DY=AH.pick({name:!0,kind:!0,organization:!0}).extend({brainName:F.string().describe("Name of the brain instance"),url:F.string().url().describe("Brain endpoint URL"),did:F.string().optional().describe("Decentralized identifier (public)"),status:X4,discoveredAt:F.string().datetime().describe("When this agent was first discovered")}),r61=DY.pick({name:!0,url:!0,status:!0}).extend({discoveredAt:F.string().datetime().optional(),slug:F.string()}),K_=B2.extend({entityType:F.literal(c$),metadata:r61}),pm=K_.extend({frontmatter:DY,about:F.string(),skills:F.array(F_),notes:F.string()}),Z_=pm.extend({url:F.string().optional(),typeLabel:F.string().optional()}),t0Q=pm.extend({url:F.string(),typeLabel:F.string()});GA();var e0Q=F.array(F_);function d61(A){let Q=e0Q.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(`
|
|
5000
5000
|
`)}function n61(A){if(!A.trim())return[];let Q=[];for(let B of A.split(`
|
|
5001
5001
|
`)){let w=B.match(/^- (.+?): (.+?)(?:\s+\[(.+?)\])?$/);if(!w)continue;let $=w[1]??"",f=w[2]??"",I=w[3],D=I?I.split(",").map((H)=>H.trim()).filter(Boolean):[];Q.push({name:$,description:f,tags:D})}return Q}var A1Q=F.object({about:F.string(),skills:F.array(F_),notes:F.string()}),o61=new RB(A1Q,{title:"Agent",mappings:[{key:"about",label:"About",type:"string"},{key:"skills",label:"Skills",type:"custom",formatter:d61,parser:n61},{key:"notes",label:"Notes",type:"string"}]});class W4 extends W2{constructor(){super({entityType:c$,schema:K_,frontmatterSchema:DY})}fromMarkdown(A){let Q=this.parseFrontMatter(A,DY),B=FE(Q.url);return{content:A,entityType:c$,metadata:{name:Q.name,url:Q.url,status:Q.status,discoveredAt:Q.discoveredAt,slug:B}}}createAgentContent(A){let Q={name:A.name,kind:A.kind,...A.organization&&{organization:A.organization},brainName:A.brainName,url:A.url,...A.did&&{did:A.did},status:X4.parse(A.status),discoveredAt:A.discoveredAt},B=o61.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=o61.parse(Q);return{about:B.about,skills:B.skills,notes:B.notes}}catch{return{about:"",skills:[],notes:""}}}parseEntity(A){return{frontmatter:this.parseFrontMatter(A.content,DY),body:this.parseAgentContent(A.content)}}}f0();var Q1Q=new W4,B1Q=tY.extend({status:X4.optional()}),w1Q=eY.extend({query:B1Q.optional()});function $1Q(A){let Q=t2(A.content,DY),B=Q1Q.parseAgentContent(A.content);return pm.parse({...A,frontmatter:Q.metadata,about:B.about,skills:B.skills,notes:B.notes})}class o2A extends r6{id=cm;name="Agent Directory DataSource";description="Fetches and transforms agent entities for rendering";config={entityType:c$,defaultSort:[{field:"discoveredAt",direction:"desc"}],defaultLimit:50,lookupField:"slug",enableNavigation:!0};constructor(A){super(A)}transformEntity(A){return $1Q(A)}buildDetailResult(A,Q){return{agent:A,prevAgent:Q?.prev??null,nextAgent:Q?.next??null}}parseQuery(A){let Q=w1Q.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}buildListResult(A,Q,B){let w=X4.safeParse(B.status);return{agents:A,pagination:Q,baseUrl:B.baseUrl,selectedStatus:w.success?w.data:"all"}}async fetch(A,Q,B){let{query:w}=this.parseQuery(A);if(w.id)return super.fetch(A,Q,B);let{items:$,pagination:f}=await this.fetchList(w,B.entityService,w.status?{filter:{metadata:{status:w.status}}}:void 0);return Q.parse(this.buildListResult($,f,w))}}f0();GA();L$();f0();async function s61(A,Q){let w=`${(A.startsWith("http")?A:`https://${A}`).replace(/\/$/,"")}/.well-known/agent-card.json`;try{let $=await Q(w);if(!$.ok)return null;let f=await $.json();return Xj(f)}catch{return null}}function s2A(A){let Q=A.trim();if(Q.startsWith("http://")||Q.startsWith("https://"))try{return new URL(Q).hostname}catch{return Q}let B=Q.match(/https?:\/\/[^\s]+?(?=[.,;:!?)]*(?:\s|$))/);if(B)try{return new URL(B[0]).hostname}catch{return B[0]}if(/^[^\s]+\.[^\s]+$/.test(Q))return Q;return""}GA();var f1Q=new W4;function a61(A){return A.trim().toLowerCase().replace(/[_\s]+/g,"-")}function oZ(A){let Q=new Set,B=[];for(let w of A){let $=a61(w);if(!$||Q.has($))continue;Q.add($),B.push($)}return B}function I1Q(A,Q){if(Q.count!==A.count)return Q.count-A.count;return A.tag.localeCompare(Q.tag)}async function t61(A,Q={}){let B=Q.minCount??1,w=Q.topN??12,$=new Map,[f,I]=await Promise.all([A.entityService.listEntities({entityType:w6}),A.entityService.listEntities({entityType:c$})]),D=(H)=>{for(let Y of oZ(H))$.set(Y,($.get(Y)??0)+1)};for(let H of f)D(H.metadata.tags);for(let H of I){let Y=f1Q.parseAgentContent(H.content);D(Y.skills.flatMap((W)=>W.tags))}return Array.from($.entries()).map(([H,Y])=>({tag:H,count:Y})).filter((H)=>H.count>=B).sort(I1Q).slice(0,w)}function e61(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(`
|
|
5002
5002
|
`)}var D1Q=new W4;function A51(A,Q={}){let B=A.anchor?.name??A.brainName,w=A.anchor?.kind??"professional",$=[];if(A.anchor?.description)$.push(A.anchor.description);if(A.description)$.push(A.description);let f=Q.status??"discovered",I=new Date().toISOString();return{content:D1Q.createAgentContent({name:B,kind:w,...A.anchor?.organization&&{organization:A.anchor.organization},brainName:A.brainName,url:A.url,status:f,discoveredAt:I,about:$.join(`
|
|
@@ -5096,7 +5096,7 @@ ${TY(B)}---
|
|
|
5096
5096
|
setView("agents");
|
|
5097
5097
|
setTagFilter("all");
|
|
5098
5098
|
});
|
|
5099
|
-
})();`;import{jsxDEV as jQ}from"preact/jsx-dev-runtime";function K1Q({item:A}){return jQ("li",{class:"list-item",children:[jQ("div",{class:"list-main",children:[jQ("span",{class:"list-name",children:A.name},void 0,!1,void 0,this),jQ("span",{class:"list-desc",children:A.description},void 0,!1,void 0,this),A.tags.length>0&&jQ("div",{class:"list-tags",children:A.tags.map((Q)=>jQ("span",{class:"tag",children:Q},`${A.id}:${Q}`,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),jQ("div",{class:"list-meta",children:A.status==="discovered"&&jQ("span",{class:"pill pill--warn",children:"review"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function Z1Q({item:A}){return jQ("li",{class:"list-item agent-network-skill-row","data-agent-network-skill-row":!0,"data-agent-network-tags":JSON.stringify(A.tags),children:[jQ("div",{class:"list-main",children:jQ("span",{class:"list-name",children:A.name},void 0,!1,void 0,this)},void 0,!1,void 0,this),jQ("div",{class:"list-meta",children:jQ("span",{class:`agent-network-source${A.sourceType==="brain"?" is-brain":""}`,children:A.sourceLabel},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function N1Q({kind:A,items:Q,active:B}){return jQ("div",{class:`agent-network-panel${B?" is-active":""}`,"data-agent-network-panel":A,children:Q.length>0?jQ("ul",{class:"list agent-network-list",children:Q.map((w)=>jQ(K1Q,{item:w},w.id,!1,void 0,this))},void 0,!1,void 0,this):jQ("p",{class:"agent-network-empty",children:"Nothing to show yet."},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function z1Q({skills:A,count:Q,filters:B}){return jQ("div",{class:"agent-network-panel","data-agent-network-panel":"skills",children:[jQ("div",{class:"agent-network-filter-row",role:"tablist","aria-label":"Filter skills by tag",children:[jQ("button",{class:"agent-network-filter is-active",type:"button","data-agent-network-tag-filter":"all","aria-pressed":"true",children:[jQ("span",{class:"count",children:Q},void 0,!1,void 0,this),jQ("span",{class:"label",children:"all"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),B.map((w)=>jQ("button",{class:`agent-network-filter${w.variant==="gap"?" is-gap":""}`,type:"button","data-agent-network-tag-filter":w.tag,"aria-pressed":"false",children:[jQ("span",{class:"count",children:w.count},void 0,!1,void 0,this),jQ("span",{class:"label",children:w.tag},void 0,!1,void 0,this)]},w.tag,!0,void 0,this))]},void 0,!0,void 0,this),A.length>0?jQ("ul",{class:"list agent-network-list agent-network-skills-list",children:A.map((w)=>jQ(Z1Q,{item:w},w.id,!1,void 0,this))},void 0,!1,void 0,this):jQ("p",{class:"agent-network-empty",children:"Nothing to show yet."},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function d_A({data:A}){let Q=I51.safeParse(A);if(!Q.success)return jQ("p",{class:"muted",children:"Nothing to show yet."},void 0,!1,void 0,this);let B=Q.data;return jQ("div",{"data-agent-network-widget":!0,"data-agent-network-view":"agents",children:[jQ("div",{class:"agent-network-view-tabs",role:"tablist","aria-label":"Browse the agent network",children:[jQ("button",{class:"agent-network-view-tab is-active",type:"button","data-agent-network-view-tab":"agents","aria-pressed":"true",children:["Agents",jQ("span",{class:"agent-network-view-count",children:B.counts.agents},void 0,!1,void 0,this)]},void 0,!0,void 0,this),jQ("button",{class:"agent-network-view-tab",type:"button","data-agent-network-view-tab":"skills","aria-pressed":"false",children:["Skills",jQ("span",{class:"agent-network-view-count",children:B.counts.skills},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),jQ("div",{class:"agent-network-kind-tabs",role:"tablist","aria-label":"Filter agents by kind",children:r_A.map((w)=>{let $=w==="all";return jQ("button",{class:`agent-network-kind-tab${$?" is-active":""}`,type:"button","data-agent-network-kind-tab":w,"aria-pressed":$?"true":"false",children:[jQ("span",{class:"agent-network-kind-count",children:B.agents[w].length},void 0,!1,void 0,this),jQ("span",{class:"agent-network-kind-label",children:w},void 0,!1,void 0,this)]},w,!0,void 0,this)})},void 0,!1,void 0,this),r_A.map((w)=>jQ(N1Q,{kind:w,items:B.agents[w],active:w==="all"},w,!1,void 0,this)),jQ(z1Q,{skills:B.skills,count:B.counts.skills,filters:B.skillFilters},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function H51(A,Q){A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"dashboard:register-widget",payload:{id:S61,pluginId:Q,title:"Agent Network",section:"secondary",priority:15,rendererName:m61,component:d_A,clientScript:t2A,dataProvider:async()=>D51(A)}}),{success:!0}})}function Y51(){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.'}f0();Rw();GA();import{jsxDEV as X51}from"preact/jsx-dev-runtime";function e2A(A){try{return new URL(A).hostname}catch{return A}}var AQA=({name:A,className:Q=""})=>{let B=A.charAt(0).toUpperCase(),w=0;for(let f=0;f<A.length;f++)w=A.charCodeAt(f)+((w<<5)-w);let $=Math.abs(w)%360;return X51("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)},QQA=({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 X51("span",{className:`inline-flex items-center rounded-full font-medium ${Q==="sm"?"px-2 py-0.5 text-xs":"px-2.5 py-0.5 text-[13px]"} ${w}`,children:A},void 0,!1,void 0,this)};import{jsxDEV as F2,Fragment as L1Q}from"preact/jsx-dev-runtime";var q1Q=({skills:A})=>{if(A.length===0)return null;return F2("div",{className:"flex gap-1.5 flex-wrap mt-2",children:A.map((Q)=>F2("span",{className:"text-[11px] px-2 py-0.5 bg-theme-subtle rounded-md text-theme-muted",children:Q.name},Q.name,!1,void 0,this))},void 0,!1,void 0,this)};function C1Q(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric"})}function W51(A,Q,B){let w=new URLSearchParams({status:Q});if(B>1)w.set("page",String(B));return`${A}?${w.toString()}`}var n_A=({agent:A})=>{let{frontmatter:Q,about:B,skills:w,url:$}=A,f=Q.status==="approved";return F2("a",{href:$,className:`flex items-start gap-5 p-6 rounded-xl border border-theme bg-theme-subtle hover:shadow-lg transition-shadow ${f?"":"opacity-70"}`,children:[F2(AQA,{name:Q.name,className:"w-12 h-12 text-lg"},void 0,!1,void 0,this),F2("div",{className:"flex-1 min-w-0",children:[F2("div",{className:"flex items-center gap-2 mb-1 flex-wrap",children:[F2("span",{className:"text-lg font-semibold text-heading",children:Q.name},void 0,!1,void 0,this),F2(QQA,{kind:Q.kind,size:"sm"},void 0,!1,void 0,this),Q.organization&&F2("span",{className:"text-xs text-theme-muted",children:["\xB7 ",Q.organization]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),F2("div",{className:"text-sm text-theme-muted mb-1",children:Q.brainName},void 0,!1,void 0,this),B&&F2("p",{className:"text-sm text-theme-muted line-clamp-2 mb-0",children:B},void 0,!1,void 0,this),f&&F2(q1Q,{skills:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this),F2("div",{className:"flex flex-col items-end gap-1 flex-shrink-0 text-right",children:[F2("span",{className:"text-xs text-theme-muted",children:e2A(Q.url)},void 0,!1,void 0,this),F2("span",{className:"text-[11px] text-theme-muted opacity-60",children:f?`Discovered ${C1Q(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)},U51=({agents:A,pageTitle:Q,pagination:B,baseUrl:w="/agents",selectedStatus:$})=>{let f=Q??"Agent Directory",I=B?.totalItems??A.length,D=A.filter((K)=>K.frontmatter.status==="approved"),H=A.filter((K)=>K.frontmatter.status==="discovered"),Y=D.length,W=H.length,G=`Your network of ${I} ${I===1?"brain":"brains"} and their anchors`;return F2(L1Q,{children:[F2(XQ,{title:f,description:G},void 0,!1,void 0,this),F2("div",{className:"agent-list bg-theme",children:F2("div",{className:"container mx-auto px-6 md:px-12 max-w-5xl py-16 md:py-24",children:[F2("div",{className:"mb-8 pb-6 border-b border-theme",children:[F2("h1",{className:"text-4xl font-bold text-heading mb-2",children:f},void 0,!1,void 0,this),F2("p",{className:"text-theme-muted mb-4",children:G},void 0,!1,void 0,this),F2("div",{className:"flex flex-wrap gap-2 text-sm mb-4",children:[F2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-heading",children:[I," total"]},void 0,!0,void 0,this),F2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-status-success",children:[Y," approved"]},void 0,!0,void 0,this),F2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-theme-muted",children:[W," discovered"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),F2("div",{className:"flex flex-wrap gap-2 text-sm",children:[F2("a",{href:w,className:`px-3 py-1 rounded-full border transition-colors ${$==="all"?"border-theme text-heading bg-theme-subtle":"border-theme text-theme-muted hover:text-heading"}`,children:"All"},void 0,!1,void 0,this),F2("a",{href:`${w}?status=approved`,className:`px-3 py-1 rounded-full border transition-colors ${$==="approved"?"border-theme text-heading bg-theme-subtle":"border-theme text-theme-muted hover:text-heading"}`,children:"Approved"},void 0,!1,void 0,this),F2("a",{href:`${w}?status=discovered`,className:`px-3 py-1 rounded-full border transition-colors ${$==="discovered"?"border-theme text-heading bg-theme-subtle":"border-theme text-theme-muted hover:text-heading"}`,children:"Discovered"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),$==="all"&&D.length>0&&F2("section",{className:"mb-10",children:[F2("div",{className:"flex items-center justify-between mb-4",children:[F2("h2",{className:"text-lg font-semibold text-heading",children:"Approved brains"},void 0,!1,void 0,this),F2("span",{className:"text-sm text-theme-muted",children:D.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),F2("div",{className:"flex flex-col gap-4",children:D.map((K)=>F2(n_A,{agent:K},K.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$==="all"&&H.length>0&&F2("section",{children:[F2("div",{className:"flex items-center justify-between mb-4",children:[F2("div",{children:[F2("h2",{className:"text-lg font-semibold text-heading",children:"Discovered brains"},void 0,!1,void 0,this),F2("p",{className:"text-sm text-theme-muted",children:"Review and approve these before calling them."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),F2("span",{className:"text-sm text-theme-muted",children:H.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),F2("div",{className:"flex flex-col gap-4",children:H.map((K)=>F2(n_A,{agent:K},K.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$!=="all"&&A.length>0&&F2("section",{children:[F2("div",{className:"flex items-center justify-between mb-4",children:[F2("h2",{className:"text-lg font-semibold text-heading",children:$==="approved"?"Approved brains":"Discovered brains"},void 0,!1,void 0,this),F2("span",{className:"text-sm text-theme-muted",children:A.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),F2("div",{className:"flex flex-col gap-4",children:A.map((K)=>F2(n_A,{agent:K},K.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.length===0&&F2("p",{className:"text-center text-theme-muted py-16",children:"No agents in your directory yet."},void 0,!1,void 0,this),B&&B.totalPages>1&&$==="all"&&F2("div",{className:"mt-12",children:F2(cJ,{currentPage:B.currentPage,totalPages:B.totalPages,baseUrl:w},void 0,!1,void 0,this)},void 0,!1,void 0,this),B&&B.totalPages>1&&$!=="all"&&F2("nav",{"aria-label":"Pagination",className:"flex items-center justify-center gap-3 mt-12",children:[B.hasPrevPage?F2("a",{href:W51(w,$,B.currentPage-1),className:"px-3 py-2 rounded-md border border-theme text-sm text-theme-muted hover:text-heading transition-colors",children:"\u2190 Prev"},void 0,!1,void 0,this):F2("span",{className:"px-3 py-2 rounded-md border border-theme text-sm text-theme-muted opacity-50",children:"\u2190 Prev"},void 0,!1,void 0,this),F2("span",{className:"text-sm text-theme-muted",children:["Page ",B.currentPage," of ",B.totalPages]},void 0,!0,void 0,this),B.hasNextPage?F2("a",{href:W51(w,$,B.currentPage+1),className:"px-3 py-2 rounded-md border border-theme text-sm text-theme-muted hover:text-heading transition-colors",children:"Next \u2192"},void 0,!1,void 0,this):F2("span",{className:"px-3 py-2 rounded-md border border-theme text-sm text-theme-muted opacity-50",children:"Next \u2192"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as f2,Fragment as b1Q}from"preact/jsx-dev-runtime";function E1Q(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"})}var lm=({children:A})=>f2("h2",{className:"text-sm font-semibold text-theme-muted uppercase tracking-wide mb-3",children:A},void 0,!1,void 0,this),M1Q=({skill:A})=>f2("div",{className:"flex items-start gap-3 px-4 py-3 bg-theme-subtle rounded-lg",children:[f2("div",{className:"flex-1",children:[f2("div",{className:"text-sm font-semibold text-heading",children:A.name},void 0,!1,void 0,this),f2("div",{className:"text-[13px] text-theme-muted",children:A.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.tags.length>0&&f2("div",{className:"flex gap-1 flex-shrink-0",children:A.tags.map((Q)=>f2("span",{className:"text-[11px] px-2 py-0.5 bg-theme rounded-md text-theme-muted",children:Q},Q,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),V1Q=({label:A,value:Q,valueClassName:B})=>f2("div",{className:"flex justify-between text-[13px]",children:[f2("span",{className:"text-theme-muted",children:A},void 0,!1,void 0,this),f2("span",{className:B??"text-heading",children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this),J51=({agent:A,prevAgent:Q,nextAgent:B})=>{let{frontmatter:w,about:$,skills:f,notes:I}=A,D=e2A(w.url),H=w.status==="approved";return f2(b1Q,{children:[f2(XQ,{title:w.name,description:$||`Agent profile for ${w.name}`},void 0,!1,void 0,this),f2("article",{className:"agent-detail",children:f2("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:[f2("a",{href:"/agents",className:"text-sm text-theme-muted hover:text-brand transition-colors mb-6 inline-block",children:"\u2190 Back to Directory"},void 0,!1,void 0,this),f2("div",{className:"flex items-start gap-6 mb-8",children:[f2(AQA,{name:w.name,className:"w-[72px] h-[72px] text-3xl"},void 0,!1,void 0,this),f2("div",{children:[f2("div",{className:"flex items-center gap-3 mb-1",children:[f2("h1",{className:"text-3xl md:text-4xl font-bold text-heading",children:w.name},void 0,!1,void 0,this),f2(QQA,{kind:w.kind},void 0,!1,void 0,this)]},void 0,!0,void 0,this),f2("div",{className:"text-base text-theme-muted mb-2",children:w.brainName},void 0,!1,void 0,this),f2("div",{className:"flex items-center gap-3 text-theme-muted",children:[w.organization&&f2("span",{className:"text-[15px]",children:w.organization},void 0,!1,void 0,this),w.organization&&f2("span",{className:"text-theme-muted opacity-40",children:"\xB7"},void 0,!1,void 0,this),f2("span",{className:"text-sm",children:["Discovered ",E1Q(w.discoveredAt)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),f2("div",{className:"border-b border-theme mb-8"},void 0,!1,void 0,this),!H&&f2("div",{className:"mb-8 rounded-xl border border-theme bg-theme-subtle px-5 py-4",children:[f2("div",{className:"text-sm font-semibold text-heading mb-1",children:"Saved for review"},void 0,!1,void 0,this),f2("p",{className:"text-sm text-theme-muted",children:"This brain is discovered but not approved yet, so it cannot be called until you approve it."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),f2("div",{className:"flex flex-col md:flex-row gap-12",children:[f2("div",{className:"flex-[2] min-w-0",children:[$&&f2("section",{className:"mb-8",children:[f2(lm,{children:"About"},void 0,!1,void 0,this),f2("p",{className:"text-[15px] text-theme leading-relaxed",children:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this),f.length>0&&f2("section",{className:"mb-8",children:[f2(lm,{children:"Skills"},void 0,!1,void 0,this),f2("div",{className:"flex flex-col gap-2.5",children:f.map((Y)=>f2(M1Q,{skill:Y},Y.name,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),I&&f2("section",{className:"mb-8",children:[f2(lm,{children:"Notes"},void 0,!1,void 0,this),f2("p",{className:"text-[15px] text-theme leading-relaxed",children:I},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),f2("aside",{className:"flex-1 md:pl-8 md:border-l border-theme-muted/20",children:[f2("section",{className:"mb-8",children:[f2(lm,{children:"Brain"},void 0,!1,void 0,this),f2("div",{className:"p-4 bg-theme-subtle rounded-xl",children:[f2("div",{className:"text-[15px] font-semibold text-heading mb-1",children:w.brainName},void 0,!1,void 0,this),w.did&&f2("div",{className:"text-xs text-theme-muted font-mono",children:w.did},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),f2("section",{className:"mb-8",children:[f2(lm,{children:"Connection"},void 0,!1,void 0,this),f2("div",{className:"flex flex-col gap-3",children:[f2("div",{children:[f2("div",{className:"text-[13px] text-theme-muted mb-0.5",children:"Endpoint"},void 0,!1,void 0,this),f2("div",{className:"text-xs text-heading font-mono",children:w.url},void 0,!1,void 0,this)]},void 0,!0,void 0,this),f2(V1Q,{label:"Status",value:w.status==="approved"?"Approved":"Discovered",valueClassName:w.status==="approved"?"text-status-success font-medium":"text-theme-muted"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),f2("a",{href:w.url.replace(/\/a2a\/?$/,""),target:"_blank",rel:"noopener noreferrer",className:"flex items-center justify-center px-5 py-3 bg-theme-dark text-theme-inverse rounded-lg text-sm font-medium hover:opacity-90 transition-opacity",children:["Visit ",D," \u2197"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),(Q??B)&&f2("nav",{className:"mt-12 pt-6 border-t border-theme flex flex-col gap-3 md:flex-row md:items-center md:justify-between",children:[f2("div",{className:"min-h-[1px]",children:Q&&f2("a",{href:Q.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[f2("span",{children:"\u2190 Previous"},void 0,!1,void 0,this),f2("span",{className:"text-heading font-medium",children:Q.frontmatter.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),f2("div",{className:"min-h-[1px] md:text-right",children:B&&f2("a",{href:B.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[f2("span",{children:"Next \u2192"},void 0,!1,void 0,this),f2("span",{className:"text-heading font-medium",children:B.frontmatter.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};var O1Q=F.object({agents:F.array(Z_),pageTitle:F.string().optional(),pagination:Y9.nullable(),baseUrl:F.string().optional(),selectedStatus:F.union([F.literal("all"),X4])});function G51(){return{[p_A]:O1({name:p_A,description:"Agent directory list page template",schema:O1Q,dataSourceId:cm,requiredPermission:"public",layout:{component:U51}}),[l_A]:O1({name:l_A,description:"Individual agent profile template",schema:F.object({agent:Z_,prevAgent:Z_.nullable(),nextAgent:Z_.nullable()}),dataSourceId:cm,requiredPermission:"public",layout:{component:J51}})}}var BQA={name:"@brains/agent-discovery",private:!0,version:"0.2.0-alpha.70",description:"Agent discovery \u2014 brain+anchor contacts and skills",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts,.tsx","lint:fix":"eslint . --ext .ts,.tsx --fix"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/dashboard":"workspace:*","@brains/plugins":"workspace:*","@brains/templates":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var _1Q=new W4;class o_A extends KQ{entityType=c$;schema=K_;adapter=_1Q;constructor(){super(g61,BQA)}interceptCreate(A,Q,B){return Q51(A,Q,B,this.id)}createGenerationHandler(A){return new i_A(this.logger.child("AgentGenerationJobHandler"),A)}getTemplates(){return G51()}getDataSources(){return[new o2A(this.logger.child("AgentDataSource"))]}async onRegister(A){H51(A,this.id)}async getInstructions(){return Y51()}}function s_A(){return new o_A}f0();GA();f0();var N_=HI,F51=HI,im=B2.extend({entityType:F.literal(w6),metadata:F51});f0();class z_ extends W2{constructor(){super({entityType:w6,schema:im,frontmatterSchema:N_})}fromMarkdown(A){let Q=this.parseFrontMatter(A,N_);return{content:A,entityType:w6,metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}f0();GA();var P1Q=F.object({skills:F.array(N_).max(8)}),K51=O1({name:"skill:skill-derivation",description:"Derive skills from topic titles and brain capabilities",dataSourceId:"shell:ai-content",schema:P1Q,useKnowledgeContext:!0,basePrompt:`You are analyzing a brain's content to identify its high-level capabilities.
|
|
5099
|
+
})();`;import{jsxDEV as jQ}from"preact/jsx-dev-runtime";function K1Q({item:A}){return jQ("li",{class:"list-item",children:[jQ("div",{class:"list-main",children:[jQ("span",{class:"list-name",children:A.name},void 0,!1,void 0,this),jQ("span",{class:"list-desc",children:A.description},void 0,!1,void 0,this),A.tags.length>0&&jQ("div",{class:"list-tags",children:A.tags.map((Q)=>jQ("span",{class:"tag",children:Q},`${A.id}:${Q}`,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),jQ("div",{class:"list-meta",children:A.status==="discovered"&&jQ("span",{class:"pill pill--warn",children:"review"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function Z1Q({item:A}){return jQ("li",{class:"list-item agent-network-skill-row","data-agent-network-skill-row":!0,"data-agent-network-tags":JSON.stringify(A.tags),children:[jQ("div",{class:"list-main",children:jQ("span",{class:"list-name",children:A.name},void 0,!1,void 0,this)},void 0,!1,void 0,this),jQ("div",{class:"list-meta",children:jQ("span",{class:`agent-network-source${A.sourceType==="brain"?" is-brain":""}`,children:A.sourceLabel},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function N1Q({kind:A,items:Q,active:B}){return jQ("div",{class:`agent-network-panel${B?" is-active":""}`,"data-agent-network-panel":A,children:Q.length>0?jQ("ul",{class:"list agent-network-list",children:Q.map((w)=>jQ(K1Q,{item:w},w.id,!1,void 0,this))},void 0,!1,void 0,this):jQ("p",{class:"agent-network-empty",children:"Nothing to show yet."},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function z1Q({skills:A,count:Q,filters:B}){return jQ("div",{class:"agent-network-panel","data-agent-network-panel":"skills",children:[jQ("div",{class:"agent-network-filter-row",role:"tablist","aria-label":"Filter skills by tag",children:[jQ("button",{class:"agent-network-filter is-active",type:"button","data-agent-network-tag-filter":"all","aria-pressed":"true",children:[jQ("span",{class:"count",children:Q},void 0,!1,void 0,this),jQ("span",{class:"label",children:"all"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),B.map((w)=>jQ("button",{class:`agent-network-filter${w.variant==="gap"?" is-gap":""}`,type:"button","data-agent-network-tag-filter":w.tag,"aria-pressed":"false",children:[jQ("span",{class:"count",children:w.count},void 0,!1,void 0,this),jQ("span",{class:"label",children:w.tag},void 0,!1,void 0,this)]},w.tag,!0,void 0,this))]},void 0,!0,void 0,this),A.length>0?jQ("ul",{class:"list agent-network-list agent-network-skills-list",children:A.map((w)=>jQ(Z1Q,{item:w},w.id,!1,void 0,this))},void 0,!1,void 0,this):jQ("p",{class:"agent-network-empty",children:"Nothing to show yet."},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function d_A({data:A}){let Q=I51.safeParse(A);if(!Q.success)return jQ("p",{class:"muted",children:"Nothing to show yet."},void 0,!1,void 0,this);let B=Q.data;return jQ("div",{"data-agent-network-widget":!0,"data-agent-network-view":"agents",children:[jQ("div",{class:"agent-network-view-tabs",role:"tablist","aria-label":"Browse the agent network",children:[jQ("button",{class:"agent-network-view-tab is-active",type:"button","data-agent-network-view-tab":"agents","aria-pressed":"true",children:["Agents",jQ("span",{class:"agent-network-view-count",children:B.counts.agents},void 0,!1,void 0,this)]},void 0,!0,void 0,this),jQ("button",{class:"agent-network-view-tab",type:"button","data-agent-network-view-tab":"skills","aria-pressed":"false",children:["Skills",jQ("span",{class:"agent-network-view-count",children:B.counts.skills},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),jQ("div",{class:"agent-network-kind-tabs",role:"tablist","aria-label":"Filter agents by kind",children:r_A.map((w)=>{let $=w==="all";return jQ("button",{class:`agent-network-kind-tab${$?" is-active":""}`,type:"button","data-agent-network-kind-tab":w,"aria-pressed":$?"true":"false",children:[jQ("span",{class:"agent-network-kind-count",children:B.agents[w].length},void 0,!1,void 0,this),jQ("span",{class:"agent-network-kind-label",children:w},void 0,!1,void 0,this)]},w,!0,void 0,this)})},void 0,!1,void 0,this),r_A.map((w)=>jQ(N1Q,{kind:w,items:B.agents[w],active:w==="all"},w,!1,void 0,this)),jQ(z1Q,{skills:B.skills,count:B.counts.skills,filters:B.skillFilters},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function H51(A,Q){A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"dashboard:register-widget",payload:{id:S61,pluginId:Q,title:"Agent Network",section:"secondary",priority:15,rendererName:m61,component:d_A,clientScript:t2A,dataProvider:async()=>D51(A)}}),{success:!0}})}function Y51(){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.'}f0();Rw();GA();import{jsxDEV as X51}from"preact/jsx-dev-runtime";function e2A(A){try{return new URL(A).hostname}catch{return A}}var AQA=({name:A,className:Q=""})=>{let B=A.charAt(0).toUpperCase(),w=0;for(let f=0;f<A.length;f++)w=A.charCodeAt(f)+((w<<5)-w);let $=Math.abs(w)%360;return X51("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)},QQA=({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 X51("span",{className:`inline-flex items-center rounded-full font-medium ${Q==="sm"?"px-2 py-0.5 text-xs":"px-2.5 py-0.5 text-[13px]"} ${w}`,children:A},void 0,!1,void 0,this)};import{jsxDEV as F2,Fragment as L1Q}from"preact/jsx-dev-runtime";var q1Q=({skills:A})=>{if(A.length===0)return null;return F2("div",{className:"flex gap-1.5 flex-wrap mt-2",children:A.map((Q)=>F2("span",{className:"text-[11px] px-2 py-0.5 bg-theme-subtle rounded-md text-theme-muted",children:Q.name},Q.name,!1,void 0,this))},void 0,!1,void 0,this)};function C1Q(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric"})}function W51(A,Q,B){let w=new URLSearchParams({status:Q});if(B>1)w.set("page",String(B));return`${A}?${w.toString()}`}var n_A=({agent:A})=>{let{frontmatter:Q,about:B,skills:w,url:$}=A,f=Q.status==="approved";return F2("a",{href:$,className:`flex items-start gap-5 p-6 rounded-xl border border-theme bg-theme-subtle hover:shadow-lg transition-shadow ${f?"":"opacity-70"}`,children:[F2(AQA,{name:Q.name,className:"w-12 h-12 text-lg"},void 0,!1,void 0,this),F2("div",{className:"flex-1 min-w-0",children:[F2("div",{className:"flex items-center gap-2 mb-1 flex-wrap",children:[F2("span",{className:"text-lg font-semibold text-heading",children:Q.name},void 0,!1,void 0,this),F2(QQA,{kind:Q.kind,size:"sm"},void 0,!1,void 0,this),Q.organization&&F2("span",{className:"text-xs text-theme-muted",children:["\xB7 ",Q.organization]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),F2("div",{className:"text-sm text-theme-muted mb-1",children:Q.brainName},void 0,!1,void 0,this),B&&F2("p",{className:"text-sm text-theme-muted line-clamp-2 mb-0",children:B},void 0,!1,void 0,this),f&&F2(q1Q,{skills:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this),F2("div",{className:"flex flex-col items-end gap-1 flex-shrink-0 text-right",children:[F2("span",{className:"text-xs text-theme-muted",children:e2A(Q.url)},void 0,!1,void 0,this),F2("span",{className:"text-[11px] text-theme-muted opacity-60",children:f?`Discovered ${C1Q(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)},U51=({agents:A,pageTitle:Q,pagination:B,baseUrl:w="/agents",selectedStatus:$})=>{let f=Q??"Agent Directory",I=B?.totalItems??A.length,D=A.filter((K)=>K.frontmatter.status==="approved"),H=A.filter((K)=>K.frontmatter.status==="discovered"),Y=D.length,W=H.length,G=`Your network of ${I} ${I===1?"brain":"brains"} and their anchors`;return F2(L1Q,{children:[F2(XQ,{title:f,description:G},void 0,!1,void 0,this),F2("div",{className:"agent-list bg-theme",children:F2("div",{className:"container mx-auto px-6 md:px-12 max-w-5xl py-16 md:py-24",children:[F2("div",{className:"mb-8 pb-6 border-b border-theme",children:[F2("h1",{className:"text-4xl font-bold text-heading mb-2",children:f},void 0,!1,void 0,this),F2("p",{className:"text-theme-muted mb-4",children:G},void 0,!1,void 0,this),F2("div",{className:"flex flex-wrap gap-2 text-sm mb-4",children:[F2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-heading",children:[I," total"]},void 0,!0,void 0,this),F2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-status-success",children:[Y," approved"]},void 0,!0,void 0,this),F2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-theme-muted",children:[W," discovered"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),F2("div",{className:"flex flex-wrap gap-2 text-sm",children:[F2("a",{href:w,className:`px-3 py-1 rounded-full border transition-colors ${$==="all"?"border-theme text-heading bg-theme-subtle":"border-theme text-theme-muted hover:text-heading"}`,children:"All"},void 0,!1,void 0,this),F2("a",{href:`${w}?status=approved`,className:`px-3 py-1 rounded-full border transition-colors ${$==="approved"?"border-theme text-heading bg-theme-subtle":"border-theme text-theme-muted hover:text-heading"}`,children:"Approved"},void 0,!1,void 0,this),F2("a",{href:`${w}?status=discovered`,className:`px-3 py-1 rounded-full border transition-colors ${$==="discovered"?"border-theme text-heading bg-theme-subtle":"border-theme text-theme-muted hover:text-heading"}`,children:"Discovered"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),$==="all"&&D.length>0&&F2("section",{className:"mb-10",children:[F2("div",{className:"flex items-center justify-between mb-4",children:[F2("h2",{className:"text-lg font-semibold text-heading",children:"Approved brains"},void 0,!1,void 0,this),F2("span",{className:"text-sm text-theme-muted",children:D.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),F2("div",{className:"flex flex-col gap-4",children:D.map((K)=>F2(n_A,{agent:K},K.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$==="all"&&H.length>0&&F2("section",{children:[F2("div",{className:"flex items-center justify-between mb-4",children:[F2("div",{children:[F2("h2",{className:"text-lg font-semibold text-heading",children:"Discovered brains"},void 0,!1,void 0,this),F2("p",{className:"text-sm text-theme-muted",children:"Review and approve these before calling them."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),F2("span",{className:"text-sm text-theme-muted",children:H.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),F2("div",{className:"flex flex-col gap-4",children:H.map((K)=>F2(n_A,{agent:K},K.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$!=="all"&&A.length>0&&F2("section",{children:[F2("div",{className:"flex items-center justify-between mb-4",children:[F2("h2",{className:"text-lg font-semibold text-heading",children:$==="approved"?"Approved brains":"Discovered brains"},void 0,!1,void 0,this),F2("span",{className:"text-sm text-theme-muted",children:A.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),F2("div",{className:"flex flex-col gap-4",children:A.map((K)=>F2(n_A,{agent:K},K.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.length===0&&F2("p",{className:"text-center text-theme-muted py-16",children:"No agents in your directory yet."},void 0,!1,void 0,this),B&&B.totalPages>1&&$==="all"&&F2("div",{className:"mt-12",children:F2(cJ,{currentPage:B.currentPage,totalPages:B.totalPages,baseUrl:w},void 0,!1,void 0,this)},void 0,!1,void 0,this),B&&B.totalPages>1&&$!=="all"&&F2("nav",{"aria-label":"Pagination",className:"flex items-center justify-center gap-3 mt-12",children:[B.hasPrevPage?F2("a",{href:W51(w,$,B.currentPage-1),className:"px-3 py-2 rounded-md border border-theme text-sm text-theme-muted hover:text-heading transition-colors",children:"\u2190 Prev"},void 0,!1,void 0,this):F2("span",{className:"px-3 py-2 rounded-md border border-theme text-sm text-theme-muted opacity-50",children:"\u2190 Prev"},void 0,!1,void 0,this),F2("span",{className:"text-sm text-theme-muted",children:["Page ",B.currentPage," of ",B.totalPages]},void 0,!0,void 0,this),B.hasNextPage?F2("a",{href:W51(w,$,B.currentPage+1),className:"px-3 py-2 rounded-md border border-theme text-sm text-theme-muted hover:text-heading transition-colors",children:"Next \u2192"},void 0,!1,void 0,this):F2("span",{className:"px-3 py-2 rounded-md border border-theme text-sm text-theme-muted opacity-50",children:"Next \u2192"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as f2,Fragment as b1Q}from"preact/jsx-dev-runtime";function E1Q(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"})}var lm=({children:A})=>f2("h2",{className:"text-sm font-semibold text-theme-muted uppercase tracking-wide mb-3",children:A},void 0,!1,void 0,this),M1Q=({skill:A})=>f2("div",{className:"flex items-start gap-3 px-4 py-3 bg-theme-subtle rounded-lg",children:[f2("div",{className:"flex-1",children:[f2("div",{className:"text-sm font-semibold text-heading",children:A.name},void 0,!1,void 0,this),f2("div",{className:"text-[13px] text-theme-muted",children:A.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.tags.length>0&&f2("div",{className:"flex gap-1 flex-shrink-0",children:A.tags.map((Q)=>f2("span",{className:"text-[11px] px-2 py-0.5 bg-theme rounded-md text-theme-muted",children:Q},Q,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),V1Q=({label:A,value:Q,valueClassName:B})=>f2("div",{className:"flex justify-between text-[13px]",children:[f2("span",{className:"text-theme-muted",children:A},void 0,!1,void 0,this),f2("span",{className:B??"text-heading",children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this),J51=({agent:A,prevAgent:Q,nextAgent:B})=>{let{frontmatter:w,about:$,skills:f,notes:I}=A,D=e2A(w.url),H=w.status==="approved";return f2(b1Q,{children:[f2(XQ,{title:w.name,description:$||`Agent profile for ${w.name}`},void 0,!1,void 0,this),f2("article",{className:"agent-detail",children:f2("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:[f2("a",{href:"/agents",className:"text-sm text-theme-muted hover:text-brand transition-colors mb-6 inline-block",children:"\u2190 Back to Directory"},void 0,!1,void 0,this),f2("div",{className:"flex items-start gap-6 mb-8",children:[f2(AQA,{name:w.name,className:"w-[72px] h-[72px] text-3xl"},void 0,!1,void 0,this),f2("div",{children:[f2("div",{className:"flex items-center gap-3 mb-1",children:[f2("h1",{className:"text-3xl md:text-4xl font-bold text-heading",children:w.name},void 0,!1,void 0,this),f2(QQA,{kind:w.kind},void 0,!1,void 0,this)]},void 0,!0,void 0,this),f2("div",{className:"text-base text-theme-muted mb-2",children:w.brainName},void 0,!1,void 0,this),f2("div",{className:"flex items-center gap-3 text-theme-muted",children:[w.organization&&f2("span",{className:"text-[15px]",children:w.organization},void 0,!1,void 0,this),w.organization&&f2("span",{className:"text-theme-muted opacity-40",children:"\xB7"},void 0,!1,void 0,this),f2("span",{className:"text-sm",children:["Discovered ",E1Q(w.discoveredAt)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),f2("div",{className:"border-b border-theme mb-8"},void 0,!1,void 0,this),!H&&f2("div",{className:"mb-8 rounded-xl border border-theme bg-theme-subtle px-5 py-4",children:[f2("div",{className:"text-sm font-semibold text-heading mb-1",children:"Saved for review"},void 0,!1,void 0,this),f2("p",{className:"text-sm text-theme-muted",children:"This brain is discovered but not approved yet, so it cannot be called until you approve it."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),f2("div",{className:"flex flex-col md:flex-row gap-12",children:[f2("div",{className:"flex-[2] min-w-0",children:[$&&f2("section",{className:"mb-8",children:[f2(lm,{children:"About"},void 0,!1,void 0,this),f2("p",{className:"text-[15px] text-theme leading-relaxed",children:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this),f.length>0&&f2("section",{className:"mb-8",children:[f2(lm,{children:"Skills"},void 0,!1,void 0,this),f2("div",{className:"flex flex-col gap-2.5",children:f.map((Y)=>f2(M1Q,{skill:Y},Y.name,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),I&&f2("section",{className:"mb-8",children:[f2(lm,{children:"Notes"},void 0,!1,void 0,this),f2("p",{className:"text-[15px] text-theme leading-relaxed",children:I},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),f2("aside",{className:"flex-1 md:pl-8 md:border-l border-theme-muted/20",children:[f2("section",{className:"mb-8",children:[f2(lm,{children:"Brain"},void 0,!1,void 0,this),f2("div",{className:"p-4 bg-theme-subtle rounded-xl",children:[f2("div",{className:"text-[15px] font-semibold text-heading mb-1",children:w.brainName},void 0,!1,void 0,this),w.did&&f2("div",{className:"text-xs text-theme-muted font-mono",children:w.did},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),f2("section",{className:"mb-8",children:[f2(lm,{children:"Connection"},void 0,!1,void 0,this),f2("div",{className:"flex flex-col gap-3",children:[f2("div",{children:[f2("div",{className:"text-[13px] text-theme-muted mb-0.5",children:"Endpoint"},void 0,!1,void 0,this),f2("div",{className:"text-xs text-heading font-mono",children:w.url},void 0,!1,void 0,this)]},void 0,!0,void 0,this),f2(V1Q,{label:"Status",value:w.status==="approved"?"Approved":"Discovered",valueClassName:w.status==="approved"?"text-status-success font-medium":"text-theme-muted"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),f2("a",{href:w.url.replace(/\/a2a\/?$/,""),target:"_blank",rel:"noopener noreferrer",className:"flex items-center justify-center px-5 py-3 bg-theme-dark text-theme-inverse rounded-lg text-sm font-medium hover:opacity-90 transition-opacity",children:["Visit ",D," \u2197"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),(Q??B)&&f2("nav",{className:"mt-12 pt-6 border-t border-theme flex flex-col gap-3 md:flex-row md:items-center md:justify-between",children:[f2("div",{className:"min-h-[1px]",children:Q&&f2("a",{href:Q.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[f2("span",{children:"\u2190 Previous"},void 0,!1,void 0,this),f2("span",{className:"text-heading font-medium",children:Q.frontmatter.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),f2("div",{className:"min-h-[1px] md:text-right",children:B&&f2("a",{href:B.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[f2("span",{children:"Next \u2192"},void 0,!1,void 0,this),f2("span",{className:"text-heading font-medium",children:B.frontmatter.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};var O1Q=F.object({agents:F.array(Z_),pageTitle:F.string().optional(),pagination:Y9.nullable(),baseUrl:F.string().optional(),selectedStatus:F.union([F.literal("all"),X4])});function G51(){return{[p_A]:O1({name:p_A,description:"Agent directory list page template",schema:O1Q,dataSourceId:cm,requiredPermission:"public",layout:{component:U51}}),[l_A]:O1({name:l_A,description:"Individual agent profile template",schema:F.object({agent:Z_,prevAgent:Z_.nullable(),nextAgent:Z_.nullable()}),dataSourceId:cm,requiredPermission:"public",layout:{component:J51}})}}var BQA={name:"@brains/agent-discovery",private:!0,version:"0.2.0-alpha.71",description:"Agent discovery \u2014 brain+anchor contacts and skills",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts,.tsx","lint:fix":"eslint . --ext .ts,.tsx --fix"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/dashboard":"workspace:*","@brains/plugins":"workspace:*","@brains/templates":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var _1Q=new W4;class o_A extends KQ{entityType=c$;schema=K_;adapter=_1Q;constructor(){super(g61,BQA)}interceptCreate(A,Q,B){return Q51(A,Q,B,this.id)}createGenerationHandler(A){return new i_A(this.logger.child("AgentGenerationJobHandler"),A)}getTemplates(){return G51()}getDataSources(){return[new o2A(this.logger.child("AgentDataSource"))]}async onRegister(A){H51(A,this.id)}async getInstructions(){return Y51()}}function s_A(){return new o_A}f0();GA();f0();var N_=HI,F51=HI,im=B2.extend({entityType:F.literal(w6),metadata:F51});f0();class z_ extends W2{constructor(){super({entityType:w6,schema:im,frontmatterSchema:N_})}fromMarkdown(A){let Q=this.parseFrontMatter(A,N_);return{content:A,entityType:w6,metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}f0();GA();var P1Q=F.object({skills:F.array(N_).max(8)}),K51=O1({name:"skill:skill-derivation",description:"Derive skills from topic titles and brain capabilities",dataSourceId:"shell:ai-content",schema:P1Q,useKnowledgeContext:!0,basePrompt:`You are analyzing a brain's content to identify its high-level capabilities.
|
|
5100
5100
|
|
|
5101
5101
|
Given knowledge domains, CONSOLIDATE related topics into broader skills.
|
|
5102
5102
|
There should be FEWER skills than topics \u2014 combine related domains.
|
|
@@ -5246,9 +5246,9 @@ Context:
|
|
|
5246
5246
|
${JSON.stringify(w,null,2)}
|
|
5247
5247
|
|
|
5248
5248
|
Draft SWOT:
|
|
5249
|
-
${JSON.stringify(B,null,2)}`}function XQA(A){return A.map((Q)=>Q.detail===null?{title:Q.title}:{title:Q.title,detail:Q.detail})}function t1Q(A,Q){let B=["strengths","weaknesses","opportunities","threats"];for(let w of B){let $=new Set(A[w].map((f)=>f.theme.trim().toLowerCase()));for(let f of Q[w]){let I=f.sourceTheme.trim().toLowerCase();if(!$.has(I))throw Error(`SWOT refinement invented theme "${f.sourceTheme}" in ${w}`)}}}class WQA{logger;context;adapter=new WG;constructor(A,Q){this.logger=A;this.context=Q}validateAndParse(A){let Q=e_A.safeParse(A??{});return Q.success?Q.data:null}async process(A,Q,B){await B.report({progress:0.2,message:"Building SWOT context"});let w=await $PA(this.context),$;if(w.summary.brainSkillCount+w.summary.approvedAgentCount+w.summary.discoveredAgentCount===0)$={strengths:[],weaknesses:[],opportunities:[],threats:[]};else{await B.report({progress:0.6,message:"Synthesizing SWOT analysis"});let{object:Y}=await this.context.ai.generateObject(await o1Q(this.context,w),APA),W=APA.parse(Y);await B.report({progress:0.75,message:"Refining SWOT language"});let G=await this.context.ai.generateObject(await a1Q(this.context,w,W),DQA);$=DQA.parse(G.object),t1Q(W,$)}let I=new Date().toISOString(),D=this.adapter.createSwotContent({strengths:XQA($.strengths),weaknesses:XQA($.weaknesses),opportunities:XQA($.opportunities),threats:XQA($.threats),derivedAt:I});await B.report({progress:0.9,message:"Saving SWOT entity"});let H=await this.context.entityService.getEntity({entityType:"swot",id:"swot"});if(H)await this.context.entityService.updateEntity({entity:{...H,content:D,metadata:{derivedAt:I}}});else await this.context.entityService.createEntity({entity:{id:"swot",entityType:"swot",content:D,metadata:{derivedAt:I}}});return this.logger.info("SWOT derivation complete",{derivedAt:I,brainSkillCount:w.summary.brainSkillCount,approvedAgentCount:w.summary.approvedAgentCount,discoveredAgentCount:w.summary.discoveredAgentCount}),{entityId:"swot"}}}GA();import{jsxDEV as v9}from"preact/jsx-dev-runtime";var UQA=F.object({title:F.string(),detail:F.string().optional()}),e1Q=F.discriminatedUnion("status",[F.object({status:F.literal("generating")}),F.object({status:F.literal("ready"),strengths:F.array(UQA).default([]),weaknesses:F.array(UQA).default([]),opportunities:F.array(UQA).default([]),threats:F.array(UQA).default([]),derivedAt:F.string()})]);function A2Q({items:A}){if(A.length===0)return v9("p",{class:"swot-empty",children:"\u2014"},void 0,!1,void 0,this);return v9("ul",{class:"swot-list",children:A.map((Q)=>v9("li",{class:"swot-item",children:[v9("b",{children:Q.title},void 0,!1,void 0,this),Q.detail?v9("span",{children:[" \u2014 ",Q.detail]},void 0,!0,void 0,this):null]},`${Q.title}:${Q.detail??""}`,!0,void 0,this))},void 0,!1,void 0,this)}function JQA({title:A,tone:Q,items:B}){return v9("section",{class:`swot-cell is-${Q}`,children:[v9("div",{class:"swot-head",children:A},void 0,!1,void 0,this),v9(A2Q,{items:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function DPA({data:A}){let Q=e1Q.safeParse(A);if(!Q.success||Q.data.status==="generating")return v9("div",{"data-swot-widget":!0,children:v9("p",{class:"muted",children:"generating assessment\u2026"},void 0,!1,void 0,this)},void 0,!1,void 0,this);let B=Q.data;return v9("div",{"data-swot-widget":!0,children:v9("div",{class:"swot",role:"grid","aria-label":"SWOT analysis of agent network",children:[v9(JQA,{title:"Strengths",tone:"s",items:B.strengths},void 0,!1,void 0,this),v9(JQA,{title:"Weaknesses",tone:"w",items:B.weaknesses},void 0,!1,void 0,this),v9(JQA,{title:"Opportunities",tone:"o",items:B.opportunities},void 0,!1,void 0,this),v9(JQA,{title:"Threats",tone:"t",items:B.threats},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)}GA();var HPA={name:"@brains/assessment",private:!0,version:"0.2.0-alpha.
|
|
5249
|
+
${JSON.stringify(B,null,2)}`}function XQA(A){return A.map((Q)=>Q.detail===null?{title:Q.title}:{title:Q.title,detail:Q.detail})}function t1Q(A,Q){let B=["strengths","weaknesses","opportunities","threats"];for(let w of B){let $=new Set(A[w].map((f)=>f.theme.trim().toLowerCase()));for(let f of Q[w]){let I=f.sourceTheme.trim().toLowerCase();if(!$.has(I))throw Error(`SWOT refinement invented theme "${f.sourceTheme}" in ${w}`)}}}class WQA{logger;context;adapter=new WG;constructor(A,Q){this.logger=A;this.context=Q}validateAndParse(A){let Q=e_A.safeParse(A??{});return Q.success?Q.data:null}async process(A,Q,B){await B.report({progress:0.2,message:"Building SWOT context"});let w=await $PA(this.context),$;if(w.summary.brainSkillCount+w.summary.approvedAgentCount+w.summary.discoveredAgentCount===0)$={strengths:[],weaknesses:[],opportunities:[],threats:[]};else{await B.report({progress:0.6,message:"Synthesizing SWOT analysis"});let{object:Y}=await this.context.ai.generateObject(await o1Q(this.context,w),APA),W=APA.parse(Y);await B.report({progress:0.75,message:"Refining SWOT language"});let G=await this.context.ai.generateObject(await a1Q(this.context,w,W),DQA);$=DQA.parse(G.object),t1Q(W,$)}let I=new Date().toISOString(),D=this.adapter.createSwotContent({strengths:XQA($.strengths),weaknesses:XQA($.weaknesses),opportunities:XQA($.opportunities),threats:XQA($.threats),derivedAt:I});await B.report({progress:0.9,message:"Saving SWOT entity"});let H=await this.context.entityService.getEntity({entityType:"swot",id:"swot"});if(H)await this.context.entityService.updateEntity({entity:{...H,content:D,metadata:{derivedAt:I}}});else await this.context.entityService.createEntity({entity:{id:"swot",entityType:"swot",content:D,metadata:{derivedAt:I}}});return this.logger.info("SWOT derivation complete",{derivedAt:I,brainSkillCount:w.summary.brainSkillCount,approvedAgentCount:w.summary.approvedAgentCount,discoveredAgentCount:w.summary.discoveredAgentCount}),{entityId:"swot"}}}GA();import{jsxDEV as v9}from"preact/jsx-dev-runtime";var UQA=F.object({title:F.string(),detail:F.string().optional()}),e1Q=F.discriminatedUnion("status",[F.object({status:F.literal("generating")}),F.object({status:F.literal("ready"),strengths:F.array(UQA).default([]),weaknesses:F.array(UQA).default([]),opportunities:F.array(UQA).default([]),threats:F.array(UQA).default([]),derivedAt:F.string()})]);function A2Q({items:A}){if(A.length===0)return v9("p",{class:"swot-empty",children:"\u2014"},void 0,!1,void 0,this);return v9("ul",{class:"swot-list",children:A.map((Q)=>v9("li",{class:"swot-item",children:[v9("b",{children:Q.title},void 0,!1,void 0,this),Q.detail?v9("span",{children:[" \u2014 ",Q.detail]},void 0,!0,void 0,this):null]},`${Q.title}:${Q.detail??""}`,!0,void 0,this))},void 0,!1,void 0,this)}function JQA({title:A,tone:Q,items:B}){return v9("section",{class:`swot-cell is-${Q}`,children:[v9("div",{class:"swot-head",children:A},void 0,!1,void 0,this),v9(A2Q,{items:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function DPA({data:A}){let Q=e1Q.safeParse(A);if(!Q.success||Q.data.status==="generating")return v9("div",{"data-swot-widget":!0,children:v9("p",{class:"muted",children:"generating assessment\u2026"},void 0,!1,void 0,this)},void 0,!1,void 0,this);let B=Q.data;return v9("div",{"data-swot-widget":!0,children:v9("div",{class:"swot",role:"grid","aria-label":"SWOT analysis of agent network",children:[v9(JQA,{title:"Strengths",tone:"s",items:B.strengths},void 0,!1,void 0,this),v9(JQA,{title:"Weaknesses",tone:"w",items:B.weaknesses},void 0,!1,void 0,this),v9(JQA,{title:"Opportunities",tone:"o",items:B.opportunities},void 0,!1,void 0,this),v9(JQA,{title:"Threats",tone:"t",items:B.threats},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)}GA();var HPA={name:"@brains/assessment",private:!0,version:"0.2.0-alpha.71",description:"Assessment outputs and capability-profile analysis",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts,.tsx","lint:fix":"eslint . --ext .ts,.tsx --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/dashboard":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var YPA=new WG;class XPA extends KQ{entityType="swot";schema=q_;adapter=YPA;initialSyncComplete=!1;constructor(){super("swot",HPA)}async onRegister(A){let Q=new WQA(this.logger.child("SwotDerivationHandler"),A);A.jobs.registerHandler("derive",Q),A.eval.registerHandler("deriveSwot",async()=>{let f=z$.from(async()=>{});if(!f)throw Error("Expected progress reporter to be created");await Q.process({reason:"eval"},"eval-swot-derive",f);let I=await A.entityService.getEntity({entityType:"swot",id:"swot"});if(!I)throw Error("Expected SWOT entity to be created during eval");return YPA.parseSwotContent(I.content).frontmatter});let B=async(f)=>{try{return await A.jobs.enqueue({type:"derive",data:{reason:f},options:{source:this.id,priority:10,deduplication:"coalesce",deduplicationKey:"swot",metadata:{operationType:"data_processing",operationTarget:`swot:${f}`}}})}catch(I){return this.logger.error("Failed to queue SWOT derivation",{error:I,reason:f}),null}},w=async(f)=>{if(!await A.entityService.getEntity({entityType:"swot",id:"swot"}))await B(f)};A.messaging.subscribe("sync:initial:completed",async()=>{return this.initialSyncComplete=!0,await w("initial-missing-entity"),{success:!0}}),A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"dashboard:register-widget",payload:{id:"swot",pluginId:this.id,title:"SWOT",section:"secondary",priority:14,rendererName:"SwotWidget",component:DPA,dataProvider:async()=>{let f=await A.entityService.getEntity({entityType:"swot",id:"swot"});if(!f)return{status:"generating"};let{frontmatter:I}=YPA.parseSwotContent(f.content);return{status:"ready",...I}}}}),{success:!0}});let $=async(f)=>{let{entityType:I}=f.payload;if(!this.initialSyncComplete)return{success:!0};if(I!=="agent"&&I!=="skill")return{success:!0};return await B("entity-change"),{success:!0}};A.messaging.subscribe("entity:created",$),A.messaging.subscribe("entity:updated",$),A.messaging.subscribe("entity:deleted",$)}}function WPA(){return new XPA}f0();d5();GA();var VZw=new WG,P51=F.object({name:F.string(),description:F.string(),tags:F.array(F.string())}),UPA=F.enum(["discovered","approved"]),B2Q=F.object({name:F.string(),kind:F.enum(["professional","team","collective"]),organization:F.string().optional(),brainName:F.string(),url:F.string().url(),did:F.string().optional(),status:UPA,discoveredAt:F.string().datetime()}),w2Q=B2.extend({entityType:F.literal("agent"),metadata:F.object({name:F.string(),url:F.string().url(),status:UPA,slug:F.string()})}),$2Q=B2.extend({entityType:F.literal("skill"),metadata:HI}),f2Q=F.object({about:F.string(),skills:F.array(P51),notes:F.string()});function I2Q(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(`
|
|
5250
5250
|
`)}function D2Q(A){if(!A.trim())return[];return A.split(`
|
|
5251
|
-
`).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 H2Q=new RB(f2Q,{title:"Agent",mappings:[{key:"about",label:"About",type:"string"},{key:"skills",label:"Skills",type:"custom",formatter:I2Q,parser:D2Q},{key:"notes",label:"Notes",type:"string"}]});class k51 extends W2{constructor(){super({entityType:"agent",schema:w2Q,frontmatterSchema:B2Q})}fromMarkdown(A){return{content:A,entityType:"agent"}}createAgentContent(A){let Q=H2Q.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 j51 extends W2{constructor(){super({entityType:"skill",schema:$2Q,frontmatterSchema:HI})}fromMarkdown(A){let Q=this.parseFrontMatter(A,HI);return{content:A,entityType:"skill",metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}var bZw=new k51,OZw=new j51,RZw=F.object({skills:F.array(HI),agents:F.array(F.object({id:F.string().optional(),name:F.string(),kind:F.enum(["professional","team","collective"]),organization:F.string().optional(),brainName:F.string(),url:F.string().url(),did:F.string().optional(),status:UPA,discoveredAt:F.string().datetime().optional(),about:F.string(),skills:F.array(P51),notes:F.string().default("")}))});var Y2Q=F.object({}).strict();function GQA(A={}){return Y2Q.parse(A),[WPA()]}f0();GA();Rw();G6();GA();f0();var FQA=Tl.extend({expertise:F.array(F.string()).optional().describe("Skills, domains, areas of focus"),currentFocus:F.string().optional().describe("What you're currently working on"),availability:F.string().optional().describe("What you're open to (consulting, speaking, etc.)")}),sZ=AH.extend(FQA.shape);f0();OU();GA();var X2Q=new AX;class KQA{postsListUrl;decksListUrl;id="professional:homepage-list";name="Homepage List DataSource";description="Fetches profile, blog posts, and presentation decks for homepage";constructor(A,Q){this.postsListUrl=A;this.decksListUrl=Q}async fetch(A,Q,B){let w=B.entityService,[$,f,I,D]=await Promise.all([eE(w),w.listEntities({entityType:"post",options:{limit:20}}),w.listEntities({entityType:"deck",options:{limit:20}}),yOA(w)]),H=X2Q.parseProfileBody($,sZ),Y=f.sort(Fk).slice(0,3).map(Xm),W=I.sort(Fk).slice(0,3).map(Fm);if(!D.cta)throw Error("CTA not configured in site-info");let G={profile:H,posts:Y,decks:W,postsListUrl:this.postsListUrl,decksListUrl:this.decksListUrl,cta:D.cta,sections:D.sections??{}};return Q.parse(G)}}f0();OU();var W2Q=new AX;class ZQA{id="professional:about";name="About Page DataSource";description="Fetches full profile data for the about page";async fetch(A,Q,B){let w=await eE(B.entityService),f={profile:W2Q.parseProfileBody(w,sZ)};return Q.parse(f)}}import{jsxDEV as Vw,Fragment as G2Q}from"preact/jsx-dev-runtime";var U2Q="grid md:grid-cols-[14rem_1px_1fr] gap-y-2 gap-x-0 md:gap-16 items-start",J2Q="border-t md:border-t-0 md:border-l border-rule-strong md:self-stretch",JPA=({number:A,title:Q,blurb:B,children:w})=>Vw("section",{className:"py-20 border-b border-rule px-6 md:px-12",children:Vw("div",{className:"max-w-6xl mx-auto",children:Vw("div",{className:U2Q,children:[Vw(kMA,{title:Q,number:A,blurb:B},void 0,!1,void 0,this),Vw("div",{className:J2Q,"aria-hidden":"true"},void 0,!1,void 0,this),Vw("div",{className:"mt-6 md:mt-0",children:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this),GPA=({profile:A,posts:Q,decks:B,postsListUrl:w,decksListUrl:$,cta:f,sections:I})=>{let D=A.tagline||A.description,H=Q.map((Z)=>({id:Z.id,url:Z.url,title:Z.metadata.title,date:Z.metadata.publishedAt||Z.created,description:Z.frontmatter.excerpt,series:Z.frontmatter.seriesName&&Z.frontmatter.seriesIndex?{name:Z.frontmatter.seriesName,index:Z.frontmatter.seriesIndex}:void 0})),Y=B.map((Z)=>({id:Z.id,url:Z.url,title:Z.frontmatter.title||Z.id,date:Z.frontmatter.publishedAt??Z.created,description:Z.frontmatter.description})),W=A.name||"Home",G=A.intro||A.description||D||"Professional site",K=Boolean(A.description)||A.expertise!==void 0&&A.expertise.length>0;return Vw(G2Q,{children:[Vw(XQ,{title:W,description:G,ogType:"website"},void 0,!1,void 0,this),Vw("div",{className:"homepage-list bg-theme",children:[Vw("header",{className:"hero-bg-pattern relative w-full px-6 md:px-12 pt-28 pb-24 md:pt-28 md:pb-24 overflow-hidden border-b border-rule",children:Vw("div",{className:"relative z-10 max-w-6xl mx-auto w-full",children:[A.name&&Vw("div",{className:"flex items-center gap-[0.6rem] mb-6 font-mono text-[0.7rem] font-medium uppercase tracking-[0.22em] text-accent",children:[Vw("span",{className:"w-[18px] h-px bg-accent","aria-hidden":"true"},void 0,!1,void 0,this),Vw("span",{children:A.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),D&&Vw("h1",{className:"font-heading text-[clamp(2.75rem,6.5vw,5.5rem)] font-normal text-heading leading-[1.02] tracking-[-0.025em] max-w-[18ch] [font-variation-settings:'opsz'_144,'SOFT'_30]",children:uAA(D,"italic font-normal text-accent [font-variation-settings:'opsz'_144,'SOFT'_80]")},void 0,!1,void 0,this),A.intro&&Vw("p",{className:"font-heading font-light text-[clamp(1.1rem,1.8vw,1.4rem)] leading-[1.5] text-theme-muted max-w-[42ch] mt-8 [font-variation-settings:'opsz'_24]",children:uAA(A.intro,"italic text-accent")},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Vw(JPA,{number:"01",title:"Essays",blurb:I.essays?.blurb,children:Vw(mAA,{items:H,viewAllUrl:w,viewAllLabel:"View all essays"},void 0,!1,void 0,this)},void 0,!1,void 0,this),Y.length>0&&Vw(JPA,{number:"02",title:"Presentations",blurb:I.presentations?.blurb,children:Vw(mAA,{items:Y,viewAllUrl:$,viewAllLabel:"View all presentations"},void 0,!1,void 0,this)},void 0,!1,void 0,this),K&&Vw(JPA,{number:"03",title:"About",blurb:I.about?.blurb,children:Vw("div",{className:"flex flex-col gap-8",children:[A.description&&Vw("p",{className:"font-heading font-light text-[1.25rem] leading-[1.55] text-theme max-w-[55ch] [font-variation-settings:'opsz'_24,'SOFT'_50]",children:A.description},void 0,!1,void 0,this),A.expertise&&A.expertise.length>0&&Vw(jMA,{subjects:A.expertise},void 0,!1,void 0,this),Vw("a",{href:"/about",className:"mt-6 inline-flex items-center gap-2 font-mono text-[0.7rem] font-medium uppercase tracking-[0.18em] text-accent pb-1 relative before:content-[''] before:absolute before:left-0 before:right-full before:bottom-0 before:h-px before:bg-accent before:transition-[right] before:duration-300 hover:before:right-0",children:["Learn more",Vw("span",{"aria-hidden":"true",children:"\u2192"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Vw(KMA,{cta:f,variant:"editorial",socialLinks:A.socialLinks},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as oB,Fragment as F2Q}from"preact/jsx-dev-runtime";var FPA=({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 oB(F2Q,{children:[oB(XQ,{title:Q,description:B,ogType:"profile"},void 0,!1,void 0,this),oB("div",{className:"about-page bg-theme",children:[oB("header",{className:"hero-bg-pattern relative w-full py-16 md:py-24 px-6 md:px-12 bg-theme overflow-hidden",children:oB("div",{className:"relative z-10 max-w-4xl mx-auto",children:[oB("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&&oB("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),oB("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-12 md:py-16",children:[A.story&&oB("section",{className:"content-section-reveal mb-20 md:mb-28",children:oB(mI,{markdown:A.story},void 0,!1,void 0,this)},void 0,!1,void 0,this),w&&oB("div",{className:"content-section-reveal grid md:grid-cols-2 gap-x-16 gap-y-12",children:[A.expertise&&A.expertise.length>0&&oB("section",{children:[oB("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Expertise"},void 0,!1,void 0,this),oB("ul",{className:"flex flex-wrap gap-3",children:A.expertise.map(($,f)=>oB("li",{className:rT({variant:"accent",size:"lg"}),children:$},f,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.currentFocus&&oB("section",{children:[oB("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Current Focus"},void 0,!1,void 0,this),oB("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&&oB("section",{children:[oB("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Availability"},void 0,!1,void 0,this),oB("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)&&oB("section",{children:[oB("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Contact"},void 0,!1,void 0,this),oB("div",{className:"space-y-4",children:[A.email&&oB("p",{className:"text-lg",children:oB("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&&oB("p",{className:"text-lg",children:oB("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&&oB("div",{className:"flex flex-wrap gap-4 mt-4",children:A.socialLinks.map(($,f)=>oB(b5,{href:$.url,external:!0,variant:"secondary",size:"md",children:$.label||$.platform},f,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as x9,Fragment as v51}from"preact/jsx-dev-runtime";var KPA=()=>{return x9(v51,{children:[x9(XQ,{title:"Thanks for subscribing!",description:"You've successfully subscribed to the newsletter."},void 0,!1,void 0,this),x9("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:x9("div",{className:"text-center max-w-md",children:[x9("div",{className:"text-6xl mb-6",children:"\uD83C\uDF89"},void 0,!1,void 0,this),x9("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Thanks for subscribing!"},void 0,!1,void 0,this),x9("p",{className:"text-lg text-theme-muted mb-8",children:"You'll receive a confirmation email shortly. Check your inbox to confirm your subscription."},void 0,!1,void 0,this),x9(b5,{href:"/",variant:"primary",children:"Back to Home"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},ZPA=()=>{return x9(v51,{children:[x9(XQ,{title:"Subscription failed",description:"There was a problem with your subscription."},void 0,!1,void 0,this),x9("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:x9("div",{className:"text-center max-w-md",children:[x9("div",{className:"text-6xl mb-6",children:"\uD83D\uDE22"},void 0,!1,void 0,this),x9("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Something went wrong"},void 0,!1,void 0,this),x9("p",{className:"text-lg text-theme-muted mb-8",children:"We couldn't process your subscription. Please try again or contact us if the problem persists."},void 0,!1,void 0,this),x9(b5,{href:"/",variant:"primary",children:"Back to Home"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};GA();var x51=F.object({label:F.string().describe("Display label for entity type (e.g., 'Essay')"),pluralName:F.string().optional().describe("URL path segment (defaults to label.toLowerCase() + 's')")}),h51=F.object({entityDisplay:F.object({post:x51,deck:x51}).describe("Display metadata for post and deck entity types (required for homepage)")});var y51={name:"@brains/site-professional",private:!0,version:"0.2.0-alpha.70",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 NPA extends Ww{dependencies=["blog","decks"];constructor(A){super("professional-site",y51,A,h51)}async onRegister(A){A.entities.extendFrontmatterSchema("anchor-profile",FQA);let Q=this.config.entityDisplay.post,B=this.config.entityDisplay.deck,w=`/${Q.pluralName??Q.label.toLowerCase()+"s"}`,$=`/${B.pluralName??B.label.toLowerCase()+"s"}`,f=new KQA(w,$);A.entities.registerDataSource(f);let I=new ZQA;A.entities.registerDataSource(I);let D=F.object({profile:sZ,posts:F.array(fG),decks:F.array(Jm),postsListUrl:F.string(),decksListUrl:F.string(),cta:xOA,sections:F.record(F.string(),dp)}),H=F.object({profile:sZ}),Y=F.object({});A.templates.register({"homepage-list":O1({name:"homepage-list",description:"Professional homepage with essays and presentations",schema:D,dataSourceId:"professional:homepage-list",requiredPermission:"public",layout:{component:GPA}}),about:O1({name:"about",description:"About page with full profile information",schema:H,dataSourceId:"professional:about",requiredPermission:"public",layout:{component:FPA}}),"subscribe-thanks":O1({name:"subscribe-thanks",description:"Newsletter subscription success page",schema:Y,requiredPermission:"public",layout:{component:KPA}}),"subscribe-error":O1({name:"subscribe-error",description:"Newsletter subscription error page",schema:Y,requiredPermission:"public",layout:{component:ZPA}})}),this.logger.info("Professional site plugin registered successfully")}async getTools(){return[]}async getResources(){return[]}}function g51(A){return new NPA(A??{})}var T51=[{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 NQA}from"preact/jsx-dev-runtime";function S51({sections:A,siteInfo:Q,slots:B,wordmark:w}){return NQA("div",{className:"flex flex-col min-h-screen bg-theme overflow-x-clip",children:[NQA(qMA,{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),NQA("main",{className:"flex-grow flex flex-col bg-theme",children:A},void 0,!1,void 0,this),NQA(NMA,{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 Z2Q={layouts:{default:S51},routes:T51,plugin:g51,entityDisplay:{post:{label:"Post"},deck:{label:"Deck"},project:{label:"Project"},series:{label:"Series",navigation:{slot:"secondary"}},topic:{label:"Topic",navigation:{slot:"secondary"}},link:{label:"Link",navigation:{slot:"secondary"}},base:{label:"Note",navigation:{show:!1}},"social-post":{label:"Social Post",pluralName:"social-posts",navigation:{slot:"secondary"}},newsletter:{label:"Newsletter",navigation:{slot:"secondary"}}}},dm=Z2Q;var m51=`/*
|
|
5251
|
+
`).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 H2Q=new RB(f2Q,{title:"Agent",mappings:[{key:"about",label:"About",type:"string"},{key:"skills",label:"Skills",type:"custom",formatter:I2Q,parser:D2Q},{key:"notes",label:"Notes",type:"string"}]});class k51 extends W2{constructor(){super({entityType:"agent",schema:w2Q,frontmatterSchema:B2Q})}fromMarkdown(A){return{content:A,entityType:"agent"}}createAgentContent(A){let Q=H2Q.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 j51 extends W2{constructor(){super({entityType:"skill",schema:$2Q,frontmatterSchema:HI})}fromMarkdown(A){let Q=this.parseFrontMatter(A,HI);return{content:A,entityType:"skill",metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}var bZw=new k51,OZw=new j51,RZw=F.object({skills:F.array(HI),agents:F.array(F.object({id:F.string().optional(),name:F.string(),kind:F.enum(["professional","team","collective"]),organization:F.string().optional(),brainName:F.string(),url:F.string().url(),did:F.string().optional(),status:UPA,discoveredAt:F.string().datetime().optional(),about:F.string(),skills:F.array(P51),notes:F.string().default("")}))});var Y2Q=F.object({}).strict();function GQA(A={}){return Y2Q.parse(A),[WPA()]}f0();GA();Rw();G6();GA();f0();var FQA=Tl.extend({expertise:F.array(F.string()).optional().describe("Skills, domains, areas of focus"),currentFocus:F.string().optional().describe("What you're currently working on"),availability:F.string().optional().describe("What you're open to (consulting, speaking, etc.)")}),sZ=AH.extend(FQA.shape);f0();OU();GA();var X2Q=new AX;class KQA{postsListUrl;decksListUrl;id="professional:homepage-list";name="Homepage List DataSource";description="Fetches profile, blog posts, and presentation decks for homepage";constructor(A,Q){this.postsListUrl=A;this.decksListUrl=Q}async fetch(A,Q,B){let w=B.entityService,[$,f,I,D]=await Promise.all([eE(w),w.listEntities({entityType:"post",options:{limit:20}}),w.listEntities({entityType:"deck",options:{limit:20}}),yOA(w)]),H=X2Q.parseProfileBody($,sZ),Y=f.sort(Fk).slice(0,3).map(Xm),W=I.sort(Fk).slice(0,3).map(Fm);if(!D.cta)throw Error("CTA not configured in site-info");let G={profile:H,posts:Y,decks:W,postsListUrl:this.postsListUrl,decksListUrl:this.decksListUrl,cta:D.cta,sections:D.sections??{}};return Q.parse(G)}}f0();OU();var W2Q=new AX;class ZQA{id="professional:about";name="About Page DataSource";description="Fetches full profile data for the about page";async fetch(A,Q,B){let w=await eE(B.entityService),f={profile:W2Q.parseProfileBody(w,sZ)};return Q.parse(f)}}import{jsxDEV as Vw,Fragment as G2Q}from"preact/jsx-dev-runtime";var U2Q="grid md:grid-cols-[14rem_1px_1fr] gap-y-2 gap-x-0 md:gap-16 items-start",J2Q="border-t md:border-t-0 md:border-l border-rule-strong md:self-stretch",JPA=({number:A,title:Q,blurb:B,children:w})=>Vw("section",{className:"py-20 border-b border-rule px-6 md:px-12",children:Vw("div",{className:"max-w-6xl mx-auto",children:Vw("div",{className:U2Q,children:[Vw(kMA,{title:Q,number:A,blurb:B},void 0,!1,void 0,this),Vw("div",{className:J2Q,"aria-hidden":"true"},void 0,!1,void 0,this),Vw("div",{className:"mt-6 md:mt-0",children:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this),GPA=({profile:A,posts:Q,decks:B,postsListUrl:w,decksListUrl:$,cta:f,sections:I})=>{let D=A.tagline||A.description,H=Q.map((Z)=>({id:Z.id,url:Z.url,title:Z.metadata.title,date:Z.metadata.publishedAt||Z.created,description:Z.frontmatter.excerpt,series:Z.frontmatter.seriesName&&Z.frontmatter.seriesIndex?{name:Z.frontmatter.seriesName,index:Z.frontmatter.seriesIndex}:void 0})),Y=B.map((Z)=>({id:Z.id,url:Z.url,title:Z.frontmatter.title||Z.id,date:Z.frontmatter.publishedAt??Z.created,description:Z.frontmatter.description})),W=A.name||"Home",G=A.intro||A.description||D||"Professional site",K=Boolean(A.description)||A.expertise!==void 0&&A.expertise.length>0;return Vw(G2Q,{children:[Vw(XQ,{title:W,description:G,ogType:"website"},void 0,!1,void 0,this),Vw("div",{className:"homepage-list bg-theme",children:[Vw("header",{className:"hero-bg-pattern relative w-full px-6 md:px-12 pt-28 pb-24 md:pt-28 md:pb-24 overflow-hidden border-b border-rule",children:Vw("div",{className:"relative z-10 max-w-6xl mx-auto w-full",children:[A.name&&Vw("div",{className:"flex items-center gap-[0.6rem] mb-6 font-mono text-[0.7rem] font-medium uppercase tracking-[0.22em] text-accent",children:[Vw("span",{className:"w-[18px] h-px bg-accent","aria-hidden":"true"},void 0,!1,void 0,this),Vw("span",{children:A.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),D&&Vw("h1",{className:"font-heading text-[clamp(2.75rem,6.5vw,5.5rem)] font-normal text-heading leading-[1.02] tracking-[-0.025em] max-w-[18ch] [font-variation-settings:'opsz'_144,'SOFT'_30]",children:uAA(D,"italic font-normal text-accent [font-variation-settings:'opsz'_144,'SOFT'_80]")},void 0,!1,void 0,this),A.intro&&Vw("p",{className:"font-heading font-light text-[clamp(1.1rem,1.8vw,1.4rem)] leading-[1.5] text-theme-muted max-w-[42ch] mt-8 [font-variation-settings:'opsz'_24]",children:uAA(A.intro,"italic text-accent")},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Vw(JPA,{number:"01",title:"Essays",blurb:I.essays?.blurb,children:Vw(mAA,{items:H,viewAllUrl:w,viewAllLabel:"View all essays"},void 0,!1,void 0,this)},void 0,!1,void 0,this),Y.length>0&&Vw(JPA,{number:"02",title:"Presentations",blurb:I.presentations?.blurb,children:Vw(mAA,{items:Y,viewAllUrl:$,viewAllLabel:"View all presentations"},void 0,!1,void 0,this)},void 0,!1,void 0,this),K&&Vw(JPA,{number:"03",title:"About",blurb:I.about?.blurb,children:Vw("div",{className:"flex flex-col gap-8",children:[A.description&&Vw("p",{className:"font-heading font-light text-[1.25rem] leading-[1.55] text-theme max-w-[55ch] [font-variation-settings:'opsz'_24,'SOFT'_50]",children:A.description},void 0,!1,void 0,this),A.expertise&&A.expertise.length>0&&Vw(jMA,{subjects:A.expertise},void 0,!1,void 0,this),Vw("a",{href:"/about",className:"mt-6 inline-flex items-center gap-2 font-mono text-[0.7rem] font-medium uppercase tracking-[0.18em] text-accent pb-1 relative before:content-[''] before:absolute before:left-0 before:right-full before:bottom-0 before:h-px before:bg-accent before:transition-[right] before:duration-300 hover:before:right-0",children:["Learn more",Vw("span",{"aria-hidden":"true",children:"\u2192"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Vw(KMA,{cta:f,variant:"editorial",socialLinks:A.socialLinks},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as oB,Fragment as F2Q}from"preact/jsx-dev-runtime";var FPA=({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 oB(F2Q,{children:[oB(XQ,{title:Q,description:B,ogType:"profile"},void 0,!1,void 0,this),oB("div",{className:"about-page bg-theme",children:[oB("header",{className:"hero-bg-pattern relative w-full py-16 md:py-24 px-6 md:px-12 bg-theme overflow-hidden",children:oB("div",{className:"relative z-10 max-w-4xl mx-auto",children:[oB("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&&oB("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),oB("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-12 md:py-16",children:[A.story&&oB("section",{className:"content-section-reveal mb-20 md:mb-28",children:oB(mI,{markdown:A.story},void 0,!1,void 0,this)},void 0,!1,void 0,this),w&&oB("div",{className:"content-section-reveal grid md:grid-cols-2 gap-x-16 gap-y-12",children:[A.expertise&&A.expertise.length>0&&oB("section",{children:[oB("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Expertise"},void 0,!1,void 0,this),oB("ul",{className:"flex flex-wrap gap-3",children:A.expertise.map(($,f)=>oB("li",{className:rT({variant:"accent",size:"lg"}),children:$},f,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.currentFocus&&oB("section",{children:[oB("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Current Focus"},void 0,!1,void 0,this),oB("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&&oB("section",{children:[oB("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Availability"},void 0,!1,void 0,this),oB("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)&&oB("section",{children:[oB("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Contact"},void 0,!1,void 0,this),oB("div",{className:"space-y-4",children:[A.email&&oB("p",{className:"text-lg",children:oB("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&&oB("p",{className:"text-lg",children:oB("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&&oB("div",{className:"flex flex-wrap gap-4 mt-4",children:A.socialLinks.map(($,f)=>oB(b5,{href:$.url,external:!0,variant:"secondary",size:"md",children:$.label||$.platform},f,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as x9,Fragment as v51}from"preact/jsx-dev-runtime";var KPA=()=>{return x9(v51,{children:[x9(XQ,{title:"Thanks for subscribing!",description:"You've successfully subscribed to the newsletter."},void 0,!1,void 0,this),x9("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:x9("div",{className:"text-center max-w-md",children:[x9("div",{className:"text-6xl mb-6",children:"\uD83C\uDF89"},void 0,!1,void 0,this),x9("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Thanks for subscribing!"},void 0,!1,void 0,this),x9("p",{className:"text-lg text-theme-muted mb-8",children:"You'll receive a confirmation email shortly. Check your inbox to confirm your subscription."},void 0,!1,void 0,this),x9(b5,{href:"/",variant:"primary",children:"Back to Home"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},ZPA=()=>{return x9(v51,{children:[x9(XQ,{title:"Subscription failed",description:"There was a problem with your subscription."},void 0,!1,void 0,this),x9("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:x9("div",{className:"text-center max-w-md",children:[x9("div",{className:"text-6xl mb-6",children:"\uD83D\uDE22"},void 0,!1,void 0,this),x9("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Something went wrong"},void 0,!1,void 0,this),x9("p",{className:"text-lg text-theme-muted mb-8",children:"We couldn't process your subscription. Please try again or contact us if the problem persists."},void 0,!1,void 0,this),x9(b5,{href:"/",variant:"primary",children:"Back to Home"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};GA();var x51=F.object({label:F.string().describe("Display label for entity type (e.g., 'Essay')"),pluralName:F.string().optional().describe("URL path segment (defaults to label.toLowerCase() + 's')")}),h51=F.object({entityDisplay:F.object({post:x51,deck:x51}).describe("Display metadata for post and deck entity types (required for homepage)")});var y51={name:"@brains/site-professional",private:!0,version:"0.2.0-alpha.71",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 NPA extends Ww{dependencies=["blog","decks"];constructor(A){super("professional-site",y51,A,h51)}async onRegister(A){A.entities.extendFrontmatterSchema("anchor-profile",FQA);let Q=this.config.entityDisplay.post,B=this.config.entityDisplay.deck,w=`/${Q.pluralName??Q.label.toLowerCase()+"s"}`,$=`/${B.pluralName??B.label.toLowerCase()+"s"}`,f=new KQA(w,$);A.entities.registerDataSource(f);let I=new ZQA;A.entities.registerDataSource(I);let D=F.object({profile:sZ,posts:F.array(fG),decks:F.array(Jm),postsListUrl:F.string(),decksListUrl:F.string(),cta:xOA,sections:F.record(F.string(),dp)}),H=F.object({profile:sZ}),Y=F.object({});A.templates.register({"homepage-list":O1({name:"homepage-list",description:"Professional homepage with essays and presentations",schema:D,dataSourceId:"professional:homepage-list",requiredPermission:"public",layout:{component:GPA}}),about:O1({name:"about",description:"About page with full profile information",schema:H,dataSourceId:"professional:about",requiredPermission:"public",layout:{component:FPA}}),"subscribe-thanks":O1({name:"subscribe-thanks",description:"Newsletter subscription success page",schema:Y,requiredPermission:"public",layout:{component:KPA}}),"subscribe-error":O1({name:"subscribe-error",description:"Newsletter subscription error page",schema:Y,requiredPermission:"public",layout:{component:ZPA}})}),this.logger.info("Professional site plugin registered successfully")}async getTools(){return[]}async getResources(){return[]}}function g51(A){return new NPA(A??{})}var T51=[{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 NQA}from"preact/jsx-dev-runtime";function S51({sections:A,siteInfo:Q,slots:B,wordmark:w}){return NQA("div",{className:"flex flex-col min-h-screen bg-theme overflow-x-clip",children:[NQA(qMA,{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),NQA("main",{className:"flex-grow flex flex-col bg-theme",children:A},void 0,!1,void 0,this),NQA(NMA,{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 Z2Q={layouts:{default:S51},routes:T51,plugin:g51,entityDisplay:{post:{label:"Post"},deck:{label:"Deck"},project:{label:"Project"},series:{label:"Series",navigation:{slot:"secondary"}},topic:{label:"Topic",navigation:{slot:"secondary"}},link:{label:"Link",navigation:{slot:"secondary"}},base:{label:"Note",navigation:{show:!1}},"social-post":{label:"Social Post",pluralName:"social-posts",navigation:{slot:"secondary"}},newsletter:{label:"Newsletter",navigation:{slot:"secondary"}}}},dm=Z2Q;var m51=`/*
|
|
5252
5252
|
* Default theme \u2014 simplified editorial base inspired by the Rizom family.
|
|
5253
5253
|
*
|
|
5254
5254
|
* This theme is intentionally less branded than @brains/theme-rizom. It
|
|
@@ -5636,7 +5636,7 @@ ${JSON.stringify(B,null,2)}`}function XQA(A){return A.map((Q)=>Q.detail===null?{
|
|
|
5636
5636
|
|
|
5637
5637
|
.btn-primary:disabled { opacity: 0.5; }
|
|
5638
5638
|
}
|
|
5639
|
-
`;var L_=m51;import{join as q2Q}from"path";var u51={name:"@brains/rover",version:"0.2.0-alpha.70",type:"module",private:!0,main:"./src/index.ts",files:["src","brain.eval.yaml","env.schema.template"],scripts:{"start:core":"cd test-apps/core && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start","start:default":"cd test-apps/default && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start","start:full":"cd test-apps/full && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start",typecheck:"tsc --noEmit",eval:"brain-eval",lint:"eslint .","lint:fix":"eslint . --fix"},dependencies:{"@brains/a2a":"workspace:*","@brains/agent-discovery":"workspace:*","@brains/analytics":"workspace:*","@brains/app":"workspace:*","@brains/assessment":"workspace:*","@brains/auth-service":"workspace:*","@brains/blog":"workspace:*","@brains/cms":"workspace:*","@brains/content-pipeline":"workspace:*","@brains/dashboard":"workspace:*","@brains/decks":"workspace:*","@brains/directory-sync":"workspace:*","@brains/discord":"workspace:*","@brains/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 c51=["prompt","note","link","wishlist","topics","directory-sync","agents","assessment","auth-service","cms","dashboard-root","mcp","webserver","discord","a2a"],p51=[...c51.filter((A)=>A!=="dashboard-root"),"image","dashboard","blog","series","decks","analytics","obsidian-vault","site-info","site-builder"],C2Q=[...p51,"portfolio","topics","content-pipeline","social-media","newsletter","stock-photo"],L2Q=["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."],l51=QK({name:"rover",version:u51.version,model:"gpt-5.4-mini",site:dm,theme:L_,presets:{core:c51,default:p51,full:C2Q},evalDisable:["discord","webserver","mcp","analytics","dashboard","dashboard-root"],agentInstructions:L2Q,capabilities:[["prompt",cC,void 0],["image",yx,void 0],["cms",uC,{}],["auth-service",Vy,void 0],["dashboard",nZ,void 0],["dashboard-root",nZ,{routePath:"/"}],["blog",lOA,{}],["series",oOA,void 0],["decks",Km,void 0],["note",xC,{}],["link",yC,{}],["portfolio",RRA,{}],["topics",M2A,{includeEntityTypes:["post","deck","project","link","anchor-profile"]}],["content-pipeline",f_A,{generationSchedules:{newsletter:"0 9 * * 1","social-post":"0 10 * * *"},generationConditions:{newsletter:{skipIfDraftExists:!0,minSourceEntities:1,sourceEntityType:"post"},"social-post":{skipIfDraftExists:!0,maxUnpublishedDrafts:5}}}],["social-media",bm,{autoGenerateOnBlogPublish:!0}],["newsletter",X61,{doubleOptIn:!0}],["obsidian-vault",V_A,{autoSync:!0}],["wishlist",u2A,{}],["stock-photo",v_A,{}],["agents",$QA,void 0],["assessment",GQA,void 0],["directory-sync",aq,{seedContent:!0,seedContentPath:q2Q(import.meta.dir,"..","seed-content"),initialSync:!0}],["analytics",h2A,{}],["rizom-ecosystem",pC,void 0],["site-info",kC,void 0],["site-builder",PC,{cms:{}}]],interfaces:[["mcp",hK,()=>({})],["discord",KZ,()=>({})],["webserver",ZZ,()=>({})],["a2a",AR,()=>({})]],permissions:{rules:[{pattern:"cli:*",level:"anchor"},{pattern:"mcp:stdio",level:"anchor"},{pattern:"mcp:http",level:"public"},{pattern:"discord:*",level:"public"}]},deployment:{cdn:{enabled:!0,provider:"bunny"},dns:{enabled:!0,provider:"bunny"}}});$K();f0();GA();GA();f0();var zQA=F.object({routeId:F.string(),sectionId:F.string()}),nm=B2.extend({entityType:F.literal("site-content"),template:F.string().optional(),content:F.string(),metadata:zQA});f0();class i51 extends W2{constructor(){super({entityType:"site-content",schema:nm,frontmatterSchema:zQA})}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 zPA=new i51;GA();var qQA=F.object({routeId:F.string().optional().describe("Optional: specific route filter"),sectionId:F.string().optional().describe("Optional: specific section filter"),dryRun:F.boolean().optional().default(!1).describe("Optional: preview changes without executing"),force:F.boolean().optional().default(!1).describe("Force regeneration even if content exists")}),mNw=F.object({jobs:F.array(F.object({jobId:F.string(),routeId:F.string(),sectionId:F.string()})),totalSections:F.number(),queuedSections:F.number(),skippedSections:F.number().optional(),batchId:F.string().optional()});class qPA{context;constructor(A){this.context=A}createJobOptions(A,Q){if(!A)return;return{source:A.operationType??Q,rootJobId:A.rootJobId??`${Q}-${Date.now()}`,metadata:{operationType:A.operationType??"content_operations",progressToken:A.progressToken,pluginId:A.pluginId??"site-content"}}}async fetchRoutes(){let A=await this.context.messaging.send({type:"site-builder:routes:list",payload:{}});if("noop"in A)throw Error("No handler for site-builder:routes:list \u2014 is site-builder plugin loaded?");if(!A.success||!A.data)throw Error("Failed to fetch routes from site-builder");return A.data}async generate(A,Q,B){let w=this.context.logger.child("SiteContentOperations"),$=await this.fetchRoutes(),f=$;if(A.routeId){if(f=$.filter((W)=>W.id===A.routeId),f.length===0)throw Error(`Route not found: ${A.routeId}`)}let I=[];for(let W of f)for(let G of W.sections){if(A.sectionId&&G.id!==A.sectionId)continue;if(G.content){w.debug("Section has static content, skipping",{routeId:W.id,sectionId:G.id});continue}if(G.template){let K=this.context.templates.getCapabilities(G.template);if(!K){w.warn("Template not found, skipping section",{routeId:W.id,sectionId:G.id,templateName:G.template});continue}if(!K.canGenerate){w.debug("Template doesn't support generation, skipping",{routeId:W.id,sectionId:G.id,templateName:G.template,capabilities:K});continue}}else{w.debug("Section has no template, skipping",{routeId:W.id,sectionId:G.id});continue}if(!A.force&&!A.dryRun){let K=`${W.id}:${G.id}`;if(await this.context.entityService.getEntity({entityType:"site-content",id:K})){w.debug("Content already exists, skipping",{routeId:W.id,sectionId:G.id});continue}}I.push({route:W,section:G})}let D=I.length;if(A.dryRun)return{jobs:[],totalSections:D,queuedSections:D,batchId:`dry-run-${Date.now()}`};let H=[],Y=[];for(let{route:W,section:G}of I){let K=`${W.id}:${G.id}`,Z=G.template,q={routeId:W.id,sectionId:G.id,entityId:K,entityType:"site-content",templateName:Z,context:{prompt:typeof G.content==="string"?G.content:void 0,data:{routeId:W.id,sectionId:G.id,routeTitle:W.title||Q?.title||"",routeDescription:W.description||Q?.description||"",sectionContent:G.content},conversationId:"system"},siteConfig:Q};Y.push({type:"shell:content-generation",data:q})}if(Y.length>0){let W=this.createJobOptions(B,"site:content-generation"),G=await this.context.jobs.enqueueBatch(Y,W);for(let K=0;K<I.length;K++){let Z=I[K];if(Z)H.push({jobId:`${G}-${K}`,routeId:Z.route.id,sectionId:Z.section.id})}return{jobs:H,totalSections:D,queuedSections:H.length,batchId:G}}return{jobs:[],totalSections:D,queuedSections:0,batchId:`empty-${Date.now()}`}}}class CPA{siteConfig;operations;constructor(A,Q){this.siteConfig=Q;this.operations=new qPA(A)}async generateContent(A,Q){let B=qQA.parse(A);return this.operations.generate(B,this.siteConfig,Q)}}d5();GA();function om(A,Q){return Q?A.optional():A}function EPA(A){switch(A.type){case"string":return om(F.string(),A.optional);case"number":return om(F.number(),A.optional);case"enum":{let Q=[...A.options];return om(F.enum(Q),A.optional)}case"object":{let Q={};for(let[B,w]of Object.entries(A.fields))Q[B]=EPA(w);return om(F.object(Q),A.optional)}case"array":{let Q=F.array(E2Q(A));if(A.minItems!==void 0)Q=Q.min(A.minItems);if(A.length!==void 0)Q=Q.length(A.length);return om(Q,A.optional)}}}function E2Q(A){let{items:Q}=A;switch(Q.type){case"string":return F.string();case"number":return F.number();case"enum":{let B=[...Q.options];return F.enum(B)}case"object":{let B={};for(let[w,$]of Object.entries(Q.fields))B[w]=EPA($);return F.object(B)}}}function LPA(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])=>LPA(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,$])=>LPA(w,$)),B}}}}function M2Q(A,Q){let B={};for(let[f,I]of Object.entries(Q.fields))B[f]=EPA(I);let w=F.object(B),$=new RB(w,{title:Q.title,mappings:Object.entries(Q.fields).map(([f,I])=>LPA(f,I))});return{name:A,description:Q.description,schema:w,formatter:$,requiredPermission:Q.requiredPermission??"public",layout:{component:Q.layout,...Q.fullscreen!==void 0?{fullscreen:Q.fullscreen}:{}},...Q.runtimeScripts?{runtimeScripts:Q.runtimeScripts}:{}}}function MPA(A){return Object.fromEntries(Object.entries(A.sections).map(([Q,B])=>[Q,M2Q(Q,B)]))}GA();var r51=F.object({namespace:F.string(),sections:F.record(F.any())}),d51=F.object({definitions:F.union([r51,F.array(r51)]).optional()});f0();function n51(A,Q){return[xQ(Q,"generate","Generate content for all routes, a specific route, or a specific section",qQA,async(B,w)=>{let $=A();if(!$)return{success:!1,error:"Site content service not initialized"};if(B.sectionId&&!B.routeId)return{success:!1,error:"sectionId requires routeId to be specified"};let f={rootJobId:`generate-${Date.now()}`,progressToken:w.progressToken,pluginId:Q,operationType:"content_operations",interfaceType:w.interfaceType,channelId:w.channelId},I=await $.generateContent(B,f);return{success:!0,message:`Generated ${I.queuedSections} of ${I.totalSections} sections. ${I.queuedSections>0?"Jobs are running in the background.":"No new content to generate."}`,data:{batchId:I.batchId,jobsQueued:I.queuedSections,totalSections:I.totalSections,jobs:I.jobs}}})]}var o51={name:"@brains/site-content",private:!0,version:"0.2.0-alpha.70",description:"Site content entity and generation orchestration",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/plugins":"workspace:*","@brains/site-info":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class VPA extends Ww{siteContentService;constructor(A={}){super("site-content",o51,A,d51)}async onRegister(A){A.entities.register("site-content",nm,zPA);for(let Q of pY(this.config.definitions))A.templates.register(MPA(Q),Q.namespace);this.siteContentService=new CPA(A)}async getTools(){return n51(()=>this.siteContentService,this.id)}}function sm(A={}){return new VPA(A)}f0();GA();Rw();GA();f0();var s51=F.enum(["available","early access","coming soon","planned"]),a51=F.object({title:F.string(),description:F.string()}),UG=F.object({name:F.string(),availability:s51,order:F.number()}),CQA=F.object({tagline:F.string(),promise:F.string(),role:F.string(),purpose:F.string(),audience:F.string(),values:F.array(F.string()).min(1),features:F.array(a51).min(1).max(6),story:F.string()}),b2Q=UG.pick({name:!0,availability:!0,order:!0}).extend({slug:F.string()}),E_=B2.extend({entityType:F.literal("product"),metadata:b2Q}),LQA=E_.extend({frontmatter:UG,body:CQA,labels:F.record(F.string(),F.string())}),EQA=LQA.extend({url:F.string().optional(),typeLabel:F.string().optional(),listUrl:F.string().optional(),listLabel:F.string().optional()});f0();GA();d5();class M_ extends RB{constructor(){super(CQA,{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 bPA extends W2{constructor(){super({entityType:"product",schema:E_,frontmatterSchema:UG,bodyFormatter:new M_})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,UG);return this.buildMarkdown(Q,B)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,UG),B=U2(Q.name);return{content:A,entityType:"product",metadata:{name:Q.name,slug:B,availability:Q.availability,order:Q.order}}}}var MQA=new bPA;GA();f0();var t51=F.object({title:F.string(),description:F.string()}),e51=F.object({title:F.string(),description:F.string()}),O2Q=F.object({title:F.string(),description:F.string()}),A$1=F.object({heading:F.string(),buttonText:F.string(),link:F.string()}),JG=F.object({headline:F.string(),tagline:F.string()}),R2Q=F.object({title:F.string(),description:F.string()}),VQA=F.object({vision:F.string(),pillars:F.array(t51).min(1).max(6),approach:F.array(R2Q).min(1).max(6),productsIntro:F.string(),technologies:F.array(O2Q).min(1).max(6),benefits:F.array(e51).min(1).max(6),cta:A$1}),Q$1=JG.pick({headline:!0}).extend({slug:F.string()}),V_=B2.extend({entityType:F.literal("products-overview"),metadata:Q$1}),am=V_.extend({frontmatter:JG,body:VQA,labels:F.record(F.string(),F.string())});f0();GA();d5();class b_ extends RB{constructor(){super(VQA,{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 OPA extends W2{constructor(){super({entityType:"products-overview",schema:V_,frontmatterSchema:JG,bodyFormatter:new b_})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,JG);return this.buildMarkdown(Q,B)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,JG),B=U2(Q.headline);return{content:A,entityType:"products-overview",metadata:{headline:Q.headline,slug:B}}}}var RPA=new OPA;f0();GA();var _2Q=F.object({entityType:F.string(),query:F.object({id:F.string().optional()}).optional()});function B$1(A,Q){let B=t2(A.content,UG),w=Q.parse(B.content),$=Q.getLabels();return LQA.parse({...A,frontmatter:B.metadata,body:w,labels:$})}function w$1(A,Q){let B=t2(A.content,JG),w=Q.parse(B.content),$=Q.getLabels();return am.parse({...A,frontmatter:B.metadata,body:w,labels:$})}class bQA{logger;id="products:entities";name="Products Entity DataSource";description="Fetches products and overview for the products page";overviewFormatter=new b_;productFormatter=new M_;constructor(A){this.logger=A;this.logger.debug("ProductsDataSource initialized")}async fetch(A,Q,B){let w=_2Q.parse(A),$=B.entityService;if(w.entityType==="products-overview"){let Y=(await $.listEntities({entityType:"products-overview",options:{limit:1}}))[0];if(!Y)throw Error("Products overview entity not found");let W=w$1(Y,this.overviewFormatter);return Q.parse(W)}if(w.query?.id){let Y=(await $.listEntities({entityType:"product",options:{filter:{metadata:{slug:w.query.id}},limit:1}}))[0];if(!Y)throw Error(`Product not found: ${w.query.id}`);return Q.parse({product:B$1(Y,this.productFormatter)})}let[f,I]=await Promise.all([$.listEntities({entityType:"products-overview",options:{limit:1}}),$.listEntities({entityType:"product",options:{sortFields:[{field:"order",direction:"asc"}]}})]),D=f[0];if(!D)throw Error("Products overview entity not found");return Q.parse({overview:w$1(D,this.overviewFormatter),products:I.map((H)=>B$1(H,this.productFormatter))})}}import{jsxDEV as B1,Fragment as j2Q}from"preact/jsx-dev-runtime";var $$1=({overview:A,products:Q})=>{let{frontmatter:B,body:w,labels:$}=A;return B1(j2Q,{children:[B1(XQ,{title:B.headline,description:B.tagline},void 0,!1,void 0,this),B1("header",{className:"relative w-full min-h-[80vh] flex items-end px-6 md:px-12 bg-brand-dark overflow-hidden",children:[B1("style",{children:`
|
|
5639
|
+
`;var L_=m51;import{join as q2Q}from"path";var u51={name:"@brains/rover",version:"0.2.0-alpha.71",type:"module",private:!0,main:"./src/index.ts",files:["src","brain.eval.yaml","env.schema.template"],scripts:{"start:core":"cd test-apps/core && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start","start:default":"cd test-apps/default && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start","start:full":"cd test-apps/full && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start",typecheck:"tsc --noEmit",eval:"brain-eval",lint:"eslint .","lint:fix":"eslint . --fix"},dependencies:{"@brains/a2a":"workspace:*","@brains/agent-discovery":"workspace:*","@brains/analytics":"workspace:*","@brains/app":"workspace:*","@brains/assessment":"workspace:*","@brains/auth-service":"workspace:*","@brains/blog":"workspace:*","@brains/cms":"workspace:*","@brains/content-pipeline":"workspace:*","@brains/dashboard":"workspace:*","@brains/decks":"workspace:*","@brains/directory-sync":"workspace:*","@brains/discord":"workspace:*","@brains/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 c51=["prompt","note","link","wishlist","topics","directory-sync","agents","assessment","auth-service","cms","dashboard-root","mcp","webserver","discord","a2a"],p51=[...c51.filter((A)=>A!=="dashboard-root"),"image","dashboard","blog","series","decks","analytics","obsidian-vault","site-info","site-builder"],C2Q=[...p51,"portfolio","topics","content-pipeline","social-media","newsletter","stock-photo"],L2Q=["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."],l51=QK({name:"rover",version:u51.version,model:"gpt-5.4-mini",site:dm,theme:L_,presets:{core:c51,default:p51,full:C2Q},evalDisable:["discord","webserver","mcp","analytics","dashboard","dashboard-root"],agentInstructions:L2Q,capabilities:[["prompt",cC,void 0],["image",yx,void 0],["cms",uC,{}],["auth-service",Vy,void 0],["dashboard",nZ,void 0],["dashboard-root",nZ,{routePath:"/"}],["blog",lOA,{}],["series",oOA,void 0],["decks",Km,void 0],["note",xC,{}],["link",yC,{}],["portfolio",RRA,{}],["topics",M2A,{includeEntityTypes:["post","deck","project","link","anchor-profile"]}],["content-pipeline",f_A,{generationSchedules:{newsletter:"0 9 * * 1","social-post":"0 10 * * *"},generationConditions:{newsletter:{skipIfDraftExists:!0,minSourceEntities:1,sourceEntityType:"post"},"social-post":{skipIfDraftExists:!0,maxUnpublishedDrafts:5}}}],["social-media",bm,{autoGenerateOnBlogPublish:!0}],["newsletter",X61,{doubleOptIn:!0}],["obsidian-vault",V_A,{autoSync:!0}],["wishlist",u2A,{}],["stock-photo",v_A,{}],["agents",$QA,void 0],["assessment",GQA,void 0],["directory-sync",aq,{seedContent:!0,seedContentPath:q2Q(import.meta.dir,"..","seed-content"),initialSync:!0}],["analytics",h2A,{}],["rizom-ecosystem",pC,void 0],["site-info",kC,void 0],["site-builder",PC,{cms:{}}]],interfaces:[["mcp",hK,()=>({})],["discord",KZ,()=>({})],["webserver",ZZ,()=>({})],["a2a",AR,()=>({})]],permissions:{rules:[{pattern:"cli:*",level:"anchor"},{pattern:"mcp:stdio",level:"anchor"},{pattern:"mcp:http",level:"public"},{pattern:"discord:*",level:"public"}]},deployment:{cdn:{enabled:!0,provider:"bunny"},dns:{enabled:!0,provider:"bunny"}}});$K();f0();GA();GA();f0();var zQA=F.object({routeId:F.string(),sectionId:F.string()}),nm=B2.extend({entityType:F.literal("site-content"),template:F.string().optional(),content:F.string(),metadata:zQA});f0();class i51 extends W2{constructor(){super({entityType:"site-content",schema:nm,frontmatterSchema:zQA})}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 zPA=new i51;GA();var qQA=F.object({routeId:F.string().optional().describe("Optional: specific route filter"),sectionId:F.string().optional().describe("Optional: specific section filter"),dryRun:F.boolean().optional().default(!1).describe("Optional: preview changes without executing"),force:F.boolean().optional().default(!1).describe("Force regeneration even if content exists")}),mNw=F.object({jobs:F.array(F.object({jobId:F.string(),routeId:F.string(),sectionId:F.string()})),totalSections:F.number(),queuedSections:F.number(),skippedSections:F.number().optional(),batchId:F.string().optional()});class qPA{context;constructor(A){this.context=A}createJobOptions(A,Q){if(!A)return;return{source:A.operationType??Q,rootJobId:A.rootJobId??`${Q}-${Date.now()}`,metadata:{operationType:A.operationType??"content_operations",progressToken:A.progressToken,pluginId:A.pluginId??"site-content"}}}async fetchRoutes(){let A=await this.context.messaging.send({type:"site-builder:routes:list",payload:{}});if("noop"in A)throw Error("No handler for site-builder:routes:list \u2014 is site-builder plugin loaded?");if(!A.success||!A.data)throw Error("Failed to fetch routes from site-builder");return A.data}async generate(A,Q,B){let w=this.context.logger.child("SiteContentOperations"),$=await this.fetchRoutes(),f=$;if(A.routeId){if(f=$.filter((W)=>W.id===A.routeId),f.length===0)throw Error(`Route not found: ${A.routeId}`)}let I=[];for(let W of f)for(let G of W.sections){if(A.sectionId&&G.id!==A.sectionId)continue;if(G.content){w.debug("Section has static content, skipping",{routeId:W.id,sectionId:G.id});continue}if(G.template){let K=this.context.templates.getCapabilities(G.template);if(!K){w.warn("Template not found, skipping section",{routeId:W.id,sectionId:G.id,templateName:G.template});continue}if(!K.canGenerate){w.debug("Template doesn't support generation, skipping",{routeId:W.id,sectionId:G.id,templateName:G.template,capabilities:K});continue}}else{w.debug("Section has no template, skipping",{routeId:W.id,sectionId:G.id});continue}if(!A.force&&!A.dryRun){let K=`${W.id}:${G.id}`;if(await this.context.entityService.getEntity({entityType:"site-content",id:K})){w.debug("Content already exists, skipping",{routeId:W.id,sectionId:G.id});continue}}I.push({route:W,section:G})}let D=I.length;if(A.dryRun)return{jobs:[],totalSections:D,queuedSections:D,batchId:`dry-run-${Date.now()}`};let H=[],Y=[];for(let{route:W,section:G}of I){let K=`${W.id}:${G.id}`,Z=G.template,q={routeId:W.id,sectionId:G.id,entityId:K,entityType:"site-content",templateName:Z,context:{prompt:typeof G.content==="string"?G.content:void 0,data:{routeId:W.id,sectionId:G.id,routeTitle:W.title||Q?.title||"",routeDescription:W.description||Q?.description||"",sectionContent:G.content},conversationId:"system"},siteConfig:Q};Y.push({type:"shell:content-generation",data:q})}if(Y.length>0){let W=this.createJobOptions(B,"site:content-generation"),G=await this.context.jobs.enqueueBatch(Y,W);for(let K=0;K<I.length;K++){let Z=I[K];if(Z)H.push({jobId:`${G}-${K}`,routeId:Z.route.id,sectionId:Z.section.id})}return{jobs:H,totalSections:D,queuedSections:H.length,batchId:G}}return{jobs:[],totalSections:D,queuedSections:0,batchId:`empty-${Date.now()}`}}}class CPA{siteConfig;operations;constructor(A,Q){this.siteConfig=Q;this.operations=new qPA(A)}async generateContent(A,Q){let B=qQA.parse(A);return this.operations.generate(B,this.siteConfig,Q)}}d5();GA();function om(A,Q){return Q?A.optional():A}function EPA(A){switch(A.type){case"string":return om(F.string(),A.optional);case"number":return om(F.number(),A.optional);case"enum":{let Q=[...A.options];return om(F.enum(Q),A.optional)}case"object":{let Q={};for(let[B,w]of Object.entries(A.fields))Q[B]=EPA(w);return om(F.object(Q),A.optional)}case"array":{let Q=F.array(E2Q(A));if(A.minItems!==void 0)Q=Q.min(A.minItems);if(A.length!==void 0)Q=Q.length(A.length);return om(Q,A.optional)}}}function E2Q(A){let{items:Q}=A;switch(Q.type){case"string":return F.string();case"number":return F.number();case"enum":{let B=[...Q.options];return F.enum(B)}case"object":{let B={};for(let[w,$]of Object.entries(Q.fields))B[w]=EPA($);return F.object(B)}}}function LPA(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])=>LPA(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,$])=>LPA(w,$)),B}}}}function M2Q(A,Q){let B={};for(let[f,I]of Object.entries(Q.fields))B[f]=EPA(I);let w=F.object(B),$=new RB(w,{title:Q.title,mappings:Object.entries(Q.fields).map(([f,I])=>LPA(f,I))});return{name:A,description:Q.description,schema:w,formatter:$,requiredPermission:Q.requiredPermission??"public",layout:{component:Q.layout,...Q.fullscreen!==void 0?{fullscreen:Q.fullscreen}:{}},...Q.runtimeScripts?{runtimeScripts:Q.runtimeScripts}:{}}}function MPA(A){return Object.fromEntries(Object.entries(A.sections).map(([Q,B])=>[Q,M2Q(Q,B)]))}GA();var r51=F.object({namespace:F.string(),sections:F.record(F.any())}),d51=F.object({definitions:F.union([r51,F.array(r51)]).optional()});f0();function n51(A,Q){return[xQ(Q,"generate","Generate content for all routes, a specific route, or a specific section",qQA,async(B,w)=>{let $=A();if(!$)return{success:!1,error:"Site content service not initialized"};if(B.sectionId&&!B.routeId)return{success:!1,error:"sectionId requires routeId to be specified"};let f={rootJobId:`generate-${Date.now()}`,progressToken:w.progressToken,pluginId:Q,operationType:"content_operations",interfaceType:w.interfaceType,channelId:w.channelId},I=await $.generateContent(B,f);return{success:!0,message:`Generated ${I.queuedSections} of ${I.totalSections} sections. ${I.queuedSections>0?"Jobs are running in the background.":"No new content to generate."}`,data:{batchId:I.batchId,jobsQueued:I.queuedSections,totalSections:I.totalSections,jobs:I.jobs}}})]}var o51={name:"@brains/site-content",private:!0,version:"0.2.0-alpha.71",description:"Site content entity and generation orchestration",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/plugins":"workspace:*","@brains/site-info":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class VPA extends Ww{siteContentService;constructor(A={}){super("site-content",o51,A,d51)}async onRegister(A){A.entities.register("site-content",nm,zPA);for(let Q of pY(this.config.definitions))A.templates.register(MPA(Q),Q.namespace);this.siteContentService=new CPA(A)}async getTools(){return n51(()=>this.siteContentService,this.id)}}function sm(A={}){return new VPA(A)}f0();GA();Rw();GA();f0();var s51=F.enum(["available","early access","coming soon","planned"]),a51=F.object({title:F.string(),description:F.string()}),UG=F.object({name:F.string(),availability:s51,order:F.number()}),CQA=F.object({tagline:F.string(),promise:F.string(),role:F.string(),purpose:F.string(),audience:F.string(),values:F.array(F.string()).min(1),features:F.array(a51).min(1).max(6),story:F.string()}),b2Q=UG.pick({name:!0,availability:!0,order:!0}).extend({slug:F.string()}),E_=B2.extend({entityType:F.literal("product"),metadata:b2Q}),LQA=E_.extend({frontmatter:UG,body:CQA,labels:F.record(F.string(),F.string())}),EQA=LQA.extend({url:F.string().optional(),typeLabel:F.string().optional(),listUrl:F.string().optional(),listLabel:F.string().optional()});f0();GA();d5();class M_ extends RB{constructor(){super(CQA,{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 bPA extends W2{constructor(){super({entityType:"product",schema:E_,frontmatterSchema:UG,bodyFormatter:new M_})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,UG);return this.buildMarkdown(Q,B)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,UG),B=U2(Q.name);return{content:A,entityType:"product",metadata:{name:Q.name,slug:B,availability:Q.availability,order:Q.order}}}}var MQA=new bPA;GA();f0();var t51=F.object({title:F.string(),description:F.string()}),e51=F.object({title:F.string(),description:F.string()}),O2Q=F.object({title:F.string(),description:F.string()}),A$1=F.object({heading:F.string(),buttonText:F.string(),link:F.string()}),JG=F.object({headline:F.string(),tagline:F.string()}),R2Q=F.object({title:F.string(),description:F.string()}),VQA=F.object({vision:F.string(),pillars:F.array(t51).min(1).max(6),approach:F.array(R2Q).min(1).max(6),productsIntro:F.string(),technologies:F.array(O2Q).min(1).max(6),benefits:F.array(e51).min(1).max(6),cta:A$1}),Q$1=JG.pick({headline:!0}).extend({slug:F.string()}),V_=B2.extend({entityType:F.literal("products-overview"),metadata:Q$1}),am=V_.extend({frontmatter:JG,body:VQA,labels:F.record(F.string(),F.string())});f0();GA();d5();class b_ extends RB{constructor(){super(VQA,{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 OPA extends W2{constructor(){super({entityType:"products-overview",schema:V_,frontmatterSchema:JG,bodyFormatter:new b_})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,JG);return this.buildMarkdown(Q,B)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,JG),B=U2(Q.headline);return{content:A,entityType:"products-overview",metadata:{headline:Q.headline,slug:B}}}}var RPA=new OPA;f0();GA();var _2Q=F.object({entityType:F.string(),query:F.object({id:F.string().optional()}).optional()});function B$1(A,Q){let B=t2(A.content,UG),w=Q.parse(B.content),$=Q.getLabels();return LQA.parse({...A,frontmatter:B.metadata,body:w,labels:$})}function w$1(A,Q){let B=t2(A.content,JG),w=Q.parse(B.content),$=Q.getLabels();return am.parse({...A,frontmatter:B.metadata,body:w,labels:$})}class bQA{logger;id="products:entities";name="Products Entity DataSource";description="Fetches products and overview for the products page";overviewFormatter=new b_;productFormatter=new M_;constructor(A){this.logger=A;this.logger.debug("ProductsDataSource initialized")}async fetch(A,Q,B){let w=_2Q.parse(A),$=B.entityService;if(w.entityType==="products-overview"){let Y=(await $.listEntities({entityType:"products-overview",options:{limit:1}}))[0];if(!Y)throw Error("Products overview entity not found");let W=w$1(Y,this.overviewFormatter);return Q.parse(W)}if(w.query?.id){let Y=(await $.listEntities({entityType:"product",options:{filter:{metadata:{slug:w.query.id}},limit:1}}))[0];if(!Y)throw Error(`Product not found: ${w.query.id}`);return Q.parse({product:B$1(Y,this.productFormatter)})}let[f,I]=await Promise.all([$.listEntities({entityType:"products-overview",options:{limit:1}}),$.listEntities({entityType:"product",options:{sortFields:[{field:"order",direction:"asc"}]}})]),D=f[0];if(!D)throw Error("Products overview entity not found");return Q.parse({overview:w$1(D,this.overviewFormatter),products:I.map((H)=>B$1(H,this.productFormatter))})}}import{jsxDEV as B1,Fragment as j2Q}from"preact/jsx-dev-runtime";var $$1=({overview:A,products:Q})=>{let{frontmatter:B,body:w,labels:$}=A;return B1(j2Q,{children:[B1(XQ,{title:B.headline,description:B.tagline},void 0,!1,void 0,this),B1("header",{className:"relative w-full min-h-[80vh] flex items-end px-6 md:px-12 bg-brand-dark overflow-hidden",children:[B1("style",{children:`
|
|
5640
5640
|
@keyframes wave-drift {
|
|
5641
5641
|
from { transform: translateX(0); }
|
|
5642
5642
|
to { transform: translateX(-50%); }
|
|
@@ -5664,7 +5664,7 @@ ${JSON.stringify(B,null,2)}`}function XQA(A){return A.map((Q)=>Q.detail===null?{
|
|
|
5664
5664
|
@media (prefers-reduced-motion: reduce) {
|
|
5665
5665
|
.detail-wave { animation: none; }
|
|
5666
5666
|
}
|
|
5667
|
-
`},void 0,!1,void 0,this),n1("div",{className:"absolute inset-0 overflow-hidden pointer-events-none",children:n1("svg",{preserveAspectRatio:"none",width:"200%",height:"100%",viewBox:"0 0 1600 400",className:"block absolute inset-0 detail-wave",children:[n1("path",{d:"M0,200 C67,140 133,140 200,200 C267,260 333,260 400,200 C467,140 533,140 600,200 C667,260 733,260 800,200 C867,140 933,140 1000,200 C1067,260 1133,260 1200,200 C1267,140 1333,140 1400,200 C1467,260 1533,260 1600,200",className:"stroke-accent",strokeWidth:"2",strokeMiterlimit:"10",fill:"none",opacity:"0.15"},void 0,!1,void 0,this),n1("path",{d:"M0,230 C67,170 133,170 200,230 C267,290 333,290 400,230 C467,170 533,170 600,230 C667,290 733,290 800,230 C867,170 933,170 1000,230 C1067,290 1133,290 1200,230 C1267,170 1333,170 1400,230 C1467,290 1533,290 1600,230",className:"stroke-accent",strokeWidth:"1.5",strokeMiterlimit:"10",fill:"none",opacity:"0.06"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),n1("div",{className:"absolute inset-0 cta-bg-pattern pointer-events-none"},void 0,!1,void 0,this),n1("div",{className:"relative z-10 max-w-5xl mx-auto w-full px-6 md:px-12 pt-12 md:pt-20 pb-16 md:pb-24",children:[n1("nav",{"aria-label":"Breadcrumb",className:"text-sm text-white/50 mb-8 hero-stagger-1",children:n1("ol",{className:"flex flex-wrap items-center gap-1",children:[n1("li",{className:"flex items-center gap-1",children:n1("a",{href:"/",className:"hover:text-white transition-colors",children:"Home"},void 0,!1,void 0,this)},void 0,!1,void 0,this),n1("li",{className:"flex items-center gap-1",children:[n1("span",{className:"mx-1","aria-hidden":"true",children:"/"},void 0,!1,void 0,this),n1("a",{href:$,className:"hover:text-white transition-colors",children:f},void 0,!1,void 0,this)]},void 0,!0,void 0,this),n1("li",{className:"flex items-center gap-1",children:[n1("span",{className:"mx-1","aria-hidden":"true",children:"/"},void 0,!1,void 0,this),n1("span",{className:"text-white font-medium",children:Q.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),n1("div",{className:"mb-6 hero-stagger-1",children:n1(Lf,{status:Q.availability},void 0,!1,void 0,this)},void 0,!1,void 0,this),n1("h1",{className:"text-5xl md:text-6xl lg:text-[7rem] font-bold text-white tracking-tighter leading-[0.95] mb-6 md:mb-8 hero-stagger-1",children:Q.name},void 0,!1,void 0,this),n1("div",{className:"w-20 h-1.5 bg-accent mb-6 md:mb-8 hero-stagger-2"},void 0,!1,void 0,this),n1("p",{className:"text-lg md:text-xl text-white/70 leading-relaxed max-w-xl hero-stagger-3",children:B.tagline},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),n1("section",{className:"bg-theme-subtle py-20 md:py-28 px-6 md:px-12",children:n1("div",{className:"max-w-4xl mx-auto space-y-16",children:[n1("div",{children:[n1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:w.promise},void 0,!1,void 0,this),n1("p",{className:"text-2xl md:text-3xl lg:text-4xl leading-relaxed text-heading font-light",children:B.promise},void 0,!1,void 0,this)]},void 0,!0,void 0,this),n1("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-12 md:gap-16",children:[n1("div",{children:[n1("div",{className:"w-8 h-1 bg-accent mb-6"},void 0,!1,void 0,this),n1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-4",children:w.role},void 0,!1,void 0,this),n1("p",{className:"text-lg leading-relaxed text-theme-muted",children:B.role},void 0,!1,void 0,this)]},void 0,!0,void 0,this),n1("div",{children:[n1("div",{className:"w-8 h-1 bg-accent mb-6"},void 0,!1,void 0,this),n1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-4",children:w.purpose},void 0,!1,void 0,this),n1("p",{className:"text-lg leading-relaxed text-theme-muted",children:B.purpose},void 0,!1,void 0,this)]},void 0,!0,void 0,this),n1("div",{children:[n1("div",{className:"w-8 h-1 bg-accent mb-6"},void 0,!1,void 0,this),n1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-4",children:w.audience},void 0,!1,void 0,this),n1("p",{className:"text-lg leading-relaxed text-theme-muted",children:B.audience},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),n1("div",{className:"flex flex-col md:flex-row md:items-center gap-6 md:gap-12",children:[n1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted whitespace-nowrap",children:w.values},void 0,!1,void 0,this),n1(NR,{tags:B.values,variant:"accent",size:"md"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),n1("section",{className:"cta-bg-pattern bg-brand py-20 md:py-32 px-6 md:px-12",children:n1("div",{className:"container mx-auto max-w-5xl",children:[n1("h2",{className:"text-sm tracking-widest uppercase text-white/50 mb-16",children:w.features},void 0,!1,void 0,this),n1("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-12 md:gap-16",children:B.features.map((D,H)=>n1("div",{children:n1("div",{className:"flex items-start gap-6",children:[n1("span",{className:"text-5xl md:text-6xl font-black text-white/10 leading-none shrink-0",children:String(H+1).padStart(2,"0")},void 0,!1,void 0,this),n1("div",{className:"pt-2",children:[n1("div",{className:"w-8 h-1 bg-accent mb-4"},void 0,!1,void 0,this),n1("h3",{className:"text-xl font-bold text-white mb-3",children:D.title},void 0,!1,void 0,this),n1("p",{className:"text-white/70 leading-relaxed",children:D.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},D.title,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),n1("section",{className:"py-20 md:py-32 px-6 md:px-12",children:n1("div",{className:"max-w-3xl mx-auto",children:[n1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-12",children:w.story},void 0,!1,void 0,this),n1("div",{className:"space-y-6",children:I.map((D,H)=>n1("p",{className:H===0?"text-2xl md:text-3xl leading-relaxed text-heading font-light":"text-lg leading-relaxed text-theme-muted",children:D},H,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),n1("section",{className:"cta-bg-pattern bg-brand-dark pt-24 md:pt-32 pb-40 md:pb-48 -mb-[60px] px-6 md:px-12",children:n1("div",{className:"max-w-4xl mx-auto",children:[n1("p",{className:"text-sm tracking-widest uppercase text-white/60 mb-4",children:Q.name},void 0,!1,void 0,this),n1("h2",{className:"text-3xl md:text-5xl font-bold text-white max-w-2xl mb-4",children:B.tagline},void 0,!1,void 0,this),n1("p",{className:"text-lg text-white/60 mb-10 max-w-xl",children:B.promise},void 0,!1,void 0,this),n1(b5,{href:$,variant:"outline-light",size:"lg",children:f},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};GA();var _PA=F.object({route:F.string().default("/products")});var I$1={name:"@brains/products",private:!0,version:"0.2.0-alpha.70",description:"Product entity management and overview page for marketing showcase",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var h2Q=F.object({overview:am,products:F.array(EQA)}),y2Q=F.object({product:EQA});class PPA extends KQ{entityType=MQA.entityType;schema=E_;adapter=MQA;constructor(A={}){super("products",I$1,A,_PA)}getTemplates(){return{"product-list":O1({name:"product-list",description:"Products page \u2014 overview + brain model cards",schema:h2Q,dataSourceId:"products:entities",requiredPermission:"public",layout:{component:$$1}}),"product-detail":O1({name:"product-detail",description:"Individual product detail page",schema:y2Q,dataSourceId:"products:entities",requiredPermission:"public",layout:{component:f$1}})}}getDataSources(){return[new bQA(this.logger.child("ProductsDataSource"))]}async onRegister(A){A.entities.register("products-overview",V_,RPA)}}function kPA(A={}){return new PPA(A)}import{join as DQQ}from"path";import{jsxDEV as OQA,Fragment as g2Q}from"preact/jsx-dev-runtime";var O_=({children:A})=>OQA(g2Q,{children:[OQA("div",{id:"bgCanvasWrap",className:"rizom-frame-canvas-wrap fixed top-0 left-0 w-full h-full pointer-events-none",children:OQA("canvas",{id:"heroCanvas",className:"w-full h-full block"},void 0,!1,void 0,this)},void 0,!1,void 0,this),OQA("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 bqw}from"preact/jsx-dev-runtime";import{jsxDEV as S2Q}from"preact/jsx-dev-runtime";var RQA="px-6 md:px-10 xl:px-20",T2Q=`${RQA} relative z-[1]`,aZ=({id:A,className:Q,children:B})=>S2Q("section",{id:A,className:s1(T2Q,Q),children:B},void 0,!1,void 0,this);import{jsxDEV as xqw}from"preact/jsx-dev-runtime";import{jsxDEV as gqw}from"preact/jsx-dev-runtime";import{jsxDEV as l2Q}from"preact/jsx-dev-runtime";var m2Q="inline-flex items-center justify-center cursor-pointer border border-solid transition-all [gap:var(--rizom-btn-gap)] [border-radius:var(--rizom-btn-radius)] [font-family:var(--rizom-btn-font-family)] [font-style:var(--rizom-btn-font-style)] [letter-spacing:var(--rizom-btn-letter-spacing)] [text-transform:var(--rizom-btn-text-transform)]",u2Q={primary:"[font-weight:var(--rizom-btn-primary-font-weight)] [color:var(--rizom-btn-primary-color)] [background:var(--rizom-btn-primary-bg)] [border-color:var(--rizom-btn-primary-border-color)] [border-width:var(--rizom-btn-primary-border-width)] [box-shadow:var(--rizom-btn-primary-shadow)] hover:[color:var(--rizom-btn-primary-hover-color)] hover:[background:var(--rizom-btn-primary-hover-bg)] hover:[border-color:var(--rizom-btn-primary-hover-border-color)] hover:[border-width:var(--rizom-btn-primary-hover-border-width)] hover:[box-shadow:var(--rizom-btn-primary-hover-shadow)] hover:[transform:var(--rizom-btn-primary-hover-transform)]","primary-strong":"duration-400 ease-[cubic-bezier(0.2,0.8,0.2,1)] [font-weight:var(--rizom-btn-primary-strong-font-weight)] [color:var(--rizom-btn-primary-strong-color)] [background:var(--rizom-btn-primary-strong-bg)] [border-color:var(--rizom-btn-primary-strong-border-color)] [border-width:var(--rizom-btn-primary-strong-border-width)] [box-shadow:var(--rizom-btn-primary-strong-shadow)] hover:[color:var(--rizom-btn-primary-strong-hover-color)] hover:[background:var(--rizom-btn-primary-strong-hover-bg)] hover:[border-color:var(--rizom-btn-primary-strong-hover-border-color)] hover:[border-width:var(--rizom-btn-primary-strong-hover-border-width)] hover:[box-shadow:var(--rizom-btn-primary-strong-hover-shadow)] hover:[transform:var(--rizom-btn-primary-strong-hover-transform)]",secondary:"[font-weight:var(--rizom-btn-secondary-font-weight)] [color:var(--rizom-btn-secondary-color)] [background:var(--rizom-btn-secondary-bg)] [border-color:var(--rizom-btn-secondary-border-color)] [border-width:var(--rizom-btn-secondary-border-width)] [box-shadow:var(--rizom-btn-secondary-shadow)] hover:[color:var(--rizom-btn-secondary-hover-color)] hover:[background:var(--rizom-btn-secondary-hover-bg)] hover:[border-color:var(--rizom-btn-secondary-hover-border-color)] hover:[border-width:var(--rizom-btn-secondary-hover-border-width)] hover:[box-shadow:var(--rizom-btn-secondary-hover-shadow)] hover:[transform:var(--rizom-btn-secondary-hover-transform)]"},c2Q={md:"text-base [padding:var(--rizom-btn-md-padding)]",lg:"text-body-md md:text-body-lg [padding:var(--rizom-btn-lg-padding-mobile)] md:[padding:var(--rizom-btn-lg-padding-desktop)]"},p2Q="w-full md:w-auto",iC=({href:A,variant:Q="primary",size:B="md",block:w=!1,className:$,children:f})=>l2Q("a",{href:A,className:s1("rizom-btn",`rizom-btn-${Q}`,`rizom-btn-${B}`,w&&"rizom-btn-block",m2Q,u2Q[Q],c2Q[B],w&&p2Q,$),children:f},void 0,!1,void 0,this);import{jsxDEV as lqw}from"preact/jsx-dev-runtime";import{jsxDEV as nqw}from"preact/jsx-dev-runtime";import{Fragment as aqw}from"preact";import{jsxDEV as eqw}from"preact/jsx-dev-runtime";import{jsxDEV as D$1}from"preact/jsx-dev-runtime";var _QA=({sections:A})=>D$1(O_,{children:D$1("main",{children:A},void 0,!1,void 0,this)},void 0,!1,void 0,this);f0();GA();var H$1=`/*
|
|
5667
|
+
`},void 0,!1,void 0,this),n1("div",{className:"absolute inset-0 overflow-hidden pointer-events-none",children:n1("svg",{preserveAspectRatio:"none",width:"200%",height:"100%",viewBox:"0 0 1600 400",className:"block absolute inset-0 detail-wave",children:[n1("path",{d:"M0,200 C67,140 133,140 200,200 C267,260 333,260 400,200 C467,140 533,140 600,200 C667,260 733,260 800,200 C867,140 933,140 1000,200 C1067,260 1133,260 1200,200 C1267,140 1333,140 1400,200 C1467,260 1533,260 1600,200",className:"stroke-accent",strokeWidth:"2",strokeMiterlimit:"10",fill:"none",opacity:"0.15"},void 0,!1,void 0,this),n1("path",{d:"M0,230 C67,170 133,170 200,230 C267,290 333,290 400,230 C467,170 533,170 600,230 C667,290 733,290 800,230 C867,170 933,170 1000,230 C1067,290 1133,290 1200,230 C1267,170 1333,170 1400,230 C1467,290 1533,290 1600,230",className:"stroke-accent",strokeWidth:"1.5",strokeMiterlimit:"10",fill:"none",opacity:"0.06"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),n1("div",{className:"absolute inset-0 cta-bg-pattern pointer-events-none"},void 0,!1,void 0,this),n1("div",{className:"relative z-10 max-w-5xl mx-auto w-full px-6 md:px-12 pt-12 md:pt-20 pb-16 md:pb-24",children:[n1("nav",{"aria-label":"Breadcrumb",className:"text-sm text-white/50 mb-8 hero-stagger-1",children:n1("ol",{className:"flex flex-wrap items-center gap-1",children:[n1("li",{className:"flex items-center gap-1",children:n1("a",{href:"/",className:"hover:text-white transition-colors",children:"Home"},void 0,!1,void 0,this)},void 0,!1,void 0,this),n1("li",{className:"flex items-center gap-1",children:[n1("span",{className:"mx-1","aria-hidden":"true",children:"/"},void 0,!1,void 0,this),n1("a",{href:$,className:"hover:text-white transition-colors",children:f},void 0,!1,void 0,this)]},void 0,!0,void 0,this),n1("li",{className:"flex items-center gap-1",children:[n1("span",{className:"mx-1","aria-hidden":"true",children:"/"},void 0,!1,void 0,this),n1("span",{className:"text-white font-medium",children:Q.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),n1("div",{className:"mb-6 hero-stagger-1",children:n1(Lf,{status:Q.availability},void 0,!1,void 0,this)},void 0,!1,void 0,this),n1("h1",{className:"text-5xl md:text-6xl lg:text-[7rem] font-bold text-white tracking-tighter leading-[0.95] mb-6 md:mb-8 hero-stagger-1",children:Q.name},void 0,!1,void 0,this),n1("div",{className:"w-20 h-1.5 bg-accent mb-6 md:mb-8 hero-stagger-2"},void 0,!1,void 0,this),n1("p",{className:"text-lg md:text-xl text-white/70 leading-relaxed max-w-xl hero-stagger-3",children:B.tagline},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),n1("section",{className:"bg-theme-subtle py-20 md:py-28 px-6 md:px-12",children:n1("div",{className:"max-w-4xl mx-auto space-y-16",children:[n1("div",{children:[n1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:w.promise},void 0,!1,void 0,this),n1("p",{className:"text-2xl md:text-3xl lg:text-4xl leading-relaxed text-heading font-light",children:B.promise},void 0,!1,void 0,this)]},void 0,!0,void 0,this),n1("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-12 md:gap-16",children:[n1("div",{children:[n1("div",{className:"w-8 h-1 bg-accent mb-6"},void 0,!1,void 0,this),n1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-4",children:w.role},void 0,!1,void 0,this),n1("p",{className:"text-lg leading-relaxed text-theme-muted",children:B.role},void 0,!1,void 0,this)]},void 0,!0,void 0,this),n1("div",{children:[n1("div",{className:"w-8 h-1 bg-accent mb-6"},void 0,!1,void 0,this),n1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-4",children:w.purpose},void 0,!1,void 0,this),n1("p",{className:"text-lg leading-relaxed text-theme-muted",children:B.purpose},void 0,!1,void 0,this)]},void 0,!0,void 0,this),n1("div",{children:[n1("div",{className:"w-8 h-1 bg-accent mb-6"},void 0,!1,void 0,this),n1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-4",children:w.audience},void 0,!1,void 0,this),n1("p",{className:"text-lg leading-relaxed text-theme-muted",children:B.audience},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),n1("div",{className:"flex flex-col md:flex-row md:items-center gap-6 md:gap-12",children:[n1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted whitespace-nowrap",children:w.values},void 0,!1,void 0,this),n1(NR,{tags:B.values,variant:"accent",size:"md"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),n1("section",{className:"cta-bg-pattern bg-brand py-20 md:py-32 px-6 md:px-12",children:n1("div",{className:"container mx-auto max-w-5xl",children:[n1("h2",{className:"text-sm tracking-widest uppercase text-white/50 mb-16",children:w.features},void 0,!1,void 0,this),n1("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-12 md:gap-16",children:B.features.map((D,H)=>n1("div",{children:n1("div",{className:"flex items-start gap-6",children:[n1("span",{className:"text-5xl md:text-6xl font-black text-white/10 leading-none shrink-0",children:String(H+1).padStart(2,"0")},void 0,!1,void 0,this),n1("div",{className:"pt-2",children:[n1("div",{className:"w-8 h-1 bg-accent mb-4"},void 0,!1,void 0,this),n1("h3",{className:"text-xl font-bold text-white mb-3",children:D.title},void 0,!1,void 0,this),n1("p",{className:"text-white/70 leading-relaxed",children:D.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},D.title,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),n1("section",{className:"py-20 md:py-32 px-6 md:px-12",children:n1("div",{className:"max-w-3xl mx-auto",children:[n1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-12",children:w.story},void 0,!1,void 0,this),n1("div",{className:"space-y-6",children:I.map((D,H)=>n1("p",{className:H===0?"text-2xl md:text-3xl leading-relaxed text-heading font-light":"text-lg leading-relaxed text-theme-muted",children:D},H,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),n1("section",{className:"cta-bg-pattern bg-brand-dark pt-24 md:pt-32 pb-40 md:pb-48 -mb-[60px] px-6 md:px-12",children:n1("div",{className:"max-w-4xl mx-auto",children:[n1("p",{className:"text-sm tracking-widest uppercase text-white/60 mb-4",children:Q.name},void 0,!1,void 0,this),n1("h2",{className:"text-3xl md:text-5xl font-bold text-white max-w-2xl mb-4",children:B.tagline},void 0,!1,void 0,this),n1("p",{className:"text-lg text-white/60 mb-10 max-w-xl",children:B.promise},void 0,!1,void 0,this),n1(b5,{href:$,variant:"outline-light",size:"lg",children:f},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};GA();var _PA=F.object({route:F.string().default("/products")});var I$1={name:"@brains/products",private:!0,version:"0.2.0-alpha.71",description:"Product entity management and overview page for marketing showcase",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var h2Q=F.object({overview:am,products:F.array(EQA)}),y2Q=F.object({product:EQA});class PPA extends KQ{entityType=MQA.entityType;schema=E_;adapter=MQA;constructor(A={}){super("products",I$1,A,_PA)}getTemplates(){return{"product-list":O1({name:"product-list",description:"Products page \u2014 overview + brain model cards",schema:h2Q,dataSourceId:"products:entities",requiredPermission:"public",layout:{component:$$1}}),"product-detail":O1({name:"product-detail",description:"Individual product detail page",schema:y2Q,dataSourceId:"products:entities",requiredPermission:"public",layout:{component:f$1}})}}getDataSources(){return[new bQA(this.logger.child("ProductsDataSource"))]}async onRegister(A){A.entities.register("products-overview",V_,RPA)}}function kPA(A={}){return new PPA(A)}import{join as DQQ}from"path";import{jsxDEV as OQA,Fragment as g2Q}from"preact/jsx-dev-runtime";var O_=({children:A})=>OQA(g2Q,{children:[OQA("div",{id:"bgCanvasWrap",className:"rizom-frame-canvas-wrap fixed top-0 left-0 w-full h-full pointer-events-none",children:OQA("canvas",{id:"heroCanvas",className:"w-full h-full block"},void 0,!1,void 0,this)},void 0,!1,void 0,this),OQA("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 bqw}from"preact/jsx-dev-runtime";import{jsxDEV as S2Q}from"preact/jsx-dev-runtime";var RQA="px-6 md:px-10 xl:px-20",T2Q=`${RQA} relative z-[1]`,aZ=({id:A,className:Q,children:B})=>S2Q("section",{id:A,className:s1(T2Q,Q),children:B},void 0,!1,void 0,this);import{jsxDEV as xqw}from"preact/jsx-dev-runtime";import{jsxDEV as gqw}from"preact/jsx-dev-runtime";import{jsxDEV as l2Q}from"preact/jsx-dev-runtime";var m2Q="inline-flex items-center justify-center cursor-pointer border border-solid transition-all [gap:var(--rizom-btn-gap)] [border-radius:var(--rizom-btn-radius)] [font-family:var(--rizom-btn-font-family)] [font-style:var(--rizom-btn-font-style)] [letter-spacing:var(--rizom-btn-letter-spacing)] [text-transform:var(--rizom-btn-text-transform)]",u2Q={primary:"[font-weight:var(--rizom-btn-primary-font-weight)] [color:var(--rizom-btn-primary-color)] [background:var(--rizom-btn-primary-bg)] [border-color:var(--rizom-btn-primary-border-color)] [border-width:var(--rizom-btn-primary-border-width)] [box-shadow:var(--rizom-btn-primary-shadow)] hover:[color:var(--rizom-btn-primary-hover-color)] hover:[background:var(--rizom-btn-primary-hover-bg)] hover:[border-color:var(--rizom-btn-primary-hover-border-color)] hover:[border-width:var(--rizom-btn-primary-hover-border-width)] hover:[box-shadow:var(--rizom-btn-primary-hover-shadow)] hover:[transform:var(--rizom-btn-primary-hover-transform)]","primary-strong":"duration-400 ease-[cubic-bezier(0.2,0.8,0.2,1)] [font-weight:var(--rizom-btn-primary-strong-font-weight)] [color:var(--rizom-btn-primary-strong-color)] [background:var(--rizom-btn-primary-strong-bg)] [border-color:var(--rizom-btn-primary-strong-border-color)] [border-width:var(--rizom-btn-primary-strong-border-width)] [box-shadow:var(--rizom-btn-primary-strong-shadow)] hover:[color:var(--rizom-btn-primary-strong-hover-color)] hover:[background:var(--rizom-btn-primary-strong-hover-bg)] hover:[border-color:var(--rizom-btn-primary-strong-hover-border-color)] hover:[border-width:var(--rizom-btn-primary-strong-hover-border-width)] hover:[box-shadow:var(--rizom-btn-primary-strong-hover-shadow)] hover:[transform:var(--rizom-btn-primary-strong-hover-transform)]",secondary:"[font-weight:var(--rizom-btn-secondary-font-weight)] [color:var(--rizom-btn-secondary-color)] [background:var(--rizom-btn-secondary-bg)] [border-color:var(--rizom-btn-secondary-border-color)] [border-width:var(--rizom-btn-secondary-border-width)] [box-shadow:var(--rizom-btn-secondary-shadow)] hover:[color:var(--rizom-btn-secondary-hover-color)] hover:[background:var(--rizom-btn-secondary-hover-bg)] hover:[border-color:var(--rizom-btn-secondary-hover-border-color)] hover:[border-width:var(--rizom-btn-secondary-hover-border-width)] hover:[box-shadow:var(--rizom-btn-secondary-hover-shadow)] hover:[transform:var(--rizom-btn-secondary-hover-transform)]"},c2Q={md:"text-base [padding:var(--rizom-btn-md-padding)]",lg:"text-body-md md:text-body-lg [padding:var(--rizom-btn-lg-padding-mobile)] md:[padding:var(--rizom-btn-lg-padding-desktop)]"},p2Q="w-full md:w-auto",iC=({href:A,variant:Q="primary",size:B="md",block:w=!1,className:$,children:f})=>l2Q("a",{href:A,className:s1("rizom-btn",`rizom-btn-${Q}`,`rizom-btn-${B}`,w&&"rizom-btn-block",m2Q,u2Q[Q],c2Q[B],w&&p2Q,$),children:f},void 0,!1,void 0,this);import{jsxDEV as lqw}from"preact/jsx-dev-runtime";import{jsxDEV as nqw}from"preact/jsx-dev-runtime";import{Fragment as aqw}from"preact";import{jsxDEV as eqw}from"preact/jsx-dev-runtime";import{jsxDEV as D$1}from"preact/jsx-dev-runtime";var _QA=({sections:A})=>D$1(O_,{children:D$1("main",{children:A},void 0,!1,void 0,this)},void 0,!1,void 0,this);f0();GA();var H$1=`/*
|
|
5668
5668
|
* Shared globals + helpers used by tree / constellation / roots canvas
|
|
5669
5669
|
* scripts. Loaded as a shared static asset by the Rizom runtime package
|
|
5670
5670
|
* so the variant canvases
|
|
@@ -8150,7 +8150,7 @@ facts, owners, or tasks. Return only the required structured JSON.`});GA();var q
|
|
|
8150
8150
|
`).map((Q)=>Q.trim()).find((Q)=>Q.length>0&&!Q.startsWith("#"))??""}var mQQ=5,uQQ=4,l$1=[$6,rI,U4];class cQA{context;constructor(A){this.context=A}async retrieve(A){let Q=A.query?.trim()??"",B=Math.max(1,A.limit??mQQ),w=await this.resolveSpaceId(A),I=(await this.loadCandidates(Q,B)).filter((D)=>{if(!w||A.includeOtherSpaces)return!0;return this.getEntitySpaceId(D.entity)===w}).filter((D)=>this.matchesIdentity(D.entity,A)).sort((D,H)=>{let Y=w?this.getEntitySpaceId(D.entity)===w:!1,W=w?this.getEntitySpaceId(H.entity)===w:!1;if(Y!==W)return Y?-1:1;if(H.score!==D.score)return H.score-D.score;return Date.parse(H.entity.updated)-Date.parse(D.entity.updated)}).slice(0,B).map((D)=>this.toMemory(D));return{query:Q,...w?{spaceId:w}:{},results:I}}async resolveSpaceId(A){if(A.interfaceType&&A.channelId)return HY({interfaceType:A.interfaceType,channelId:A.channelId});if(!A.conversationId)return;let Q=await this.context.conversations.get(A.conversationId);return Q?HY(Q):void 0}async loadCandidates(A,Q){let B=Q*uQQ;if(A.length>0)return(await this.context.entityService.search({query:A,options:{types:l$1,limit:B}})).map((f)=>({entity:f.entity,score:f.score,excerpt:f.excerpt}));return(await Promise.all(l$1.map(($)=>this.context.entityService.listEntities({entityType:$,options:{limit:B,sortFields:[{field:"updated",direction:"desc"}]}})))).flat().map(($)=>({entity:$,score:0,excerpt:$u($)}))}toMemory(A){let{entity:Q}=A,B=Q.metadata;return{id:Q.id,entityType:Q.entityType,conversationId:B.conversationId,spaceId:this.getEntitySpaceId(Q),channelId:B.channelId,...B.channelName?{channelName:B.channelName}:{},interfaceType:B.interfaceType,updated:Q.updated,score:A.score,excerpt:A.excerpt||$u(Q),...Q.entityType===$6?{messageCount:Q.metadata.messageCount,entryCount:Q.metadata.entryCount}:{status:Q.metadata.status}}}matchesIdentity(A,Q){if(!Q.actorId&&!Q.canonicalId)return!0;return this.getIdentityReferences(A).some((B)=>{if(Q.canonicalId&&B.canonicalId===Q.canonicalId)return!0;if(!Q.actorId)return!1;return B.actorId===Q.actorId||B.sourceActorIds?.includes(Q.actorId)===!0})}getIdentityReferences(A){if(this.isSummaryEntity(A))return A.metadata.participants??[];if(this.isDecisionEntity(A))return[...A.metadata.decidedBy??[],...A.metadata.mentionedBy??[]];return[...A.metadata.assignedTo??[],...A.metadata.requestedBy??[]]}isSummaryEntity(A){return A.entityType===$6}isDecisionEntity(A){return A.entityType===rI}getEntitySpaceId(A){let Q=A.metadata;if("spaceId"in Q&&typeof Q.spaceId==="string")return Q.spaceId;return HY(Q)}}var cPA=F.object({role:F.enum(["user","assistant","system"]),content:F.string(),timestamp:F.string().datetime().optional(),actor:nE.optional(),source:oE.optional()}),cQQ=F.object({conversationId:F.string().default("eval-conversation"),messages:F.array(cPA)}),pQQ=F.object({conversationId:F.string()}),lQQ=F.object({conversationId:F.string().default("eval-conversation"),interfaceType:F.string().default("eval"),channelId:F.string().default("eval-channel"),channelName:F.string().optional(),projectionDecision:F.enum(["update","append"]).default("update"),existingSummary:F.string().optional(),existingMessageCount:F.number().int().min(0).default(0),messages:F.array(cPA)}),pQA=F.object({actorId:F.string(),canonicalId:F.string().optional(),displayName:F.string().optional()}),iQQ=pQA.extend({roles:F.array(F.enum(["user","assistant","system"])).default(["user"]),sourceActorIds:F.array(F.string()).optional()}),rQQ=F.object({actorId:F.string().optional(),canonicalId:F.string().optional(),displayName:F.string()}),dQQ=F.object({id:F.string(),entityType:F.enum(["summary","decision","action-item"]),content:F.string(),excerpt:F.string().optional(),score:F.number().optional(),conversationId:F.string(),interfaceType:F.string(),channelId:F.string(),channelName:F.string().optional(),updated:F.string().datetime().optional(),status:F.string().optional(),participants:F.array(iQQ).optional(),decidedBy:F.array(pQA).optional(),mentionedBy:F.array(pQA).optional(),assignedTo:F.array(rQQ).optional(),requestedBy:F.array(pQA).optional()}),nQQ=F.object({query:F.string().optional(),conversationId:F.string().optional(),interfaceType:F.string().optional(),channelId:F.string().optional(),limit:F.number().int().min(1).optional(),includeOtherSpaces:F.boolean().optional(),actorId:F.string().optional(),canonicalId:F.string().optional(),memory:F.array(dQQ).optional()}),oQQ=F.object({conversationId:F.string().default("eval-conversation"),existingSummary:F.string().optional(),existingMessageCount:F.number().int().min(0).default(0),messages:F.array(cPA)});function r$1(A){let{context:Q,logger:B,config:w}=A;Q.eval.registerHandler("summarizeMessages",async($)=>{let f=cQQ.parse($),I=uPA(f.messages,f.conversationId),H=await new v_(Q,B,w).extract(I);return H.entries.map((Y)=>{let W=H.decisions.filter((K)=>K.timeRange.start>=Y.timeRange.start).filter((K)=>K.timeRange.end<=Y.timeRange.end).map((K)=>K.text),G=H.actionItems.filter((K)=>K.timeRange.start>=Y.timeRange.start).filter((K)=>K.timeRange.end<=Y.timeRange.end).map((K)=>K.text);return{...Y,decisions:W,actionItems:G,keyPointsText:Y.keyPoints.join(`
|
|
8151
8151
|
`),decisionsText:W.join(`
|
|
8152
8152
|
`),actionItemsText:G.join(`
|
|
8153
|
-
`)}})}),Q.eval.registerHandler("decideProjection",async($)=>{let f=oQQ.parse($),I=uPA(f.messages,f.conversationId),D=f.existingSummary?i$1({conversationId:f.conversationId,content:f.existingSummary,messageCount:f.existingMessageCount,projectionVersion:w.projectionVersion}):null;return new eZ(Q,B,w).decideProjection(I,D)}),Q.eval.registerHandler("retrieveMemory",async($)=>{let f=nQQ.parse($),I=f.memory?tQQ(Q,f.memory):Q;return new cQA(I).retrieve(f)}),Q.eval.registerHandler("projectMessages",async($)=>{let f=lQQ.parse($),I=uPA(f.messages,f.conversationId),D=sQQ({conversationId:f.conversationId,interfaceType:f.interfaceType,channelId:f.channelId,channelName:f.channelName,messages:I}),H=f.existingSummary?i$1({conversationId:f.conversationId,content:f.existingSummary,messageCount:f.existingMessageCount,projectionVersion:w.projectionVersion}):null,Y=[],W=[],G=aQQ({context:Q,conversation:D,messages:I,existing:H,upserted:Y,deleted:W,projectionDecision:f.projectionDecision});return{result:await new eZ(G,B,w).projectConversation(f.conversationId),summaries:Y.filter((q)=>q.entityType==="summary"),decisions:Y.filter((q)=>q.entityType==="decision"),actionItems:Y.filter((q)=>q.entityType==="action-item"),deleted:W}}),Q.eval.registerHandler("projectConversation",async($)=>{let f=pQQ.parse($);return new eZ(Q,B,w).projectConversation(f.conversationId)})}function i$1(A){return{id:A.conversationId,entityType:"summary",content:A.content,contentHash:"eval-existing-summary",created:"2026-01-01T00:00:00.000Z",updated:"2026-01-01T00:00:00.000Z",metadata:{conversationId:A.conversationId,channelId:"eval-channel",interfaceType:"eval",messageCount:A.messageCount,entryCount:1,sourceHash:"eval-source-hash",projectionVersion:A.projectionVersion}}}function uPA(A,Q){return A.map((B,w)=>{let $=B.timestamp??new Date(Date.UTC(2026,0,1,0,w)).toISOString();return{id:`eval-message-${w+1}`,conversationId:Q,role:B.role,content:B.content,timestamp:$,metadata:{...B.actor?{actor:B.actor}:{},...B.source?{source:B.source}:{}}}})}function sQQ(A){let Q=A.messages[0],B=A.messages[A.messages.length-1],w=Q?.timestamp??"2026-01-01T00:00:00.000Z",$=B?.timestamp??w;return{id:A.conversationId,sessionId:A.conversationId,interfaceType:A.interfaceType,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},startedAt:w,lastActiveAt:$,createdAt:w,updatedAt:$,metadata:{}}}function aQQ(A){let Q=HY(A.conversation);return{...A.context,spaces:[Q],conversations:{...A.context.conversations,get:async()=>A.conversation,getMessages:async()=>A.messages},ai:{...A.context.ai,generateObject:async()=>({object:{decision:A.projectionDecision,rationale:"Forced by eval input"}})},entityService:{...A.context.entityService,getEntity:async({entityType:B})=>B==="summary"?A.existing:null,listEntities:async()=>[],deleteEntity:async(B)=>{return A.deleted.push(B),!0},upsertEntity:async({entity:B})=>{return A.upserted.push(B),{entityId:B.id,jobId:"eval-upsert",created:!0,skipped:!1}}}}}function tQQ(A,Q){let B=Q.map(eQQ),w=B.map(($,f)=>({entity:$,score:Q[f]?.score??1,excerpt:Q[f]?.excerpt??$u($)}));return{...A,entityService:{...A.entityService,search:async()=>w,listEntities:async({entityType:$})=>B.filter((f)=>f.entityType===$)}}}function eQQ(A){if(A.entityType==="summary")return ABQ(A);if(A.entityType==="decision")return QBQ(A);return BBQ(A)}function pPA(A){let Q=A.updated??"2026-01-01T00:00:00.000Z";return{id:A.id,content:A.content,contentHash:xB(A.content),created:Q,updated:Q}}function ABQ(A){return{...pPA(A),entityType:"summary",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,messageCount:3,entryCount:1,sourceHash:`source-${A.id}`,projectionVersion:1,...A.participants?{participants:A.participants}:{}}}}function QBQ(A){return{...pPA(A),entityType:"decision",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,spaceId:HY(A),timeRange:{start:"2026-01-01T00:00:00.000Z",end:"2026-01-01T00:01:00.000Z"},sourceSummaryId:A.conversationId,sourceMessageCount:2,projectionVersion:1,status:A.status==="superseded"?"superseded":"active",...A.decidedBy?{decidedBy:A.decidedBy}:{},...A.mentionedBy?{mentionedBy:A.mentionedBy}:{}}}}function BBQ(A){let Q=A.status==="done"||A.status==="dropped"?A.status:"open";return{...pPA(A),entityType:"action-item",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,spaceId:HY(A),timeRange:{start:"2026-01-01T00:00:00.000Z",end:"2026-01-01T00:01:00.000Z"},sourceSummaryId:A.conversationId,sourceMessageCount:2,projectionVersion:1,status:Q,...A.assignedTo?{assignedTo:A.assignedTo}:{},...A.requestedBy?{requestedBy:A.requestedBy}:{}}}}var d$1={name:"@brains/conversation-memory",private:!0,version:"0.2.0-alpha.70",description:"Plugin for deriving durable conversation memory",type:"module",main:"./src/index.ts",exports:{".":"./src/index.ts"},scripts:{test:"bun test",typecheck:"tsc --noEmit",lint:"eslint src test --ext .ts,.tsx",eval:"cd evals && bun run brain-eval","lint:fix":"eslint src test --ext .ts,.tsx --fix"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/conversation-service":"workspace:*","@brains/dashboard":"workspace:*","@brains/plugins":"workspace:*","@brains/templates":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/node":"^20.0.0",eslint:"^8.56.0",typescript:"^5.3.3"}};var $BQ=new zW,fBQ=new P_,IBQ=new k_,DBQ=F.object({conversationId:F.string()});class lPA extends KQ{entityType=$6;schema=em;adapter=$BQ;constructor(A={}){super(kQA,d$1,A,hPA)}getConfig(){return this.config}getTemplates(){return{"summary-list":E$1,"summary-detail":M$1,"ai-response":V$1}}getDataSources(){return[new mPA(this.logger.child("SummaryDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableProjection)return[];return[{id:"conversation-memory-projection",targetType:$6,job:{type:K$1,handler:new gQA(A,this.logger,this.config)},initialSync:{shouldEnqueue:async()=>A.spaces.length>0&&!await qN(A,$6),jobData:{mode:"rebuild-all",reason:"initial-sync"},jobOptions:{source:xPA,deduplication:"coalesce",deduplicationKey:"conversation-memory:rebuild-all:initial-sync",metadata:{operationType:"data_processing",operationTarget:"conversation-memory:rebuild-all",pluginId:kQA}}},sourceChange:{sourceKind:yl,sourceTypes:[yl],shouldEnqueue:(Q)=>this.shouldEnqueueConversationProjection(A,Q),events:[Dj],jobData:(Q)=>{let{conversationId:B}=this.parseConversationMessagePayload(Q);return{mode:"conversation",conversationId:B,reason:"message-added"}},jobOptions:(Q)=>{let{conversationId:B}=this.parseConversationMessagePayload(Q);return{priority:5,delayMs:this.config.projectionDelayMs,source:xPA,deduplication:"skip",deduplicationKey:`conversation-memory:${B}`,metadata:{operationType:"data_processing",operationTarget:`conversation-memory:${B}`,pluginId:kQA}}}}}]}parseConversationMessagePayload(A){return DBQ.parse(A)}async shouldEnqueueConversationProjection(A,Q){let{conversationId:B}=this.parseConversationMessagePayload(Q),w=await A.conversations.get(B);if(!w)return!1;return nC({conversation:w,spaces:A.spaces}).eligible}async onRegister(A){A.entities.register(rI,Au,fBQ),A.entities.register(U4,Qu,IBQ),R$1({context:A,pluginId:this.id}),P$1({context:A,pluginId:this.id}),m$1({context:A,pluginId:this.id}),p$1({context:A,pluginId:this.id,config:this.config}),r$1({context:A,logger:this.logger,config:this.config})}}function iPA(A){return new lPA(A)}f0();GA();f0();var GG=F.object({title:F.string(),section:F.string(),order:F.number().int(),sourcePath:F.string(),description:F.string().optional(),slug:F.string().optional()}),n$1=GG.pick({title:!0,section:!0,order:!0,description:!0}).extend({slug:F.string()}),y_=B2.extend({entityType:F.literal("doc"),metadata:n$1}),FG=y_.extend({frontmatter:GG,body:F.string()});f0();GA();class rPA extends W2{constructor(){super({entityType:"doc",schema:y_,frontmatterSchema:GG})}toMarkdown(A){let Q=this.extractBody(A.content),B=this.parseFrontMatter(A.content,GG);return this.buildMarkdown(Q,B)}fromMarkdown(A){let Q=this.parseFrontMatter(A,GG),B=Q.slug??U2(Q.title);return{content:A,entityType:"doc",metadata:{title:Q.title,section:Q.section,order:Q.order,slug:B,...Q.description?{description:Q.description}:{}}}}}var lQA=new rPA;f0();function o$1(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 s$1(A){let Q=t2(A.content,GG);return FG.parse({...A,frontmatter:Q.metadata,body:Q.content})}class iQA extends r6{id="docs:entities";name="Docs Entity DataSource";description="Fetches and transforms doc entities for rendering";config={entityType:"doc",defaultSort:[{field:"order",direction:"asc"},{field:"section",direction:"asc"},{field:"title",direction:"asc"}],defaultLimit:100,enableNavigation:!0};constructor(A){super(A)}transformEntity(A){return s$1(A)}async fetch(A,Q,B){let w=this.parseQuery(A);if(!w.query.id){let W=await this.fetchList({...w.query,limit:1000,page:void 0,pageSize:void 0},B.entityService);return Q.parse(this.buildListResult(W.items,null,w.query))}let[$,f]=await Promise.all([this.fetchDetail(w.query.id,B.entityService),this.fetchList({limit:1000},B.entityService)]),I=o$1(f.items),D=I.findIndex((W)=>W.id===$.item.id),H=D>0?I[D-1]:null,Y=D>=0&&D<I.length-1?I[D+1]:null;return Q.parse({doc:$.item,docs:I,prevDoc:H,nextDoc:Y})}buildDetailResult(A,Q){return{doc:A,docs:[A],prevDoc:Q?.prev??null,nextDoc:Q?.next??null}}buildListResult(A,Q,B){return{docs:o$1(A),pagination:Q,baseUrl:B.baseUrl}}}f0();Rw();GA();import{jsxDEV as H5}from"preact/jsx-dev-runtime";var HBQ=["I","II","III","IV","V","VI","VII","VIII","IX","X"];function fu(A){return[...A].sort((Q,B)=>{let w=Q.metadata.order-B.metadata.order;if(w!==0)return w;return Q.metadata.title.localeCompare(B.metadata.title)})}function rQA(A){let Q=new Map;for(let B of fu(A)){let w=B.metadata.section;Q.set(w,[...Q.get(w)??[],B])}return[...Q.entries()].map(([B,w])=>({section:B,docs:w}))}function g_(A){return`/docs/${A.metadata.slug}`}function dQA(A){return`section-${A+1}`}function T_(A){return HBQ[A]??String(A+1)}var e$1="text-[var(--docs-text)] font-bold",A91="text-[var(--docs-accent)] font-bold",Q91="text-[var(--docs-text-muted)]",YBQ="docs-font-label text-xs uppercase tracking-[0.18em] text-[var(--docs-accent)]",XBQ="docs-font-display text-[var(--docs-heading)]",a$1="inline-flex items-center justify-center rounded-lg border px-[18px] py-2.5 text-sm font-semibold transition-colors duration-150",t$1="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",dPA="docs-font-label text-[13px] text-[var(--docs-text-light)] transition-colors duration-150 hover:text-[var(--docs-text)]",qW={wrap:"mx-auto max-w-6xl px-6 pt-20 md:px-12 md:pt-24",label:YBQ,display:XBQ,button:`${a$1} border-[var(--docs-text)] text-[var(--docs-text)] hover:border-[var(--docs-accent)] hover:text-[var(--docs-accent)]`,primaryButton:`${a$1} border-[var(--docs-accent)] bg-[var(--docs-accent)] text-white hover:bg-transparent hover:text-[var(--docs-accent)]`},B91=()=>H5("nav",{className:"docs-header fixed inset-x-0 top-0 z-[100] flex items-center justify-between px-6 py-4 md:px-10 md:py-5 xl:px-20",children:[H5("a",{href:"/docs",className:"docs-font-body text-xl font-bold","aria-label":"Brains docs",children:[H5("span",{className:e$1,children:"brains"},void 0,!1,void 0,this),H5("span",{className:A91,children:"."},void 0,!1,void 0,this),H5("span",{className:Q91,children:"docs"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),H5("div",{className:"docs-header__nav flex items-center gap-4 md:gap-8",children:[H5("a",{className:t$1,href:"/docs/roadmap",children:"Roadmap"},void 0,!1,void 0,this),H5("a",{className:t$1,href:"https://github.com/rizom-ai/brains",children:"GitHub"},void 0,!1,void 0,this),H5("a",{href:"https://rizom.ai",className:"inline-flex items-center justify-center rounded-lg border border-[var(--docs-text)] px-4 py-2 text-[13px] font-semibold text-[var(--docs-text)] transition-colors duration-150 hover:border-[var(--docs-accent)] hover:text-[var(--docs-accent)] md:px-6 md:py-2.5 md:text-[15px]",children:"Get Brains"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),w91=()=>H5("footer",{className:"flex flex-col items-center justify-between gap-4 border-t border-[var(--docs-border-light)] py-8 text-center md:flex-row md:gap-6 md:py-6 md:text-left",children:[H5("a",{href:"https://rizom.ai",className:"docs-font-body text-[15px] font-bold",children:[H5("span",{className:e$1,children:"rizom"},void 0,!1,void 0,this),H5("span",{className:A91,children:"."},void 0,!1,void 0,this),H5("span",{className:Q91,children:"ai"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),H5("div",{className:"flex flex-wrap items-center justify-center gap-6 md:justify-end",children:[H5("a",{className:dPA,href:"/docs/roadmap",children:"Roadmap"},void 0,!1,void 0,this),H5("a",{className:dPA,href:"https://github.com/rizom-ai/brains",children:"GitHub"},void 0,!1,void 0,this),H5("a",{className:dPA,href:"https://rizom.ai",children:"Rizom"},void 0,!1,void 0,this),H5("button",{id:"themeToggle",className:"docs-font-label cursor-pointer rounded-md border border-[var(--docs-text-light)] bg-transparent px-2.5 py-1.5 text-[13px] text-[var(--docs-text-light)] transition-colors duration-150 hover:border-[var(--docs-text)] hover:text-[var(--docs-text)]",type:"button",children:"\u2600 Light"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),WBQ=`
|
|
8153
|
+
`)}})}),Q.eval.registerHandler("decideProjection",async($)=>{let f=oQQ.parse($),I=uPA(f.messages,f.conversationId),D=f.existingSummary?i$1({conversationId:f.conversationId,content:f.existingSummary,messageCount:f.existingMessageCount,projectionVersion:w.projectionVersion}):null;return new eZ(Q,B,w).decideProjection(I,D)}),Q.eval.registerHandler("retrieveMemory",async($)=>{let f=nQQ.parse($),I=f.memory?tQQ(Q,f.memory):Q;return new cQA(I).retrieve(f)}),Q.eval.registerHandler("projectMessages",async($)=>{let f=lQQ.parse($),I=uPA(f.messages,f.conversationId),D=sQQ({conversationId:f.conversationId,interfaceType:f.interfaceType,channelId:f.channelId,channelName:f.channelName,messages:I}),H=f.existingSummary?i$1({conversationId:f.conversationId,content:f.existingSummary,messageCount:f.existingMessageCount,projectionVersion:w.projectionVersion}):null,Y=[],W=[],G=aQQ({context:Q,conversation:D,messages:I,existing:H,upserted:Y,deleted:W,projectionDecision:f.projectionDecision});return{result:await new eZ(G,B,w).projectConversation(f.conversationId),summaries:Y.filter((q)=>q.entityType==="summary"),decisions:Y.filter((q)=>q.entityType==="decision"),actionItems:Y.filter((q)=>q.entityType==="action-item"),deleted:W}}),Q.eval.registerHandler("projectConversation",async($)=>{let f=pQQ.parse($);return new eZ(Q,B,w).projectConversation(f.conversationId)})}function i$1(A){return{id:A.conversationId,entityType:"summary",content:A.content,contentHash:"eval-existing-summary",created:"2026-01-01T00:00:00.000Z",updated:"2026-01-01T00:00:00.000Z",metadata:{conversationId:A.conversationId,channelId:"eval-channel",interfaceType:"eval",messageCount:A.messageCount,entryCount:1,sourceHash:"eval-source-hash",projectionVersion:A.projectionVersion}}}function uPA(A,Q){return A.map((B,w)=>{let $=B.timestamp??new Date(Date.UTC(2026,0,1,0,w)).toISOString();return{id:`eval-message-${w+1}`,conversationId:Q,role:B.role,content:B.content,timestamp:$,metadata:{...B.actor?{actor:B.actor}:{},...B.source?{source:B.source}:{}}}})}function sQQ(A){let Q=A.messages[0],B=A.messages[A.messages.length-1],w=Q?.timestamp??"2026-01-01T00:00:00.000Z",$=B?.timestamp??w;return{id:A.conversationId,sessionId:A.conversationId,interfaceType:A.interfaceType,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},startedAt:w,lastActiveAt:$,createdAt:w,updatedAt:$,metadata:{}}}function aQQ(A){let Q=HY(A.conversation);return{...A.context,spaces:[Q],conversations:{...A.context.conversations,get:async()=>A.conversation,getMessages:async()=>A.messages},ai:{...A.context.ai,generateObject:async()=>({object:{decision:A.projectionDecision,rationale:"Forced by eval input"}})},entityService:{...A.context.entityService,getEntity:async({entityType:B})=>B==="summary"?A.existing:null,listEntities:async()=>[],deleteEntity:async(B)=>{return A.deleted.push(B),!0},upsertEntity:async({entity:B})=>{return A.upserted.push(B),{entityId:B.id,jobId:"eval-upsert",created:!0,skipped:!1}}}}}function tQQ(A,Q){let B=Q.map(eQQ),w=B.map(($,f)=>({entity:$,score:Q[f]?.score??1,excerpt:Q[f]?.excerpt??$u($)}));return{...A,entityService:{...A.entityService,search:async()=>w,listEntities:async({entityType:$})=>B.filter((f)=>f.entityType===$)}}}function eQQ(A){if(A.entityType==="summary")return ABQ(A);if(A.entityType==="decision")return QBQ(A);return BBQ(A)}function pPA(A){let Q=A.updated??"2026-01-01T00:00:00.000Z";return{id:A.id,content:A.content,contentHash:xB(A.content),created:Q,updated:Q}}function ABQ(A){return{...pPA(A),entityType:"summary",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,messageCount:3,entryCount:1,sourceHash:`source-${A.id}`,projectionVersion:1,...A.participants?{participants:A.participants}:{}}}}function QBQ(A){return{...pPA(A),entityType:"decision",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,spaceId:HY(A),timeRange:{start:"2026-01-01T00:00:00.000Z",end:"2026-01-01T00:01:00.000Z"},sourceSummaryId:A.conversationId,sourceMessageCount:2,projectionVersion:1,status:A.status==="superseded"?"superseded":"active",...A.decidedBy?{decidedBy:A.decidedBy}:{},...A.mentionedBy?{mentionedBy:A.mentionedBy}:{}}}}function BBQ(A){let Q=A.status==="done"||A.status==="dropped"?A.status:"open";return{...pPA(A),entityType:"action-item",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,spaceId:HY(A),timeRange:{start:"2026-01-01T00:00:00.000Z",end:"2026-01-01T00:01:00.000Z"},sourceSummaryId:A.conversationId,sourceMessageCount:2,projectionVersion:1,status:Q,...A.assignedTo?{assignedTo:A.assignedTo}:{},...A.requestedBy?{requestedBy:A.requestedBy}:{}}}}var d$1={name:"@brains/conversation-memory",private:!0,version:"0.2.0-alpha.71",description:"Plugin for deriving durable conversation memory",type:"module",main:"./src/index.ts",exports:{".":"./src/index.ts"},scripts:{test:"bun test",typecheck:"tsc --noEmit",lint:"eslint src test --ext .ts,.tsx",eval:"cd evals && bun run brain-eval","lint:fix":"eslint src test --ext .ts,.tsx --fix"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/conversation-service":"workspace:*","@brains/dashboard":"workspace:*","@brains/plugins":"workspace:*","@brains/templates":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/node":"^20.0.0",eslint:"^8.56.0",typescript:"^5.3.3"}};var $BQ=new zW,fBQ=new P_,IBQ=new k_,DBQ=F.object({conversationId:F.string()});class lPA extends KQ{entityType=$6;schema=em;adapter=$BQ;constructor(A={}){super(kQA,d$1,A,hPA)}getConfig(){return this.config}getTemplates(){return{"summary-list":E$1,"summary-detail":M$1,"ai-response":V$1}}getDataSources(){return[new mPA(this.logger.child("SummaryDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableProjection)return[];return[{id:"conversation-memory-projection",targetType:$6,job:{type:K$1,handler:new gQA(A,this.logger,this.config)},initialSync:{shouldEnqueue:async()=>A.spaces.length>0&&!await qN(A,$6),jobData:{mode:"rebuild-all",reason:"initial-sync"},jobOptions:{source:xPA,deduplication:"coalesce",deduplicationKey:"conversation-memory:rebuild-all:initial-sync",metadata:{operationType:"data_processing",operationTarget:"conversation-memory:rebuild-all",pluginId:kQA}}},sourceChange:{sourceKind:yl,sourceTypes:[yl],shouldEnqueue:(Q)=>this.shouldEnqueueConversationProjection(A,Q),events:[Dj],jobData:(Q)=>{let{conversationId:B}=this.parseConversationMessagePayload(Q);return{mode:"conversation",conversationId:B,reason:"message-added"}},jobOptions:(Q)=>{let{conversationId:B}=this.parseConversationMessagePayload(Q);return{priority:5,delayMs:this.config.projectionDelayMs,source:xPA,deduplication:"skip",deduplicationKey:`conversation-memory:${B}`,metadata:{operationType:"data_processing",operationTarget:`conversation-memory:${B}`,pluginId:kQA}}}}}]}parseConversationMessagePayload(A){return DBQ.parse(A)}async shouldEnqueueConversationProjection(A,Q){let{conversationId:B}=this.parseConversationMessagePayload(Q),w=await A.conversations.get(B);if(!w)return!1;return nC({conversation:w,spaces:A.spaces}).eligible}async onRegister(A){A.entities.register(rI,Au,fBQ),A.entities.register(U4,Qu,IBQ),R$1({context:A,pluginId:this.id}),P$1({context:A,pluginId:this.id}),m$1({context:A,pluginId:this.id}),p$1({context:A,pluginId:this.id,config:this.config}),r$1({context:A,logger:this.logger,config:this.config})}}function iPA(A){return new lPA(A)}f0();GA();f0();var GG=F.object({title:F.string(),section:F.string(),order:F.number().int(),sourcePath:F.string(),description:F.string().optional(),slug:F.string().optional()}),n$1=GG.pick({title:!0,section:!0,order:!0,description:!0}).extend({slug:F.string()}),y_=B2.extend({entityType:F.literal("doc"),metadata:n$1}),FG=y_.extend({frontmatter:GG,body:F.string()});f0();GA();class rPA extends W2{constructor(){super({entityType:"doc",schema:y_,frontmatterSchema:GG})}toMarkdown(A){let Q=this.extractBody(A.content),B=this.parseFrontMatter(A.content,GG);return this.buildMarkdown(Q,B)}fromMarkdown(A){let Q=this.parseFrontMatter(A,GG),B=Q.slug??U2(Q.title);return{content:A,entityType:"doc",metadata:{title:Q.title,section:Q.section,order:Q.order,slug:B,...Q.description?{description:Q.description}:{}}}}}var lQA=new rPA;f0();function o$1(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 s$1(A){let Q=t2(A.content,GG);return FG.parse({...A,frontmatter:Q.metadata,body:Q.content})}class iQA extends r6{id="docs:entities";name="Docs Entity DataSource";description="Fetches and transforms doc entities for rendering";config={entityType:"doc",defaultSort:[{field:"order",direction:"asc"},{field:"section",direction:"asc"},{field:"title",direction:"asc"}],defaultLimit:100,enableNavigation:!0};constructor(A){super(A)}transformEntity(A){return s$1(A)}async fetch(A,Q,B){let w=this.parseQuery(A);if(!w.query.id){let W=await this.fetchList({...w.query,limit:1000,page:void 0,pageSize:void 0},B.entityService);return Q.parse(this.buildListResult(W.items,null,w.query))}let[$,f]=await Promise.all([this.fetchDetail(w.query.id,B.entityService),this.fetchList({limit:1000},B.entityService)]),I=o$1(f.items),D=I.findIndex((W)=>W.id===$.item.id),H=D>0?I[D-1]:null,Y=D>=0&&D<I.length-1?I[D+1]:null;return Q.parse({doc:$.item,docs:I,prevDoc:H,nextDoc:Y})}buildDetailResult(A,Q){return{doc:A,docs:[A],prevDoc:Q?.prev??null,nextDoc:Q?.next??null}}buildListResult(A,Q,B){return{docs:o$1(A),pagination:Q,baseUrl:B.baseUrl}}}f0();Rw();GA();import{jsxDEV as H5}from"preact/jsx-dev-runtime";var HBQ=["I","II","III","IV","V","VI","VII","VIII","IX","X"];function fu(A){return[...A].sort((Q,B)=>{let w=Q.metadata.order-B.metadata.order;if(w!==0)return w;return Q.metadata.title.localeCompare(B.metadata.title)})}function rQA(A){let Q=new Map;for(let B of fu(A)){let w=B.metadata.section;Q.set(w,[...Q.get(w)??[],B])}return[...Q.entries()].map(([B,w])=>({section:B,docs:w}))}function g_(A){return`/docs/${A.metadata.slug}`}function dQA(A){return`section-${A+1}`}function T_(A){return HBQ[A]??String(A+1)}var e$1="text-[var(--docs-text)] font-bold",A91="text-[var(--docs-accent)] font-bold",Q91="text-[var(--docs-text-muted)]",YBQ="docs-font-label text-xs uppercase tracking-[0.18em] text-[var(--docs-accent)]",XBQ="docs-font-display text-[var(--docs-heading)]",a$1="inline-flex items-center justify-center rounded-lg border px-[18px] py-2.5 text-sm font-semibold transition-colors duration-150",t$1="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",dPA="docs-font-label text-[13px] text-[var(--docs-text-light)] transition-colors duration-150 hover:text-[var(--docs-text)]",qW={wrap:"mx-auto max-w-6xl px-6 pt-20 md:px-12 md:pt-24",label:YBQ,display:XBQ,button:`${a$1} border-[var(--docs-text)] text-[var(--docs-text)] hover:border-[var(--docs-accent)] hover:text-[var(--docs-accent)]`,primaryButton:`${a$1} border-[var(--docs-accent)] bg-[var(--docs-accent)] text-white hover:bg-transparent hover:text-[var(--docs-accent)]`},B91=()=>H5("nav",{className:"docs-header fixed inset-x-0 top-0 z-[100] flex items-center justify-between px-6 py-4 md:px-10 md:py-5 xl:px-20",children:[H5("a",{href:"/docs",className:"docs-font-body text-xl font-bold","aria-label":"Brains docs",children:[H5("span",{className:e$1,children:"brains"},void 0,!1,void 0,this),H5("span",{className:A91,children:"."},void 0,!1,void 0,this),H5("span",{className:Q91,children:"docs"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),H5("div",{className:"docs-header__nav flex items-center gap-4 md:gap-8",children:[H5("a",{className:t$1,href:"/docs/roadmap",children:"Roadmap"},void 0,!1,void 0,this),H5("a",{className:t$1,href:"https://github.com/rizom-ai/brains",children:"GitHub"},void 0,!1,void 0,this),H5("a",{href:"https://rizom.ai",className:"inline-flex items-center justify-center rounded-lg border border-[var(--docs-text)] px-4 py-2 text-[13px] font-semibold text-[var(--docs-text)] transition-colors duration-150 hover:border-[var(--docs-accent)] hover:text-[var(--docs-accent)] md:px-6 md:py-2.5 md:text-[15px]",children:"Get Brains"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),w91=()=>H5("footer",{className:"flex flex-col items-center justify-between gap-4 border-t border-[var(--docs-border-light)] py-8 text-center md:flex-row md:gap-6 md:py-6 md:text-left",children:[H5("a",{href:"https://rizom.ai",className:"docs-font-body text-[15px] font-bold",children:[H5("span",{className:e$1,children:"rizom"},void 0,!1,void 0,this),H5("span",{className:A91,children:"."},void 0,!1,void 0,this),H5("span",{className:Q91,children:"ai"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),H5("div",{className:"flex flex-wrap items-center justify-center gap-6 md:justify-end",children:[H5("a",{className:dPA,href:"/docs/roadmap",children:"Roadmap"},void 0,!1,void 0,this),H5("a",{className:dPA,href:"https://github.com/rizom-ai/brains",children:"GitHub"},void 0,!1,void 0,this),H5("a",{className:dPA,href:"https://rizom.ai",children:"Rizom"},void 0,!1,void 0,this),H5("button",{id:"themeToggle",className:"docs-font-label cursor-pointer rounded-md border border-[var(--docs-text-light)] bg-transparent px-2.5 py-1.5 text-[13px] text-[var(--docs-text-light)] transition-colors duration-150 hover:border-[var(--docs-text)] hover:text-[var(--docs-text)]",type:"button",children:"\u2600 Light"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),WBQ=`
|
|
8154
8154
|
.docs-handbook {
|
|
8155
8155
|
--docs-bg: var(--color-bg, #0d0a1a);
|
|
8156
8156
|
--docs-bg-card: var(--color-bg-card, #1a0a3e);
|
|
@@ -8302,7 +8302,7 @@ facts, owners, or tasks. Return only the required structured JSON.`});GA();var q
|
|
|
8302
8302
|
background: transparent;
|
|
8303
8303
|
}
|
|
8304
8304
|
|
|
8305
|
-
`,$91=()=>H5("style",{children:WBQ},void 0,!1,void 0,this);import{jsxDEV as Y2,Fragment as UBQ}from"preact/jsx-dev-runtime";var nQA=({title:A,description:Q,children:B,detail:w=!1,footer:$=!1,contentClassName:f=""})=>Y2(UBQ,{children:[Y2(XQ,{title:A,description:Q},void 0,!1,void 0,this),Y2($91,{},void 0,!1,void 0,this),Y2("div",{className:`docs-handbook${w?" docs-handbook--detail":""}`,children:[Y2(B91,{},void 0,!1,void 0,this),Y2("div",{className:`${qW.wrap} ${f}`.trim(),children:[B,$&&Y2(w91,{},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),f91=({docsCount:A,sectionsCount:Q,startDoc:B})=>Y2("section",{className:"border-b border-[var(--docs-text)] py-14 md:py-24 md:pb-[72px]",children:[Y2("p",{className:`${qW.label} mb-8`,children:"Handbook \xB7 Brains docs"},void 0,!1,void 0,this),Y2("h1",{className:`${qW.display} m-0 max-w-[16ch] text-5xl leading-[1.05] tracking-[-0.02em] md:text-7xl`,children:["Build, run, and publish"," ",Y2("em",{className:"text-[var(--docs-accent)]",children:"brains."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Y2("p",{className:"mt-8 max-w-[52ch] text-lg leading-[1.65] text-[var(--docs-text-muted)]",children:"Documentation for composing brain models, managing markdown entities, wiring interfaces, and shipping generated sites."},void 0,!1,void 0,this),Y2("dl",{className:"mt-10 flex flex-wrap gap-7 docs-font-label text-xs tracking-[0.06em] text-[var(--docs-text-light)] md:mt-14 md:gap-12",children:[Y2("div",{children:[Y2("strong",{className:"mb-0.5 block font-medium text-[var(--docs-text)]",children:A},void 0,!1,void 0,this),"Documents"]},void 0,!0,void 0,this),Y2("div",{children:[Y2("strong",{className:"mb-0.5 block font-medium text-[var(--docs-text)]",children:Q},void 0,!1,void 0,this),"Sections"]},void 0,!0,void 0,this),Y2("div",{children:[Y2("strong",{className:"mb-0.5 block font-medium text-[var(--docs-text)]",children:"April 2026"},void 0,!1,void 0,this),"Updated"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Y2("div",{className:"mt-9 flex flex-wrap gap-3.5",children:[B&&Y2("a",{className:qW.primaryButton,href:g_(B),children:"Start reading"},void 0,!1,void 0,this),Y2("a",{className:qW.button,href:"#sections",children:"Browse sections"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),I91=({groups:A})=>Y2("aside",{className:"docs-rail sticky top-8 hidden docs-font-label text-xs tracking-[0.06em] text-[var(--docs-text-light)] min-[861px]:block","aria-label":"Documentation sections",children:[Y2("p",{className:"m-0 mb-3.5 font-medium text-[var(--docs-text)]",children:"Sections"},void 0,!1,void 0,this),Y2("ol",{className:"m-0 list-none p-0",children:A.map((Q,B)=>Y2("li",{className:"grid grid-cols-[32px_1fr] gap-2 py-1.5",children:[Y2("span",{className:"docs-font-display text-[var(--docs-text-light)] italic",children:[T_(B),"."]},void 0,!0,void 0,this),Y2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:`#${dQA(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),D91=({group:A,index:Q})=>Y2("article",{className:"mb-16 last:mb-0",id:dQA(Q),children:[Y2("header",{className:"mb-2 grid grid-cols-[36px_auto_1fr] items-baseline gap-x-3 border-b border-[var(--docs-border)] pb-3.5 md:grid-cols-[48px_auto_1fr] md:gap-x-5",children:[Y2("span",{className:"text-right docs-font-display text-3xl leading-[1.1] text-[var(--docs-accent)] italic md:text-4xl",children:[T_(Q),"."]},void 0,!0,void 0,this),Y2("h2",{className:`${qW.display} m-0 text-3xl leading-[1.1] tracking-[-0.015em] md:text-4xl`,children:A.section},void 0,!1,void 0,this),Y2("span",{className:"docs-chapter__leader"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Y2("ol",{className:"m-0 list-none p-0",children:A.docs.map((B)=>Y2("li",{className:"border-b border-[var(--docs-border-light)] last:border-b-0",children:Y2("a",{className:"group block py-[18px] pl-12 md:pl-[68px]",href:g_(B),children:[Y2("p",{className:"m-0 text-[22px] leading-[1.2] tracking-[-0.005em] transition-colors duration-150 group-hover:text-[var(--docs-accent)]",children:B.metadata.title},void 0,!1,void 0,this),B.metadata.description&&Y2("p",{className:"mt-1.5 mb-0 max-w-[70ch] text-sm leading-[1.55] text-[var(--docs-text-muted)]",children:B.metadata.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},B.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),H91=({title:A})=>Y2("nav",{className:"mb-8 flex flex-wrap items-baseline gap-2.5 docs-font-label text-[11px] uppercase tracking-[0.06em] text-[var(--docs-text-light)]","aria-label":"Breadcrumb",children:[Y2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/",children:"Home"},void 0,!1,void 0,this),Y2("span",{children:"/"},void 0,!1,void 0,this),Y2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/docs",children:"Docs"},void 0,!1,void 0,this),Y2("span",{children:"/"},void 0,!1,void 0,this),Y2("span",{children:A},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Y91=({groups:A,activeGroupIndex:Q,activeSlug:B})=>Y2("aside",{className:"docs-detail-rail sticky top-24 hidden max-h-[calc(100vh-120px)] overflow-auto pr-2 min-[861px]:block","aria-label":"Documentation navigation",children:Y2("nav",{className:"docs-font-label text-xs tracking-[0.06em] text-[var(--docs-text-light)]",children:[Y2("p",{className:"m-0 mb-4 border-b border-[var(--docs-text)] pb-3 text-[11px] uppercase tracking-[0.08em] text-[var(--docs-text-light)]",children:"Documentation"},void 0,!1,void 0,this),Y2("ol",{className:"m-0 list-none p-0",children:A.map((w,$)=>{let f=$===Q;return Y2("li",{className:f?"mb-[22px]":"mb-3.5",children:[Y2("a",{className:`mb-2 flex items-baseline gap-2.5 docs-font-label text-[11px] uppercase leading-[1.4] tracking-[0.06em] transition-colors duration-150 hover:text-[var(--docs-text)] ${f?"text-[var(--docs-text)]":"text-[var(--docs-text-muted)]"}`,href:`/docs#${dQA($)}`,children:[Y2("span",{className:"docs-font-display text-sm text-[var(--docs-accent)] italic",children:[T_($),"."]},void 0,!0,void 0,this)," ",w.section]},void 0,!0,void 0,this),f&&Y2("ol",{className:"mt-0.5 list-none p-0",children:w.docs.map((I)=>{let D=I.metadata.slug===B;return Y2("li",{children:Y2("a",{className:`docs-rail__doc relative block py-1.5 docs-font-body text-sm leading-[1.4] tracking-normal transition-[color,padding-left] duration-150 hover:text-[var(--docs-text)] ${D?"pl-3.5 font-medium text-[var(--docs-accent)]":"text-[var(--docs-text-muted)]"}`,href:g_(I),"aria-current":D?"page":void 0,children:I.metadata.title},void 0,!1,void 0,this)},I.id,!1,void 0,this)})},void 0,!1,void 0,this)]},w.section,!0,void 0,this)})},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),X91=({prevDoc:A,nextDoc:Q})=>{if(!A&&!Q)return null;return Y2("nav",{className:"mt-12 grid grid-cols-1 gap-5 border-t border-[var(--docs-border)] pt-7 md:grid-cols-2","aria-label":"Previous and next docs",children:[A?Y2("a",{className:"group border-t border-[var(--docs-border-light)] pt-[18px] transition-colors duration-150 hover:border-[var(--docs-accent)]",href:g_(A),children:[Y2("span",{className:"block docs-font-label text-[10.5px] uppercase tracking-[0.22em] text-[var(--docs-text-light)]",children:"Previous"},void 0,!1,void 0,this),Y2("span",{className:"mt-2 block docs-font-display text-[22px] leading-[1.2] text-[var(--docs-heading)] transition-colors duration-150 group-hover:text-[var(--docs-accent)]",children:["\u2190 ",A.metadata.title]},void 0,!0,void 0,this)]},void 0,!0,void 0,this):Y2("span",{},void 0,!1,void 0,this),Q&&Y2("a",{className:"group border-t border-[var(--docs-border-light)] pt-[18px] text-left transition-colors duration-150 hover:border-[var(--docs-accent)] md:text-right",href:g_(Q),children:[Y2("span",{className:"block docs-font-label text-[10.5px] uppercase tracking-[0.22em] text-[var(--docs-text-light)]",children:"Next"},void 0,!1,void 0,this),Y2("span",{className:"mt-2 block docs-font-display text-[22px] leading-[1.2] text-[var(--docs-heading)] transition-colors duration-150 group-hover:text-[var(--docs-accent)]",children:[Q.metadata.title," \u2192"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as S_}from"preact/jsx-dev-runtime";var nPA=({docs:A})=>{let Q=fu(A),B=rQA(Q),$=Q.filter((f)=>f.metadata.slug!=="index")[0]??Q[0];return S_(nQA,{title:"Documentation",description:"Brains documentation",children:[S_(f91,{docsCount:A.length,sectionsCount:B.length,startDoc:$},void 0,!1,void 0,this),S_("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:[S_(I91,{groups:B},void 0,!1,void 0,this),S_("div",{children:B.map((f,I)=>S_(D91,{group:f,index:I},f.section,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as dI}from"preact/jsx-dev-runtime";var oPA=({doc:A,docs:Q,prevDoc:B,nextDoc:w})=>{let $=rQA(Q.length>0?Q:[A]),f=fu(Q.length>0?Q:[A]),I=f.findIndex((H)=>H.metadata.slug===A.metadata.slug),D=Math.max($.findIndex((H)=>H.docs.some((Y)=>Y.metadata.slug===A.metadata.slug)),0);return dI(nQA,{title:A.metadata.title,description:A.metadata.description??A.metadata.section,detail:!0,footer:!0,contentClassName:"pt-16",children:[dI(H91,{title:A.metadata.title},void 0,!1,void 0,this),dI("div",{className:"grid items-start gap-10 py-8 pb-24 md:grid-cols-[240px_minmax(0,1fr)] md:gap-20",children:[dI(Y91,{groups:$,activeGroupIndex:D,activeSlug:A.metadata.slug},void 0,!1,void 0,this),dI("article",{className:"min-w-0",children:[dI("header",{className:"mb-10 border-b border-[var(--docs-border)] pb-8",children:[dI("p",{className:`${qW.label} m-0 mb-6 flex items-baseline gap-3`,children:[dI("span",{className:"docs-font-display text-lg leading-none tracking-normal normal-case text-[var(--docs-accent)] italic",children:[T_(D),"."]},void 0,!0,void 0,this)," ",A.metadata.section,I>=0?` \xB7 ${I+1}/${f.length}`:""]},void 0,!0,void 0,this),dI("h1",{className:`${qW.display} m-0 max-w-[18ch] text-4xl leading-[1.05] tracking-[-0.02em] md:text-6xl`,children:A.metadata.title},void 0,!1,void 0,this),A.metadata.description&&dI("p",{className:"mt-6 max-w-[56ch] docs-font-display text-[22px] font-[350] leading-[1.5] text-[var(--docs-text-muted)]",children:A.metadata.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this),dI("div",{className:"docs-article__body",children:dI(mI,{markdown:A.body},void 0,!1,void 0,this)},void 0,!1,void 0,this),dI(X91,{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 JBQ=F.object({docs:F.array(FG),pagination:Y9.nullable(),baseUrl:F.string().optional()}),GBQ=F.object({doc:FG,docs:F.array(FG),prevDoc:FG.nullable(),nextDoc:FG.nullable()});function W91(){return{"doc-list":O1({name:"doc-list",description:"Documentation index template",schema:JBQ,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:nPA}}),"doc-detail":O1({name:"doc-detail",description:"Documentation page template",schema:GBQ,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:oPA}})}}var U91={name:"@brains/doc",private:!0,version:"0.2.0-alpha.70",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 sPA extends KQ{entityType=lQA.entityType;schema=y_;adapter=lQA;constructor(){super("docs",U91,{},void 0)}getTemplates(){return W91()}getDataSources(){return[new iQA(this.logger.child("DocDataSource"))]}}function aPA(){return new sPA}f0();GA();GA();d5();var J91=F.object({label:F.string(),href:F.string()}),G91=F.object({label:F.string(),title:F.string(),detail:F.string()}),KBQ=F.object({eyebrow:F.string(),name:F.string(),sub:F.string()}),ZBQ=F.object({tone:F.enum(["capture","synthesis","share"]),title:F.string(),text:F.string()}),tPA=F.object({captures:F.number(),links:F.number(),topics:F.number(),summaries:F.number(),peers:F.number()}),m_=F.object({eyebrow:F.string(),headline:F.string(),intro:F.string(),primaryCta:J91,secondaryCta:J91,inputs:F.array(G91).min(1),outputs:F.array(G91).min(1),core:KBQ,legend:F.array(ZBQ).min(1)}),ePA=m_.extend({counts:tPA}),F91={eyebrow:"A team brain, diagrammed",headline:"Relay sits between the work and the world, and keeps both honest.",intro:"Capture sources flow into a shared brain; the brain organizes, summarizes, and \u2014 selectively \u2014 exposes a public surface. Everything else stays private and operational.",primaryCta:{label:"See it on a real team",href:"#diagram"},secondaryCta:{label:"Read the model",href:"/about"},inputs:[{label:"Source \xB7 chat",title:"Discord",detail:"Shared decisions and field notes captured in flow."},{label:"Source \xB7 agent",title:"MCP / CLI",detail:"Structured captures from tools and assistants."},{label:"Source \xB7 web",title:"Links & docs",detail:"External material indexed with sourceable metadata."}],outputs:[{label:"Surface \xB7 public",title:"Default site",detail:"A small, durable face onto what the team currently knows."},{label:"Surface \xB7 agents",title:"A2A exchange",detail:"Peer brains coordinate over an approved, signed protocol."},{label:"Surface \xB7 query",title:"Team Q&A",detail:"Ask the brain in chat; answers cite the captures behind them."}],core:{eyebrow:"The relay",name:"brain",sub:"capture \u2192 topics \u2192 summaries"},legend:[{tone:"capture",title:"Capture",text:"Anything the team already does that produces a trace \u2014 chat messages, links, deploys, decisions."},{tone:"synthesis",title:"Synthesis",text:"The work the brain does on its own time \u2014 clustering captures into topics, summaries, and durable memory."},{tone:"share",title:"Share",text:"A small, opinionated public surface and an approved agent-to-agent protocol. Most memory stays private."}]},K91=new RB(m_,{title:"Home diagram",mappings:[{key:"eyebrow",label:"Eyebrow",type:"string"},{key:"headline",label:"Headline",type:"string"},{key:"intro",label:"Intro",type:"string"},{key:"primaryCta",label:"Primary CTA",type:"object",children:[{key:"label",label:"Label",type:"string"},{key:"href",label:"Href",type:"string"}]},{key:"secondaryCta",label:"Secondary CTA",type:"object",children:[{key:"label",label:"Label",type:"string"},{key:"href",label:"Href",type:"string"}]},{key:"inputs",label:"Inputs",type:"array",itemType:"object",itemMappings:[{key:"label",label:"Label",type:"string"},{key:"title",label:"Title",type:"string"},{key:"detail",label:"Detail",type:"string"}]},{key:"outputs",label:"Outputs",type:"array",itemType:"object",itemMappings:[{key:"label",label:"Label",type:"string"},{key:"title",label:"Title",type:"string"},{key:"detail",label:"Detail",type:"string"}]},{key:"core",label:"Core",type:"object",children:[{key:"eyebrow",label:"Eyebrow",type:"string"},{key:"name",label:"Name",type:"string"},{key:"sub",label:"Sub",type:"string"}]},{key:"legend",label:"Legend",type:"array",itemType:"object",itemMappings:[{key:"tone",label:"Tone",type:"string"},{key:"title",label:"Title",type:"string"},{key:"text",label:"Text",type:"string"}]}]});function oQA(A){return K91.parse(A)}function Z91(A){return K91.format(A)}GA();var NBQ=F.object({query:F.object({routeId:F.string().default("home"),sectionId:F.string().default("diagram")}).default({routeId:"home",sectionId:"diagram"})}).passthrough(),zBQ={captures:"base",links:"link",topics:"topic",summaries:"summary",peers:"agent"};class AkA{id="relay-site:home-counts";name="Relay homepage counts";description="Fetches Relay homepage content and live entity counts for the system diagram";async fetch(A,Q,B){let w=NBQ.parse(A??{}),$=await this.fetchContent(B,w.query.routeId,w.query.sectionId),f=await this.fetchCounts(B);return Q.parse({...$,counts:f})}async fetchContent(A,Q,B){let w=await A.entityService.getEntity({entityType:"site-content",id:`${Q}:${B}`});if(!w?.content)return F91;return m_.parse(oQA(w.content))}async fetchCounts(A){let Q=await Promise.all(Object.entries(zBQ).map(async([B,w])=>[B,await this.countOrZero(A,w)]));return tPA.parse(Object.fromEntries(Q))}async countOrZero(A,Q){if(!A.entityService.hasEntityType(Q))return 0;try{return await A.entityService.countEntities({entityType:Q})}catch{return 0}}}import{jsxDEV as w1}from"preact/jsx-dev-runtime";var N91=F.object({label:F.string(),href:F.string()}),qBQ=F.object({eyebrow:F.string(),headline:F.string(),intro:F.string(),primaryCta:N91,secondaryCta:N91,signals:F.array(F.object({label:F.string(),value:F.string(),note:F.string()}))}),CBQ=F.object({eyebrow:F.string(),title:F.string(),intro:F.string(),steps:F.array(F.object({phase:F.string(),title:F.string(),text:F.string()}))}),LBQ=F.object({title:F.string(),intro:F.string(),cards:F.array(F.object({label:F.string(),title:F.string(),text:F.string()}))}),EBQ=F.object({title:F.string(),intro:F.string(),points:F.array(F.string())}),MBQ={title:"Relay is a collaborative team-memory brain.",intro:"It exists for teams that need to remember together: capturing what happened, summarizing why it matters, and coordinating with trusted peer brains when work crosses boundaries.",points:["Not a personal blog engine or portfolio shell.","Not a marketing automation stack.","A small public face for a larger private knowledge workflow."]},VBQ="font-body text-[15px] text-theme-muted transition-colors hover:text-theme";function z91({href:A,label:Q}){return w1("a",{href:A,className:VBQ,children:Q},void 0,!1,void 0,this)}function bBQ({siteInfo:A,children:Q}){let B=[...A.navigation.primary,...A.navigation.secondary],w=A.cta??{buttonText:"Start here",buttonLink:"/about"};return w1(O_,{children:[w1("nav",{className:"fixed left-0 right-0 top-0 z-[100] flex items-center justify-between border-b border-theme-light bg-nav-fade px-6 py-4 backdrop-blur-[12px] md:px-10 xl:px-20",children:[w1("a",{href:"/",className:"font-nav text-[20px]","aria-label":"Relay home",children:[w1("span",{className:"font-bold text-theme",children:"relay"},void 0,!1,void 0,this),w1("span",{className:"font-bold text-accent",children:"."},void 0,!1,void 0,this),w1("span",{className:"text-theme-muted",children:"brain"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),w1("div",{className:"flex items-center gap-5 md:gap-8",children:[w1("div",{className:"hidden items-center gap-6 md:flex",children:B.map(($)=>w1(z91,{...$},`${$.href}-${$.label}`,!1,void 0,this))},void 0,!1,void 0,this),w1("a",{href:w.buttonLink,className:"rounded-[999px] border border-theme px-4 py-2 font-body text-[13px] font-semibold text-theme transition-colors hover:border-accent hover:text-accent md:px-5",children:w.buttonText},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),w1("main",{children:Q},void 0,!1,void 0,this),w1("footer",{className:"relative z-[1] border-t border-theme-light px-6 py-8 md:px-10 xl:px-20",children:w1("div",{className:"flex flex-col gap-4 md:flex-row md:items-center md:justify-between",children:[w1("div",{children:[w1("p",{className:"font-label text-label-sm uppercase tracking-[0.22em] text-theme-light",children:A.copyright},void 0,!1,void 0,this),w1("p",{className:"mt-2 max-w-[560px] font-body text-body-xs text-theme-muted",children:A.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this),w1("div",{className:"flex flex-wrap items-center gap-5",children:[B.map(($)=>w1(z91,{...$},`footer-${$.href}-${$.label}`,!1,void 0,this)),w1("button",{id:"themeToggle","aria-label":"Toggle light mode",className:"rounded-md border border-theme-light bg-transparent px-2.5 py-1.5 font-body text-label-md text-theme-light transition-colors hover:border-theme hover:text-theme",children:"\u2600 Light"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}var OBQ=({sections:A,siteInfo:Q})=>w1(bBQ,{siteInfo:Q,children:A},void 0,!1,void 0,this);function RBQ({eyebrow:A,headline:Q,intro:B,primaryCta:w,secondaryCta:$,signals:f}){return w1(aZ,{className:"min-h-[92vh] pt-[152px] pb-20 md:pt-[190px]",children:w1("div",{className:"grid gap-10 lg:grid-cols-[minmax(0,1fr)_420px] lg:items-end",children:[w1("div",{children:[w1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:A},void 0,!1,void 0,this),w1("h1",{className:"mt-7 max-w-[980px] font-display text-display-lg text-theme",children:Q},void 0,!1,void 0,this),w1("p",{className:"mt-7 max-w-[720px] font-body text-body-lg text-theme-muted",children:B},void 0,!1,void 0,this),w1("div",{className:"mt-10 flex flex-col gap-3 sm:flex-row",children:[w1(iC,{href:w.href,size:"lg",variant:"primary-strong",children:w.label},void 0,!1,void 0,this),w1(iC,{href:$.href,size:"lg",variant:"secondary",children:$.label},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),w1("div",{className:"rounded-[32px] border border-card-relay-border bg-card-relay-bg p-5 shadow-[0_24px_90px_var(--color-glow-relay)] backdrop-blur-sm",children:[w1("p",{className:"font-label text-label-xs uppercase tracking-[0.24em] text-theme-light",children:"Live relay signals"},void 0,!1,void 0,this),w1("div",{className:"mt-5 grid gap-3",children:f.map((I)=>w1("div",{className:"rounded-[22px] border border-card-divider bg-bg-muted p-5",children:[w1("div",{className:"flex items-center justify-between gap-4",children:[w1("p",{className:"font-label text-label-xs uppercase tracking-[0.18em] text-secondary",children:I.label},void 0,!1,void 0,this),w1("span",{className:"h-2 w-2 rounded-full bg-accent shadow-[0_0_22px_var(--color-accent)]"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),w1("p",{className:"mt-4 font-display text-display-sm text-theme",children:I.value},void 0,!1,void 0,this),w1("p",{className:"mt-2 font-body text-body-xs text-theme-muted",children:I.note},void 0,!1,void 0,this)]},I.label,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)}function _BQ({eyebrow:A,title:Q,intro:B,steps:w}){return w1(aZ,{id:"operating-loop",className:"py-section",children:[w1("div",{className:"max-w-[840px]",children:[w1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-secondary",children:A},void 0,!1,void 0,this),w1("h2",{className:"mt-5 font-display text-display-md text-theme",children:Q},void 0,!1,void 0,this),w1("p",{className:"mt-5 font-body text-body-md text-theme-muted",children:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this),w1("div",{className:"mt-12 grid gap-4 md:grid-cols-3",children:w.map(($)=>w1("article",{className:"min-h-[300px] rounded-[28px] border border-card-panel-border bg-card-panel-bg p-6",children:[w1("p",{className:"font-label text-label-sm text-accent",children:$.phase},void 0,!1,void 0,this),w1("h3",{className:"mt-16 font-display text-display-sm text-theme",children:$.title},void 0,!1,void 0,this),w1("p",{className:"mt-4 font-body text-body-sm text-theme-muted",children:$.text},void 0,!1,void 0,this)]},$.phase,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function PBQ({title:A,intro:Q,cards:B}){return w1(aZ,{className:"py-section",children:w1("div",{className:"rounded-[36px] border border-theme-light bg-bg-muted p-6 md:p-10",children:w1("div",{className:"grid gap-8 lg:grid-cols-[360px_1fr]",children:[w1("div",{children:[w1("h2",{className:"font-display text-display-md text-theme",children:A},void 0,!1,void 0,this),w1("p",{className:"mt-5 font-body text-body-md text-theme-muted",children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this),w1("div",{className:"grid gap-4",children:B.map((w)=>w1("article",{className:"rounded-[24px] border border-card-divider bg-bg-subtle/70 p-5",children:[w1("p",{className:"font-label text-label-xs uppercase tracking-[0.22em] text-accent",children:w.label},void 0,!1,void 0,this),w1("h3",{className:"mt-3 font-nav text-heading-lg text-theme",children:w.title},void 0,!1,void 0,this),w1("p",{className:"mt-2 font-body text-body-sm text-theme-muted",children:w.text},void 0,!1,void 0,this)]},w.title,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function kBQ({title:A,intro:Q,points:B}){return w1(aZ,{className:"min-h-[78vh] pt-[150px] pb-section md:pt-[190px]",children:[w1("div",{className:"max-w-[920px]",children:[w1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:"Relay model"},void 0,!1,void 0,this),w1("h1",{className:"mt-6 font-display text-display-lg text-theme",children:A},void 0,!1,void 0,this),w1("p",{className:"mt-7 font-body text-body-lg text-theme-muted",children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this),w1("div",{className:"mt-12 grid gap-4 md:grid-cols-3",children:B.map((w)=>w1("div",{className:"rounded-[24px] border border-card-panel-current-border bg-card-panel-current-bg p-6 font-body text-body-md text-theme",children:w},w,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}var jBQ=(A)=>{switch(A){case"capture":return"bg-accent";case"synthesis":return"bg-secondary";case"share":return"bg-accent-bright"}},vBQ=(A)=>new Intl.NumberFormat("en",{notation:A>999?"compact":"standard"}).format(A),Iu=(A,Q,B=`${Q}s`)=>`${vBQ(A)} ${A===1?Q:B}`;function xBQ({eyebrow:A,headline:Q,intro:B,primaryCta:w,secondaryCta:$,inputs:f,outputs:I,core:D,legend:H,counts:Y}){let W=[{key:"captures",className:"top-[-10px] left-1/2 -translate-x-1/2",label:Iu(Y.captures,"capture")},{key:"topics",className:"top-1/2 right-[-28px] -translate-y-1/2",label:Iu(Y.topics,"topic")},{key:"peers",className:"bottom-[-10px] left-1/2 -translate-x-1/2",label:Iu(Y.peers,"peer brain")},{key:"summaries",className:"top-1/2 left-[-28px] -translate-y-1/2",label:Iu(Y.summaries,"summary","summaries")}];return w1(aZ,{className:"pt-[150px] pb-section md:pt-[190px]",id:"diagram",children:[w1("div",{className:"mx-auto max-w-[1040px] text-center",children:[w1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:A},void 0,!1,void 0,this),w1("h1",{className:"mx-auto mt-7 max-w-[22ch] font-display text-display-lg text-theme",children:Q},void 0,!1,void 0,this),w1("p",{className:"mx-auto mt-7 max-w-[64ch] font-body text-body-lg text-theme-muted",children:B},void 0,!1,void 0,this),w1("div",{className:"mt-10 flex flex-col justify-center gap-3 sm:flex-row",children:[w1(iC,{href:w.href,size:"lg",variant:"primary-strong",children:w.label},void 0,!1,void 0,this),w1(iC,{href:$.href,size:"lg",variant:"secondary",children:$.label},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),w1("div",{className:"mx-auto mt-20 max-w-[1020px] rounded-[32px] border border-theme-light bg-[radial-gradient(circle_at_1px_1px,rgb(255_255_255_/_0.05)_1px,transparent_0),linear-gradient(180deg,rgb(255_255_255_/_0.02),transparent)] bg-[length:24px_24px,100%_100%] px-6 py-14",children:[w1("div",{className:"grid items-center gap-8 lg:grid-cols-[1fr_1.4fr_1fr]",children:[w1("div",{className:"flex flex-col gap-3.5",children:f.map((G)=>w1("div",{className:"rounded-2xl border border-card-panel-border border-l-2 border-l-accent bg-card-panel-bg px-4 py-4 text-left backdrop-blur-sm",children:[w1("p",{className:"font-label text-[10px] uppercase tracking-[0.22em] text-secondary",children:G.label},void 0,!1,void 0,this),w1("h2",{className:"mt-1.5 font-display text-[18px] font-medium text-theme",children:G.title},void 0,!1,void 0,this),w1("p",{className:"mt-1 font-body text-[13px] leading-[1.5] text-theme-muted",children:G.detail},void 0,!1,void 0,this)]},`${G.label}-${G.title}`,!0,void 0,this))},void 0,!1,void 0,this),w1("div",{className:"relative mx-auto grid aspect-square w-full max-w-[320px] place-items-center rounded-full bg-[radial-gradient(circle_at_center,rgb(232_119_34_/_0.25),transparent_65%)]",children:[w1("div",{className:"absolute inset-0 rounded-full border border-dashed border-accent/30"},void 0,!1,void 0,this),w1("div",{className:"absolute inset-6 animate-spin rounded-full border border-dashed border-secondary/40 [animation-duration:28s]"},void 0,!1,void 0,this),W.map((G)=>w1("span",{className:`absolute whitespace-nowrap rounded-full border border-theme bg-bg px-2.5 py-1 font-label text-[10px] uppercase tracking-[0.18em] text-theme-light ${G.className}`,children:G.label},G.key,!1,void 0,this)),w1("div",{className:"relative z-[1] px-6 text-center",children:[w1("p",{className:"font-label text-[10px] uppercase tracking-[0.28em] text-accent",children:D.eyebrow},void 0,!1,void 0,this),w1("p",{className:"mt-2 font-display text-[36px] leading-none text-theme",children:D.name},void 0,!1,void 0,this),w1("p",{className:"mt-2 font-body text-[13px] text-theme-muted",children:D.sub},void 0,!1,void 0,this),w1("p",{className:"mt-4 font-label text-[10px] uppercase tracking-[0.18em] text-theme-light",children:[Iu(Y.links,"link")," indexed"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),w1("div",{className:"flex flex-col gap-3.5",children:I.map((G)=>w1("div",{className:"rounded-2xl border border-card-panel-border border-r-2 border-r-secondary bg-card-panel-bg px-4 py-4 text-left backdrop-blur-sm",children:[w1("p",{className:"font-label text-[10px] uppercase tracking-[0.22em] text-secondary",children:G.label},void 0,!1,void 0,this),w1("h2",{className:"mt-1.5 font-display text-[18px] font-medium text-theme",children:G.title},void 0,!1,void 0,this),w1("p",{className:"mt-1 font-body text-[13px] leading-[1.5] text-theme-muted",children:G.detail},void 0,!1,void 0,this)]},`${G.label}-${G.title}`,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),w1("div",{className:"mt-14 grid gap-4 border-t border-theme-light pt-8 md:grid-cols-3",children:H.map((G)=>w1("div",{className:"text-left",children:[w1("h2",{className:"font-display text-[16px] font-medium text-theme",children:[w1("span",{className:`mr-2.5 inline-block h-3 w-3 rounded-[3px] align-middle ${jBQ(G.tone)}`},void 0,!1,void 0,this),G.title]},void 0,!0,void 0,this),w1("p",{className:"mt-1.5 font-body text-[13px] leading-[1.6] text-theme-muted",children:G.text},void 0,!1,void 0,this)]},G.title,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}var hBQ=O1({name:"home-diagram",description:"Relay homepage system diagram with live entity counts",schema:ePA,formatter:{parse:(A)=>ePA.parse({...oQA(A),counts:{captures:0,links:0,topics:0,summaries:0,peers:0}}),format:(A)=>Z91(m_.parse(A))},dataSourceId:"relay-site:home-counts",requiredPermission:"public",layout:{component:xBQ}}),yBQ=(A)=>RBQ(qBQ.parse(A)),gBQ=(A)=>_BQ(CBQ.parse(A)),TBQ=(A)=>PBQ(LBQ.parse(A)),SBQ=(A)=>kBQ(EBQ.parse(A)),q91={type:"object",label:"CTA",fields:{label:{type:"string",label:"Label"},href:{type:"string",label:"Href"}}},C91={namespace:"relay-site",sections:{"home-hero":{title:"Home hero",description:"Relay homepage hero section",layout:yBQ,fields:{eyebrow:{type:"string",label:"Eyebrow"},headline:{type:"string",label:"Headline"},intro:{type:"string",label:"Intro"},primaryCta:{...q91,label:"Primary CTA"},secondaryCta:{...q91,label:"Secondary CTA"},signals:{type:"array",label:"Signals",minItems:1,items:{type:"object",label:"Signal",fields:{label:{type:"string",label:"Label"},value:{type:"string",label:"Value"},note:{type:"string",label:"Note"}}}}}},"home-loop":{title:"Home operating loop",description:"Relay capture, synthesis, and sharing loop",layout:gBQ,fields:{eyebrow:{type:"string",label:"Eyebrow"},title:{type:"string",label:"Title"},intro:{type:"string",label:"Intro"},steps:{type:"array",label:"Steps",minItems:1,items:{type:"object",label:"Step",fields:{phase:{type:"string",label:"Phase"},title:{type:"string",label:"Title"},text:{type:"string",label:"Text"}}}}}},"home-surface":{title:"Home surface",description:"Relay default template explanation cards",layout:TBQ,fields:{title:{type:"string",label:"Title"},intro:{type:"string",label:"Intro"},cards:{type:"array",label:"Cards",minItems:1,items:{type:"object",label:"Card",fields:{label:{type:"string",label:"Label"},title:{type:"string",label:"Title"},text:{type:"string",label:"Text"}}}}}},about:{title:"About Relay",description:"Default Relay about page",layout:SBQ,fields:{title:{type:"string",label:"Title"},intro:{type:"string",label:"Intro"},points:{type:"array",label:"Points",minItems:1,items:{type:"string",label:"Point"}}}}}},mBQ=[{id:"home",path:"/",title:"Relay",description:"Collaborative team memory and synthesis brain",layout:"default",navigation:{show:!0,label:"Home",slot:"secondary",priority:10},sections:[{id:"diagram",template:"relay-site:home-diagram"}]},{id:"about",path:"/about",title:"About Relay",description:"What Relay is designed to do",layout:"default",navigation:{show:!0,label:"About",slot:"primary",priority:20},sections:[{id:"about",template:"relay-site:about",content:MBQ}]}],L91=vPA({packageName:"@brains/relay/site",contentNamespace:"relay-site",themeProfile:"studio",layout:OBQ,routes:mBQ,templates:{"home-diagram":hBQ},dataSources:[new AkA]});var E91=["prompt","directory-sync","note","link","topics","conversation-memory","agents","assessment","auth-service","cms","dashboard","mcp","webserver","discord","a2a"],M91=[...E91,"image","site-info","site-content","site-builder"],cBQ=[...M91,"docs","decks"],pBQ=["Relay is a collaborative team-memory and synthesis brain. Optimize for capturing shared context, finding what the team already knows, summarizing cross-source evidence, and coordinating with peer brains.","Relay is not Rover-for-teams: do not default to personal branding, blog publishing, newsletters, social media, portfolio, or marketing workflows unless the installed plugins and user request explicitly support them.",'Relay entity mappings: "memo", "note", "team note", "capture" \u2192 entityType: base; "summary", "sync", "team digest" \u2192 entityType: summary; "decision" \u2192 entityType: decision; "action item", "todo" \u2192 entityType: action-item; "handbook", "doc", "documentation" \u2192 entityType: doc; "deck", "walkthrough", "presentation" \u2192 entityType: deck; "agent", "peer brain", "contact" \u2192 entityType: agent.'],V91=QK({name:"relay",version:"0.1.0",model:"gpt-5.4-mini",site:L91,theme:R_,presets:{core:E91,default:M91,full:cBQ},evalDisable:["webserver","mcp","discord"],agentInstructions:pBQ,capabilities:[["prompt",cC,void 0],["note",xC,{}],["link",yC,{}],["image",yx,void 0],["topics",M2A,{includeEntityTypes:["base","link","summary","agent","swot","deck","doc","anchor-profile","brain-character"],extractableStatuses:["published","draft"]}],["conversation-memory",iPA,{}],["docs",aPA,void 0],["decks",Km,void 0],["agents",$QA,void 0],["assessment",GQA,void 0],["auth-service",Vy,void 0],["cms",uC,{}],["dashboard",nZ,void 0],["directory-sync",aq,{seedContent:!0,seedContentPath:uBQ(import.meta.dir,"..","seed-content"),initialSync:!0}],["site-content",sm,{definitions:C91}],["rizom-ecosystem",pC,void 0],["site-info",kC,void 0],["site-builder",PC,{}]],interfaces:[["mcp",hK,()=>({})],["discord",KZ,()=>({captureUrls:!0})],["a2a",AR,()=>({})],["webserver",ZZ,()=>({})]],permissions:{rules:[{pattern:"cli:*",level:"anchor"},{pattern:"mcp:stdio",level:"anchor"},{pattern:"mcp:http",level:"anchor"},{pattern:"discord:*",level:"public"}]},deployment:{cdn:{enabled:!0,provider:"bunny"}}});import{readFileSync as L5Q}from"fs";import{join as E5Q}from"path";import{execSync as M5Q}from"child_process";import{parseArgs as rBQ}from"util";var dBQ={model:{type:"string"},domain:{type:"string"},"content-repo":{type:"string"},backend:{type:"string"},"push-to":{type:"string"},"ai-api-key":{type:"string"},"no-interactive":{type:"boolean"},preview:{type:"boolean"},deploy:{type:"boolean"},regen:{type:"boolean"},all:{type:"boolean"},only:{type:"string"},"dry-run":{type:"boolean"},"startup-check":{type:"boolean"},"storage-dir":{type:"string"},yes:{type:"boolean"},remote:{type:"string"},token:{type:"string"},help:{type:"boolean",short:"h"},version:{type:"boolean",short:"v"}};function CW(A,Q){let B=A[Q];return typeof B==="string"?B:void 0}function A3(A,Q){let B=A[Q];return typeof B==="boolean"?B:void 0}function b91(A){let{values:Q,positionals:B}=rBQ({args:A,options:dBQ,allowPositionals:!0,strict:!1});if(Q.help)return{command:"help",args:[],flags:{help:!0}};if(Q.version)return{command:"version",args:[],flags:{version:!0}};return{command:B[0]??"help",args:B.slice(1),flags:{model:CW(Q,"model"),domain:CW(Q,"domain"),"content-repo":CW(Q,"content-repo"),backend:CW(Q,"backend"),"push-to":CW(Q,"push-to"),"ai-api-key":CW(Q,"ai-api-key"),"no-interactive":A3(Q,"no-interactive"),preview:A3(Q,"preview"),deploy:A3(Q,"deploy"),regen:A3(Q,"regen"),all:A3(Q,"all"),only:CW(Q,"only"),"dry-run":A3(Q,"dry-run"),"startup-check":A3(Q,"startup-check"),"storage-dir":CW(Q,"storage-dir"),yes:A3(Q,"yes"),remote:CW(Q,"remote"),token:CW(Q,"token")}}}Du();import{mkdirSync as U5Q}from"fs";import{join as J5Q}from"path";import{execSync as G5Q}from"child_process";var aQA={name:"@rizom/brain",version:"0.2.0-alpha.70",description:"Brain runtime + CLI \u2014 scaffold, run, and manage AI brain instances",type:"module",bin:{brain:"./dist/brain.js"},exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.js"},"./cli":"./dist/brain.js","./plugins":{types:"./dist/plugins.d.ts",import:"./dist/plugins.js"},"./entities":{types:"./dist/entities.d.ts",import:"./dist/entities.js"},"./services":{types:"./dist/services.d.ts",import:"./dist/services.js"},"./interfaces":{types:"./dist/interfaces.d.ts",import:"./dist/interfaces.js"},"./templates":{types:"./dist/templates.d.ts",import:"./dist/templates.js"},"./site":{types:"./dist/site.d.ts",import:"./dist/site.js"},"./themes":{types:"./dist/themes.d.ts",import:"./dist/themes.js"},"./deploy":{types:"./dist/deploy.d.ts",import:"./dist/deploy.js"},"./tsconfig.instance.json":"./tsconfig.instance.json"},files:["dist","templates","tsconfig.instance.json"],scripts:{build:"bun scripts/build.ts",prepublishOnly:"bun scripts/build.ts","dev:start":"bun dist/brain.js start",typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts"},dependencies:{"@clack/prompts":"^0.11.0","@modelcontextprotocol/sdk":"^1.24.0","@tailwindcss/postcss":"^4.1.13","@tailwindcss/typography":"^0.5.19",postcss:"^8.5.6",preact:"^10.27.2","preact-render-to-string":"^6.3.1",tailwindcss:"^4.1.11"},optionalDependencies:{"@bitwarden/sdk-napi":"^1.0.0","@libsql/client":"^0.15.7","@tailwindcss/oxide":"^4.1.4","better-sqlite3":"^11.8.1",lightningcss:"^1.29.2","react-devtools-core":"^6.1.1",sharp:"^0.34.5"},devDependencies:{"@brains/app":"workspace:*","@brains/content-formatters":"workspace:*","@brains/deploy-support":"workspace:*","@brains/eslint-config":"workspace:*","@brains/mcp-service":"workspace:*","@brains/plugins":"workspace:*","@brains/ranger":"workspace:*","@brains/relay":"workspace:*","@brains/rover":"workspace:*","@brains/site-composition":"workspace:*","@brains/site-default":"workspace:*","@brains/site-personal":"workspace:*","@brains/site-professional":"workspace:*","@brains/theme-default":"workspace:*","@brains/theme-rizom":"workspace:*","@brains/typescript-config":"workspace:*","@brains/utils":"workspace:*","@types/bun":"latest",rollup:"^4.60.2","rollup-plugin-dts":"^6.4.1",typescript:"^5.3.3"},publishConfig:{access:"public"},repository:{type:"git",url:"https://github.com/rizom-ai/brains.git",directory:"packages/brain-cli"},license:"Apache-2.0",author:"Yeehaa <yeehaa@rizom.ai> (https://rizom.ai)",homepage:"https://github.com/rizom-ai/brains/tree/main/packages/brain-cli#readme",bugs:"https://github.com/rizom-ai/brains/issues",engines:{bun:">=1.3.3"},keywords:["brain","ai","cli","mcp","agent","personal-ai","knowledge-management"]};import{mkdirSync as u91,writeFileSync as Yu,chmodSync as Xu,existsSync as XkA,readFileSync as WkA}from"fs";import{basename as UkA,dirname as JkA,join as L8,resolve as OwQ}from"path";import{fileURLToPath as RwQ}from"url";var O91=`ARG BUN_VERSION=1.3.10
|
|
8305
|
+
`,$91=()=>H5("style",{children:WBQ},void 0,!1,void 0,this);import{jsxDEV as Y2,Fragment as UBQ}from"preact/jsx-dev-runtime";var nQA=({title:A,description:Q,children:B,detail:w=!1,footer:$=!1,contentClassName:f=""})=>Y2(UBQ,{children:[Y2(XQ,{title:A,description:Q},void 0,!1,void 0,this),Y2($91,{},void 0,!1,void 0,this),Y2("div",{className:`docs-handbook${w?" docs-handbook--detail":""}`,children:[Y2(B91,{},void 0,!1,void 0,this),Y2("div",{className:`${qW.wrap} ${f}`.trim(),children:[B,$&&Y2(w91,{},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),f91=({docsCount:A,sectionsCount:Q,startDoc:B})=>Y2("section",{className:"border-b border-[var(--docs-text)] py-14 md:py-24 md:pb-[72px]",children:[Y2("p",{className:`${qW.label} mb-8`,children:"Handbook \xB7 Brains docs"},void 0,!1,void 0,this),Y2("h1",{className:`${qW.display} m-0 max-w-[16ch] text-5xl leading-[1.05] tracking-[-0.02em] md:text-7xl`,children:["Build, run, and publish"," ",Y2("em",{className:"text-[var(--docs-accent)]",children:"brains."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Y2("p",{className:"mt-8 max-w-[52ch] text-lg leading-[1.65] text-[var(--docs-text-muted)]",children:"Documentation for composing brain models, managing markdown entities, wiring interfaces, and shipping generated sites."},void 0,!1,void 0,this),Y2("dl",{className:"mt-10 flex flex-wrap gap-7 docs-font-label text-xs tracking-[0.06em] text-[var(--docs-text-light)] md:mt-14 md:gap-12",children:[Y2("div",{children:[Y2("strong",{className:"mb-0.5 block font-medium text-[var(--docs-text)]",children:A},void 0,!1,void 0,this),"Documents"]},void 0,!0,void 0,this),Y2("div",{children:[Y2("strong",{className:"mb-0.5 block font-medium text-[var(--docs-text)]",children:Q},void 0,!1,void 0,this),"Sections"]},void 0,!0,void 0,this),Y2("div",{children:[Y2("strong",{className:"mb-0.5 block font-medium text-[var(--docs-text)]",children:"April 2026"},void 0,!1,void 0,this),"Updated"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Y2("div",{className:"mt-9 flex flex-wrap gap-3.5",children:[B&&Y2("a",{className:qW.primaryButton,href:g_(B),children:"Start reading"},void 0,!1,void 0,this),Y2("a",{className:qW.button,href:"#sections",children:"Browse sections"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),I91=({groups:A})=>Y2("aside",{className:"docs-rail sticky top-8 hidden docs-font-label text-xs tracking-[0.06em] text-[var(--docs-text-light)] min-[861px]:block","aria-label":"Documentation sections",children:[Y2("p",{className:"m-0 mb-3.5 font-medium text-[var(--docs-text)]",children:"Sections"},void 0,!1,void 0,this),Y2("ol",{className:"m-0 list-none p-0",children:A.map((Q,B)=>Y2("li",{className:"grid grid-cols-[32px_1fr] gap-2 py-1.5",children:[Y2("span",{className:"docs-font-display text-[var(--docs-text-light)] italic",children:[T_(B),"."]},void 0,!0,void 0,this),Y2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:`#${dQA(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),D91=({group:A,index:Q})=>Y2("article",{className:"mb-16 last:mb-0",id:dQA(Q),children:[Y2("header",{className:"mb-2 grid grid-cols-[36px_auto_1fr] items-baseline gap-x-3 border-b border-[var(--docs-border)] pb-3.5 md:grid-cols-[48px_auto_1fr] md:gap-x-5",children:[Y2("span",{className:"text-right docs-font-display text-3xl leading-[1.1] text-[var(--docs-accent)] italic md:text-4xl",children:[T_(Q),"."]},void 0,!0,void 0,this),Y2("h2",{className:`${qW.display} m-0 text-3xl leading-[1.1] tracking-[-0.015em] md:text-4xl`,children:A.section},void 0,!1,void 0,this),Y2("span",{className:"docs-chapter__leader"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Y2("ol",{className:"m-0 list-none p-0",children:A.docs.map((B)=>Y2("li",{className:"border-b border-[var(--docs-border-light)] last:border-b-0",children:Y2("a",{className:"group block py-[18px] pl-12 md:pl-[68px]",href:g_(B),children:[Y2("p",{className:"m-0 text-[22px] leading-[1.2] tracking-[-0.005em] transition-colors duration-150 group-hover:text-[var(--docs-accent)]",children:B.metadata.title},void 0,!1,void 0,this),B.metadata.description&&Y2("p",{className:"mt-1.5 mb-0 max-w-[70ch] text-sm leading-[1.55] text-[var(--docs-text-muted)]",children:B.metadata.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},B.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),H91=({title:A})=>Y2("nav",{className:"mb-8 flex flex-wrap items-baseline gap-2.5 docs-font-label text-[11px] uppercase tracking-[0.06em] text-[var(--docs-text-light)]","aria-label":"Breadcrumb",children:[Y2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/",children:"Home"},void 0,!1,void 0,this),Y2("span",{children:"/"},void 0,!1,void 0,this),Y2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/docs",children:"Docs"},void 0,!1,void 0,this),Y2("span",{children:"/"},void 0,!1,void 0,this),Y2("span",{children:A},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Y91=({groups:A,activeGroupIndex:Q,activeSlug:B})=>Y2("aside",{className:"docs-detail-rail sticky top-24 hidden max-h-[calc(100vh-120px)] overflow-auto pr-2 min-[861px]:block","aria-label":"Documentation navigation",children:Y2("nav",{className:"docs-font-label text-xs tracking-[0.06em] text-[var(--docs-text-light)]",children:[Y2("p",{className:"m-0 mb-4 border-b border-[var(--docs-text)] pb-3 text-[11px] uppercase tracking-[0.08em] text-[var(--docs-text-light)]",children:"Documentation"},void 0,!1,void 0,this),Y2("ol",{className:"m-0 list-none p-0",children:A.map((w,$)=>{let f=$===Q;return Y2("li",{className:f?"mb-[22px]":"mb-3.5",children:[Y2("a",{className:`mb-2 flex items-baseline gap-2.5 docs-font-label text-[11px] uppercase leading-[1.4] tracking-[0.06em] transition-colors duration-150 hover:text-[var(--docs-text)] ${f?"text-[var(--docs-text)]":"text-[var(--docs-text-muted)]"}`,href:`/docs#${dQA($)}`,children:[Y2("span",{className:"docs-font-display text-sm text-[var(--docs-accent)] italic",children:[T_($),"."]},void 0,!0,void 0,this)," ",w.section]},void 0,!0,void 0,this),f&&Y2("ol",{className:"mt-0.5 list-none p-0",children:w.docs.map((I)=>{let D=I.metadata.slug===B;return Y2("li",{children:Y2("a",{className:`docs-rail__doc relative block py-1.5 docs-font-body text-sm leading-[1.4] tracking-normal transition-[color,padding-left] duration-150 hover:text-[var(--docs-text)] ${D?"pl-3.5 font-medium text-[var(--docs-accent)]":"text-[var(--docs-text-muted)]"}`,href:g_(I),"aria-current":D?"page":void 0,children:I.metadata.title},void 0,!1,void 0,this)},I.id,!1,void 0,this)})},void 0,!1,void 0,this)]},w.section,!0,void 0,this)})},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),X91=({prevDoc:A,nextDoc:Q})=>{if(!A&&!Q)return null;return Y2("nav",{className:"mt-12 grid grid-cols-1 gap-5 border-t border-[var(--docs-border)] pt-7 md:grid-cols-2","aria-label":"Previous and next docs",children:[A?Y2("a",{className:"group border-t border-[var(--docs-border-light)] pt-[18px] transition-colors duration-150 hover:border-[var(--docs-accent)]",href:g_(A),children:[Y2("span",{className:"block docs-font-label text-[10.5px] uppercase tracking-[0.22em] text-[var(--docs-text-light)]",children:"Previous"},void 0,!1,void 0,this),Y2("span",{className:"mt-2 block docs-font-display text-[22px] leading-[1.2] text-[var(--docs-heading)] transition-colors duration-150 group-hover:text-[var(--docs-accent)]",children:["\u2190 ",A.metadata.title]},void 0,!0,void 0,this)]},void 0,!0,void 0,this):Y2("span",{},void 0,!1,void 0,this),Q&&Y2("a",{className:"group border-t border-[var(--docs-border-light)] pt-[18px] text-left transition-colors duration-150 hover:border-[var(--docs-accent)] md:text-right",href:g_(Q),children:[Y2("span",{className:"block docs-font-label text-[10.5px] uppercase tracking-[0.22em] text-[var(--docs-text-light)]",children:"Next"},void 0,!1,void 0,this),Y2("span",{className:"mt-2 block docs-font-display text-[22px] leading-[1.2] text-[var(--docs-heading)] transition-colors duration-150 group-hover:text-[var(--docs-accent)]",children:[Q.metadata.title," \u2192"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as S_}from"preact/jsx-dev-runtime";var nPA=({docs:A})=>{let Q=fu(A),B=rQA(Q),$=Q.filter((f)=>f.metadata.slug!=="index")[0]??Q[0];return S_(nQA,{title:"Documentation",description:"Brains documentation",children:[S_(f91,{docsCount:A.length,sectionsCount:B.length,startDoc:$},void 0,!1,void 0,this),S_("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:[S_(I91,{groups:B},void 0,!1,void 0,this),S_("div",{children:B.map((f,I)=>S_(D91,{group:f,index:I},f.section,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as dI}from"preact/jsx-dev-runtime";var oPA=({doc:A,docs:Q,prevDoc:B,nextDoc:w})=>{let $=rQA(Q.length>0?Q:[A]),f=fu(Q.length>0?Q:[A]),I=f.findIndex((H)=>H.metadata.slug===A.metadata.slug),D=Math.max($.findIndex((H)=>H.docs.some((Y)=>Y.metadata.slug===A.metadata.slug)),0);return dI(nQA,{title:A.metadata.title,description:A.metadata.description??A.metadata.section,detail:!0,footer:!0,contentClassName:"pt-16",children:[dI(H91,{title:A.metadata.title},void 0,!1,void 0,this),dI("div",{className:"grid items-start gap-10 py-8 pb-24 md:grid-cols-[240px_minmax(0,1fr)] md:gap-20",children:[dI(Y91,{groups:$,activeGroupIndex:D,activeSlug:A.metadata.slug},void 0,!1,void 0,this),dI("article",{className:"min-w-0",children:[dI("header",{className:"mb-10 border-b border-[var(--docs-border)] pb-8",children:[dI("p",{className:`${qW.label} m-0 mb-6 flex items-baseline gap-3`,children:[dI("span",{className:"docs-font-display text-lg leading-none tracking-normal normal-case text-[var(--docs-accent)] italic",children:[T_(D),"."]},void 0,!0,void 0,this)," ",A.metadata.section,I>=0?` \xB7 ${I+1}/${f.length}`:""]},void 0,!0,void 0,this),dI("h1",{className:`${qW.display} m-0 max-w-[18ch] text-4xl leading-[1.05] tracking-[-0.02em] md:text-6xl`,children:A.metadata.title},void 0,!1,void 0,this),A.metadata.description&&dI("p",{className:"mt-6 max-w-[56ch] docs-font-display text-[22px] font-[350] leading-[1.5] text-[var(--docs-text-muted)]",children:A.metadata.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this),dI("div",{className:"docs-article__body",children:dI(mI,{markdown:A.body},void 0,!1,void 0,this)},void 0,!1,void 0,this),dI(X91,{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 JBQ=F.object({docs:F.array(FG),pagination:Y9.nullable(),baseUrl:F.string().optional()}),GBQ=F.object({doc:FG,docs:F.array(FG),prevDoc:FG.nullable(),nextDoc:FG.nullable()});function W91(){return{"doc-list":O1({name:"doc-list",description:"Documentation index template",schema:JBQ,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:nPA}}),"doc-detail":O1({name:"doc-detail",description:"Documentation page template",schema:GBQ,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:oPA}})}}var U91={name:"@brains/doc",private:!0,version:"0.2.0-alpha.71",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 sPA extends KQ{entityType=lQA.entityType;schema=y_;adapter=lQA;constructor(){super("docs",U91,{},void 0)}getTemplates(){return W91()}getDataSources(){return[new iQA(this.logger.child("DocDataSource"))]}}function aPA(){return new sPA}f0();GA();GA();d5();var J91=F.object({label:F.string(),href:F.string()}),G91=F.object({label:F.string(),title:F.string(),detail:F.string()}),KBQ=F.object({eyebrow:F.string(),name:F.string(),sub:F.string()}),ZBQ=F.object({tone:F.enum(["capture","synthesis","share"]),title:F.string(),text:F.string()}),tPA=F.object({captures:F.number(),links:F.number(),topics:F.number(),summaries:F.number(),peers:F.number()}),m_=F.object({eyebrow:F.string(),headline:F.string(),intro:F.string(),primaryCta:J91,secondaryCta:J91,inputs:F.array(G91).min(1),outputs:F.array(G91).min(1),core:KBQ,legend:F.array(ZBQ).min(1)}),ePA=m_.extend({counts:tPA}),F91={eyebrow:"A team brain, diagrammed",headline:"Relay sits between the work and the world, and keeps both honest.",intro:"Capture sources flow into a shared brain; the brain organizes, summarizes, and \u2014 selectively \u2014 exposes a public surface. Everything else stays private and operational.",primaryCta:{label:"See it on a real team",href:"#diagram"},secondaryCta:{label:"Read the model",href:"/about"},inputs:[{label:"Source \xB7 chat",title:"Discord",detail:"Shared decisions and field notes captured in flow."},{label:"Source \xB7 agent",title:"MCP / CLI",detail:"Structured captures from tools and assistants."},{label:"Source \xB7 web",title:"Links & docs",detail:"External material indexed with sourceable metadata."}],outputs:[{label:"Surface \xB7 public",title:"Default site",detail:"A small, durable face onto what the team currently knows."},{label:"Surface \xB7 agents",title:"A2A exchange",detail:"Peer brains coordinate over an approved, signed protocol."},{label:"Surface \xB7 query",title:"Team Q&A",detail:"Ask the brain in chat; answers cite the captures behind them."}],core:{eyebrow:"The relay",name:"brain",sub:"capture \u2192 topics \u2192 summaries"},legend:[{tone:"capture",title:"Capture",text:"Anything the team already does that produces a trace \u2014 chat messages, links, deploys, decisions."},{tone:"synthesis",title:"Synthesis",text:"The work the brain does on its own time \u2014 clustering captures into topics, summaries, and durable memory."},{tone:"share",title:"Share",text:"A small, opinionated public surface and an approved agent-to-agent protocol. Most memory stays private."}]},K91=new RB(m_,{title:"Home diagram",mappings:[{key:"eyebrow",label:"Eyebrow",type:"string"},{key:"headline",label:"Headline",type:"string"},{key:"intro",label:"Intro",type:"string"},{key:"primaryCta",label:"Primary CTA",type:"object",children:[{key:"label",label:"Label",type:"string"},{key:"href",label:"Href",type:"string"}]},{key:"secondaryCta",label:"Secondary CTA",type:"object",children:[{key:"label",label:"Label",type:"string"},{key:"href",label:"Href",type:"string"}]},{key:"inputs",label:"Inputs",type:"array",itemType:"object",itemMappings:[{key:"label",label:"Label",type:"string"},{key:"title",label:"Title",type:"string"},{key:"detail",label:"Detail",type:"string"}]},{key:"outputs",label:"Outputs",type:"array",itemType:"object",itemMappings:[{key:"label",label:"Label",type:"string"},{key:"title",label:"Title",type:"string"},{key:"detail",label:"Detail",type:"string"}]},{key:"core",label:"Core",type:"object",children:[{key:"eyebrow",label:"Eyebrow",type:"string"},{key:"name",label:"Name",type:"string"},{key:"sub",label:"Sub",type:"string"}]},{key:"legend",label:"Legend",type:"array",itemType:"object",itemMappings:[{key:"tone",label:"Tone",type:"string"},{key:"title",label:"Title",type:"string"},{key:"text",label:"Text",type:"string"}]}]});function oQA(A){return K91.parse(A)}function Z91(A){return K91.format(A)}GA();var NBQ=F.object({query:F.object({routeId:F.string().default("home"),sectionId:F.string().default("diagram")}).default({routeId:"home",sectionId:"diagram"})}).passthrough(),zBQ={captures:"base",links:"link",topics:"topic",summaries:"summary",peers:"agent"};class AkA{id="relay-site:home-counts";name="Relay homepage counts";description="Fetches Relay homepage content and live entity counts for the system diagram";async fetch(A,Q,B){let w=NBQ.parse(A??{}),$=await this.fetchContent(B,w.query.routeId,w.query.sectionId),f=await this.fetchCounts(B);return Q.parse({...$,counts:f})}async fetchContent(A,Q,B){let w=await A.entityService.getEntity({entityType:"site-content",id:`${Q}:${B}`});if(!w?.content)return F91;return m_.parse(oQA(w.content))}async fetchCounts(A){let Q=await Promise.all(Object.entries(zBQ).map(async([B,w])=>[B,await this.countOrZero(A,w)]));return tPA.parse(Object.fromEntries(Q))}async countOrZero(A,Q){if(!A.entityService.hasEntityType(Q))return 0;try{return await A.entityService.countEntities({entityType:Q})}catch{return 0}}}import{jsxDEV as w1}from"preact/jsx-dev-runtime";var N91=F.object({label:F.string(),href:F.string()}),qBQ=F.object({eyebrow:F.string(),headline:F.string(),intro:F.string(),primaryCta:N91,secondaryCta:N91,signals:F.array(F.object({label:F.string(),value:F.string(),note:F.string()}))}),CBQ=F.object({eyebrow:F.string(),title:F.string(),intro:F.string(),steps:F.array(F.object({phase:F.string(),title:F.string(),text:F.string()}))}),LBQ=F.object({title:F.string(),intro:F.string(),cards:F.array(F.object({label:F.string(),title:F.string(),text:F.string()}))}),EBQ=F.object({title:F.string(),intro:F.string(),points:F.array(F.string())}),MBQ={title:"Relay is a collaborative team-memory brain.",intro:"It exists for teams that need to remember together: capturing what happened, summarizing why it matters, and coordinating with trusted peer brains when work crosses boundaries.",points:["Not a personal blog engine or portfolio shell.","Not a marketing automation stack.","A small public face for a larger private knowledge workflow."]},VBQ="font-body text-[15px] text-theme-muted transition-colors hover:text-theme";function z91({href:A,label:Q}){return w1("a",{href:A,className:VBQ,children:Q},void 0,!1,void 0,this)}function bBQ({siteInfo:A,children:Q}){let B=[...A.navigation.primary,...A.navigation.secondary],w=A.cta??{buttonText:"Start here",buttonLink:"/about"};return w1(O_,{children:[w1("nav",{className:"fixed left-0 right-0 top-0 z-[100] flex items-center justify-between border-b border-theme-light bg-nav-fade px-6 py-4 backdrop-blur-[12px] md:px-10 xl:px-20",children:[w1("a",{href:"/",className:"font-nav text-[20px]","aria-label":"Relay home",children:[w1("span",{className:"font-bold text-theme",children:"relay"},void 0,!1,void 0,this),w1("span",{className:"font-bold text-accent",children:"."},void 0,!1,void 0,this),w1("span",{className:"text-theme-muted",children:"brain"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),w1("div",{className:"flex items-center gap-5 md:gap-8",children:[w1("div",{className:"hidden items-center gap-6 md:flex",children:B.map(($)=>w1(z91,{...$},`${$.href}-${$.label}`,!1,void 0,this))},void 0,!1,void 0,this),w1("a",{href:w.buttonLink,className:"rounded-[999px] border border-theme px-4 py-2 font-body text-[13px] font-semibold text-theme transition-colors hover:border-accent hover:text-accent md:px-5",children:w.buttonText},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),w1("main",{children:Q},void 0,!1,void 0,this),w1("footer",{className:"relative z-[1] border-t border-theme-light px-6 py-8 md:px-10 xl:px-20",children:w1("div",{className:"flex flex-col gap-4 md:flex-row md:items-center md:justify-between",children:[w1("div",{children:[w1("p",{className:"font-label text-label-sm uppercase tracking-[0.22em] text-theme-light",children:A.copyright},void 0,!1,void 0,this),w1("p",{className:"mt-2 max-w-[560px] font-body text-body-xs text-theme-muted",children:A.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this),w1("div",{className:"flex flex-wrap items-center gap-5",children:[B.map(($)=>w1(z91,{...$},`footer-${$.href}-${$.label}`,!1,void 0,this)),w1("button",{id:"themeToggle","aria-label":"Toggle light mode",className:"rounded-md border border-theme-light bg-transparent px-2.5 py-1.5 font-body text-label-md text-theme-light transition-colors hover:border-theme hover:text-theme",children:"\u2600 Light"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}var OBQ=({sections:A,siteInfo:Q})=>w1(bBQ,{siteInfo:Q,children:A},void 0,!1,void 0,this);function RBQ({eyebrow:A,headline:Q,intro:B,primaryCta:w,secondaryCta:$,signals:f}){return w1(aZ,{className:"min-h-[92vh] pt-[152px] pb-20 md:pt-[190px]",children:w1("div",{className:"grid gap-10 lg:grid-cols-[minmax(0,1fr)_420px] lg:items-end",children:[w1("div",{children:[w1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:A},void 0,!1,void 0,this),w1("h1",{className:"mt-7 max-w-[980px] font-display text-display-lg text-theme",children:Q},void 0,!1,void 0,this),w1("p",{className:"mt-7 max-w-[720px] font-body text-body-lg text-theme-muted",children:B},void 0,!1,void 0,this),w1("div",{className:"mt-10 flex flex-col gap-3 sm:flex-row",children:[w1(iC,{href:w.href,size:"lg",variant:"primary-strong",children:w.label},void 0,!1,void 0,this),w1(iC,{href:$.href,size:"lg",variant:"secondary",children:$.label},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),w1("div",{className:"rounded-[32px] border border-card-relay-border bg-card-relay-bg p-5 shadow-[0_24px_90px_var(--color-glow-relay)] backdrop-blur-sm",children:[w1("p",{className:"font-label text-label-xs uppercase tracking-[0.24em] text-theme-light",children:"Live relay signals"},void 0,!1,void 0,this),w1("div",{className:"mt-5 grid gap-3",children:f.map((I)=>w1("div",{className:"rounded-[22px] border border-card-divider bg-bg-muted p-5",children:[w1("div",{className:"flex items-center justify-between gap-4",children:[w1("p",{className:"font-label text-label-xs uppercase tracking-[0.18em] text-secondary",children:I.label},void 0,!1,void 0,this),w1("span",{className:"h-2 w-2 rounded-full bg-accent shadow-[0_0_22px_var(--color-accent)]"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),w1("p",{className:"mt-4 font-display text-display-sm text-theme",children:I.value},void 0,!1,void 0,this),w1("p",{className:"mt-2 font-body text-body-xs text-theme-muted",children:I.note},void 0,!1,void 0,this)]},I.label,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)}function _BQ({eyebrow:A,title:Q,intro:B,steps:w}){return w1(aZ,{id:"operating-loop",className:"py-section",children:[w1("div",{className:"max-w-[840px]",children:[w1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-secondary",children:A},void 0,!1,void 0,this),w1("h2",{className:"mt-5 font-display text-display-md text-theme",children:Q},void 0,!1,void 0,this),w1("p",{className:"mt-5 font-body text-body-md text-theme-muted",children:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this),w1("div",{className:"mt-12 grid gap-4 md:grid-cols-3",children:w.map(($)=>w1("article",{className:"min-h-[300px] rounded-[28px] border border-card-panel-border bg-card-panel-bg p-6",children:[w1("p",{className:"font-label text-label-sm text-accent",children:$.phase},void 0,!1,void 0,this),w1("h3",{className:"mt-16 font-display text-display-sm text-theme",children:$.title},void 0,!1,void 0,this),w1("p",{className:"mt-4 font-body text-body-sm text-theme-muted",children:$.text},void 0,!1,void 0,this)]},$.phase,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function PBQ({title:A,intro:Q,cards:B}){return w1(aZ,{className:"py-section",children:w1("div",{className:"rounded-[36px] border border-theme-light bg-bg-muted p-6 md:p-10",children:w1("div",{className:"grid gap-8 lg:grid-cols-[360px_1fr]",children:[w1("div",{children:[w1("h2",{className:"font-display text-display-md text-theme",children:A},void 0,!1,void 0,this),w1("p",{className:"mt-5 font-body text-body-md text-theme-muted",children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this),w1("div",{className:"grid gap-4",children:B.map((w)=>w1("article",{className:"rounded-[24px] border border-card-divider bg-bg-subtle/70 p-5",children:[w1("p",{className:"font-label text-label-xs uppercase tracking-[0.22em] text-accent",children:w.label},void 0,!1,void 0,this),w1("h3",{className:"mt-3 font-nav text-heading-lg text-theme",children:w.title},void 0,!1,void 0,this),w1("p",{className:"mt-2 font-body text-body-sm text-theme-muted",children:w.text},void 0,!1,void 0,this)]},w.title,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function kBQ({title:A,intro:Q,points:B}){return w1(aZ,{className:"min-h-[78vh] pt-[150px] pb-section md:pt-[190px]",children:[w1("div",{className:"max-w-[920px]",children:[w1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:"Relay model"},void 0,!1,void 0,this),w1("h1",{className:"mt-6 font-display text-display-lg text-theme",children:A},void 0,!1,void 0,this),w1("p",{className:"mt-7 font-body text-body-lg text-theme-muted",children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this),w1("div",{className:"mt-12 grid gap-4 md:grid-cols-3",children:B.map((w)=>w1("div",{className:"rounded-[24px] border border-card-panel-current-border bg-card-panel-current-bg p-6 font-body text-body-md text-theme",children:w},w,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}var jBQ=(A)=>{switch(A){case"capture":return"bg-accent";case"synthesis":return"bg-secondary";case"share":return"bg-accent-bright"}},vBQ=(A)=>new Intl.NumberFormat("en",{notation:A>999?"compact":"standard"}).format(A),Iu=(A,Q,B=`${Q}s`)=>`${vBQ(A)} ${A===1?Q:B}`;function xBQ({eyebrow:A,headline:Q,intro:B,primaryCta:w,secondaryCta:$,inputs:f,outputs:I,core:D,legend:H,counts:Y}){let W=[{key:"captures",className:"top-[-10px] left-1/2 -translate-x-1/2",label:Iu(Y.captures,"capture")},{key:"topics",className:"top-1/2 right-[-28px] -translate-y-1/2",label:Iu(Y.topics,"topic")},{key:"peers",className:"bottom-[-10px] left-1/2 -translate-x-1/2",label:Iu(Y.peers,"peer brain")},{key:"summaries",className:"top-1/2 left-[-28px] -translate-y-1/2",label:Iu(Y.summaries,"summary","summaries")}];return w1(aZ,{className:"pt-[150px] pb-section md:pt-[190px]",id:"diagram",children:[w1("div",{className:"mx-auto max-w-[1040px] text-center",children:[w1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:A},void 0,!1,void 0,this),w1("h1",{className:"mx-auto mt-7 max-w-[22ch] font-display text-display-lg text-theme",children:Q},void 0,!1,void 0,this),w1("p",{className:"mx-auto mt-7 max-w-[64ch] font-body text-body-lg text-theme-muted",children:B},void 0,!1,void 0,this),w1("div",{className:"mt-10 flex flex-col justify-center gap-3 sm:flex-row",children:[w1(iC,{href:w.href,size:"lg",variant:"primary-strong",children:w.label},void 0,!1,void 0,this),w1(iC,{href:$.href,size:"lg",variant:"secondary",children:$.label},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),w1("div",{className:"mx-auto mt-20 max-w-[1020px] rounded-[32px] border border-theme-light bg-[radial-gradient(circle_at_1px_1px,rgb(255_255_255_/_0.05)_1px,transparent_0),linear-gradient(180deg,rgb(255_255_255_/_0.02),transparent)] bg-[length:24px_24px,100%_100%] px-6 py-14",children:[w1("div",{className:"grid items-center gap-8 lg:grid-cols-[1fr_1.4fr_1fr]",children:[w1("div",{className:"flex flex-col gap-3.5",children:f.map((G)=>w1("div",{className:"rounded-2xl border border-card-panel-border border-l-2 border-l-accent bg-card-panel-bg px-4 py-4 text-left backdrop-blur-sm",children:[w1("p",{className:"font-label text-[10px] uppercase tracking-[0.22em] text-secondary",children:G.label},void 0,!1,void 0,this),w1("h2",{className:"mt-1.5 font-display text-[18px] font-medium text-theme",children:G.title},void 0,!1,void 0,this),w1("p",{className:"mt-1 font-body text-[13px] leading-[1.5] text-theme-muted",children:G.detail},void 0,!1,void 0,this)]},`${G.label}-${G.title}`,!0,void 0,this))},void 0,!1,void 0,this),w1("div",{className:"relative mx-auto grid aspect-square w-full max-w-[320px] place-items-center rounded-full bg-[radial-gradient(circle_at_center,rgb(232_119_34_/_0.25),transparent_65%)]",children:[w1("div",{className:"absolute inset-0 rounded-full border border-dashed border-accent/30"},void 0,!1,void 0,this),w1("div",{className:"absolute inset-6 animate-spin rounded-full border border-dashed border-secondary/40 [animation-duration:28s]"},void 0,!1,void 0,this),W.map((G)=>w1("span",{className:`absolute whitespace-nowrap rounded-full border border-theme bg-bg px-2.5 py-1 font-label text-[10px] uppercase tracking-[0.18em] text-theme-light ${G.className}`,children:G.label},G.key,!1,void 0,this)),w1("div",{className:"relative z-[1] px-6 text-center",children:[w1("p",{className:"font-label text-[10px] uppercase tracking-[0.28em] text-accent",children:D.eyebrow},void 0,!1,void 0,this),w1("p",{className:"mt-2 font-display text-[36px] leading-none text-theme",children:D.name},void 0,!1,void 0,this),w1("p",{className:"mt-2 font-body text-[13px] text-theme-muted",children:D.sub},void 0,!1,void 0,this),w1("p",{className:"mt-4 font-label text-[10px] uppercase tracking-[0.18em] text-theme-light",children:[Iu(Y.links,"link")," indexed"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),w1("div",{className:"flex flex-col gap-3.5",children:I.map((G)=>w1("div",{className:"rounded-2xl border border-card-panel-border border-r-2 border-r-secondary bg-card-panel-bg px-4 py-4 text-left backdrop-blur-sm",children:[w1("p",{className:"font-label text-[10px] uppercase tracking-[0.22em] text-secondary",children:G.label},void 0,!1,void 0,this),w1("h2",{className:"mt-1.5 font-display text-[18px] font-medium text-theme",children:G.title},void 0,!1,void 0,this),w1("p",{className:"mt-1 font-body text-[13px] leading-[1.5] text-theme-muted",children:G.detail},void 0,!1,void 0,this)]},`${G.label}-${G.title}`,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),w1("div",{className:"mt-14 grid gap-4 border-t border-theme-light pt-8 md:grid-cols-3",children:H.map((G)=>w1("div",{className:"text-left",children:[w1("h2",{className:"font-display text-[16px] font-medium text-theme",children:[w1("span",{className:`mr-2.5 inline-block h-3 w-3 rounded-[3px] align-middle ${jBQ(G.tone)}`},void 0,!1,void 0,this),G.title]},void 0,!0,void 0,this),w1("p",{className:"mt-1.5 font-body text-[13px] leading-[1.6] text-theme-muted",children:G.text},void 0,!1,void 0,this)]},G.title,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}var hBQ=O1({name:"home-diagram",description:"Relay homepage system diagram with live entity counts",schema:ePA,formatter:{parse:(A)=>ePA.parse({...oQA(A),counts:{captures:0,links:0,topics:0,summaries:0,peers:0}}),format:(A)=>Z91(m_.parse(A))},dataSourceId:"relay-site:home-counts",requiredPermission:"public",layout:{component:xBQ}}),yBQ=(A)=>RBQ(qBQ.parse(A)),gBQ=(A)=>_BQ(CBQ.parse(A)),TBQ=(A)=>PBQ(LBQ.parse(A)),SBQ=(A)=>kBQ(EBQ.parse(A)),q91={type:"object",label:"CTA",fields:{label:{type:"string",label:"Label"},href:{type:"string",label:"Href"}}},C91={namespace:"relay-site",sections:{"home-hero":{title:"Home hero",description:"Relay homepage hero section",layout:yBQ,fields:{eyebrow:{type:"string",label:"Eyebrow"},headline:{type:"string",label:"Headline"},intro:{type:"string",label:"Intro"},primaryCta:{...q91,label:"Primary CTA"},secondaryCta:{...q91,label:"Secondary CTA"},signals:{type:"array",label:"Signals",minItems:1,items:{type:"object",label:"Signal",fields:{label:{type:"string",label:"Label"},value:{type:"string",label:"Value"},note:{type:"string",label:"Note"}}}}}},"home-loop":{title:"Home operating loop",description:"Relay capture, synthesis, and sharing loop",layout:gBQ,fields:{eyebrow:{type:"string",label:"Eyebrow"},title:{type:"string",label:"Title"},intro:{type:"string",label:"Intro"},steps:{type:"array",label:"Steps",minItems:1,items:{type:"object",label:"Step",fields:{phase:{type:"string",label:"Phase"},title:{type:"string",label:"Title"},text:{type:"string",label:"Text"}}}}}},"home-surface":{title:"Home surface",description:"Relay default template explanation cards",layout:TBQ,fields:{title:{type:"string",label:"Title"},intro:{type:"string",label:"Intro"},cards:{type:"array",label:"Cards",minItems:1,items:{type:"object",label:"Card",fields:{label:{type:"string",label:"Label"},title:{type:"string",label:"Title"},text:{type:"string",label:"Text"}}}}}},about:{title:"About Relay",description:"Default Relay about page",layout:SBQ,fields:{title:{type:"string",label:"Title"},intro:{type:"string",label:"Intro"},points:{type:"array",label:"Points",minItems:1,items:{type:"string",label:"Point"}}}}}},mBQ=[{id:"home",path:"/",title:"Relay",description:"Collaborative team memory and synthesis brain",layout:"default",navigation:{show:!0,label:"Home",slot:"secondary",priority:10},sections:[{id:"diagram",template:"relay-site:home-diagram"}]},{id:"about",path:"/about",title:"About Relay",description:"What Relay is designed to do",layout:"default",navigation:{show:!0,label:"About",slot:"primary",priority:20},sections:[{id:"about",template:"relay-site:about",content:MBQ}]}],L91=vPA({packageName:"@brains/relay/site",contentNamespace:"relay-site",themeProfile:"studio",layout:OBQ,routes:mBQ,templates:{"home-diagram":hBQ},dataSources:[new AkA]});var E91=["prompt","directory-sync","note","link","topics","conversation-memory","agents","assessment","auth-service","cms","dashboard","mcp","webserver","discord","a2a"],M91=[...E91,"image","site-info","site-content","site-builder"],cBQ=[...M91,"docs","decks"],pBQ=["Relay is a collaborative team-memory and synthesis brain. Optimize for capturing shared context, finding what the team already knows, summarizing cross-source evidence, and coordinating with peer brains.","Relay is not Rover-for-teams: do not default to personal branding, blog publishing, newsletters, social media, portfolio, or marketing workflows unless the installed plugins and user request explicitly support them.",'Relay entity mappings: "memo", "note", "team note", "capture" \u2192 entityType: base; "summary", "sync", "team digest" \u2192 entityType: summary; "decision" \u2192 entityType: decision; "action item", "todo" \u2192 entityType: action-item; "handbook", "doc", "documentation" \u2192 entityType: doc; "deck", "walkthrough", "presentation" \u2192 entityType: deck; "agent", "peer brain", "contact" \u2192 entityType: agent.'],V91=QK({name:"relay",version:"0.1.0",model:"gpt-5.4-mini",site:L91,theme:R_,presets:{core:E91,default:M91,full:cBQ},evalDisable:["webserver","mcp","discord"],agentInstructions:pBQ,capabilities:[["prompt",cC,void 0],["note",xC,{}],["link",yC,{}],["image",yx,void 0],["topics",M2A,{includeEntityTypes:["base","link","summary","agent","swot","deck","doc","anchor-profile","brain-character"],extractableStatuses:["published","draft"]}],["conversation-memory",iPA,{}],["docs",aPA,void 0],["decks",Km,void 0],["agents",$QA,void 0],["assessment",GQA,void 0],["auth-service",Vy,void 0],["cms",uC,{}],["dashboard",nZ,void 0],["directory-sync",aq,{seedContent:!0,seedContentPath:uBQ(import.meta.dir,"..","seed-content"),initialSync:!0}],["site-content",sm,{definitions:C91}],["rizom-ecosystem",pC,void 0],["site-info",kC,void 0],["site-builder",PC,{}]],interfaces:[["mcp",hK,()=>({})],["discord",KZ,()=>({captureUrls:!0})],["a2a",AR,()=>({})],["webserver",ZZ,()=>({})]],permissions:{rules:[{pattern:"cli:*",level:"anchor"},{pattern:"mcp:stdio",level:"anchor"},{pattern:"mcp:http",level:"anchor"},{pattern:"discord:*",level:"public"}]},deployment:{cdn:{enabled:!0,provider:"bunny"}}});import{readFileSync as L5Q}from"fs";import{join as E5Q}from"path";import{execSync as M5Q}from"child_process";import{parseArgs as rBQ}from"util";var dBQ={model:{type:"string"},domain:{type:"string"},"content-repo":{type:"string"},backend:{type:"string"},"push-to":{type:"string"},"ai-api-key":{type:"string"},"no-interactive":{type:"boolean"},preview:{type:"boolean"},deploy:{type:"boolean"},regen:{type:"boolean"},all:{type:"boolean"},only:{type:"string"},"dry-run":{type:"boolean"},"startup-check":{type:"boolean"},"storage-dir":{type:"string"},yes:{type:"boolean"},remote:{type:"string"},token:{type:"string"},help:{type:"boolean",short:"h"},version:{type:"boolean",short:"v"}};function CW(A,Q){let B=A[Q];return typeof B==="string"?B:void 0}function A3(A,Q){let B=A[Q];return typeof B==="boolean"?B:void 0}function b91(A){let{values:Q,positionals:B}=rBQ({args:A,options:dBQ,allowPositionals:!0,strict:!1});if(Q.help)return{command:"help",args:[],flags:{help:!0}};if(Q.version)return{command:"version",args:[],flags:{version:!0}};return{command:B[0]??"help",args:B.slice(1),flags:{model:CW(Q,"model"),domain:CW(Q,"domain"),"content-repo":CW(Q,"content-repo"),backend:CW(Q,"backend"),"push-to":CW(Q,"push-to"),"ai-api-key":CW(Q,"ai-api-key"),"no-interactive":A3(Q,"no-interactive"),preview:A3(Q,"preview"),deploy:A3(Q,"deploy"),regen:A3(Q,"regen"),all:A3(Q,"all"),only:CW(Q,"only"),"dry-run":A3(Q,"dry-run"),"startup-check":A3(Q,"startup-check"),"storage-dir":CW(Q,"storage-dir"),yes:A3(Q,"yes"),remote:CW(Q,"remote"),token:CW(Q,"token")}}}Du();import{mkdirSync as U5Q}from"fs";import{join as J5Q}from"path";import{execSync as G5Q}from"child_process";var aQA={name:"@rizom/brain",version:"0.2.0-alpha.71",description:"Brain runtime + CLI \u2014 scaffold, run, and manage AI brain instances",type:"module",bin:{brain:"./dist/brain.js"},exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.js"},"./cli":"./dist/brain.js","./plugins":{types:"./dist/plugins.d.ts",import:"./dist/plugins.js"},"./entities":{types:"./dist/entities.d.ts",import:"./dist/entities.js"},"./services":{types:"./dist/services.d.ts",import:"./dist/services.js"},"./interfaces":{types:"./dist/interfaces.d.ts",import:"./dist/interfaces.js"},"./templates":{types:"./dist/templates.d.ts",import:"./dist/templates.js"},"./site":{types:"./dist/site.d.ts",import:"./dist/site.js"},"./themes":{types:"./dist/themes.d.ts",import:"./dist/themes.js"},"./deploy":{types:"./dist/deploy.d.ts",import:"./dist/deploy.js"},"./tsconfig.instance.json":"./tsconfig.instance.json"},files:["dist","templates","tsconfig.instance.json"],scripts:{build:"bun scripts/build.ts",prepublishOnly:"bun scripts/build.ts","dev:start":"bun dist/brain.js start",typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts"},dependencies:{"@clack/prompts":"^0.11.0","@modelcontextprotocol/sdk":"^1.24.0","@tailwindcss/postcss":"^4.1.13","@tailwindcss/typography":"^0.5.19",postcss:"^8.5.6",preact:"^10.27.2","preact-render-to-string":"^6.3.1",tailwindcss:"^4.1.11"},optionalDependencies:{"@bitwarden/sdk-napi":"^1.0.0","@libsql/client":"^0.15.7","@tailwindcss/oxide":"^4.1.4","better-sqlite3":"^11.8.1",lightningcss:"^1.29.2","react-devtools-core":"^6.1.1",sharp:"^0.34.5"},devDependencies:{"@brains/app":"workspace:*","@brains/content-formatters":"workspace:*","@brains/deploy-support":"workspace:*","@brains/eslint-config":"workspace:*","@brains/mcp-service":"workspace:*","@brains/plugins":"workspace:*","@brains/ranger":"workspace:*","@brains/relay":"workspace:*","@brains/rover":"workspace:*","@brains/site-composition":"workspace:*","@brains/site-default":"workspace:*","@brains/site-personal":"workspace:*","@brains/site-professional":"workspace:*","@brains/theme-default":"workspace:*","@brains/theme-rizom":"workspace:*","@brains/typescript-config":"workspace:*","@brains/utils":"workspace:*","@types/bun":"latest",rollup:"^4.60.2","rollup-plugin-dts":"^6.4.1",typescript:"^5.3.3"},publishConfig:{access:"public"},repository:{type:"git",url:"https://github.com/rizom-ai/brains.git",directory:"packages/brain-cli"},license:"Apache-2.0",author:"Yeehaa <yeehaa@rizom.ai> (https://rizom.ai)",homepage:"https://github.com/rizom-ai/brains/tree/main/packages/brain-cli#readme",bugs:"https://github.com/rizom-ai/brains/issues",engines:{bun:">=1.3.3"},keywords:["brain","ai","cli","mcp","agent","personal-ai","knowledge-management"]};import{mkdirSync as u91,writeFileSync as Yu,chmodSync as Xu,existsSync as XkA,readFileSync as WkA}from"fs";import{basename as UkA,dirname as JkA,join as L8,resolve as OwQ}from"path";import{fileURLToPath as RwQ}from"url";var O91=`ARG BUN_VERSION=1.3.10
|
|
8306
8306
|
FROM oven/bun:\${BUN_VERSION}-slim AS runtime
|
|
8307
8307
|
|
|
8308
8308
|
WORKDIR /app
|