@rizom/brain 0.2.0-alpha.60 → 0.2.0-alpha.61
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/brain.js +31 -31
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/site.js +4 -4
- package/dist/site.js.map +1 -1
- package/package.json +1 -1
package/dist/brain.js
CHANGED
|
@@ -568,7 +568,7 @@ ${G}`,args:{...$,...D,id:f.id,confirmed:!0,contentHash:f.contentHash}}},{visibil
|
|
|
568
568
|
hash text NOT NULL,
|
|
569
569
|
created_at numeric
|
|
570
570
|
)
|
|
571
|
-
`;await A.session.run($);let f=(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 Y of B)if(!f||Number(f[2])<Y.folderMillis){for(let H of Y.sql)D.push(A.run(hA.raw(H)));D.push(A.run(hA`INSERT INTO ${hA.identifier(w)} ("hash", "created_at") VALUES(${Y.hash}, ${Y.folderMillis})`))}await A.session.migrate(D)}var rr=l(()=>{Z80();z5()});async function z80(A,Q){let B=Q?.child("entity-migrate")??QQ.getInstance().child("entity-migrate"),{db:w,client:$,url:I}=Nl(A);B.debug("Running entity database migrations...");try{await ql($,I);let D=import.meta.url.includes("/dist/")?new URL("./migrations/entity-service",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await vM(w,{migrationsFolder:D}),await Cl($),B.debug("Entity database migrations completed successfully")}catch(f){throw B.error("Entity database migration failed:",f),f}finally{$.close()}}var N80=l(()=>{rr();K9A();JA()});async function q80(A,Q){let B=Q?.child("job-queue-migrate")??QQ.getInstance().child("job-queue-migrate"),{db:w,client:$,url:I}=Kl(A);B.debug("Running job queue migrations...");try{await Zl($,I);let D=import.meta.url.includes("/dist/")?new URL("./migrations/job-queue",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await vM(w,{migrationsFolder:D}),B.debug("Job queue migrations completed successfully")}catch(f){throw B.error("Job queue migration failed:",f),f}finally{$.close()}}var C80=l(()=>{rr();I9A();JA()});async function E80(A,Q){let B=Q?.child("conversation-migrate")??QQ.getInstance().child("conversation-migrate"),{db:w,client:$,url:I}=kl(A);B.debug("Running conversation database migrations...");try{if(I.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 vM(w,{migrationsFolder:D}),B.debug("Conversation database migrations completed successfully")}catch(f){throw B.error("Conversation database migration failed:",f),f}finally{$.close()}}var L80=l(()=>{rr();s9A();JA()});class xx{logger;migrations;constructor(A,Q){this.logger=A,this.migrations=Q??{getStandardConfigWithDirectories:Wj,migrateEntities:z80,migrateJobQueue:q80,migrateConversations:E80}}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 lHA=l(()=>{lr();N80();C80();L80()});var dr;var iHA=l(()=>{JA();dr=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 V80;var M80=l(()=>{V80={name:"@brains/chat-repl",private:!0,version:"0.2.0-alpha.60",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 mQ=x((mg1,nr)=>{(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 I(QA,FA,cA){this.props=QA,this.context=FA,this.refs=uA,this.updater=cA||VA}function f(){}function D(QA){return""+QA}function Y(QA){try{D(QA);var FA=!1}catch(f0){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 H(QA){if(QA==null)return null;if(typeof QA==="function")return QA.$$typeof===H0?null:QA.displayName||QA.name||null;if(typeof QA==="string")return QA;switch(QA){case BA:return"Fragment";case UA:return"Profiler";case d:return"StrictMode";case K0:return"Suspense";case qA:return"SuspenseList";case LA:return"Activity"}if(typeof QA==="object")switch(typeof QA.tag==="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),QA.$$typeof){case r: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:H(QA.type)||"Memo";case z0:FA=QA._payload,QA=QA._init;try{return H(QA(FA))}catch(cA){}}return null}function W(QA){if(QA===BA)return"<>";if(typeof QA==="object"&&QA!==null&&QA.$$typeof===z0)return"<...>";try{var FA=H(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(bA.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=H(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,f0,O0){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:f0}),Object.defineProperty(QA,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:O0}),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 j(QA){P(QA)?QA._store&&(QA._store.validated=1):typeof QA==="object"&&QA!==null&&QA.$$typeof===z0&&(QA._payload.status==="fulfilled"?P(QA._payload.value)&&QA._payload.value._store&&(QA._payload.value._store.validated=1):QA._store&&(QA._store.validated=1))}function P(QA){return typeof QA==="object"&&QA!==null&&QA.$$typeof===t}function o(QA){var FA={"=":"=0",":":"=2"};return"$"+QA.replace(/[=:]/g,function(cA){return FA[cA]})}function n(QA,FA){return typeof QA==="object"&&QA!==null&&QA.key!=null?(Y(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(f,f):(QA.status="pending",QA.then(function(FA){QA.status==="pending"&&(QA.status="fulfilled",QA.value=FA)},function(FA){QA.status==="pending"&&(QA.status="rejected",QA.reason=FA)})),QA.status){case"fulfilled":return QA.value;case"rejected":throw QA.reason}}throw QA}function v(QA,FA,cA,w0,f0){var O0=typeof QA;if(O0==="undefined"||O0==="boolean")QA=null;var eA=!1;if(QA===null)eA=!0;else switch(O0){case"bigint":case"string":case"number":eA=!0;break;case"object":switch(QA.$$typeof){case t:case r:eA=!0;break;case z0:return eA=QA._init,v(eA(QA._payload),FA,cA,w0,f0)}}if(eA){eA=QA,f0=f0(eA);var t0=w0===""?"."+n(eA,0):w0;return N0(f0)?(cA="",t0!=null&&(cA=t0.replace(gA,"$&/")+"/"),v(f0,FA,cA,"",function(S1){return S1})):f0!=null&&(P(f0)&&(f0.key!=null&&(eA&&eA.key===f0.key||Y(f0.key)),cA=R(f0,cA+(f0.key==null||eA&&eA.key===f0.key?"":(""+f0.key).replace(gA,"$&/")+"/")+t0),w0!==""&&eA!=null&&P(eA)&&eA.key==null&&eA._store&&!eA._store.validated&&(cA._store.validated=2),f0=cA),FA.push(f0)),1}if(eA=0,t0=w0===""?".":w0+":",N0(QA))for(var Q1=0;Q1<QA.length;Q1++)w0=QA[Q1],O0=t0+n(w0,Q1),eA+=v(w0,FA,cA,O0,f0);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,O0=t0+n(w0,Q1++),eA+=v(w0,FA,cA,O0,f0);else if(O0==="object"){if(typeof QA.then==="function")return v(S(QA),FA,cA,w0,f0);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=[],f0=0;return v(QA,w0,"","",function(O0){return FA.call(cA,O0,f0++)}),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(f0){if(QA._status===0||QA._status===-1){QA._status=1,QA._result=f0;var O0=QA._ioInfo;O0!=null&&(O0.end=performance.now()),cA.status===void 0&&(cA.status="fulfilled",cA.value=f0)}},function(f0){if(QA._status===0||QA._status===-1){QA._status=2,QA._result=f0;var O0=QA._ioInfo;O0!=null&&(O0.end=performance.now()),cA.status===void 0&&(cA.status="rejected",cA.reason=f0)}}),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
|
|
571
|
+
`;await A.session.run($);let f=(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 Y of B)if(!f||Number(f[2])<Y.folderMillis){for(let H of Y.sql)D.push(A.run(hA.raw(H)));D.push(A.run(hA`INSERT INTO ${hA.identifier(w)} ("hash", "created_at") VALUES(${Y.hash}, ${Y.folderMillis})`))}await A.session.migrate(D)}var rr=l(()=>{Z80();z5()});async function z80(A,Q){let B=Q?.child("entity-migrate")??QQ.getInstance().child("entity-migrate"),{db:w,client:$,url:I}=Nl(A);B.debug("Running entity database migrations...");try{await ql($,I);let D=import.meta.url.includes("/dist/")?new URL("./migrations/entity-service",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await vM(w,{migrationsFolder:D}),await Cl($),B.debug("Entity database migrations completed successfully")}catch(f){throw B.error("Entity database migration failed:",f),f}finally{$.close()}}var N80=l(()=>{rr();K9A();JA()});async function q80(A,Q){let B=Q?.child("job-queue-migrate")??QQ.getInstance().child("job-queue-migrate"),{db:w,client:$,url:I}=Kl(A);B.debug("Running job queue migrations...");try{await Zl($,I);let D=import.meta.url.includes("/dist/")?new URL("./migrations/job-queue",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await vM(w,{migrationsFolder:D}),B.debug("Job queue migrations completed successfully")}catch(f){throw B.error("Job queue migration failed:",f),f}finally{$.close()}}var C80=l(()=>{rr();I9A();JA()});async function E80(A,Q){let B=Q?.child("conversation-migrate")??QQ.getInstance().child("conversation-migrate"),{db:w,client:$,url:I}=kl(A);B.debug("Running conversation database migrations...");try{if(I.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 vM(w,{migrationsFolder:D}),B.debug("Conversation database migrations completed successfully")}catch(f){throw B.error("Conversation database migration failed:",f),f}finally{$.close()}}var L80=l(()=>{rr();s9A();JA()});class xx{logger;migrations;constructor(A,Q){this.logger=A,this.migrations=Q??{getStandardConfigWithDirectories:Wj,migrateEntities:z80,migrateJobQueue:q80,migrateConversations:E80}}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 lHA=l(()=>{lr();N80();C80();L80()});var dr;var iHA=l(()=>{JA();dr=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 V80;var M80=l(()=>{V80={name:"@brains/chat-repl",private:!0,version:"0.2.0-alpha.61",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 mQ=x((mg1,nr)=>{(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 I(QA,FA,cA){this.props=QA,this.context=FA,this.refs=uA,this.updater=cA||VA}function f(){}function D(QA){return""+QA}function Y(QA){try{D(QA);var FA=!1}catch(f0){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 H(QA){if(QA==null)return null;if(typeof QA==="function")return QA.$$typeof===H0?null:QA.displayName||QA.name||null;if(typeof QA==="string")return QA;switch(QA){case BA:return"Fragment";case UA:return"Profiler";case d:return"StrictMode";case K0:return"Suspense";case qA:return"SuspenseList";case LA:return"Activity"}if(typeof QA==="object")switch(typeof QA.tag==="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),QA.$$typeof){case r: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:H(QA.type)||"Memo";case z0:FA=QA._payload,QA=QA._init;try{return H(QA(FA))}catch(cA){}}return null}function W(QA){if(QA===BA)return"<>";if(typeof QA==="object"&&QA!==null&&QA.$$typeof===z0)return"<...>";try{var FA=H(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(bA.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=H(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,f0,O0){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:f0}),Object.defineProperty(QA,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:O0}),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 j(QA){P(QA)?QA._store&&(QA._store.validated=1):typeof QA==="object"&&QA!==null&&QA.$$typeof===z0&&(QA._payload.status==="fulfilled"?P(QA._payload.value)&&QA._payload.value._store&&(QA._payload.value._store.validated=1):QA._store&&(QA._store.validated=1))}function P(QA){return typeof QA==="object"&&QA!==null&&QA.$$typeof===t}function o(QA){var FA={"=":"=0",":":"=2"};return"$"+QA.replace(/[=:]/g,function(cA){return FA[cA]})}function n(QA,FA){return typeof QA==="object"&&QA!==null&&QA.key!=null?(Y(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(f,f):(QA.status="pending",QA.then(function(FA){QA.status==="pending"&&(QA.status="fulfilled",QA.value=FA)},function(FA){QA.status==="pending"&&(QA.status="rejected",QA.reason=FA)})),QA.status){case"fulfilled":return QA.value;case"rejected":throw QA.reason}}throw QA}function v(QA,FA,cA,w0,f0){var O0=typeof QA;if(O0==="undefined"||O0==="boolean")QA=null;var eA=!1;if(QA===null)eA=!0;else switch(O0){case"bigint":case"string":case"number":eA=!0;break;case"object":switch(QA.$$typeof){case t:case r:eA=!0;break;case z0:return eA=QA._init,v(eA(QA._payload),FA,cA,w0,f0)}}if(eA){eA=QA,f0=f0(eA);var t0=w0===""?"."+n(eA,0):w0;return N0(f0)?(cA="",t0!=null&&(cA=t0.replace(gA,"$&/")+"/"),v(f0,FA,cA,"",function(S1){return S1})):f0!=null&&(P(f0)&&(f0.key!=null&&(eA&&eA.key===f0.key||Y(f0.key)),cA=R(f0,cA+(f0.key==null||eA&&eA.key===f0.key?"":(""+f0.key).replace(gA,"$&/")+"/")+t0),w0!==""&&eA!=null&&P(eA)&&eA.key==null&&eA._store&&!eA._store.validated&&(cA._store.validated=2),f0=cA),FA.push(f0)),1}if(eA=0,t0=w0===""?".":w0+":",N0(QA))for(var Q1=0;Q1<QA.length;Q1++)w0=QA[Q1],O0=t0+n(w0,Q1),eA+=v(w0,FA,cA,O0,f0);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,O0=t0+n(w0,Q1++),eA+=v(w0,FA,cA,O0,f0);else if(O0==="object"){if(typeof QA.then==="function")return v(S(QA),FA,cA,w0,f0);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=[],f0=0;return v(QA,w0,"","",function(O0){return FA.call(cA,O0,f0++)}),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(f0){if(QA._status===0||QA._status===-1){QA._status=1,QA._result=f0;var O0=QA._ioInfo;O0!=null&&(O0.end=performance.now()),cA.status===void 0&&(cA.status="fulfilled",cA.value=f0)}},function(f0){if(QA._status===0||QA._status===-1){QA._status=2,QA._result=f0;var O0=QA._ioInfo;O0!=null&&(O0.end=performance.now()),cA.status===void 0&&(cA.status="rejected",cA.reason=f0)}}),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
|
|
572
572
|
|
|
573
573
|
Your code should look like:
|
|
574
574
|
const MyComponent = lazy(() => import('./MyComponent'))
|
|
@@ -1735,7 +1735,7 @@ Example bad output: "A dreamlike crystal formation glowing with ethereal light i
|
|
|
1735
1735
|
Title: "${A.entityTitle??D}"
|
|
1736
1736
|
|
|
1737
1737
|
Content:
|
|
1738
|
-
${A.entityContent}`,up1);Y=w+R.imagePrompt}catch(R){this.logger.warn("AI prompt distillation failed, using fallback",{error:h0(R)})}}await this.reportProgress(B,{progress:v2.PROCESS,message:"Generating image"});let H=this.context.identity.get(),W=this.context.identity.getProfile(),K=m70(H,W)+Y,Z;try{Z=await this.context.ai.generateImage(K,{...$&&{aspectRatio:$}})}catch(R){return this.logger.error("Image generation failed",{jobId:Q,error:h0(R)}),r8.failure(R)}await this.reportProgress(B,{progress:v2.GENERATE,message:"Creating image entity"});let q=F2(D),L=iF.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}),I&&f){await this.reportProgress(B,{progress:v2.SAVE,message:`Updating ${I} with cover image`});let R=await bl(this.context.entityService,I,f,this.logger);if(!R)return r8.failure(Error(`Target entity not found: ${I}/${f}`));let j=HL(R,q);await this.context.entities.update(j),this.logger.debug("Updated target entity with cover image",{targetEntityType:I,targetEntityId:f,imageId:q})}return await this.reportProgress(B,{progress:v2.COMPLETE,message:"Image generation complete"}),this.logger.info("Image generation job complete",{jobId:Q,imageId:q,targetEntityType:I,targetEntityId:f}),{success:!0,imageId:q}}catch(Y){return this.logger.error("Image generation job failed",{jobId:Q,error:h0(Y)}),r8.failure(Y)}}summarizeDataForLog(A){return{title:A.title,promptLength:A.prompt.length,aspectRatio:A.aspectRatio,targetEntityType:A.targetEntityType,targetEntityId:A.targetEntityId}}}var u70={name:"@brains/image-plugin",private:!0,version:"0.2.0-alpha.60",description:"Plugin for AI-powered image generation and management",type:"module",main:"./src/index.ts",exports:{".":"./src/index.ts"},scripts:{test:"bun test",typecheck:"tsc --noEmit",lint:"eslint src test --ext .ts","lint:fix":"eslint src test --ext .ts --fix"},dependencies:{"@brains/entity-service":"workspace:*","@brains/image":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","@types/node":"^20.0.0",typescript:"^5.3.3"}};var lp1=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 fUA extends FQ{entityType=iF.entityType;schema=Mv;adapter=iF;constructor(A={}){super("image",u70,A,lp1)}getEntityTypeConfig(){return{embeddable:!1}}async interceptCreate(A,Q,B){if(!A.targetEntityType||!A.targetEntityId)return{kind:"continue",input:A};let w=await ZD(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 Un(A,this.logger)}async onRegister(A){let Q=new Un(A,this.logger);A.jobs.registerHandler("image-generate",Q)}}function Vv(A){return new fUA(A)}I0();import{StdioServerTransport as ip1}from"@modelcontextprotocol/sdk/server/stdio.js";function c70(){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 DUA(){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 Jn(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 DUA()}class GY{static instance=null;mcpServer=null;transport=null;config;logger;static getInstance(A){return GY.instance??=new GY(A),GY.instance}static resetInstance(){if(GY.instance)GY.instance.stop(),GY.instance=null}static createFresh(A){return new GY(A)}constructor(A={}){this.config=A,this.logger=this.config.logger?Jn(this.config.logger):c70()}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 ip1,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 rp1}from"@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";import{isInitializeRequest as dp1}from"@modelcontextprotocol/sdk/types.js";var np1={"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 op1(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 yU{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?Jn(this.config.logger):DUA(),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 yU.instance??=new yU(A),yU.instance}static resetInstance(){yU.instance=null}static createFresh(A){return new yU(A)}withCors(A){let Q=new Headers(A.headers);for(let[B,w]of Object.entries(np1))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:`${op1(A)}/.well-known/oauth-protected-resource`,...Q};return`Bearer ${Object.entries(w).map(([I,f])=>`${I}="${sp1(f)}"`).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??[],I=$.filter((f)=>!w.scope?.includes(f));if(I.length>0)return this.logger.warn(`Authentication failed: Missing required scope(s): ${I.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&&dp1(B))w=new rp1({sessionIdGenerator:()=>p70(),onsessioninitialized:(I)=>{this.logger.info(`Session initialized: ${I}`),this.transports[I]=w},onsessionclosed:(I)=>{this.logger.info(`Session closed: ${I}`),delete this.transports[I]}}),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 sp1(A){return A.replace(/["\\]/g,(Q)=>`\\${Q}`)}import{randomUUID as tp1}from"crypto";import{mkdir as ep1,readFile as Al1,writeFile as Ql1,chmod as Bl1}from"fs/promises";import{dirname as wl1,join as $l1}from"path";function l70(A){let Q=A.toLowerCase();return Q==="localhost"||Q==="[::1]"||Q==="::1"||Q.startsWith("127.")}function i70(A){try{return new URL(A)}catch{return}}function YUA(A,Q){if(A===Q)return!0;let B=i70(A),w=i70(Q);if(!B||!w)return!1;if(!l70(B.hostname)||!l70(w.hostname))return!1;return B.protocol===w.protocol&&B.port===w.port&&ap1(B.pathname,w.pathname)&&B.search===w.search&&B.hash===w.hash}function ap1(A,Q){return A===Q||A===`${Q}/debug`||Q===`${A}/debug`}function HUA(A,Q){return A.some((B)=>YUA(B,Q))}var Il1="oauth-auth-codes.json",fl1=600;function r70(){return Math.floor(Date.now()/1000)}function Dl1(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 Yl1(A){if(!A||typeof A!=="object")return{codes:[]};let Q=A.codes;if(!Array.isArray(Q))return{codes:[]};return{codes:Q.filter(Dl1)}}async function Hl1(A){let Q=await crypto.subtle.digest("SHA-256",new TextEncoder().encode(A));return Buffer.from(Q).toString("base64url")}class Gn{storeFile;writeQueue=Promise.resolve();constructor(A){this.storeFile=$l1(A.storageDir,A.storeFile??Il1)}async createCode(A){let Q=r70(),B={code:`ocd_${tp1()}`,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+fl1};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=r70(),B;if(await this.enqueueWrite(async()=>{let w=await this.readStore(),$=w.codes.findIndex((D)=>D.code===A.code),I=$>=0?w.codes[$]:void 0;if(!I)throw new FY("Authorization code not found");if(I.consumed_at!==void 0)throw new FY("Authorization code already consumed");if(I.expires_at<=Q)throw new FY("Authorization code expired");if(I.client_id!==A.clientId)throw new FY("Authorization code client mismatch");if(!YUA(I.redirect_uri,A.redirectUri))throw new FY("Authorization code redirect URI mismatch");let f=await Hl1(A.codeVerifier);if(I.code_challenge!==f)throw new FY("PKCE verification failed");B={...I,consumed_at:Q},w.codes[$]=B,await this.writeStore(w)}),!B)throw new FY("Authorization code not consumed");return B}async enqueueWrite(A){return this.writeQueue=this.writeQueue.then(A,A),this.writeQueue}async readStore(){try{return Yl1(JSON.parse(await Al1(this.storeFile,"utf8")))}catch(A){if(A.code==="ENOENT")return{codes:[]};throw A}}async writeStore(A){await ep1(wl1(this.storeFile),{recursive:!0,mode:448}),await Ql1(this.storeFile,`${JSON.stringify(A,null,2)}
|
|
1738
|
+
${A.entityContent}`,up1);Y=w+R.imagePrompt}catch(R){this.logger.warn("AI prompt distillation failed, using fallback",{error:h0(R)})}}await this.reportProgress(B,{progress:v2.PROCESS,message:"Generating image"});let H=this.context.identity.get(),W=this.context.identity.getProfile(),K=m70(H,W)+Y,Z;try{Z=await this.context.ai.generateImage(K,{...$&&{aspectRatio:$}})}catch(R){return this.logger.error("Image generation failed",{jobId:Q,error:h0(R)}),r8.failure(R)}await this.reportProgress(B,{progress:v2.GENERATE,message:"Creating image entity"});let q=F2(D),L=iF.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}),I&&f){await this.reportProgress(B,{progress:v2.SAVE,message:`Updating ${I} with cover image`});let R=await bl(this.context.entityService,I,f,this.logger);if(!R)return r8.failure(Error(`Target entity not found: ${I}/${f}`));let j=HL(R,q);await this.context.entities.update(j),this.logger.debug("Updated target entity with cover image",{targetEntityType:I,targetEntityId:f,imageId:q})}return await this.reportProgress(B,{progress:v2.COMPLETE,message:"Image generation complete"}),this.logger.info("Image generation job complete",{jobId:Q,imageId:q,targetEntityType:I,targetEntityId:f}),{success:!0,imageId:q}}catch(Y){return this.logger.error("Image generation job failed",{jobId:Q,error:h0(Y)}),r8.failure(Y)}}summarizeDataForLog(A){return{title:A.title,promptLength:A.prompt.length,aspectRatio:A.aspectRatio,targetEntityType:A.targetEntityType,targetEntityId:A.targetEntityId}}}var u70={name:"@brains/image-plugin",private:!0,version:"0.2.0-alpha.61",description:"Plugin for AI-powered image generation and management",type:"module",main:"./src/index.ts",exports:{".":"./src/index.ts"},scripts:{test:"bun test",typecheck:"tsc --noEmit",lint:"eslint src test --ext .ts","lint:fix":"eslint src test --ext .ts --fix"},dependencies:{"@brains/entity-service":"workspace:*","@brains/image":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","@types/node":"^20.0.0",typescript:"^5.3.3"}};var lp1=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 fUA extends FQ{entityType=iF.entityType;schema=Mv;adapter=iF;constructor(A={}){super("image",u70,A,lp1)}getEntityTypeConfig(){return{embeddable:!1}}async interceptCreate(A,Q,B){if(!A.targetEntityType||!A.targetEntityId)return{kind:"continue",input:A};let w=await ZD(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 Un(A,this.logger)}async onRegister(A){let Q=new Un(A,this.logger);A.jobs.registerHandler("image-generate",Q)}}function Vv(A){return new fUA(A)}I0();import{StdioServerTransport as ip1}from"@modelcontextprotocol/sdk/server/stdio.js";function c70(){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 DUA(){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 Jn(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 DUA()}class GY{static instance=null;mcpServer=null;transport=null;config;logger;static getInstance(A){return GY.instance??=new GY(A),GY.instance}static resetInstance(){if(GY.instance)GY.instance.stop(),GY.instance=null}static createFresh(A){return new GY(A)}constructor(A={}){this.config=A,this.logger=this.config.logger?Jn(this.config.logger):c70()}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 ip1,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 rp1}from"@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";import{isInitializeRequest as dp1}from"@modelcontextprotocol/sdk/types.js";var np1={"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 op1(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 yU{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?Jn(this.config.logger):DUA(),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 yU.instance??=new yU(A),yU.instance}static resetInstance(){yU.instance=null}static createFresh(A){return new yU(A)}withCors(A){let Q=new Headers(A.headers);for(let[B,w]of Object.entries(np1))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:`${op1(A)}/.well-known/oauth-protected-resource`,...Q};return`Bearer ${Object.entries(w).map(([I,f])=>`${I}="${sp1(f)}"`).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??[],I=$.filter((f)=>!w.scope?.includes(f));if(I.length>0)return this.logger.warn(`Authentication failed: Missing required scope(s): ${I.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&&dp1(B))w=new rp1({sessionIdGenerator:()=>p70(),onsessioninitialized:(I)=>{this.logger.info(`Session initialized: ${I}`),this.transports[I]=w},onsessionclosed:(I)=>{this.logger.info(`Session closed: ${I}`),delete this.transports[I]}}),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 sp1(A){return A.replace(/["\\]/g,(Q)=>`\\${Q}`)}import{randomUUID as tp1}from"crypto";import{mkdir as ep1,readFile as Al1,writeFile as Ql1,chmod as Bl1}from"fs/promises";import{dirname as wl1,join as $l1}from"path";function l70(A){let Q=A.toLowerCase();return Q==="localhost"||Q==="[::1]"||Q==="::1"||Q.startsWith("127.")}function i70(A){try{return new URL(A)}catch{return}}function YUA(A,Q){if(A===Q)return!0;let B=i70(A),w=i70(Q);if(!B||!w)return!1;if(!l70(B.hostname)||!l70(w.hostname))return!1;return B.protocol===w.protocol&&B.port===w.port&&ap1(B.pathname,w.pathname)&&B.search===w.search&&B.hash===w.hash}function ap1(A,Q){return A===Q||A===`${Q}/debug`||Q===`${A}/debug`}function HUA(A,Q){return A.some((B)=>YUA(B,Q))}var Il1="oauth-auth-codes.json",fl1=600;function r70(){return Math.floor(Date.now()/1000)}function Dl1(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 Yl1(A){if(!A||typeof A!=="object")return{codes:[]};let Q=A.codes;if(!Array.isArray(Q))return{codes:[]};return{codes:Q.filter(Dl1)}}async function Hl1(A){let Q=await crypto.subtle.digest("SHA-256",new TextEncoder().encode(A));return Buffer.from(Q).toString("base64url")}class Gn{storeFile;writeQueue=Promise.resolve();constructor(A){this.storeFile=$l1(A.storageDir,A.storeFile??Il1)}async createCode(A){let Q=r70(),B={code:`ocd_${tp1()}`,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+fl1};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=r70(),B;if(await this.enqueueWrite(async()=>{let w=await this.readStore(),$=w.codes.findIndex((D)=>D.code===A.code),I=$>=0?w.codes[$]:void 0;if(!I)throw new FY("Authorization code not found");if(I.consumed_at!==void 0)throw new FY("Authorization code already consumed");if(I.expires_at<=Q)throw new FY("Authorization code expired");if(I.client_id!==A.clientId)throw new FY("Authorization code client mismatch");if(!YUA(I.redirect_uri,A.redirectUri))throw new FY("Authorization code redirect URI mismatch");let f=await Hl1(A.codeVerifier);if(I.code_challenge!==f)throw new FY("PKCE verification failed");B={...I,consumed_at:Q},w.codes[$]=B,await this.writeStore(w)}),!B)throw new FY("Authorization code not consumed");return B}async enqueueWrite(A){return this.writeQueue=this.writeQueue.then(A,A),this.writeQueue}async readStore(){try{return Yl1(JSON.parse(await Al1(this.storeFile,"utf8")))}catch(A){if(A.code==="ENOENT")return{codes:[]};throw A}}async writeStore(A){await ep1(wl1(this.storeFile),{recursive:!0,mode:448}),await Ql1(this.storeFile,`${JSON.stringify(A,null,2)}
|
|
1739
1739
|
`,{mode:384}),await Bl1(this.storeFile,384)}}class FY extends Error{constructor(A){super(A);this.name="InvalidGrantError"}}import{randomUUID as cH0}from"crypto";JA();import{randomUUID as d70}from"crypto";import{mkdir as Xl1,readFile as Wl1,writeFile as Ul1,chmod as Jl1}from"fs/promises";import{dirname as Gl1,join as Fl1}from"path";var Kl1="oauth-clients.json",Zl1=F.enum(["none","client_secret_basic","client_secret_post"]),zl1=F.object({redirect_uris:F.array(F.string().url()).min(1),token_endpoint_auth_method:Zl1.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 Nl1(){return Math.floor(Date.now()/1000)}function ql1(){return`ocs_${d70().replaceAll("-","")}`}function Cl1(A){if(!A||typeof A!=="object")return{clients:[]};let Q=A.clients;if(!Array.isArray(Q))return{clients:[]};return{clients:Q.filter(El1)}}function El1(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 Fn{storeFile;writeQueue=Promise.resolve();constructor(A){this.storeFile=Fl1(A.storageDir,A.storeFile??Kl1)}async registerClient(A){let Q=zl1.safeParse(A);if(!Q.success)throw new Ov(Q.error.message);let B=Q.data,w=Nl1(),$=`oc_${d70()}`,I=B.token_endpoint_auth_method==="none",f={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}:{},...!I?{client_secret:ql1(),client_secret_expires_at:0}:{}};return await this.enqueueWrite(async()=>{let D=await this.readStore();D.clients.push(f),await this.writeStore(D)}),f}async getClient(A){return(await this.readStore()).clients.find((B)=>B.client_id===A)}async enqueueWrite(A){return this.writeQueue=this.writeQueue.then(A,A),this.writeQueue}async readStore(){try{return Cl1(JSON.parse(await Wl1(this.storeFile,"utf8")))}catch(A){if(A.code==="ENOENT")return{clients:[]};throw A}}async writeStore(A){await Xl1(Gl1(this.storeFile),{recursive:!0,mode:448}),await Ul1(this.storeFile,`${JSON.stringify(A,null,2)}
|
|
1740
1740
|
`,{mode:384}),await Jl1(this.storeFile,384)}}class Ov extends Error{constructor(A){super(A);this.name="InvalidClientMetadataError"}}function n70(A){return Buffer.from(JSON.stringify(A)).toString("base64url")}function Ll1(A){let Q=new Uint8Array(A);if(Q.length===64)return Q;if(Q[0]!==48)return Q;let B=2;if(Q[1]&&Q[1]>128)B+=Q[1]-128;if(Q[B]!==2)throw Error("Invalid DER ECDSA signature");let w=Q[B+1];if(w===void 0)throw Error("Invalid DER ECDSA signature");let $=B+2,I=Q.slice($,$+w);if(B=$+w,Q[B]!==2)throw Error("Invalid DER ECDSA signature");let f=Q[B+1];if(f===void 0)throw Error("Invalid DER ECDSA signature");let D=B+2,Y=Q.slice(D,D+f);return new Uint8Array([...o70(I),...o70(Y)])}function o70(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 XUA(A,Q){let B={typ:"JWT",alg:"ES256",kid:A.kid},w=`${n70(B)}.${n70(Q)}`,$=await crypto.subtle.importKey("jwk",A,{name:"ECDSA",namedCurve:"P-256"},!1,["sign"]),I=await crypto.subtle.sign({name:"ECDSA",hash:"SHA-256"},$,new TextEncoder().encode(w));return`${w}.${Buffer.from(Ll1(I)).toString("base64url")}`}import{createHash as Ml1}from"crypto";import{mkdir as Vl1,readFile as Ol1,writeFile as bl1,chmod as Rl1}from"fs/promises";import{dirname as _l1,join as Pl1}from"path";var kl1="oauth-signing-key.jwk";function s70(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 a70(A){let Q=JSON.stringify({crv:A.crv,kty:A.kty,x:A.x,y:A.y});return Ml1("sha256").update(Q).digest("base64url")}function jl1(A){return{kty:"EC",crv:"P-256",x:A.x,y:A.y,kid:A.kid,use:"sig",alg:"ES256"}}async function xl1(){let A=await crypto.subtle.generateKey({name:"ECDSA",namedCurve:"P-256"},!0,["sign","verify"]),Q=await crypto.subtle.exportKey("jwk",A.privateKey);if(!s70(Q))throw Error("Generated OAuth signing key is not a P-256 private JWK");let B=a70(Q);return{...Q,kid:B,use:"sig",alg:"ES256"}}class Kn{keyFile;cachedKey;loadPromise;constructor(A){this.keyFile=Pl1(A.storageDir,A.keyFile??kl1)}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 xl1();return await Vl1(_l1(this.keyFile),{recursive:!0,mode:448}),await bl1(this.keyFile,`${JSON.stringify(Q,null,2)}
|
|
1741
1741
|
`,{mode:384}),await Rl1(this.keyFile,384),Q}async getPublicJwk(){return jl1(await this.getPrivateJwk())}async readExistingKey(){try{let A=JSON.parse(await Ol1(this.keyFile,"utf8"));if(!s70(A))throw Error(`OAuth signing key at ${this.keyFile} is not a private P-256 JWK`);let Q=typeof A.kid==="string"?A.kid:a70(A);return{...A,kid:Q,use:"sig",alg:"ES256"}}catch(A){if(A.code==="ENOENT")return;throw A}}}var T2={};zB(T2,{trimPadding:()=>e70,toUTF8String:()=>cl1,toBuffer:()=>Tl1,toBase64:()=>ml1,isBase64URL:()=>ll1,isBase64:()=>pl1,fromUTF8String:()=>ul1,fromBuffer:()=>Sl1});var t70=(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},vl1=t70("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"),hl1=t70("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"),yl1=/^[-A-Za-z0-9\-_]*$/,gl1=/^[-A-Za-z0-9+/]*={0,3}$/,WX={};WX.toArrayBuffer=(A,Q)=>{let B=A.length,w=A.length*0.75,$,I=0,f,D,Y,H;if(A[A.length-1]==="="){if(w--,A[A.length-2]==="=")w--}let W=new ArrayBuffer(w),G=new Uint8Array(W),K=Q?hl1:vl1;for($=0;$<B;$+=4)f=K[A.charCodeAt($)],D=K[A.charCodeAt($+1)],Y=K[A.charCodeAt($+2)],H=K[A.charCodeAt($+3)],G[I++]=f<<2|D>>4,G[I++]=(D&15)<<4|Y>>2,G[I++]=(Y&3)<<6|H&63;return W};WX.fromArrayBuffer=(A,Q)=>{let B=new Uint8Array(A),w,$="",I=B.length,f=Q?"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_":"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";for(w=0;w<I;w+=3)$+=f[B[w]>>2],$+=f[(B[w]&3)<<4|B[w+1]>>4],$+=f[(B[w+1]&15)<<2|B[w+2]>>6],$+=f[B[w+2]&63];let D=I%3;if(D===2)$=$.substring(0,$.length-1)+(Q?"":"=");else if(D===1)$=$.substring(0,$.length-2)+(Q?"":"==");return $};WX.toString=(A,Q)=>{return new TextDecoder().decode(WX.toArrayBuffer(A,Q))};WX.fromString=(A,Q)=>{return WX.fromArrayBuffer(new TextEncoder().encode(A),Q)};WX.validate=(A,Q)=>{if(!(typeof A==="string"||A instanceof String))return!1;try{return Q?yl1.test(A):gl1.test(A)}catch(B){return!1}};WX.base64=WX;var gU=WX;function Tl1(A,Q="base64url"){let B=gU.toArrayBuffer(A,Q==="base64url");return new Uint8Array(B)}function Sl1(A,Q="base64url"){let B=new Uint8Array(A);return gU.fromArrayBuffer(B.buffer,Q==="base64url")}function ml1(A){let Q=gU.toArrayBuffer(A,!0);return gU.fromArrayBuffer(Q)}function ul1(A){return gU.fromString(A,!0)}function cl1(A){return gU.toString(A,!0)}function pl1(A){return gU.validate(A,!1)}function ll1(A){return A=e70(A),gU.validate(A,!0)}function e70(A){return A.replace(/=/g,"")}var $7={};zB($7,{encode:()=>Wi1,decodeFirst:()=>Xi1});function FV(A,Q,B){if(Q<24)return[Q,1];let w=A.byteLength-B-1,$=new DataView(A.buffer,B+1),I,f=0;switch(Q){case 24:{if(w>0)I=$.getUint8(0),f=2;break}case 25:{if(w>1)I=$.getUint16(0,!1),f=3;break}case 26:{if(w>3)I=$.getUint32(0,!1),f=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(I&&I>=24)return[I,f];throw Error("Length not supported or not well formed")}var Zn=0,bv=1,WUA=2,UUA=3,JUA=4,GUA=5,FUA=6,AI0=7;function UX(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==bv){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 Nn{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 QI0(A,Q,B){return FV(A,Q,B)}function il1(A,Q,B){let[w,$]=QI0(A,Q,B);return[-w-1,$]}function BI0(A,Q,B){let[w,$]=FV(A,Q,B),I=B+$;return[new Uint8Array(A.buffer.slice(I,I+w)),$+w]}var rl1=new TextDecoder;function dl1(A,Q,B){let[w,$]=BI0(A,Q,B);return[rl1.decode(w),$]}function nl1(A,Q,B){if(Q===0)return[[],1];let[w,$]=FV(A,Q,B),I=$,f=[];for(let D=0;D<w;D++){if(A.byteLength-B-I<=0)throw Error("array is not supported or well formed");let[H,W]=BN(A,B+I);f.push(H),I+=W}return[f,I]}var zn="Map is not supported or well formed";function ol1(A,Q,B){if(Q===0)return[new Map,1];let[w,$]=FV(A,Q,B),I=$,f=new Map;for(let D=0;D<w;D++){let Y=A.byteLength-B-I;if(Y<=0)throw Error(zn);let[H,W]=BN(A,B+I);if(I+=W,Y-=W,Y<=0)throw Error(zn);if(typeof H!=="string"&&typeof H!=="number")throw Error(zn);if(f.has(H))throw Error(zn);let[G,K]=BN(A,B+I);I+=K,f.set(H,G)}return[f,I]}function sl1(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 al1(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 tl1(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 el1(A,Q,B){let[w,$]=FV(A,Q,B),[I,f]=BN(A,B+$);return[new Nn(w,I),$+f]}function BN(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 Zn:return QI0(A,$,Q);case bv:return il1(A,$,Q);case WUA:return BI0(A,$,Q);case UUA:return dl1(A,$,Q);case JUA:return nl1(A,$,Q);case GUA:return ol1(A,$,Q);case FUA:return el1(A,$,Q);case AI0: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 sl1(A,Q);case 26:return al1(A,Q);case 27:return tl1(A,Q)}}throw Error(`Unsupported or not well formed at ${Q}`)}function Ai1(A){if(A===!0)return 245;else if(A===!1)return 244;else if(A===null)return 246;return 247}function Qi1(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 Bi1(A){if(typeof A=="number"){if(Number.isSafeInteger(A))if(A<0)return UX(bv,Math.abs(A));else return UX(Zn,A);return[Qi1(A)]}else if(A<0n)return UX(bv,A*-1n);else return UX(Zn,A)}var wi1=new TextEncoder;function $i1(A,Q){Q.push(...UX(UUA,A.length)),Q.push(wi1.encode(A))}function Ii1(A,Q){Q.push(...UX(WUA,A.length)),Q.push(A)}function fi1(A,Q){Q.push(...UX(JUA,A.length));for(let B of A)Rv(B,Q)}function Di1(A,Q){Q.push(new Uint8Array(UX(GUA,A.size)));for(let[B,w]of A.entries())Rv(B,Q),Rv(w,Q)}function Yi1(A,Q){Q.push(...UX(FUA,A.tag)),Rv(A.value,Q)}function Rv(A,Q){if(typeof A=="boolean"||A===null||A==null){Q.push(Ai1(A));return}if(typeof A=="number"||typeof A=="bigint"){Q.push(...Bi1(A));return}if(typeof A=="string"){$i1(A,Q);return}if(A instanceof Uint8Array){Ii1(A,Q);return}if(Array.isArray(A)){fi1(A,Q);return}if(A instanceof Map){Di1(A,Q);return}if(A instanceof Nn){Yi1(A,Q);return}throw Error("Not implemented")}function KUA(A,Q){if(A.byteLength===0||A.byteLength<=Q||Q<0)throw Error("No data");if(A instanceof Uint8Array)return BN(new DataView(A.buffer),Q);else if(A instanceof ArrayBuffer)return BN(new DataView(A),Q);return BN(A,Q)}function ZUA(A){let Q=[];Rv(A,Q);let B=0;for(let I of Q)if(typeof I=="number")B+=1;else B+=I.length;let w=new Uint8Array(B),$=0;for(let I of Q)if(typeof I=="number")w[$]=I,$+=1;else w.set(I,$),$+=I.length;return w}function Xi1(A){let Q=new Uint8Array(A),B=KUA(Q,0),[w]=B;return w}function Wi1(A){return ZUA(A)}var GX={};zB(GX,{verify:()=>gY0,getRandomValues:()=>DI0,digest:()=>fI0});function wI0(A){let Q=A.get(y2.kty);return zUA(Q)&&Q===Xf.OKP}function rF(A){let Q=A.get(y2.kty);return zUA(Q)&&Q===Xf.EC2}function KV(A){let Q=A.get(y2.kty);return zUA(Q)&&Q===Xf.RSA}var y2;(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"})(y2||(y2={}));var Xf;(function(A){A[A.OKP=1]="OKP",A[A.EC2=2]="EC2",A[A.RSA=3]="RSA"})(Xf||(Xf={}));function zUA(A){return Object.values(Xf).indexOf(A)>=0}var H$;(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"})(H$||(H$={}));function $I0(A){return Object.values(H$).indexOf(A)>=0}var $Q;(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"})($Q||($Q={}));function JX(A){return Object.values($Q).indexOf(A)>=0}function dF(A){if([$Q.RS1].indexOf(A)>=0)return"SHA-1";else if([$Q.ES256,$Q.PS256,$Q.RS256].indexOf(A)>=0)return"SHA-256";else if([$Q.ES384,$Q.PS384,$Q.RS384].indexOf(A)>=0)return"SHA-384";else if([$Q.ES512,$Q.PS512,$Q.RS512,$Q.EdDSA].indexOf(A)>=0)return"SHA-512";throw Error(`Could not map COSE alg value of ${A} to a WebCrypto alg`)}var _v=void 0;function a7(){return new Promise((Q,B)=>{if(_v)return Q(_v);let w=Ji1.stubThisGlobalThisCrypto();if(w)return _v=w,Q(_v);return B(new II0)})}class II0 extends Error{constructor(){super("An instance of the Crypto API could not be located");this.name="MissingWebCrypto"}}var Ji1={stubThisGlobalThisCrypto:()=>globalThis.crypto,setCachedCrypto:(A)=>{_v=A}};async function fI0(A,Q){let B=await a7(),w=dF(Q),$=await B.subtle.digest(w,A);return new Uint8Array($)}async function DI0(A){return(await a7()).getRandomValues(A),A}async function ZV(A){let Q=await a7(),{keyData:B,algorithm:w}=A;return Q.subtle.importKey("jwk",B,w,!1,["verify"])}async function qn(A){let{cosePublicKey:Q,signature:B,data:w,shaHashOverride:$}=A,I=await a7(),f=Q.get(y2.alg),D=Q.get(y2.crv),Y=Q.get(y2.x),H=Q.get(y2.y);if(!f)throw Error("Public key was missing alg (EC2)");if(!D)throw Error("Public key was missing crv (EC2)");if(!Y)throw Error("Public key was missing x (EC2)");if(!H)throw Error("Public key was missing y (EC2)");let W;if(D===H$.P256)W="P-256";else if(D===H$.P384)W="P-384";else if(D===H$.P521)W="P-521";else throw Error(`Unexpected COSE crv value of ${D} (EC2)`);let G={kty:"EC",crv:W,x:T2.fromBuffer(Y),y:T2.fromBuffer(H),ext:!1},Z=await ZV({keyData:G,algorithm:{name:"ECDSA",namedCurve:W}}),q=dF(f);if($)q=dF($);let L={name:"ECDSA",hash:{name:q}};return I.subtle.verify(L,Z,B,w)}function NUA(A){if([$Q.EdDSA].indexOf(A)>=0)return"Ed25519";else if([$Q.ES256,$Q.ES384,$Q.ES512,$Q.ES256K].indexOf(A)>=0)return"ECDSA";else if([$Q.RS256,$Q.RS384,$Q.RS512,$Q.RS1].indexOf(A)>=0)return"RSASSA-PKCS1-v1_5";else if([$Q.PS256,$Q.PS384,$Q.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 Cn(A){let{cosePublicKey:Q,signature:B,data:w,shaHashOverride:$}=A,I=await a7(),f=Q.get(y2.alg),D=Q.get(y2.n),Y=Q.get(y2.e);if(!f)throw Error("Public key was missing alg (RSA)");if(!JX(f))throw Error(`Public key had invalid alg ${f} (RSA)`);if(!D)throw Error("Public key was missing n (RSA)");if(!Y)throw Error("Public key was missing e (RSA)");let H={kty:"RSA",alg:"",n:T2.fromBuffer(D),e:T2.fromBuffer(Y),ext:!1},W={name:NUA(f),hash:{name:dF(f)}},G={name:NUA(f)};if($)W.hash.name=dF($);if(W.name==="RSASSA-PKCS1-v1_5"){if(W.hash.name==="SHA-256")H.alg="RS256";else if(W.hash.name==="SHA-384")H.alg="RS384";else if(W.hash.name==="SHA-512")H.alg="RS512";else if(W.hash.name==="SHA-1")H.alg="RS1"}else if(W.name==="RSA-PSS"){let Z=0;if(W.hash.name==="SHA-256")H.alg="PS256",Z=32;else if(W.hash.name==="SHA-384")H.alg="PS384",Z=48;else if(W.hash.name==="SHA-512")H.alg="PS512",Z=64;G.saltLength=Z}else throw Error(`Unexpected RSA key algorithm ${f} (${W.name})`);let K=await ZV({keyData:H,algorithm:W});return I.subtle.verify(G,K,B,w)}function En(A){let Q=Y2.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 t6(A){let Q;if(typeof A==="string")if(T2.isBase64URL(A))Q=T2.toBase64(A);else if(T2.isBase64(A))Q=A;else throw Error("Certificate is not a valid base64 or base64url string");else Q=T2.fromBuffer(A,"base64");let B="";for(let w=0;w<Math.ceil(Q.length/64);w+=1){let $=64*w;B+=`${Q.substr($,64)}
|
|
@@ -2313,7 +2313,7 @@ ${R}`)}if(w!==void 0&&I?.algorithms!==void 0){let C=I.algorithms.map((R)=>R.alg)
|
|
|
2313
2313
|
</form>
|
|
2314
2314
|
</main>
|
|
2315
2315
|
</body>
|
|
2316
|
-
</html>`}function bFA(A){return new Response(A,{headers:{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store"}})}function RFA(A){let Q=`${new URL(A.url).pathname}${new URL(A.url).search}`;return new Response(oH0(Q,"Operator login required"),{status:401,headers:{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store"}})}function Bs(A){let Q=ao(A),B=new URL(Q);return{origin:B.origin,rpID:B.hostname}}function _X(A){return A.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""")}I0();JA();var aH0={name:"@brains/auth-service",private:!0,version:"0.2.0-alpha.60",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 cn1=F.object({issuer:F.string().optional(),trustedIssuers:F.array(F.string()).default([]),allowLocalhostIssuers:F.boolean().optional(),storageDir:F.string().default("./data/auth")}),pn1=F.object({}),$s;function hO(){return $s}class PFA extends Ww{service;constructor(A={}){super("auth-service",aH0,A,cn1)}async onRegister(A){await super.onRegister(A);let Q=this.config.issuer??A.siteUrl;this.service=new ws({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(),$s=this.service}async onShutdown(){if($s===this.service)$s=void 0;this.service=void 0}async getTools(){return[jQ(this.id,"get_passkey_setup_url","Get the first-passkey setup URL when operator setup is required. Anchor-only.",pn1,async()=>{let A=this.getService();if(await A.hasPasskeyCredentials())return _8({status:"complete"});let Q=await A.getOperatorSetupRequired();if(Q)return _8({status:"setup_required",setupUrl:Q.setupUrl,expiresAt:Q.expiresAt});return _8({status:"unavailable",reason:"Passkey setup URL is not available."})},{visibility:"anchor"})]}getWebRoutes(){let A=(Q)=>this.getService().handleRequest(Q);return[{path:"/.well-known/oauth-authorization-server",method:"GET",public:!0,handler:A},{path:"/.well-known/oauth-authorization-server",method:"OPTIONS",public:!0,handler:A},{path:"/.well-known/jwks.json",method:"GET",public:!0,handler:A},{path:"/.well-known/jwks.json",method:"OPTIONS",public:!0,handler:A},{path:"/.well-known/oauth-protected-resource",method:"GET",public:!0,handler:A},{path:"/.well-known/oauth-protected-resource",method:"OPTIONS",public:!0,handler:A},{path:"/setup",method:"GET",public:!0,handler:A},{path:"/login",method:"GET",public:!0,handler:A},{path:"/logout",method:"GET",public:!0,handler:A},{path:"/logout",method:"POST",public:!0,handler:A},{path:"/authorize",method:"GET",public:!0,handler:A},{path:"/authorize",method:"POST",public:!0,handler:A},{path:"/register",method:"POST",public:!0,handler:A},{path:"/register",method:"OPTIONS",public:!0,handler:A},{path:"/token",method:"POST",public:!0,handler:A},{path:"/token",method:"OPTIONS",public:!0,handler:A},{path:"/revoke",method:"POST",public:!0,handler:A},{path:"/revoke",method:"OPTIONS",public:!0,handler:A},{path:"/webauthn/register/options",method:"POST",public:!0,handler:A},{path:"/webauthn/register/verify",method:"POST",public:!0,handler:A},{path:"/webauthn/auth/options",method:"POST",public:!0,handler:A},{path:"/webauthn/auth/verify",method:"POST",public:!0,handler:A}]}getService(){if(!this.service)throw Error("AuthServicePlugin has not been registered");return this.service}}function Gy(A){return new PFA(A)}JA();var kFA=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 tH0(A,Q){return[]}I0();function jFA(A,Q){A.messaging.subscribe("job-progress",async(B)=>{let w=VL.safeParse(B.payload);if(!w.success)return Q.warn("Received invalid job-progress message",{error:w.error.message}),{success:!1};let $=w.data,I=$.type,f=$.status,D=$.id;if(Q.debug(`${I} ${D} - ${f}:`,{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 eH0={name:"@brains/mcp",private:!0,version:"0.2.0-alpha.60",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 EK extends dH{mcpTransport;stdioServer;httpServer;domain;constructor(A={}){let Q={...A,authToken:A.authToken??process.env.MCP_AUTH_TOKEN};super("mcp",eH0,Q,kFA)}async getTools(){return tH0(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});jFA(A,this.logger)}getOrCreateHttpServer(){if(this.httpServer)return this.httpServer;let A=hO();return this.httpServer=yU.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||hO()))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=GY.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(){GY.resetInstance(),yU.resetInstance()}}I0();JA();var dD=D1(pS0(),1);JA();I0();var JCA=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),...Dj.shape,captureUrlEmoji:F.string().default("\uD83D\uDD16")});var lS0={name:"@brains/discord",private:!0,version:"0.2.0-alpha.60",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 GCA=2000,IC2=8000,fC2=100;function De(A){return!!A&&typeof A==="object"&&"send"in A&&"sendTyping"in A}class wZ extends Gz{client=null;fetchText;pendingConfirmations=new Map;typingIntervals=new Map;constructor(A,Q={}){super("discord",lS0,A,JCA);this.fetchText=Q.fetchText??Tp}async onRegister(A){await super.onRegister(A),this.client=new dD.Client({intents:[dD.GatewayIntentBits.Guilds,dD.GatewayIntentBits.GuildMessages,dD.GatewayIntentBits.MessageContent,dD.GatewayIntentBits.DirectMessages],partials:[dD.Partials.Channel]}),this.client.on(dD.Events.MessageCreate,(Q)=>{this.handleMessage(Q)}),this.client.once(dD.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(!De(B))return;let w=Ck(Q,GCA);for(let $ of w)B.send($).catch((I)=>this.logger.error("Failed to send message",{error:I}))}async sendMessageWithId({channelId:A,message:Q}){if(!A||!this.client)return;let B=this.client.channels.cache.get(A);if(!De(B))return;let w=Ck(Q,GCA),$;for(let I of w)$=(await B.send(I)).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(!De(w))return!1;try{return await(await w.messages.fetch(Q)).edit(B.slice(0,GCA)),!0}catch{return!1}}supportsMessageEditing(){return!0}async handleMessage(A){if(A.author.id===this.client?.user?.id)return;if(!this.context)return;let Q=!A.guild,B=A.channel.isThread();if(Q&&!this.config.allowDMs)return;let w=!!this.client?.user&&A.mentions.has(this.client.user,{ignoreEveryone:!0});if(A.author.bot&&!w)return;let $=B&&"ownerId"in A.channel&&A.channel.ownerId===this.client?.user?.id;if(this.config.allowedChannels.length>0&&!Q&&!this.config.allowedChannels.includes(A.channel.id))return;if(!Q&&!$&&this.config.requireMention&&!w){if(this.config.captureUrls){let D=this.extractCaptureableUrls(A.content,this.config.blockedUrlDomains);if(D.length>0){await A.react(this.config.captureUrlEmoji).catch((Y)=>this.logger.debug("React failed",{error:Y}));for(let Y of D)await this.captureUrlViaAgent(Y,A.channel.id,A.author.id,"discord").catch((H)=>this.logger.error("URL capture failed",{error:H,url:Y}))}}return}let I=this.stripMention(A.content);if(A.attachments.size>0){let D=this.context.permissions.getUserLevel("discord",A.author.id);if(D==="anchor"||D==="trusted")for(let H of A.attachments.values()){let W=H.name,G=H.contentType??void 0,K=H.size;if(!this.isUploadableTextFile(W,G))continue;if(!this.isFileSizeAllowed(K))continue;try{let Z=await this.fetchText(H.url);I+=`
|
|
2316
|
+
</html>`}function bFA(A){return new Response(A,{headers:{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store"}})}function RFA(A){let Q=`${new URL(A.url).pathname}${new URL(A.url).search}`;return new Response(oH0(Q,"Operator login required"),{status:401,headers:{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store"}})}function Bs(A){let Q=ao(A),B=new URL(Q);return{origin:B.origin,rpID:B.hostname}}function _X(A){return A.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""")}I0();JA();var aH0={name:"@brains/auth-service",private:!0,version:"0.2.0-alpha.61",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 cn1=F.object({issuer:F.string().optional(),trustedIssuers:F.array(F.string()).default([]),allowLocalhostIssuers:F.boolean().optional(),storageDir:F.string().default("./data/auth")}),pn1=F.object({}),$s;function hO(){return $s}class PFA extends Ww{service;constructor(A={}){super("auth-service",aH0,A,cn1)}async onRegister(A){await super.onRegister(A);let Q=this.config.issuer??A.siteUrl;this.service=new ws({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(),$s=this.service}async onShutdown(){if($s===this.service)$s=void 0;this.service=void 0}async getTools(){return[jQ(this.id,"get_passkey_setup_url","Get the first-passkey setup URL when operator setup is required. Anchor-only.",pn1,async()=>{let A=this.getService();if(await A.hasPasskeyCredentials())return _8({status:"complete"});let Q=await A.getOperatorSetupRequired();if(Q)return _8({status:"setup_required",setupUrl:Q.setupUrl,expiresAt:Q.expiresAt});return _8({status:"unavailable",reason:"Passkey setup URL is not available."})},{visibility:"anchor"})]}getWebRoutes(){let A=(Q)=>this.getService().handleRequest(Q);return[{path:"/.well-known/oauth-authorization-server",method:"GET",public:!0,handler:A},{path:"/.well-known/oauth-authorization-server",method:"OPTIONS",public:!0,handler:A},{path:"/.well-known/jwks.json",method:"GET",public:!0,handler:A},{path:"/.well-known/jwks.json",method:"OPTIONS",public:!0,handler:A},{path:"/.well-known/oauth-protected-resource",method:"GET",public:!0,handler:A},{path:"/.well-known/oauth-protected-resource",method:"OPTIONS",public:!0,handler:A},{path:"/setup",method:"GET",public:!0,handler:A},{path:"/login",method:"GET",public:!0,handler:A},{path:"/logout",method:"GET",public:!0,handler:A},{path:"/logout",method:"POST",public:!0,handler:A},{path:"/authorize",method:"GET",public:!0,handler:A},{path:"/authorize",method:"POST",public:!0,handler:A},{path:"/register",method:"POST",public:!0,handler:A},{path:"/register",method:"OPTIONS",public:!0,handler:A},{path:"/token",method:"POST",public:!0,handler:A},{path:"/token",method:"OPTIONS",public:!0,handler:A},{path:"/revoke",method:"POST",public:!0,handler:A},{path:"/revoke",method:"OPTIONS",public:!0,handler:A},{path:"/webauthn/register/options",method:"POST",public:!0,handler:A},{path:"/webauthn/register/verify",method:"POST",public:!0,handler:A},{path:"/webauthn/auth/options",method:"POST",public:!0,handler:A},{path:"/webauthn/auth/verify",method:"POST",public:!0,handler:A}]}getService(){if(!this.service)throw Error("AuthServicePlugin has not been registered");return this.service}}function Gy(A){return new PFA(A)}JA();var kFA=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 tH0(A,Q){return[]}I0();function jFA(A,Q){A.messaging.subscribe("job-progress",async(B)=>{let w=VL.safeParse(B.payload);if(!w.success)return Q.warn("Received invalid job-progress message",{error:w.error.message}),{success:!1};let $=w.data,I=$.type,f=$.status,D=$.id;if(Q.debug(`${I} ${D} - ${f}:`,{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 eH0={name:"@brains/mcp",private:!0,version:"0.2.0-alpha.61",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 EK extends dH{mcpTransport;stdioServer;httpServer;domain;constructor(A={}){let Q={...A,authToken:A.authToken??process.env.MCP_AUTH_TOKEN};super("mcp",eH0,Q,kFA)}async getTools(){return tH0(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});jFA(A,this.logger)}getOrCreateHttpServer(){if(this.httpServer)return this.httpServer;let A=hO();return this.httpServer=yU.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||hO()))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=GY.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(){GY.resetInstance(),yU.resetInstance()}}I0();JA();var dD=D1(pS0(),1);JA();I0();var JCA=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),...Dj.shape,captureUrlEmoji:F.string().default("\uD83D\uDD16")});var lS0={name:"@brains/discord",private:!0,version:"0.2.0-alpha.61",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 GCA=2000,IC2=8000,fC2=100;function De(A){return!!A&&typeof A==="object"&&"send"in A&&"sendTyping"in A}class wZ extends Gz{client=null;fetchText;pendingConfirmations=new Map;typingIntervals=new Map;constructor(A,Q={}){super("discord",lS0,A,JCA);this.fetchText=Q.fetchText??Tp}async onRegister(A){await super.onRegister(A),this.client=new dD.Client({intents:[dD.GatewayIntentBits.Guilds,dD.GatewayIntentBits.GuildMessages,dD.GatewayIntentBits.MessageContent,dD.GatewayIntentBits.DirectMessages],partials:[dD.Partials.Channel]}),this.client.on(dD.Events.MessageCreate,(Q)=>{this.handleMessage(Q)}),this.client.once(dD.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(!De(B))return;let w=Ck(Q,GCA);for(let $ of w)B.send($).catch((I)=>this.logger.error("Failed to send message",{error:I}))}async sendMessageWithId({channelId:A,message:Q}){if(!A||!this.client)return;let B=this.client.channels.cache.get(A);if(!De(B))return;let w=Ck(Q,GCA),$;for(let I of w)$=(await B.send(I)).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(!De(w))return!1;try{return await(await w.messages.fetch(Q)).edit(B.slice(0,GCA)),!0}catch{return!1}}supportsMessageEditing(){return!0}async handleMessage(A){if(A.author.id===this.client?.user?.id)return;if(!this.context)return;let Q=!A.guild,B=A.channel.isThread();if(Q&&!this.config.allowDMs)return;let w=!!this.client?.user&&A.mentions.has(this.client.user,{ignoreEveryone:!0});if(A.author.bot&&!w)return;let $=B&&"ownerId"in A.channel&&A.channel.ownerId===this.client?.user?.id;if(this.config.allowedChannels.length>0&&!Q&&!this.config.allowedChannels.includes(A.channel.id))return;if(!Q&&!$&&this.config.requireMention&&!w){if(this.config.captureUrls){let D=this.extractCaptureableUrls(A.content,this.config.blockedUrlDomains);if(D.length>0){await A.react(this.config.captureUrlEmoji).catch((Y)=>this.logger.debug("React failed",{error:Y}));for(let Y of D)await this.captureUrlViaAgent(Y,A.channel.id,A.author.id,"discord").catch((H)=>this.logger.error("URL capture failed",{error:H,url:Y}))}}return}let I=this.stripMention(A.content);if(A.attachments.size>0){let D=this.context.permissions.getUserLevel("discord",A.author.id);if(D==="anchor"||D==="trusted")for(let H of A.attachments.values()){let W=H.name,G=H.contentType??void 0,K=H.size;if(!this.isUploadableTextFile(W,G))continue;if(!this.isFileSizeAllowed(K))continue;try{let Z=await this.fetchText(H.url);I+=`
|
|
2317
2317
|
|
|
2318
2318
|
`+this.formatFileUploadMessage(W,Z)}catch(Z){this.logger.error("Failed to download attachment",{error:Z,filename:W})}}}if(I=I.trim(),!I)return;let f=A.channel.id;await this.routeToAgent(I,f,A)}async routeToAgent(A,Q,B){if(!this.context)return;let w=this.context.agent,$=Q;if(this.config.useThreads&&B.guild&&!B.channel.isThread())try{$=(await B.startThread({name:WF(A,fC2),autoArchiveDuration:this.config.threadAutoArchive})).id}catch(Y){this.logger.error("Failed to create thread",{error:Y})}let I=`discord-${$}`,f=this.context.permissions.getUserLevel("discord",B.author.id),D=B.guild?.name??"DM";this.startProcessingInput($);try{let Y=this.client?.channels.cache.get($);if(De(Y))this.startTypingIndicator(Y);if(this.pendingConfirmations.has(I)){await this.handleConfirmationResponse(A,I,$);return}let H=await w.chat(A,I,{userPermissionLevel:f,interfaceType:"discord",channelId:$,channelName:D});if(H.pendingConfirmation)this.pendingConfirmations.set(I,!0);let W=await this.sendMessageWithId({channelId:$,message:H.text});if(W&&H.toolResults){for(let G of H.toolResults)if(G.jobId)this.trackAgentResponseForJob(G.jobId,W,$)}}catch(Y){this.logger.error("Error handling message",{error:Y,channelId:$}),this.sendMessageToChannel({channelId:$,message:`**Error:** ${Y instanceof Error?Y.message:"Unknown error"}`})}finally{this.endProcessingInput(),this.stopTypingIndicator($)}}async handleConfirmationResponse(A,Q,B){let w=yL(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}))},IC2);this.typingIntervals.set(A.id,Q)}stopTypingIndicator(A){let Q=this.typingIntervals.get(A);if(Q)clearInterval(Q),this.typingIntervals.delete(A)}stripMention(A){if(!this.client?.user)return A;return A.replace(new RegExp(`<@!?${this.client.user.id}>`,"g"),"").trim()}}I0();import{resolve as mb,join as rC2}from"path";var FCA=(A,Q,B)=>{return(w,$)=>{let I=-1;return f(0);async function f(D){if(D<=I)throw Error("next() called multiple times");I=D;let Y,H=!1,W;if(A[D])W=A[D][0][0],w.req.routeIndex=D;else W=D===A.length&&$||void 0;if(W)try{Y=await W(w,()=>f(D+1))}catch(G){if(G instanceof Error&&Q)w.error=G,Y=await Q(G,w),H=!0;else throw G}else if(w.finalized===!1&&B)Y=await B(w);if(Y&&(w.finalized===!1||H))w.res=Y;return w}}};var iS0=Symbol();var rS0=async(A,Q=Object.create(null))=>{let{all:B=!1,dot:w=!1}=Q,I=(A instanceof Ye?A.raw.headers:A.headers).get("Content-Type");if(I?.startsWith("multipart/form-data")||I?.startsWith("application/x-www-form-urlencoded"))return DC2(A,{all:B,dot:w});return{}};async function DC2(A,Q){let B=await A.formData();if(B)return YC2(B,Q);return{}}function YC2(A,Q){let B=Object.create(null);if(A.forEach((w,$)=>{if(!(Q.all||$.endsWith("[]")))B[$]=w;else HC2(B,$,w)}),Q.dot)Object.entries(B).forEach(([w,$])=>{if(w.includes("."))XC2(B,w,$),delete B[w]});return B}var HC2=(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]},XC2=(A,Q,B)=>{let w=A,$=Q.split(".");$.forEach((I,f)=>{if(f===$.length-1)w[I]=B;else{if(!w[I]||typeof w[I]!=="object"||Array.isArray(w[I])||w[I]instanceof File)w[I]=Object.create(null);w=w[I]}})};var ZCA=(A)=>{let Q=A.split("/");if(Q[0]==="")Q.shift();return Q},dS0=(A)=>{let{groups:Q,path:B}=WC2(A),w=ZCA(B);return UC2(w,Q)},WC2=(A)=>{let Q=[];return A=A.replace(/\{[^}]+\}/g,(B,w)=>{let $=`@${w}`;return Q.push([$,B]),$}),{groups:Q,path:A}},UC2=(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},He={},nS0=(A,Q)=>{if(A==="*")return"*";let B=A.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);if(B){let w=`${A}#${Q}`;if(!He[w])if(B[2])He[w]=Q&&Q[0]!==":"&&Q[0]!=="*"?[w,B[1],new RegExp(`^${B[2]}(?=/${Q})`)]:[A,B[1],new RegExp(`^${B[2]}$`)];else He[w]=[A,B[1],!0];return He[w]}return null},Xe=(A,Q)=>{try{return Q(A)}catch{return A.replace(/(?:%[0-9A-Fa-f]{2})+/g,(B)=>{try{return Q(B)}catch{return B}})}},zCA=(A)=>Xe(A,decodeURI),NCA=(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 I=Q.indexOf("?",w),f=Q.indexOf("#",w),D=I===-1?f===-1?void 0:f:f===-1?I:Math.min(I,f),Y=Q.slice(B,D);return zCA(Y.includes("%25")?Y.replace(/%25/g,"%2525"):Y)}else if($===63||$===35)break}return Q.slice(B,w)};var oS0=(A)=>{let Q=NCA(A);return Q.length>1&&Q.at(-1)==="/"?Q.slice(0,-1):Q},Pq=(A,Q,...B)=>{if(B.length)Q=Pq(Q,...B);return`${A?.[0]==="/"?"":"/"}${A}${Q==="/"?"":`${A?.at(-1)==="/"?"":"/"}${Q?.[0]==="/"?Q.slice(1):Q}`}`},We=(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 I=$.replace("?","");w+="/"+I,B.push(w)}else w+="/"+$}),B.filter(($,I,f)=>f.indexOf($)===I)},KCA=(A)=>{if(!/[%+]/.test(A))return A;if(A.indexOf("+")!==-1)A=A.replace(/\+/g," ");return A.indexOf("%")!==-1?Xe(A,qCA):A},sS0=(A,Q,B)=>{let w;if(!B&&Q&&!/[%+]/.test(Q)){let f=A.indexOf("?",8);if(f===-1)return;if(!A.startsWith(Q,f+1))f=A.indexOf(`&${Q}`,f+1);while(f!==-1){let D=A.charCodeAt(f+Q.length+1);if(D===61){let Y=f+Q.length+2,H=A.indexOf("&",Y);return KCA(A.slice(Y,H===-1?void 0:H))}else if(D==38||isNaN(D))return"";f=A.indexOf(`&${Q}`,f+1)}if(w=/[%+]/.test(A),!w)return}let $={};w??=/[%+]/.test(A);let I=A.indexOf("?",8);while(I!==-1){let f=A.indexOf("&",I+1),D=A.indexOf("=",I);if(D>f&&f!==-1)D=-1;let Y=A.slice(I+1,D===-1?f===-1?void 0:f:D);if(w)Y=KCA(Y);if(I=f,Y==="")continue;let H;if(D===-1)H="";else if(H=A.slice(D+1,f===-1?void 0:f),w)H=KCA(H);if(B){if(!($[Y]&&Array.isArray($[Y])))$[Y]=[];$[Y].push(H)}else $[Y]??=H}return Q?$[Q]:$},aS0=sS0,tS0=(A,Q)=>{return sS0(A,Q,!0)},qCA=decodeURIComponent;var eS0=(A)=>Xe(A,qCA),Ye=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.#I()}#B(A){let Q=this.#Q[0][this.routeIndex][1][A],B=this.#$(Q);return B&&/\%/.test(B)?eS0(B):B}#I(){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)?eS0(w):w}return A}#$(A){return this.#Q[1]?this.#Q[1][A]:A}query(A){return aS0(this.url,A)}queries(A){return tS0(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 rS0(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((I)=>{if($==="json")I=JSON.stringify(I);return new Response(I)[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[iS0](){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 Am0={Stringify:1,BeforeStream:2,Stream:3},Qm0=(A,Q)=>{let B=new String(A);return B.isEscaped=!0,B.callbacks=Q,B};var CCA=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 I=A.callbacks;if(!I?.length)return Promise.resolve(A);if($)$[0]+=A;else $=[A];let f=Promise.all(I.map((D)=>D({phase:Q,buffer:$,context:w}))).then((D)=>Promise.all(D.filter(Boolean).map((Y)=>CCA(Y,Q,!1,w,$))).then(()=>$[0]));if(B)return Qm0(await f,I);else return f};var JC2="text/plain; charset=UTF-8",ECA=(A,Q)=>{return{"Content-Type":A,...Q}},tg=(A,Q)=>new Response(A,Q),Bm0=class{#A;#Q;env={};#B;finalized=!1;error;#I;#$;#w;#X;#Y;#H;#D;#W;#U;constructor(A,Q){if(this.#A=A,Q)this.#$=Q.executionCtx,this.env=Q.env,this.#H=Q.notFoundHandler,this.#U=Q.path,this.#W=Q.matchResult}get req(){return this.#Q??=new Ye(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||=tg(null,{headers:this.#D??=new Headers})}set res(A){if(this.#w&&A){A=tg(A.body,A);for(let[Q,B]of this.#w.headers.entries()){if(Q==="content-type")continue;if(Q==="set-cookie"){let w=this.#w.headers.getSetCookie();A.headers.delete("set-cookie");for(let $ of w)A.headers.append("set-cookie",$)}else A.headers.set(Q,B)}}this.#w=A,this.finalized=!0}render=(...A)=>{return this.#Y??=(Q)=>this.html(Q),this.#Y(...A)};setLayout=(A)=>this.#X=A;getLayout=()=>this.#X;setRenderer=(A)=>{this.#Y=A};header=(A,Q,B)=>{if(this.finalized)this.#w=tg(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.#I=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)}#f(A,Q,B){let w=this.#w?new Headers(this.#w.headers):this.#D??new Headers;if(typeof Q==="object"&&"headers"in Q){let I=Q.headers instanceof Headers?Q.headers:new Headers(Q.headers);for(let[f,D]of I)if(f.toLowerCase()==="set-cookie")w.append(f,D);else w.set(f,D)}if(B)for(let[I,f]of Object.entries(B))if(typeof f==="string")w.set(I,f);else{w.delete(I);for(let D of f)w.append(I,D)}let $=typeof Q==="number"?Q:Q?.status??this.#I;return tg(A,{status:$,headers:w})}newResponse=(...A)=>this.#f(...A);body=(A,Q,B)=>this.#f(A,Q,B);text=(A,Q,B)=>{return!this.#D&&!this.#I&&!Q&&!B&&!this.finalized?new Response(A):this.#f(A,Q,ECA(JC2,B))};json=(A,Q,B)=>{return this.#f(JSON.stringify(A),Q,ECA("application/json",B))};html=(A,Q,B)=>{let w=($)=>this.#f($,Q,ECA("text/html; charset=UTF-8",B));return typeof A==="object"?CCA(A,Am0.Stringify,!1,{}).then(w):w(A)};redirect=(A,Q)=>{let B=String(A);return this.header("Location",!/[^\x00-\xFF]/.test(B)?B:encodeURI(B)),this.newResponse(null,Q??302)};notFound=()=>{return this.#H??=()=>tg(),this.#H(this)}};var Fw="ALL",wm0="all",$m0=["get","post","put","delete","options","patch"],Ue="Can not add a route since the matcher is already built.",Je=class extends Error{};var LCA="__COMPOSED_HANDLER";var GC2=(A)=>{return A.text("404 Not Found",404)},Im0=(A,Q)=>{if("getResponse"in A){let B=A.getResponse();return Q.newResponse(B.body,B)}return console.error(A),Q.text("Internal Server Error",500)},fm0=class A{get;post;put;delete;options;patch;all;on;use;router;getPath;_basePath="/";#A="/";routes=[];constructor(Q={}){[...$m0,wm0].forEach((I)=>{this[I]=(f,...D)=>{if(typeof f==="string")this.#A=f;else this.#I(I,this.#A,f);return D.forEach((Y)=>{this.#I(I,this.#A,Y)}),this}}),this.on=(I,f,...D)=>{for(let Y of[f].flat()){this.#A=Y;for(let H of[I].flat())D.map((W)=>{this.#I(H.toUpperCase(),this.#A,W)})}return this},this.use=(I,...f)=>{if(typeof I==="string")this.#A=I;else this.#A="*",f.unshift(I);return f.forEach((D)=>{this.#I(Fw,this.#A,D)}),this};let{strict:w,...$}=Q;Object.assign(this,$),this.getPath=w??!0?Q.getPath??NCA:oS0}#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=GC2;errorHandler=Im0;route(Q,B){let w=this.basePath(Q);return B.routes.map(($)=>{let I;if(B.errorHandler===Im0)I=$.handler;else I=async(f,D)=>(await FCA([],B.errorHandler)(f,()=>$.handler(f,D))).res,I[LCA]=$.handler;w.#I($.method,$.path,I)}),this}basePath(Q){let B=this.#Q();return B._basePath=Pq(this._basePath,Q),B}onError=(Q)=>{return this.errorHandler=Q,this};notFound=(Q)=>{return this.#B=Q,this};mount(Q,B,w){let $,I;if(w)if(typeof w==="function")I=w;else if(I=w.optionHandler,w.replaceRequest===!1)$=(Y)=>Y;else $=w.replaceRequest;let f=I?(Y)=>{let H=I(Y);return Array.isArray(H)?H:[H]}:(Y)=>{let H=void 0;try{H=Y.executionCtx}catch{}return[Y.env,H]};$||=(()=>{let Y=Pq(this._basePath,Q),H=Y==="/"?0:Y.length;return(W)=>{let G=new URL(W.url);return G.pathname=G.pathname.slice(H)||"/",new Request(G,W)}})();let D=async(Y,H)=>{let W=await B($(Y.req.raw),...f(Y));if(W)return W;await H()};return this.#I(Fw,Pq(Q,"*"),D),this}#I(Q,B,w){Q=Q.toUpperCase(),B=Pq(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 I=this.getPath(Q,{env:w}),f=this.router.match($,I),D=new Bm0(Q,{path:I,matchResult:f,env:w,executionCtx:B,notFoundHandler:this.#B});if(f[0].length===1){let H;try{H=f[0][0][0][0](D,async()=>{D.res=await this.#B(D)})}catch(W){return this.#$(W,D)}return H instanceof Promise?H.then((W)=>W||(D.finalized?D.res:this.#B(D))).catch((W)=>this.#$(W,D)):H??this.#B(D)}let Y=FCA(f[0],this.errorHandler,this.#B);return(async()=>{try{let H=await Y(D);if(!H.finalized)throw Error("Context is not finalized. Did you forget to return a Response object or `await next()`?");return H.res}catch(H){return this.#$(H,D)}})()}fetch=(Q,...B)=>{return this.#w(Q,B[1],B[0],Q.method)};request=(Q,B,w,$)=>{if(Q instanceof Request)return this.fetch(B?new Request(Q,B):Q,w,$);return Q=Q.toString(),this.fetch(new Request(/^https?:\/\//.test(Q)?Q:`http://localhost${Pq("/",Q)}`,B),w,$)};fire=()=>{addEventListener("fetch",(Q)=>{Q.respondWith(this.#w(Q.request,Q,void 0,Q.request.method))})}};var eg=[];function Ge(A,Q){let B=this.buildAllMatchers(),w=($,I)=>{let f=B[$]||B[Fw],D=f[2][I];if(D)return D;let Y=I.match(f[0]);if(!Y)return[[],eg];let H=Y.indexOf("",1);return[f[1][H],Y]};return this.match=w,w(A,Q)}var Fe="[^/]+",AT=".*",QT="(?:|/.*)",kq=Symbol(),FC2=new Set(".\\+*[^]$()");function KC2(A,Q){if(A.length===1)return Q.length===1?A<Q?-1:1:-1;if(Q.length===1)return 1;if(A===AT||A===QT)return 1;else if(Q===AT||Q===QT)return-1;if(A===Fe)return 1;else if(Q===Fe)return-1;return A.length===Q.length?A<Q?-1:1:Q.length-A.length}var Dm0=class A{#A;#Q;#B=Object.create(null);insert(Q,B,w,$,I){if(Q.length===0){if(this.#A!==void 0)throw kq;if(I)return;this.#A=B;return}let[f,...D]=Q,Y=f==="*"?D.length===0?["","",AT]:["","",Fe]:f==="/*"?["","",QT]:f.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/),H;if(Y){let W=Y[1],G=Y[2]||Fe;if(W&&Y[2]){if(G===".*")throw kq;if(G=G.replace(/^\((?!\?:)(?=[^)]+\)$)/,"(?:"),/\((?!\?:)/.test(G))throw kq}if(H=this.#B[G],!H){if(Object.keys(this.#B).some((K)=>K!==AT&&K!==QT))throw kq;if(I)return;if(H=this.#B[G]=new A,W!=="")H.#Q=$.varIndex++}if(!I&&W!=="")w.push([W,H.#Q])}else if(H=this.#B[f],!H){if(Object.keys(this.#B).some((W)=>W.length>1&&W!==AT&&W!==QT))throw kq;if(I)return;H=this.#B[f]=new A}H.insert(D,B,w,$,I)}buildRegExpStr(){let B=Object.keys(this.#B).sort(KC2).map((w)=>{let $=this.#B[w];return(typeof $.#Q==="number"?`(${w})@${$.#Q}`:FC2.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 Ym0=class{#A={varIndex:0};#Q=new Dm0;insert(A,Q,B){let w=[],$=[];for(let f=0;;){let D=!1;if(A=A.replace(/\{[^}]+\}/g,(Y)=>{let H=`@\\${f}`;return $[f]=[H,Y],f++,D=!0,H}),!D)break}let I=A.match(/(?::[^\/]+)|(?:\/\*$)|./g)||[];for(let f=$.length-1;f>=0;f--){let[D]=$[f];for(let Y=I.length-1;Y>=0;Y--)if(I[Y].indexOf(D)!==-1){I[Y]=I[Y].replace(D,$[f][1]);break}}return this.#Q.insert(I,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,($,I,f)=>{if(I!==void 0)return B[++Q]=Number(I),"$()";if(f!==void 0)return w[Number(f)]=++Q,"";return""}),[new RegExp(`^${A}`),B,w]}};var ZC2=[/^$/,[],Object.create(null)],Hm0=Object.create(null);function Xm0(A){return Hm0[A]??=new RegExp(A==="*"?"":`^${A.replace(/\/\*$|([.\\+*[^\]$()])/g,(Q,B)=>B?`\\${B}`:"(?:|/.*)")}$`)}function zC2(){Hm0=Object.create(null)}function NC2(A){let Q=new Ym0,B=[];if(A.length===0)return ZC2;let w=A.map((H)=>[!/\*|\/:/.test(H[0]),...H]).sort(([H,W],[G,K])=>H?1:G?-1:W.length-K.length),$=Object.create(null);for(let H=0,W=-1,G=w.length;H<G;H++){let[K,Z,q]=w[H];if(K)$[Z]=[q.map(([C])=>[C,Object.create(null)]),eg];else W++;let L;try{L=Q.insert(Z,W,K)}catch(C){throw C===kq?new Je(Z):C}if(K)continue;B[W]=q.map(([C,R])=>{let j=Object.create(null);R-=1;for(;R>=0;R--){let[P,o]=L[R];j[P]=o}return[C,j]})}let[I,f,D]=Q.buildRegExp();for(let H=0,W=B.length;H<W;H++)for(let G=0,K=B[H].length;G<K;G++){let Z=B[H][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 Y=[];for(let H in f)Y[H]=B[f[H]];return[I,Y,$]}function gb(A,Q){if(!A)return;for(let B of Object.keys(A).sort((w,$)=>$.length-w.length))if(Xm0(B).test(Q))return[...A[B]];return}var Ke=class{name="RegExpRouter";#A;#Q;constructor(){this.#A={[Fw]:Object.create(null)},this.#Q={[Fw]:Object.create(null)}}add(A,Q,B){let w=this.#A,$=this.#Q;if(!w||!$)throw Error(Ue);if(!w[A])[w,$].forEach((D)=>{D[A]=Object.create(null),Object.keys(D[Fw]).forEach((Y)=>{D[A][Y]=[...D[Fw][Y]]})});if(Q==="/*")Q="*";let I=(Q.match(/\/:/g)||[]).length;if(/\*$/.test(Q)){let D=Xm0(Q);if(A===Fw)Object.keys(w).forEach((Y)=>{w[Y][Q]||=gb(w[Y],Q)||gb(w[Fw],Q)||[]});else w[A][Q]||=gb(w[A],Q)||gb(w[Fw],Q)||[];Object.keys(w).forEach((Y)=>{if(A===Fw||A===Y)Object.keys(w[Y]).forEach((H)=>{D.test(H)&&w[Y][H].push([B,I])})}),Object.keys($).forEach((Y)=>{if(A===Fw||A===Y)Object.keys($[Y]).forEach((H)=>D.test(H)&&$[Y][H].push([B,I]))});return}let f=We(Q)||[Q];for(let D=0,Y=f.length;D<Y;D++){let H=f[D];Object.keys($).forEach((W)=>{if(A===Fw||A===W)$[W][H]||=[...gb(w[W],H)||gb(w[Fw],H)||[]],$[W][H].push([B,I-Y+D+1])})}}match=Ge;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,zC2(),A}#B(A){let Q=[],B=A===Fw;if([this.#A,this.#Q].forEach((w)=>{let $=w[A]?Object.keys(w[A]).map((I)=>[I,w[A][I]]):[];if($.length!==0)B||=!0,Q.push(...$);else if(A!==Fw)Q.push(...Object.keys(w[Fw]).map((I)=>[I,w[Fw][I]]))}),!B)return null;else return NC2(Q)}};var qC2=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))}#I(A,Q,B,w,$){let I=this.#A[A];if(!$)I[2][Q][0].push([B,{}]);else w.forEach((f)=>{if(typeof f==="number")I[1][f].push([B,$]);else I[2][f||Q][0].push([B,$])})}add(A,Q,B){if(!this.#A[A]){let $=this.#A[Fw],I={};for(let f in $[2])I[f]=[$[2][f][0].slice(),eg];this.#A[A]=[$[0],$[1].map((f)=>Array.isArray(f)?f.slice():0),I]}if(Q==="/*"||Q==="*"){let $=[B,{}];if(A===Fw)for(let I in this.#A)this.#B(I,$);else this.#B(A,$);return}let w=this.#Q[Q];if(!w)throw Error(`Path ${Q} is not registered`);for(let[$,I]of w)if(A===Fw)for(let f in this.#A)this.#I(f,Q,B,$,I);else this.#I(A,Q,B,$,I)}buildAllMatchers(){return this.#A}match=Ge};var MCA=class{name="SmartRouter";#A=[];#Q=[];constructor(A){this.#A=A.routers}add(A,Q,B){if(!this.#Q)throw Error(Ue);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,I=0,f;for(;I<$;I++){let D=B[I];try{for(let Y=0,H=w.length;Y<H;Y++)D.add(...w[Y]);f=D.match(A,Q)}catch(Y){if(Y instanceof Je)continue;throw Y}this.match=D.match.bind(D),this.#A=[D],this.#Q=void 0;break}if(I===$)throw Error("Fatal error");return this.name=`SmartRouter + ${this.activeRouter.name}`,f}get activeRouter(){if(this.#Q||this.#A.length!==1)throw Error("No active router has been determined yet.");return this.#A[0]}};var BT=Object.create(null),CC2=(A)=>{for(let Q in A)return!0;return!1},Wm0=class A{#A;#Q;#B;#I=0;#$=BT;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.#I=++this.#I;let $=this,I=dS0(B),f=[];for(let D=0,Y=I.length;D<Y;D++){let H=I[D],W=I[D+1],G=nS0(H,W),K=Array.isArray(G)?G[0]:H;if(K in $.#Q){if($=$.#Q[K],G)f.push(G[1]);continue}if($.#Q[K]=new A,G)$.#B.push(G),f.push(G[1]);$=$.#Q[K]}return $.#A.push({[Q]:{handler:w,possibleKeys:f.filter((D,Y,H)=>H.indexOf(D)===Y),score:this.#I}}),$}#w(Q,B,w,$,I){for(let f=0,D=B.#A.length;f<D;f++){let Y=B.#A[f],H=Y[w]||Y[Fw],W={};if(H!==void 0){if(H.params=Object.create(null),Q.push(H),$!==BT||I&&I!==BT)for(let G=0,K=H.possibleKeys.length;G<K;G++){let Z=H.possibleKeys[G],q=W[H.score];H.params[Z]=I?.[Z]&&!q?I[Z]:$[Z]??I?.[Z],W[H.score]=!0}}}}search(Q,B){let w=[];this.#$=BT;let I=[this],f=ZCA(B),D=[],Y=f.length,H=null;for(let W=0;W<Y;W++){let G=f[W],K=W===Y-1,Z=[];for(let L=0,C=I.length;L<C;L++){let R=I[L],j=R.#Q[G];if(j)if(j.#$=R.#$,K){if(j.#Q["*"])this.#w(w,j.#Q["*"],Q,R.#$);this.#w(w,j,Q,R.#$)}else Z.push(j);for(let P=0,o=R.#B.length;P<o;P++){let n=R.#B[P],S=R.#$===BT?{}:{...R.#$};if(n==="*"){let c=R.#Q["*"];if(c)this.#w(w,c,Q,R.#$),c.#$=S,Z.push(c);continue}let[v,y,g]=n;if(!G&&!(g instanceof RegExp))continue;let AA=R.#Q[v];if(g instanceof RegExp){if(H===null){H=Array(Y);let YA=B[0]==="/"?1:0;for(let _=0;_<Y;_++)H[_]=YA,YA+=f[_].length+1}let c=B.substring(H[W]),GA=g.exec(c);if(GA){if(S[y]=GA[0],this.#w(w,AA,Q,R.#$,S),CC2(AA.#Q)){AA.#$=S;let YA=GA[0].match(/\//)?.length??0;(D[YA]||=[]).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();I=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 VCA=class{name="TrieRouter";#A;constructor(){this.#A=new Wm0}add(A,Q,B){let w=We(Q);if(w){for(let $=0,I=w.length;$<I;$++)this.#A.insert(A,w[$],B);return}this.#A.insert(A,Q,B)}match(A,Q){return this.#A.search(A,Q)}};var Tb=class extends fm0{constructor(A={}){super(A);this.router=A.router??new MCA({routers:[new Ke,new VCA]})}};import{stat as OC2}from"fs/promises";import{join as bC2}from"path";var Sb=/^\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 OCA=(A,Q=LC2)=>{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 EC2={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"},LC2=EC2;var Um0=(...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 Jm0={br:".br",zstd:".zst",gzip:".gz"},MC2=Object.keys(Jm0),VC2="index.html",Gm0=(A)=>{let Q=A.root??"./",B=A.path,w=A.join??Um0;return async($,I)=>{if($.finalized)return I();let f;if(A.path)f=A.path;else try{if(f=zCA($.req.path),/(?:^|[\/\\])\.\.(?:$|[\/\\])/.test(f))throw Error()}catch{return await A.onNotFound?.($.req.path,$),I()}let D=w(Q,!B&&A.rewriteRequestPath?A.rewriteRequestPath(f):f);if(A.isDir&&await A.isDir(D))D=w(D,VC2);let Y=A.getContent,H=await Y(D,$);if(H instanceof Response)return $.newResponse(H.body,H);if(H){let W=A.mimes&&OCA(D,A.mimes)||OCA(D);if($.header("Content-Type",W||"application/octet-stream"),A.precompressed&&(!W||Sb.test(W))){let G=new Set($.req.header("Accept-Encoding")?.split(",").map((K)=>K.trim()));for(let K of MC2){if(!G.has(K))continue;let Z=await Y(D+Jm0[K],$);if(Z){H=Z,$.header("Content-Encoding",K),$.header("Vary","Accept-Encoding",{append:!0});break}}}return await A.onFound?.(D,$),$.body(H)}await A.onNotFound?.(D,$),await I();return}};var bCA=(A)=>{return async function(B,w){return Gm0({...A,getContent:async(f)=>{let D=Bun.file(f);return await D.exists()?D:null},join:bC2,isDir:async(f)=>{let D;try{D=(await OC2(f)).isDirectory()}catch{}return D}})(B,w)}};var RCA="x-hono-disable-ssg",pvB=(()=>{try{return new Response("SSG is disabled",{status:404,headers:{[RCA]:"true"}})}catch{return null}})();var{write:MhB}=Bun;var PC2=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 Fm0=(A)=>{return(...Q)=>{if(typeof Q[0]==="function"){let[B,w]=Q;return async function(I,f){let D=await B(I),Y=await A(I,D,w);if(Y)return Y;await f()}}else{let[B,w,$]=Q;return(async()=>{let I=await A(B,w,$);if(!I)throw Error("Failed to upgrade WebSocket");return I})()}}};var Ze=(A)=>("server"in A.env)?A.env.server:A.env;var kC2=Fm0((A,Q)=>{let B=Ze(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 jC2=["gzip","deflate"],xC2=/(?:^|,)\s*?no-transform\s*?(?:,|$)/i,Km0=(A)=>{let Q=A?.threshold??1024;return async function(w,$){await $();let I=w.res.headers.get("Content-Length");if(w.res.headers.has("Content-Encoding")||w.res.headers.has("Transfer-Encoding")||w.req.method==="HEAD"||I&&Number(I)<Q||!vC2(w.res)||!hC2(w.res))return;let f=w.req.header("Accept-Encoding"),D=A?.encoding??jC2.find((H)=>f?.includes(H));if(!D||!w.res.body)return;let Y=new CompressionStream(D);w.res=new Response(w.res.body.pipeThrough(Y),w.res),w.res.headers.delete("Content-Length"),w.res.headers.set("Content-Encoding",D)}},vC2=(A)=>{let Q=A.headers.get("Content-Type");return Q&&Sb.test(Q)},hC2=(A)=>{let Q=A.headers.get("Cache-Control");return!Q||!xC2.test(Q)};import{Readable as Zm0}from"stream";import{createDeflate as yC2,createGzip as gC2}from"zlib";var TC2=["gzip","deflate"],SC2=/(?:^|,)\s*?no-transform\s*?(?:,|$)/i,zm0=(A)=>{if(typeof CompressionStream<"u")return Km0(A);let Q=A?.threshold??1024;return async function(w,$){await $();let I=w.res.headers.get("Content-Length");if(w.res.headers.has("Content-Encoding")||w.res.headers.has("Transfer-Encoding")||w.req.method==="HEAD"||I&&Number(I)<Q||!mC2(w.res)||!uC2(w.res))return;let f=w.req.header("Accept-Encoding"),D=A?.encoding??TC2.find((Y)=>f?.includes(Y));if(!D||!w.res.body)return;try{let Y=D==="gzip"?gC2():yC2(),H=w.res.body,G=Zm0.fromWeb(H).pipe(Y),K=Zm0.toWeb(G);w.res=new Response(K,w.res),w.res.headers.delete("Content-Length"),w.res.headers.set("Content-Encoding",D)}catch(Y){console.error("Compression error:",Y)}}},mC2=(A)=>{let Q=A.headers.get("Content-Type");return Q&&Sb.test(Q)},uC2=(A)=>{let Q=A.headers.get("Cache-Control");return!Q||!SC2.test(Q)};var cC2=(A,Q)=>{if(!A)return Q;let B=new Uint8Array(new ArrayBuffer(A.byteLength+Q.byteLength));return B.set(new Uint8Array(A),0),B.set(Q,A.byteLength),B},Nm0=async(A,Q)=>{if(!A)return null;let B=void 0,w=A.getReader();for(;;){let{value:$,done:I}=await w.read();if(I)break;B=await Q(cC2(B,$))}if(!B)return null;return Array.prototype.map.call(new Uint8Array(B),($)=>$.toString(16).padStart(2,"0")).join("")};var pC2=["cache-control","content-location","date","etag","expires","vary"],qm0=(A)=>A.replace(/^W\//,"");function lC2(A,Q){return Q!=null&&Q.split(/,\s*/).some((B)=>qm0(B)===qm0(A))}function iC2(A){if(!A){if(crypto&&crypto.subtle)A=(Q)=>crypto.subtle.digest({name:"SHA-1"},Q)}return A}var Cm0=(A)=>{let Q=A?.retainedHeaders??pC2,B=A?.weak??!1,w=iC2(A?.generateDigest);return async function(I,f){let D=I.req.header("If-None-Match")??null;await f();let Y=I.res,H=Y.headers.get("ETag");if(!H){if(!w)return;let W=await Nm0(Y.clone().body,w);if(W===null)return;H=B?`W/"${W}"`:`"${W}"`}if(lC2(H,D))I.res=new Response(null,{status:304,statusText:"Not Modified",headers:{ETag:H}}),I.res.headers.forEach((W,G)=>{if(Q.indexOf(G.toLowerCase())===-1)I.res.headers.delete(G)});else I.res.headers.set("ETag",H)}};I0();function ze(A,Q){return async(B)=>{let w=B.req.raw,$=w.headers.get("content-type")??"",I=w.headers.get("accept")?.includes("application/json"),f={};if($.includes("application/json"))f=await w.json();else if($.includes("form")){let Z=await w.formData();for(let[q,L]of Z.entries())f[q]=L}let D=`${A.pluginId}_${A.definition.tool}`,Y=await Q.send({type:`plugin:${A.pluginId}:tool:execute`,payload:{toolName:D,args:f,interfaceType:"webserver",userId:"anonymous"},sender:"webserver"}),H=typeof Y==="object"&&"data"in Y?Y.data:Y,W=_k.safeParse(H),G=W.success?W.data:H,K=W.success&&W.data.success===!0;if(I)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 Em0="public, max-age=31536000, immutable";class Ne{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:mb(process.cwd(),A.productionDistDir),sharedImagesDir:mb(process.cwd(),A.sharedImagesDir),...A.previewDistDir&&{previewDistDir:mb(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 Tb;if(A.healthEndpoint)Q.get("/health",async(B)=>{if(this.options.getHealthData){let w=await this.options.getHealthData();return B.json({status:"healthy",...w},200)}return B.json({status:"healthy"},200)});if(Q.use("/*",async(B,w)=>{let $=await this.handleDynamicRoute(B,A);if($)return $;return w()}),A.compress)Q.use("/*",zm0());return Q.use("/*",Cm0()),Q.use("/*",async(B,w)=>{if(await w(),A.immutableExtensions.test(B.req.path))B.header("Cache-Control",Em0);else B.header("Cache-Control",A.defaultCache)}),Q.use("/*",this.createCleanUrlMiddleware(A.distDir)),Q.use("/*",bCA({root:A.distDir})),Q.notFound(async(B)=>{let w=Bun.file(rC2(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((f)=>{let D=f.definition.method??"GET";return f.fullPath===w&&D===B});if($)return $.definition.handler(A.req.raw);let I=this.getCurrentApiRoutes().find((f)=>{let D=f.definition.method;return f.fullPath===w&&D===B});if(I&&this.options.messageBus)return ze(I,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=mb(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":Em0}})}createCleanUrlMiddleware(A){return async(Q,B)=>{let w=Q.req.path;if(w.includes(".")||w==="/"){await B();return}let $=mb(A,`.${w}`,"index.html");if(!$.startsWith(A)){await B();return}let I=Bun.file($);if(await I.exists())return Q.html(await I.text());let f=mb(A,`.${w}.html`);if(f.startsWith(A)){let D=Bun.file(f);if(await D.exists())return Q.html(await D.text())}await B()}}}import{existsSync as Mm0}from"fs";import{join as Vm0}from"path";JA();var _CA=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 PCA=`<!DOCTYPE html>
|
|
2319
2319
|
<html lang="en">
|
|
@@ -2382,7 +2382,7 @@ ${R}`)}if(w!==void 0&&I?.algorithms!==void 0){let C=I.algorithms.map((R)=>R.alg)
|
|
|
2382
2382
|
<p>Once built, this page will be replaced with your actual website.</p>
|
|
2383
2383
|
</div>
|
|
2384
2384
|
</body>
|
|
2385
|
-
</html>`;var Lm0={name:"@brains/webserver",private:!0,version:"0.2.0-alpha.
|
|
2385
|
+
</html>`;var Lm0={name:"@brains/webserver",private:!0,version:"0.2.0-alpha.61",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 $Z extends dH{serverManager;siteUrl;previewUrl;constructor(A={}){super("webserver",Lm0,A,_CA)}async onRegister(A){if(this.siteUrl=A.siteUrl,this.previewUrl=A.previewUrl,this.siteUrl)A.endpoints.register({label:"Site",url:this.siteUrl,priority:10});if(this.config.enablePreview&&this.previewUrl)A.endpoints.register({label:"Preview",url:this.previewUrl,priority:20});this.serverManager=new Ne({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&&!Mm0(this.config.previewDistDir))await A(this.config.previewDistDir,{recursive:!0}),await Q(Vm0(this.config.previewDistDir,"index.html"),PCA),this.logger.debug(`Created preview directory at ${this.config.previewDistDir}`);if(!Mm0(this.config.productionDistDir))await A(this.config.productionDistDir,{recursive:!0}),await Q(Vm0(this.config.productionDistDir,"index.html"),PCA),this.logger.debug(`Created production directory at ${this.config.productionDistDir}`)}}I0();JA();var Om0=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)});I0();function nC2(A,Q){return`${A.name} is ${Q.name}'s ${A.role}. Its purpose is: ${A.purpose}.`}function bm0(A){let{character:Q,profile:B,version:w,domain:$,organization:I,tools:f}=A,Y=`${A.baseUrl??($?`https://${$}`:"http://localhost:8080")}/a2a`,H=A.skills&&A.skills.length>0?A.skills.map((K)=>({id:K.name.toLowerCase().replace(/\s+/g,"-"),name:K.name,description:K.description,tags:K.tags,examples:K.examples})):f.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(I)W.organization=I;let G=[{uri:hl,description:"Anchor (operator) identity for this brain",params:W}];return{name:Q.name,description:nC2(Q,B),url:Y,version:w,protocolVersion:"0.2.2",capabilities:{streaming:!0,pushNotifications:!1,extensions:G},skills:H,defaultInputModes:["text/plain"],defaultOutputModes:["text/plain"],...I&&{provider:{organization:I,url:Y}},...A.authEnabled&&{securitySchemes:{bearerAuth:{type:"http",scheme:"bearer"}},security:[{bearerAuth:[]}]}}}I0();var kCA=new Set(["completed","failed","canceled","rejected"]);class jCA{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(kCA.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(),I={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:[I]},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 I={kind:"message",messageId:crypto.randomUUID(),role:"agent",parts:[{kind:"text",text:B}],contextId:w.task.contextId,taskId:A};w.task.status.message=I,w.task.history??=[],w.task.history.push(I)}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}}JA();var Rm0=F.array(F.object({kind:F.string(),text:F.string().optional(),data:F.record(F.unknown()).optional()})),oC2=F.object({message:F.object({kind:F.literal("message").optional(),messageId:F.string().optional(),role:F.enum(["user","agent"]).optional(),parts:Rm0,contextId:F.string().optional(),taskId:F.string().optional()}),configuration:F.object({historyLength:F.number().optional()}).optional()}),_m0=F.object({id:F.string(),historyLength:F.number().optional()});function xCA(A,Q){return{jsonrpc:"2.0",id:A,result:Q}}function lX(A,Q,B){return{jsonrpc:"2.0",id:A,error:{code:Q,message:B}}}var Pm0=F.object({jsonrpc:F.string(),id:F.union([F.string(),F.number()]),method:F.string(),params:F.record(F.unknown()).optional()});async function km0(A,Q){let{id:B,method:w,params:$}=A;switch(w){case"message/send":return sC2(B,$??{},Q);case"tasks/get":return tC2(B,$??{},Q);case"tasks/cancel":return eC2(B,$??{},Q);default:return lX(B,-32601,`Method not found: ${w}`)}}async function sC2(A,Q,B){let w=oC2.safeParse(Q);if(!w.success)return lX(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 lX(A,-32602,"Message must contain at least one text part");let I=$.map((W)=>W.text).join(`
|
|
2386
2386
|
`),f=w.data.message.contextId,D=B.taskManager.createTask(I,f),Y=D.task.id;B.taskManager.updateState(Y,"working"),aC2(Y,I,D.conversationId,B);let H=B.taskManager.getTask(Y);if(!H)return lX(A,-32603,"Internal error: task disappeared");return xCA(A,H.task)}function aC2(A,Q,B,w){w.agentService.chat(Q,B,{userPermissionLevel:w.callerPermissionLevel,interfaceType:"a2a"}).then(($)=>{w.taskManager.updateState(A,"completed",$.text)}).catch(($)=>{let I=$ instanceof Error?$.message:"Unknown error";w.taskManager.updateState(A,"failed",`Error: ${I}`)})}var jm0=F.object({message:F.object({kind:F.string(),parts:Rm0,contextId:F.string().optional()})});function xm0(A,Q,B){let $=Q.parts.filter((H)=>H.kind==="text"&&typeof H.text==="string").map((H)=>H.text).join(`
|
|
2387
2387
|
`)||"No message text",I=B.taskManager.createTask($,Q.contextId),f=I.task.id;B.taskManager.updateState(f,"working");let D=new TextEncoder,Y=new ReadableStream({start(H){let W=!1;function G(L){if(W)return;try{H.enqueue(D.encode(`data: ${JSON.stringify(L)}
|
|
2388
2388
|
|
|
@@ -2390,7 +2390,7 @@ ${R}`)}if(w!==void 0&&I?.algorithms!==void 0){let C=I.algorithms.map((R)=>R.alg)
|
|
|
2390
2390
|
|
|
2391
2391
|
`);$=f.pop()??"";for(let D of f){let Y=D.split(`
|
|
2392
2392
|
`).find((C)=>C.startsWith("data: "));if(!Y)continue;let H;try{H=JSON.parse(Y.slice(6))}catch{return B.cancel().catch(()=>{}),{success:!1,error:"Malformed SSE event from remote agent"}}let W=H.result;if(!W)continue;if(W.final!==!0)continue;B.cancel().catch(()=>{});let K=W.status,Z=K?.state??"unknown",L=(K?.message?.parts??[]).filter((C)=>C.kind==="text"&&typeof C.text==="string").map((C)=>C.text).join(`
|
|
2393
|
-
`)||"No response text";return{success:!0,data:{state:Z,response:L}}}I=await hm0(B,Q)}return{success:!1,error:"Stream ended without a terminal event"}}class wT extends Error{timeoutMs;constructor(A){super(`request timed out after ${A}ms`);this.timeoutMs=A;this.name="A2ARequestTimeoutError"}}class $T extends Error{timeoutMs;constructor(A){super(`A2A stream stalled waiting for final event after ${A}ms`);this.timeoutMs=A;this.name="A2AStreamIdleTimeoutError"}}async function DE2(A,Q,B,w){let $=new AbortController,I;try{return await Promise.race([A(Q,{...B,signal:$.signal}),new Promise((f,D)=>{I=setTimeout(()=>{$.abort(),D(new wT(w))},w)})])}catch(f){if(f instanceof wT)throw f;if($.signal.aborted)throw new wT(w);throw f}finally{if(I)clearTimeout(I)}}async function hm0(A,Q){let B;try{return await Promise.race([A.read(),new Promise((w,$)=>{B=setTimeout(()=>$(new $T(Q)),Q)})])}catch(w){if(w instanceof $T)A.cancel().catch(()=>{});throw w}finally{if(B)clearTimeout(B)}}function YE2(A){if(A instanceof wT||A instanceof $T)return!0;return A instanceof Error}function HE2(A,Q){let B=Q>1?` after ${Q} attempts`:"";if(A instanceof $T)return`${A.message}${B}`;let w=A instanceof Error?A.message:"Unknown network error";return`Failed to reach remote agent${B}: ${w}`}function gm0(A={}){let Q=A.fetch??globalThis.fetch,B={requestTimeoutMs:A.requestTimeoutMs??AE2,streamIdleTimeoutMs:A.streamIdleTimeoutMs??QE2,maxNetworkAttempts:A.maxNetworkAttempts??BE2};return{name:"a2a_call",description:"Call a saved remote A2A agent by its local directory id. Use only a saved agent id such as yeehaa.io. Never pass a display name like Brain, never pass a full URL, and do not use this tool to probe whether an agent exists. If the user gives a URL, an unsaved agent, or an ambiguous name, ask them to add/save or clarify the agent first.",inputSchema:vm0,visibility:"anchor",handler:async(w)=>{let $=F.object(vm0).safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};let{agent:I,message:f}=$.data,D=wE2(I);if(!D)return{success:!1,error:"Invalid agent id. Use a saved agent id from your directory, not a URL."};if(!A.entityService)return{success:!1,error:"Agent directory is unavailable. Add the agent first, then try again."};let Y=await A.entityService.getEntity({entityType:"agent",id:D});if(!Y)return{success:!1,error:`Agent ${D} is not in your directory. Add it first.`};if(Y.metadata.status!=="approved")return{success:!1,error:`Agent ${D} is discovered but not approved yet. Approve it first.`};let H=`https://${D}`,W=await $E2(H,Q);if(!W)return{success:!1,error:`Could not fetch Agent Card from ${H}`};let G=W.url,K;if(A.outboundTokens)try{let Z=new URL(G).hostname;K=A.outboundTokens[Z]}catch{}return IE2(G,f,Q,K,B)}}}var vCA={name:"@brains/a2a",private:!0,version:"0.2.0-alpha.60",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 WE2={"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization","X-Content-Type-Options":"nosniff"};class ub extends dH{agentCard;taskManager=new jCA;agentService;permissionContext;app;hasWebserver=!1;constructor(A={}){super("a2a",vCA,A,Om0)}async onRegister(A){if(await super.onRegister(A),this.hasWebserver=A.plugins.has("webserver"),this.agentService=A.agent,this.permissionContext=A.permissions,this.hasWebserver)this.logger.info("A2A interface registered",{domain:A.domain});else this.logger.info("A2A interface registered in tool-only mode",{domain:A.domain})}async onReady(A){await this.rebuildAgentCard(A)}async rebuildAgentCard(A){let Q=A.identity.get(),B=A.identity.getProfile(),w=A.tools.listForPermissionLevel("public"),$=this.config.trustedTokens&&Object.keys(this.config.trustedTokens).length>0,I;if(A.entityService.hasEntityType("skill"))try{let f=await A.entityService.listEntities({entityType:"skill"});if(f.length>0)I=f.map((D)=>Af.safeParse(D.metadata)).filter((D)=>D.success).map((D)=>D.data)}catch{}this.agentCard=bm0({character:Q,profile:B,version:vCA.version,domain:A.domain,organization:this.config.organization,tools:w,skills:I,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(WE2))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 Tb;return A.get("/.well-known/agent-card.json",(Q)=>{if(!this.agentCard)return this.withCors(Q.json({error:"Agent Card not ready"},503));return this.withCors(Q.json(this.agentCard))}),A.get("/a2a",(Q)=>{return this.withCors(Q.json({error:"Use POST with JSON-RPC 2.0 requests.",agentCard:"/.well-known/agent-card.json"},405))}),A.options("/a2a",()=>this.withCors(new Response(null,{status:204}))),A.post("/a2a",async(Q)=>{if(!this.agentService)return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32603,message:"Agent service not ready"},id:null},503));let B;try{B=await Q.req.json()}catch{return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32700,message:"Parse error"},id:null}))}let w=Pm0.safeParse(B);if(!w.success)return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32600,message:"Invalid request"},id:null}));let $=this.resolveCallerPermission(Q.req.header("Authorization"));if(w.data.method==="message/stream"){let f=jm0.safeParse(w.data.params??{});if(!f.success)return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32602,message:`Invalid params: ${f.error.message}`},id:w.data.id}));let{stream:D}=xm0(w.data.id,f.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 I=await km0(w.data,{taskManager:this.taskManager,agentService:this.agentService,callerPermissionLevel:$});return this.withCors(Q.json(I))}),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[gm0({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")}}}}I0();class hCA{logger;handleImport;handleDelete;deleteOnFileRemoval;fileOperations;constructor(A,Q,B,w,$=!0){if(this.logger=A,this.fileOperations=w,this.deleteOnFileRemoval=$,B)this.handleImport=async(I)=>{let f=await B({type:"directory-import",data:{paths:[I]}});this.logger.debug("Queued import job for file change",{jobId:f,path:I})},this.handleDelete=async(I)=>{if(!this.deleteOnFileRemoval){this.logger.warn("File deleted but deleteOnFileRemoval is disabled",{path:I});return}try{let{entityType:f,id:D}=this.fileOperations.parseEntityFromPath(I),Y=await B({type:"directory-delete",data:{entityId:D,entityType:f,filePath:I}});this.logger.info("Queued delete job for removed file",{jobId:Y,path:I,entityId:D,entityType:f})}catch(f){this.logger.warn("Could not extract entity info from deleted file",{path:I,error:f})}};else this.handleImport=async(I)=>{await Q([I])},this.handleDelete=async(I)=>{this.logger.warn("File deleted but no job queue available",{path:I})}}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 Qp0=D1(tc0(),1);import{extname as Hb2}from"path";var Se=[".png",".jpg",".jpeg",".webp",".gif",".svg"];function hq(A){let Q=Hb2(A).toLowerCase();return Se.includes(Q)}function ec0(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 vEA(A){switch(A.toLowerCase()){case"jpeg":return".jpg";case"svg+xml":return".svg";default:return`.${A.toLowerCase()}`}}import{isAbsolute as Xb2,relative as Wb2,sep as Ap0,join as Ub2}from"path";function nD(A,Q){return Xb2(Q)?Q:Ub2(A,Q)}function nb(A,Q){let B=nD(A,Q),w=Wb2(A,B);return Ap0==="/"?w:w.split(Ap0).join("/")}function Jb2(A,Q){if(!nb(Q,A).startsWith("image/"))return!1;return hq(A)}function Gb2(A,Q){if(nb(Q,A).split("/")[0]?.startsWith("_"))return!1;if(A.endsWith(".md"))return!0;return Jb2(A,Q)}class hEA{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=Qp0.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(!Gb2(Q,this.syncPath))return;this.logger.debug("File change detected",{event:A,path:Q});let B=nb(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=nD(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 Bp0(A,Q){if(A?.isWatching())return Q.logger.debug("Already watching directory"),A;return Fb2(Q)}function wp0(A){if(A)A.stop();return}function $p0(A,Q){if(A)A.setCallback(Q)}async function Fb2(A){let{logger:Q,syncPath:B,watchInterval:w,importEntities:$,jobQueueCallback:I,fileOperations:f,deleteOnFileRemoval:D}=A,Y=new hCA(Q,$,I,f,D),H=new hEA({syncPath:B,watchInterval:w,logger:Q,onFileChange:async(W,G)=>{await Y.handleFileChange(W,G)}});return await H.start(),H}async function Ip0(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:$}}I0();class yEA{logger;syncPath;constructor(A,Q){this.logger=A,this.syncPath=Q}prepareBatchOperations(A,Q){if(A.length===0)return{operations:[],exportOperationsCount:0,importOperationsCount:0,totalFiles:0};let B=[],w=this.createImportOperations(A);B.push(...w);let $=w.length;if(Q?.includeCleanup)B.push({type:"directory-cleanup",data:{}});let I=A.length;return this.logger.debug("Prepared batch operations",{exportOperationsCount:0,importOperationsCount:$,totalFiles:I}),{operations:B,exportOperationsCount:0,importOperationsCount:$,totalFiles:I}}async queueSyncBatch(A,Q,B,w,$){let I=this.prepareBatchOperations(B,$);if(I.operations.length===0)return this.logger.debug("No sync operations needed",{source:Q}),null;return{batchId:await A.jobs.enqueueBatch(I.operations,{source:Q,rootJobId:w?.rootJobId??F6(),metadata:{progressToken:w?.progressToken,operationType:"file_operations",operationTarget:this.syncPath,pluginId:w?.pluginId??"directory-sync",interfaceType:w?.interfaceType,channelId:w?.channelId}}),operationCount:I.operations.length,exportOperationsCount:I.exportOperationsCount,importOperationsCount:I.importOperationsCount,totalFiles:I.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 gEA{logger;fileOperations;syncInProgress=!1;batchOperationsManager;constructor(A,Q,B){this.logger=A;this.fileOperations=B;this.batchOperationsManager=new yEA(A,Q)}async queueSyncBatch(A,Q,B,w){if(this.syncInProgress)return this.logger.debug("Sync already in progress, skipping",{source:Q}),null;this.syncInProgress=!0;try{let $=await this.fileOperations.getAllSyncFiles();return await this.batchOperationsManager.queueSyncBatch(A,Q,$,B,w)}finally{this.syncInProgress=!1}}}class TEA{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 qb2,extname as Cb2}from"path";import{extname as Kb2,join as me}from"path";function ue(A,Q){let w=nb(A,Q).split("/"),$,I;if(w.length===1)$="base",I=w;else if(w.length>1&&w[0])$=w[0],I=w.slice(1);else $="base",I=w;let f;if(I.length>1){let D=I[I.length-1];if(D)I[I.length-1]=fp0(D);f=I.join(":")}else f=fp0(I[0]??"");return{entityType:$,id:f}}function Dp0(A,Q,B,w=".md"){let $=Q.split(":").filter((H)=>H.length>0),I=B==="base";if($.length===1)return I?me(A,`${$[0]}${w}`):me(A,B,`${$[0]}${w}`);let f=$;if($[0]===B)f=$.slice(1);let D=f[f.length-1],Y=f.slice(0,-1);if(I)return me(A,...Y,`${D}${w}`);return me(A,B,...Y,`${D}${w}`)}function Yp0(A){if(A.entityType!=="image")return".md";let Q=A.metadata.format;if(Q)return vEA(Q);let B=A.content.match(/^data:image\/([a-z+]+);base64,/i);return B?.[1]?vEA(B[1]):".md"}function fp0(A){let Q=Kb2(A).toLowerCase();return Q===".md"||Se.includes(Q)?A.slice(0,-Q.length):A}KD();import{mkdir as Eb2,readFile as pe,writeFile as Gp0,stat as Lb2,utimes as Mb2}from"fs/promises";import{join as ce}from"path";import{mkdir as Hp0,readdir as zb2,stat as Nb2}from"fs/promises";import{access as Zb2}from"fs/promises";async function oD(A){try{return await Zb2(A),!0}catch{return!1}}async function SEA(A,Q){return Jp0(A,Q,{includeImages:!1})}async function Xp0(A,Q){return Jp0(A,Q,{includeImages:!0})}async function Wp0(A,Q){if(!await oD(A))await Hp0(A,{recursive:!0});for(let B of Q)if(B!=="base")await Hp0(ce(A,B),{recursive:!0})}async function Up0(A,Q){let B=[],w={totalFiles:0,byEntityType:{}};if(!await oD(A))return{files:B,stats:w};let $=await SEA(A,Q);for(let I of $)try{let f=ce(A,I),D=await Nb2(f),{entityType:Y}=ue(A,I);B.push({path:I,entityType:Y,modified:D.mtime}),w.totalFiles++,w.byEntityType[Y]=(w.byEntityType[Y]??0)+1}catch{continue}return{files:B,stats:w}}async function Jp0(A,Q,B){let w=[];if(!await oD(A))return w;let $=async(I,f="",D=!1)=>{let Y=await zb2(I,{withFileTypes:!0});for(let H of Y){let W=f?ce(f,H.name):H.name;if(H.isFile()&&!H.name.endsWith(".invalid")){if(H.name.endsWith(".md"))w.push(W);else if(B.includeImages&&D&&hq(H.name))w.push(W)}else if(H.isDirectory()&&!H.name.startsWith(".")){if(f===""&&!Q.hasEntityType(H.name))continue;let G=ce(I,H.name),K=H.name==="image"&&f==="";await $(G,W,D||K)}}};return await $(A),w}class mEA{syncPath;entityService;constructor(A,Q){this.syncPath=A,this.entityService=Q}parseEntityFromPath(A){return ue(this.syncPath,A)}async readEntity(A){let Q=nD(this.syncPath,A),B=await Lb2(Q),{entityType:w,id:$}=this.parseEntityFromPath(A),I=B.birthtime.getTime()>0?B.birthtime:B.mtime,f=B.mtime,D;if(hq(A)){let H=(await pe(Q)).toString("base64"),W=Cb2(A);D=`data:${ec0(W)};base64,${H}`}else D=await pe(Q,"utf-8");return{entityType:w,id:$,content:D,created:I,updated:f}}async writeEntity(A){let Q=this.getEntityFilePath(A),B=A.entityType==="image",w;if(B){let I=A.content.match(/^data:image\/[a-z+]+;base64,(.+)$/i);w=I?.[1]?Buffer.from(I[1],"base64"):Buffer.from(A.content,"base64")}else w=this.entityService.serializeEntity(A);if(await oD(Q)){let I=B?await pe(Q):await pe(Q,"utf-8"),f=xB(B?I.toString("base64"):I),D=xB(B?w.toString("base64"):w);if(f===D)return}if(A.entityType!=="base")await Eb2(qb2(Q),{recursive:!0});if(B)await Gp0(Q,w);else await Gp0(Q,w,"utf-8");let $=new Date(A.updated);await Mb2(Q,$,$)}getFilePath(A,Q,B=".md"){return Dp0(this.syncPath,A,Q,B)}getEntityFilePath(A){return this.getFilePath(A.id,A.entityType,Yp0(A))}async getAllMarkdownFiles(){return SEA(this.syncPath,this.entityService)}async getAllSyncFiles(){return Xp0(this.syncPath,this.entityService)}async ensureDirectoryStructure(A){await Wp0(this.syncPath,A)}shouldUpdateEntity(A,Q){let B=xB(Q.content);return A.contentHash!==B}async gatherFileStatus(){return Up0(this.syncPath,this.entityService)}async syncDirectoryExists(){return oD(this.syncPath)}async fileExists(A){return oD(A)}}JA();async function le(A,Q,B,w){let{sourceUrl:$}=A,I=await Q.listEntities({entityType:"image",options:{filter:{metadata:{sourceUrl:$}},limit:1}});if(I[0])return w.debug("Reusing existing image entity",{sourceUrl:$,imageId:I[0].id}),I[0].id;let f=await B($),{base64:D}=pF(f),Y=QN(D),H=lF(D);if(!Y||!H)throw Error("Could not detect image format or dimensions");let W=await Q.createEntity({entity:{id:A.id,entityType:"image",content:f,metadata:{title:A.title,alt:A.alt,format:Y,width:H.width,height:H.height,sourceUrl:$}}});return w.debug("Created image entity from URL",{sourceUrl:$,imageId:W.entityId}),W.entityId}var Fp0=F.object({title:F.string(),slug:F.string().optional(),coverImageUrl:F.string().url(),coverImageId:F.string().optional(),coverImageAlt:F.string().optional()});class uEA{entityService;fetcher;logger;constructor(A,Q,B=m7){this.entityService=A;this.fetcher=B;this.logger=Q.child("FrontmatterImageConverter")}detectCoverImageUrl(A){let Q;try{Q=S4(A)}catch{return null}let{frontmatter:B}=Q,w=Fp0.safeParse(B);if(!w.success)return null;if(w.data.coverImageId)return null;let{title:$,slug:I,coverImageUrl:f,coverImageAlt:D}=w.data;if(!HU(f))return null;return{sourceUrl:f,postTitle:$,postSlug:I??F2($),customAlt:D}}async convert(A){let Q;try{Q=S4(A)}catch(H){return this.logger.debug("Parse failed",{error:H}),{content:A,converted:!1}}let{frontmatter:B}=Q,w=Fp0.safeParse(B);if(!w.success)return{content:A,converted:!1};if(w.data.coverImageId)return{content:A,converted:!1};let{title:$,slug:I,coverImageUrl:f,coverImageAlt:D}=w.data;if(!HU(f))return{content:A,converted:!1};let Y={postTitle:$,postSlug:I??F2($),sourceUrl:f,customAlt:D};try{let H=await this.createImageEntity(Y),W={...B};return delete W.coverImageUrl,delete W.coverImageAlt,W.coverImageId=H,{content:e3(W,Q.content),converted:!0,imageId:H}}catch(H){return this.logger.warn("Failed to convert coverImageUrl",{url:f,error:h0(H)}),{content:A,converted:!1}}}async createImageEntity(A){let{postTitle:Q,postSlug:B,sourceUrl:w,customAlt:$}=A,I=`Cover image for ${Q}`;return le({id:`${B}-cover`,title:I,alt:$??I,sourceUrl:w},this.entityService,this.fetcher,this.logger)}}JA();class zT{entityService;fetcher;logger;constructor(A,Q,B=m7){this.entityService=A;this.fetcher=B;this.logger=Q.child("MarkdownImageConverter")}detectInlineImages(A,Q){let B=[],w=qp(A);for(let $ of w){if(!HU($.url))continue;if($.url.startsWith("entity://"))continue;let I=this.reconstructMarkdown($);B.push({sourceUrl:$.url,alt:$.alt,originalMarkdown:I,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,I=0;for(let f of B)try{let D=await this.createImageEntity(f,I++),Y=``;w=w.replace(f.originalMarkdown,Y),$++,this.logger.debug("Converted inline image",{sourceUrl:f.sourceUrl,imageId:D})}catch(D){this.logger.warn("Failed to convert inline image",{sourceUrl:f.sourceUrl,error:h0(D)})}return{content:w,converted:$>0,convertedCount:$}}async createImageEntity(A,Q){let{sourceUrl:B,alt:w,postSlug:$}=A;return le({id:`${$}-inline-${Q}`,title:w||`Inline image ${Q+1} for ${$}`,alt:w||"",sourceUrl:B},this.entityService,this.fetcher,this.logger)}}class cEA{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:[]},I=A??await this.fileOperations.getAllSyncFiles(),f=I.length;await Q.report({progress:0,message:`Starting import of ${f} files`});for(let D=0;D<f;D+=B){let Y=I.slice(D,D+B),H=await w(Y);$.imported+=H.imported,$.skipped+=H.skipped,$.failed+=H.failed,$.quarantined+=H.quarantined,$.errors.push(...H.errors),$.quarantinedFiles.push(...H.quarantinedFiles),$.jobIds.push(...H.jobIds);let W=Math.min(D+B,f),G=Math.round(W/f*40);await Q.report({progress:G,message:`Imported ${W}/${f} 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 I=await w(A);return await Q.report({progress:100,message:`Exported ${I.exported} entities`}),this.logger.debug("Export completed",I),I}}JA();import{rename as Vb2,appendFile as Ob2,readFile as bb2,writeFile as Rb2,access as _b2}from"fs/promises";import{join as Kp0}from"path";class pEA{logger;syncPath;constructor(A,Q){this.logger=A;this.syncPath=Q}isValidationError(A){if(A instanceof F.ZodError)return!0;let Q=h0(A);return Q.includes("invalid_type")||Q.includes("invalid_enum_value")||Q.includes("Required")||Q.includes("Invalid frontmatter")||Q.includes("Unknown entity type")}async quarantineInvalidFile(A,Q,B,w){let $=w(A),I=`${$}.invalid`;try{await Vb2($,I),B.quarantined++,B.quarantinedFiles.push(A);let f=Kp0(this.syncPath,".import-errors.log"),D=new Date().toISOString(),Y=h0(Q),H=`${D} - ${A}: ${Y}
|
|
2393
|
+
`)||"No response text";return{success:!0,data:{state:Z,response:L}}}I=await hm0(B,Q)}return{success:!1,error:"Stream ended without a terminal event"}}class wT extends Error{timeoutMs;constructor(A){super(`request timed out after ${A}ms`);this.timeoutMs=A;this.name="A2ARequestTimeoutError"}}class $T extends Error{timeoutMs;constructor(A){super(`A2A stream stalled waiting for final event after ${A}ms`);this.timeoutMs=A;this.name="A2AStreamIdleTimeoutError"}}async function DE2(A,Q,B,w){let $=new AbortController,I;try{return await Promise.race([A(Q,{...B,signal:$.signal}),new Promise((f,D)=>{I=setTimeout(()=>{$.abort(),D(new wT(w))},w)})])}catch(f){if(f instanceof wT)throw f;if($.signal.aborted)throw new wT(w);throw f}finally{if(I)clearTimeout(I)}}async function hm0(A,Q){let B;try{return await Promise.race([A.read(),new Promise((w,$)=>{B=setTimeout(()=>$(new $T(Q)),Q)})])}catch(w){if(w instanceof $T)A.cancel().catch(()=>{});throw w}finally{if(B)clearTimeout(B)}}function YE2(A){if(A instanceof wT||A instanceof $T)return!0;return A instanceof Error}function HE2(A,Q){let B=Q>1?` after ${Q} attempts`:"";if(A instanceof $T)return`${A.message}${B}`;let w=A instanceof Error?A.message:"Unknown network error";return`Failed to reach remote agent${B}: ${w}`}function gm0(A={}){let Q=A.fetch??globalThis.fetch,B={requestTimeoutMs:A.requestTimeoutMs??AE2,streamIdleTimeoutMs:A.streamIdleTimeoutMs??QE2,maxNetworkAttempts:A.maxNetworkAttempts??BE2};return{name:"a2a_call",description:"Call a saved remote A2A agent by its local directory id. Use only a saved agent id such as yeehaa.io. Never pass a display name like Brain, never pass a full URL, and do not use this tool to probe whether an agent exists. If the user gives a URL, an unsaved agent, or an ambiguous name, ask them to add/save or clarify the agent first.",inputSchema:vm0,visibility:"anchor",handler:async(w)=>{let $=F.object(vm0).safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};let{agent:I,message:f}=$.data,D=wE2(I);if(!D)return{success:!1,error:"Invalid agent id. Use a saved agent id from your directory, not a URL."};if(!A.entityService)return{success:!1,error:"Agent directory is unavailable. Add the agent first, then try again."};let Y=await A.entityService.getEntity({entityType:"agent",id:D});if(!Y)return{success:!1,error:`Agent ${D} is not in your directory. Add it first.`};if(Y.metadata.status!=="approved")return{success:!1,error:`Agent ${D} is discovered but not approved yet. Approve it first.`};let H=`https://${D}`,W=await $E2(H,Q);if(!W)return{success:!1,error:`Could not fetch Agent Card from ${H}`};let G=W.url,K;if(A.outboundTokens)try{let Z=new URL(G).hostname;K=A.outboundTokens[Z]}catch{}return IE2(G,f,Q,K,B)}}}var vCA={name:"@brains/a2a",private:!0,version:"0.2.0-alpha.61",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 WE2={"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization","X-Content-Type-Options":"nosniff"};class ub extends dH{agentCard;taskManager=new jCA;agentService;permissionContext;app;hasWebserver=!1;constructor(A={}){super("a2a",vCA,A,Om0)}async onRegister(A){if(await super.onRegister(A),this.hasWebserver=A.plugins.has("webserver"),this.agentService=A.agent,this.permissionContext=A.permissions,this.hasWebserver)this.logger.info("A2A interface registered",{domain:A.domain});else this.logger.info("A2A interface registered in tool-only mode",{domain:A.domain})}async onReady(A){await this.rebuildAgentCard(A)}async rebuildAgentCard(A){let Q=A.identity.get(),B=A.identity.getProfile(),w=A.tools.listForPermissionLevel("public"),$=this.config.trustedTokens&&Object.keys(this.config.trustedTokens).length>0,I;if(A.entityService.hasEntityType("skill"))try{let f=await A.entityService.listEntities({entityType:"skill"});if(f.length>0)I=f.map((D)=>Af.safeParse(D.metadata)).filter((D)=>D.success).map((D)=>D.data)}catch{}this.agentCard=bm0({character:Q,profile:B,version:vCA.version,domain:A.domain,organization:this.config.organization,tools:w,skills:I,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(WE2))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 Tb;return A.get("/.well-known/agent-card.json",(Q)=>{if(!this.agentCard)return this.withCors(Q.json({error:"Agent Card not ready"},503));return this.withCors(Q.json(this.agentCard))}),A.get("/a2a",(Q)=>{return this.withCors(Q.json({error:"Use POST with JSON-RPC 2.0 requests.",agentCard:"/.well-known/agent-card.json"},405))}),A.options("/a2a",()=>this.withCors(new Response(null,{status:204}))),A.post("/a2a",async(Q)=>{if(!this.agentService)return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32603,message:"Agent service not ready"},id:null},503));let B;try{B=await Q.req.json()}catch{return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32700,message:"Parse error"},id:null}))}let w=Pm0.safeParse(B);if(!w.success)return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32600,message:"Invalid request"},id:null}));let $=this.resolveCallerPermission(Q.req.header("Authorization"));if(w.data.method==="message/stream"){let f=jm0.safeParse(w.data.params??{});if(!f.success)return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32602,message:`Invalid params: ${f.error.message}`},id:w.data.id}));let{stream:D}=xm0(w.data.id,f.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 I=await km0(w.data,{taskManager:this.taskManager,agentService:this.agentService,callerPermissionLevel:$});return this.withCors(Q.json(I))}),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[gm0({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")}}}}I0();class hCA{logger;handleImport;handleDelete;deleteOnFileRemoval;fileOperations;constructor(A,Q,B,w,$=!0){if(this.logger=A,this.fileOperations=w,this.deleteOnFileRemoval=$,B)this.handleImport=async(I)=>{let f=await B({type:"directory-import",data:{paths:[I]}});this.logger.debug("Queued import job for file change",{jobId:f,path:I})},this.handleDelete=async(I)=>{if(!this.deleteOnFileRemoval){this.logger.warn("File deleted but deleteOnFileRemoval is disabled",{path:I});return}try{let{entityType:f,id:D}=this.fileOperations.parseEntityFromPath(I),Y=await B({type:"directory-delete",data:{entityId:D,entityType:f,filePath:I}});this.logger.info("Queued delete job for removed file",{jobId:Y,path:I,entityId:D,entityType:f})}catch(f){this.logger.warn("Could not extract entity info from deleted file",{path:I,error:f})}};else this.handleImport=async(I)=>{await Q([I])},this.handleDelete=async(I)=>{this.logger.warn("File deleted but no job queue available",{path:I})}}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 Qp0=D1(tc0(),1);import{extname as Hb2}from"path";var Se=[".png",".jpg",".jpeg",".webp",".gif",".svg"];function hq(A){let Q=Hb2(A).toLowerCase();return Se.includes(Q)}function ec0(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 vEA(A){switch(A.toLowerCase()){case"jpeg":return".jpg";case"svg+xml":return".svg";default:return`.${A.toLowerCase()}`}}import{isAbsolute as Xb2,relative as Wb2,sep as Ap0,join as Ub2}from"path";function nD(A,Q){return Xb2(Q)?Q:Ub2(A,Q)}function nb(A,Q){let B=nD(A,Q),w=Wb2(A,B);return Ap0==="/"?w:w.split(Ap0).join("/")}function Jb2(A,Q){if(!nb(Q,A).startsWith("image/"))return!1;return hq(A)}function Gb2(A,Q){if(nb(Q,A).split("/")[0]?.startsWith("_"))return!1;if(A.endsWith(".md"))return!0;return Jb2(A,Q)}class hEA{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=Qp0.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(!Gb2(Q,this.syncPath))return;this.logger.debug("File change detected",{event:A,path:Q});let B=nb(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=nD(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 Bp0(A,Q){if(A?.isWatching())return Q.logger.debug("Already watching directory"),A;return Fb2(Q)}function wp0(A){if(A)A.stop();return}function $p0(A,Q){if(A)A.setCallback(Q)}async function Fb2(A){let{logger:Q,syncPath:B,watchInterval:w,importEntities:$,jobQueueCallback:I,fileOperations:f,deleteOnFileRemoval:D}=A,Y=new hCA(Q,$,I,f,D),H=new hEA({syncPath:B,watchInterval:w,logger:Q,onFileChange:async(W,G)=>{await Y.handleFileChange(W,G)}});return await H.start(),H}async function Ip0(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:$}}I0();class yEA{logger;syncPath;constructor(A,Q){this.logger=A,this.syncPath=Q}prepareBatchOperations(A,Q){if(A.length===0)return{operations:[],exportOperationsCount:0,importOperationsCount:0,totalFiles:0};let B=[],w=this.createImportOperations(A);B.push(...w);let $=w.length;if(Q?.includeCleanup)B.push({type:"directory-cleanup",data:{}});let I=A.length;return this.logger.debug("Prepared batch operations",{exportOperationsCount:0,importOperationsCount:$,totalFiles:I}),{operations:B,exportOperationsCount:0,importOperationsCount:$,totalFiles:I}}async queueSyncBatch(A,Q,B,w,$){let I=this.prepareBatchOperations(B,$);if(I.operations.length===0)return this.logger.debug("No sync operations needed",{source:Q}),null;return{batchId:await A.jobs.enqueueBatch(I.operations,{source:Q,rootJobId:w?.rootJobId??F6(),metadata:{progressToken:w?.progressToken,operationType:"file_operations",operationTarget:this.syncPath,pluginId:w?.pluginId??"directory-sync",interfaceType:w?.interfaceType,channelId:w?.channelId}}),operationCount:I.operations.length,exportOperationsCount:I.exportOperationsCount,importOperationsCount:I.importOperationsCount,totalFiles:I.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 gEA{logger;fileOperations;syncInProgress=!1;batchOperationsManager;constructor(A,Q,B){this.logger=A;this.fileOperations=B;this.batchOperationsManager=new yEA(A,Q)}async queueSyncBatch(A,Q,B,w){if(this.syncInProgress)return this.logger.debug("Sync already in progress, skipping",{source:Q}),null;this.syncInProgress=!0;try{let $=await this.fileOperations.getAllSyncFiles();return await this.batchOperationsManager.queueSyncBatch(A,Q,$,B,w)}finally{this.syncInProgress=!1}}}class TEA{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 qb2,extname as Cb2}from"path";import{extname as Kb2,join as me}from"path";function ue(A,Q){let w=nb(A,Q).split("/"),$,I;if(w.length===1)$="base",I=w;else if(w.length>1&&w[0])$=w[0],I=w.slice(1);else $="base",I=w;let f;if(I.length>1){let D=I[I.length-1];if(D)I[I.length-1]=fp0(D);f=I.join(":")}else f=fp0(I[0]??"");return{entityType:$,id:f}}function Dp0(A,Q,B,w=".md"){let $=Q.split(":").filter((H)=>H.length>0),I=B==="base";if($.length===1)return I?me(A,`${$[0]}${w}`):me(A,B,`${$[0]}${w}`);let f=$;if($[0]===B)f=$.slice(1);let D=f[f.length-1],Y=f.slice(0,-1);if(I)return me(A,...Y,`${D}${w}`);return me(A,B,...Y,`${D}${w}`)}function Yp0(A){if(A.entityType!=="image")return".md";let Q=A.metadata.format;if(Q)return vEA(Q);let B=A.content.match(/^data:image\/([a-z+]+);base64,/i);return B?.[1]?vEA(B[1]):".md"}function fp0(A){let Q=Kb2(A).toLowerCase();return Q===".md"||Se.includes(Q)?A.slice(0,-Q.length):A}KD();import{mkdir as Eb2,readFile as pe,writeFile as Gp0,stat as Lb2,utimes as Mb2}from"fs/promises";import{join as ce}from"path";import{mkdir as Hp0,readdir as zb2,stat as Nb2}from"fs/promises";import{access as Zb2}from"fs/promises";async function oD(A){try{return await Zb2(A),!0}catch{return!1}}async function SEA(A,Q){return Jp0(A,Q,{includeImages:!1})}async function Xp0(A,Q){return Jp0(A,Q,{includeImages:!0})}async function Wp0(A,Q){if(!await oD(A))await Hp0(A,{recursive:!0});for(let B of Q)if(B!=="base")await Hp0(ce(A,B),{recursive:!0})}async function Up0(A,Q){let B=[],w={totalFiles:0,byEntityType:{}};if(!await oD(A))return{files:B,stats:w};let $=await SEA(A,Q);for(let I of $)try{let f=ce(A,I),D=await Nb2(f),{entityType:Y}=ue(A,I);B.push({path:I,entityType:Y,modified:D.mtime}),w.totalFiles++,w.byEntityType[Y]=(w.byEntityType[Y]??0)+1}catch{continue}return{files:B,stats:w}}async function Jp0(A,Q,B){let w=[];if(!await oD(A))return w;let $=async(I,f="",D=!1)=>{let Y=await zb2(I,{withFileTypes:!0});for(let H of Y){let W=f?ce(f,H.name):H.name;if(H.isFile()&&!H.name.endsWith(".invalid")){if(H.name.endsWith(".md"))w.push(W);else if(B.includeImages&&D&&hq(H.name))w.push(W)}else if(H.isDirectory()&&!H.name.startsWith(".")){if(f===""&&!Q.hasEntityType(H.name))continue;let G=ce(I,H.name),K=H.name==="image"&&f==="";await $(G,W,D||K)}}};return await $(A),w}class mEA{syncPath;entityService;constructor(A,Q){this.syncPath=A,this.entityService=Q}parseEntityFromPath(A){return ue(this.syncPath,A)}async readEntity(A){let Q=nD(this.syncPath,A),B=await Lb2(Q),{entityType:w,id:$}=this.parseEntityFromPath(A),I=B.birthtime.getTime()>0?B.birthtime:B.mtime,f=B.mtime,D;if(hq(A)){let H=(await pe(Q)).toString("base64"),W=Cb2(A);D=`data:${ec0(W)};base64,${H}`}else D=await pe(Q,"utf-8");return{entityType:w,id:$,content:D,created:I,updated:f}}async writeEntity(A){let Q=this.getEntityFilePath(A),B=A.entityType==="image",w;if(B){let I=A.content.match(/^data:image\/[a-z+]+;base64,(.+)$/i);w=I?.[1]?Buffer.from(I[1],"base64"):Buffer.from(A.content,"base64")}else w=this.entityService.serializeEntity(A);if(await oD(Q)){let I=B?await pe(Q):await pe(Q,"utf-8"),f=xB(B?I.toString("base64"):I),D=xB(B?w.toString("base64"):w);if(f===D)return}if(A.entityType!=="base")await Eb2(qb2(Q),{recursive:!0});if(B)await Gp0(Q,w);else await Gp0(Q,w,"utf-8");let $=new Date(A.updated);await Mb2(Q,$,$)}getFilePath(A,Q,B=".md"){return Dp0(this.syncPath,A,Q,B)}getEntityFilePath(A){return this.getFilePath(A.id,A.entityType,Yp0(A))}async getAllMarkdownFiles(){return SEA(this.syncPath,this.entityService)}async getAllSyncFiles(){return Xp0(this.syncPath,this.entityService)}async ensureDirectoryStructure(A){await Wp0(this.syncPath,A)}shouldUpdateEntity(A,Q){let B=xB(Q.content);return A.contentHash!==B}async gatherFileStatus(){return Up0(this.syncPath,this.entityService)}async syncDirectoryExists(){return oD(this.syncPath)}async fileExists(A){return oD(A)}}JA();async function le(A,Q,B,w){let{sourceUrl:$}=A,I=await Q.listEntities({entityType:"image",options:{filter:{metadata:{sourceUrl:$}},limit:1}});if(I[0])return w.debug("Reusing existing image entity",{sourceUrl:$,imageId:I[0].id}),I[0].id;let f=await B($),{base64:D}=pF(f),Y=QN(D),H=lF(D);if(!Y||!H)throw Error("Could not detect image format or dimensions");let W=await Q.createEntity({entity:{id:A.id,entityType:"image",content:f,metadata:{title:A.title,alt:A.alt,format:Y,width:H.width,height:H.height,sourceUrl:$}}});return w.debug("Created image entity from URL",{sourceUrl:$,imageId:W.entityId}),W.entityId}var Fp0=F.object({title:F.string(),slug:F.string().optional(),coverImageUrl:F.string().url(),coverImageId:F.string().optional(),coverImageAlt:F.string().optional()});class uEA{entityService;fetcher;logger;constructor(A,Q,B=m7){this.entityService=A;this.fetcher=B;this.logger=Q.child("FrontmatterImageConverter")}detectCoverImageUrl(A){let Q;try{Q=S4(A)}catch{return null}let{frontmatter:B}=Q,w=Fp0.safeParse(B);if(!w.success)return null;if(w.data.coverImageId)return null;let{title:$,slug:I,coverImageUrl:f,coverImageAlt:D}=w.data;if(!HU(f))return null;return{sourceUrl:f,postTitle:$,postSlug:I??F2($),customAlt:D}}async convert(A){let Q;try{Q=S4(A)}catch(H){return this.logger.debug("Parse failed",{error:H}),{content:A,converted:!1}}let{frontmatter:B}=Q,w=Fp0.safeParse(B);if(!w.success)return{content:A,converted:!1};if(w.data.coverImageId)return{content:A,converted:!1};let{title:$,slug:I,coverImageUrl:f,coverImageAlt:D}=w.data;if(!HU(f))return{content:A,converted:!1};let Y={postTitle:$,postSlug:I??F2($),sourceUrl:f,customAlt:D};try{let H=await this.createImageEntity(Y),W={...B};return delete W.coverImageUrl,delete W.coverImageAlt,W.coverImageId=H,{content:e3(W,Q.content),converted:!0,imageId:H}}catch(H){return this.logger.warn("Failed to convert coverImageUrl",{url:f,error:h0(H)}),{content:A,converted:!1}}}async createImageEntity(A){let{postTitle:Q,postSlug:B,sourceUrl:w,customAlt:$}=A,I=`Cover image for ${Q}`;return le({id:`${B}-cover`,title:I,alt:$??I,sourceUrl:w},this.entityService,this.fetcher,this.logger)}}JA();class zT{entityService;fetcher;logger;constructor(A,Q,B=m7){this.entityService=A;this.fetcher=B;this.logger=Q.child("MarkdownImageConverter")}detectInlineImages(A,Q){let B=[],w=qp(A);for(let $ of w){if(!HU($.url))continue;if($.url.startsWith("entity://"))continue;let I=this.reconstructMarkdown($);B.push({sourceUrl:$.url,alt:$.alt,originalMarkdown:I,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,I=0;for(let f of B)try{let D=await this.createImageEntity(f,I++),Y=``;w=w.replace(f.originalMarkdown,Y),$++,this.logger.debug("Converted inline image",{sourceUrl:f.sourceUrl,imageId:D})}catch(D){this.logger.warn("Failed to convert inline image",{sourceUrl:f.sourceUrl,error:h0(D)})}return{content:w,converted:$>0,convertedCount:$}}async createImageEntity(A,Q){let{sourceUrl:B,alt:w,postSlug:$}=A;return le({id:`${$}-inline-${Q}`,title:w||`Inline image ${Q+1} for ${$}`,alt:w||"",sourceUrl:B},this.entityService,this.fetcher,this.logger)}}class cEA{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:[]},I=A??await this.fileOperations.getAllSyncFiles(),f=I.length;await Q.report({progress:0,message:`Starting import of ${f} files`});for(let D=0;D<f;D+=B){let Y=I.slice(D,D+B),H=await w(Y);$.imported+=H.imported,$.skipped+=H.skipped,$.failed+=H.failed,$.quarantined+=H.quarantined,$.errors.push(...H.errors),$.quarantinedFiles.push(...H.quarantinedFiles),$.jobIds.push(...H.jobIds);let W=Math.min(D+B,f),G=Math.round(W/f*40);await Q.report({progress:G,message:`Imported ${W}/${f} 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 I=await w(A);return await Q.report({progress:100,message:`Exported ${I.exported} entities`}),this.logger.debug("Export completed",I),I}}JA();import{rename as Vb2,appendFile as Ob2,readFile as bb2,writeFile as Rb2,access as _b2}from"fs/promises";import{join as Kp0}from"path";class pEA{logger;syncPath;constructor(A,Q){this.logger=A;this.syncPath=Q}isValidationError(A){if(A instanceof F.ZodError)return!0;let Q=h0(A);return Q.includes("invalid_type")||Q.includes("invalid_enum_value")||Q.includes("Required")||Q.includes("Invalid frontmatter")||Q.includes("Unknown entity type")}async quarantineInvalidFile(A,Q,B,w){let $=w(A),I=`${$}.invalid`;try{await Vb2($,I),B.quarantined++,B.quarantinedFiles.push(A);let f=Kp0(this.syncPath,".import-errors.log"),D=new Date().toISOString(),Y=h0(Q),H=`${D} - ${A}: ${Y}
|
|
2394
2394
|
\u2192 ${A}.invalid
|
|
2395
2395
|
|
|
2396
2396
|
`;await Ob2(f,H),this.logger.warn("Quarantined invalid entity file",{originalPath:A,quarantinePath:`${A}.invalid`,error:Y})}catch(f){this.logger.error("Failed to quarantine invalid file",{path:A,error:f}),B.failed++,B.errors.push({path:A,error:"Failed to quarantine invalid file"})}}async markAsRecoveredIfNeeded(A){let Q=Kp0(this.syncPath,".import-errors.log");try{await _b2(Q)}catch{return}try{let B=await bb2(Q,"utf-8");if(B.includes(A)){let $=`${new Date().toISOString()} - [RECOVERED] ${A}
|
|
@@ -2416,7 +2416,7 @@ ${R}`)}if(w!==void 0&&I?.algorithms!==void 0){let C=I.algorithms.map((R)=>R.alg)
|
|
|
2416
2416
|
*...and ${A.files.length-10} more files*`)}if(A.exists&&A.stats.totalFiles===0)Q.push(`
|
|
2417
2417
|
## Getting Started
|
|
2418
2418
|
`),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(`
|
|
2419
|
-
`)}}I0();class KAA extends tB{directorySync;constructor(A,Q,B){super(A,{schema:cLA,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}}}I0();class ZAA extends tB{directorySync;constructor(A,Q,B){super(A,{schema:uLA,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}}}I0();class zAA extends tB{directorySync;context;constructor(A,Q,B){super(A,{schema:mLA,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 I={imported:0,skipped:0,failed:0,quarantined:0,quarantinedFiles:[],errors:[],jobIds:[]},f={exported:0,failed:0,errors:[]};if($!=="export")if(await B.report({progress:10,message:"Scanning directory for changes"}),I=await this.importWithProgress(A.paths,B),$==="import")await this.waitForImportJobs(I.jobIds,B),await B.report({progress:100,message:`Import complete: ${I.imported} imported`});else await B.report({progress:50,message:`Imported ${I.imported} entities`}),await this.waitForImportJobs(I.jobIds,B),await B.report({progress:56,message:"Processing complete, starting export"});if($!=="import"){let Y=$==="export"?10:60;await B.report({progress:Y,message:"Exporting entities to directory"}),f=await this.exportWithProgress(A.entityTypes,B),await B.report({progress:100,message:$==="export"?`Export complete: ${f.exported} exported`:`Sync complete: ${I.imported} imported, ${f.exported} exported`})}let D=Date.now()-w;return this.logger.info("Directory sync job completed",{jobId:Q,duration:D,imported:I.imported,exported:f.exported}),{import:I,export:f,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,I=Date.now(),f=async()=>{let Y=(await Promise.all(A.map((W)=>B.getAsyncJobStatus(W)))).filter((W)=>W&&(W.status==="completed"||W.status==="failed")).length;if(Y===A.length){this.logger.debug("All import jobs completed");return}if(Date.now()-I>w){this.logger.warn(`Timeout waiting for import jobs (${Y}/${A.length} completed)`);return}let H=Math.round(Y/A.length*100);return await Q.report({progress:50+Math.round(H*0.05),message:`Processing ${Y}/${A.length} entities`}),await new Promise((W)=>setTimeout(W,$)),f()};return f()}summarizeDataForLog(A){return{operation:A.operation,syncDirection:A.syncDirection}}}I0();class NAA extends tB{context;constructor(A,Q,B){super(A,{schema:GAA,jobTypeName:"directory-delete"});this.context=Q}async process(A,Q,B){let w=GAA.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}}}I0();JA();var zk2=F.object({});class qAA extends tB{directorySync;constructor(A,Q){super(A,{schema:zk2,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}}I0();JA();import{readFile as Nk2,writeFile as qk2}from"fs/promises";var Ck2=pLA;class CAA extends tB{context;fetcher;constructor(A,Q,B=m7){super(Q,{schema:Ck2,jobTypeName:"cover-image-convert"});this.context=A,this.fetcher=B}async process(A,Q,B){let{filePath:w,sourceUrl:$,postTitle:I,postSlug:f,customAlt:D}=A;this.logger.debug("Starting image conversion job",{jobId:Q,filePath:w,sourceUrl:$,postSlug:f});try{await this.reportProgress(B,{progress:v2.INIT,message:`Reading file: ${w}`});let Y;try{Y=await Nk2(w,"utf-8")}catch(L){return this.logger.error("Failed to read file",{filePath:w,error:h0(L)}),r8.failure(L)}let H;try{H=S4(Y)}catch(L){return this.logger.warn("Failed to parse markdown",{filePath:w,error:h0(L)}),r8.failure(L)}let W=H.frontmatter;if(W.coverImageId)return this.logger.debug("File already has coverImageId, skipping",{filePath:w}),await this.reportProgress(B,{progress:v2.COMPLETE,message:"Already converted"}),{success:!0,skipped:!0};await this.reportProgress(B,{progress:v2.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:v2.EXTRACT,message:`Reusing existing image: ${K}`});else{await this.reportProgress(B,{progress:v2.PROCESS,message:`Fetching image from ${$}`});let L;try{L=await this.fetcher($)}catch(n){return this.logger.error("Failed to fetch image",{sourceUrl:$,error:h0(n)}),r8.failure(n)}await this.reportProgress(B,{progress:v2.GENERATE,message:"Creating image entity"});let{base64:C}=pF(L),R=QN(C),j=lF(C);if(!R||!j)return this.logger.error("Could not detect image format or dimensions",{sourceUrl:$}),r8.failure(Error("Could not detect image format or dimensions"));K=`${f}-cover`;let P=`Cover image for ${I}`,o=D??P;await this.context.entityService.createEntity({entity:{id:K,entityType:"image",content:L,metadata:{title:P,alt:o,format:R,width:j.width,height:j.height,sourceUrl:$}}}),this.logger.debug("Created image entity",{imageId:K,sourceUrl:$}),await this.reportProgress(B,{progress:v2.EXTRACT,message:`Created image: ${K}`})}await this.reportProgress(B,{progress:v2.SAVE,message:"Updating file"});let Z={...W};delete Z.coverImageUrl,delete Z.coverImageAlt,Z.coverImageId=K;let q=e3(Z,H.content);try{await qk2(w,q,"utf-8")}catch(L){return this.logger.error("Failed to write file",{filePath:w,error:h0(L)}),r8.failure(L)}return await this.reportProgress(B,{progress:v2.COMPLETE,message:"Conversion complete"}),this.logger.info("Image conversion complete",{filePath:w,imageId:K,sourceUrl:$}),{success:!0,imageId:K}}catch(Y){return this.logger.error("Image conversion job failed",{jobId:Q,filePath:w,error:h0(Y)}),r8.failure(Y)}}summarizeDataForLog(A){return{filePath:A.filePath,sourceUrl:A.sourceUrl,postSlug:A.postSlug}}}I0();JA();import{readFile as Ek2,writeFile as Lk2}from"fs/promises";class EAA extends tB{converter;constructor(A,Q,B=m7){super(Q,{schema:lLA,jobTypeName:"inline-image-convert"});this.converter=new zT(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:v2.INIT,message:`Reading file: ${w}`});let I;try{I=await Ek2(w,"utf-8")}catch(Y){let H=h0(Y);return this.logger.error("Failed to read file",{filePath:w,error:H}),{success:!1,error:H}}await this.reportProgress(B,{progress:v2.FETCH,message:"Detecting inline images"});let f=this.converter.detectInlineImages(I,$);if(f.length===0)return this.logger.debug("No inline images to convert",{filePath:w}),await this.reportProgress(B,{progress:v2.COMPLETE,message:"No images to convert"}),{success:!0,skipped:!0,convertedCount:0};this.logger.debug("Found inline images to convert",{filePath:w,count:f.length}),await this.reportProgress(B,{progress:v2.PROCESS,message:`Converting ${f.length} images`});let D=await this.converter.convert(I,$);if(!D.converted)return this.logger.debug("No images were converted",{filePath:w}),await this.reportProgress(B,{progress:v2.COMPLETE,message:"No images converted"}),{success:!0,skipped:!0,convertedCount:0};await this.reportProgress(B,{progress:v2.SAVE,message:"Writing updated file"});try{await Lk2(w,D.content,"utf-8")}catch(Y){let H=h0(Y);return this.logger.error("Failed to write file",{filePath:w,error:H}),{success:!1,error:H}}return await this.reportProgress(B,{progress:v2.COMPLETE,message:"Conversion complete"}),this.logger.info("Inline image conversion complete",{filePath:w,convertedCount:D.convertedCount}),{success:!0,convertedCount:D.convertedCount}}catch(I){let f=h0(I);return this.logger.error("Inline image conversion job failed",{jobId:Q,filePath:w,error:f}),{success:!1,error:f}}}summarizeDataForLog(A){return{filePath:A.filePath,postSlug:A.postSlug}}}function rr0(A,Q,B){let w=($)=>B.child($);A.jobs.registerHandler("directory-sync",new zAA(w("DirectorySyncJobHandler"),A,Q)),A.jobs.registerHandler("directory-export",new KAA(w("DirectoryExportJobHandler"),A,Q)),A.jobs.registerHandler("directory-import",new ZAA(w("DirectoryImportJobHandler"),A,Q)),A.jobs.registerHandler("directory-delete",new NAA(w("DirectoryDeleteJobHandler"),A,Q)),A.jobs.registerHandler("directory-cleanup",new qAA(w("DirectoryCleanupJobHandler"),Q)),A.jobs.registerHandler("cover-image-convert",new CAA(A,w("CoverImageConversionJobHandler"))),A.jobs.registerHandler("inline-image-convert",new EAA(A,w("InlineImageConversionJobHandler"))),B.debug("Registered async job handlers")}I0();import{unlink as Mk2,access as Vk2}from"fs/promises";function dr0(A,Q,B,w){let{subscribe:$}=A.messaging,{entityService:I}=A;$("entity:created",async(f)=>{let{entity:D}=f.payload;try{await Q.fileOps.writeEntity(D),B.debug("Auto-exported created entity",{id:D.id,entityType:D.entityType})}catch(Y){B.error("Auto-export FAILED for created entity",{id:D.id,entityType:D.entityType,error:Y instanceof Error?Y.message:String(Y),stack:Y instanceof Error?Y.stack:void 0})}return{success:!0}}),$("entity:updated",async(f)=>{let{entityType:D,entityId:Y}=f.payload;try{let H=await I.getEntity({entityType:D,id:Y});if(!H)return B.debug("Entity not found in DB, skipping export",{entityType:D,entityId:Y}),{success:!1};await Q.fileOps.writeEntity(H),B.debug("Auto-exported updated entity",{id:H.id,entityType:H.entityType})}catch(H){B.error("Auto-export FAILED for updated entity",{entityType:D,entityId:Y,error:H instanceof Error?H.message:String(H),stack:H instanceof Error?H.stack:void 0})}return{success:!0}}),$("entity:deleted",async(f)=>{let{entityId:D,entityType:Y}=f.payload,H=Q.fileOps.getFilePath(D,Y);if(await Vk2(H).then(()=>!0,()=>!1))await Mk2(H),B.debug("Auto-deleted entity file",{id:D,entityType:Y,path:H});return{success:!0}}),B.debug("Setup auto-sync for entity events",{entityTypes:w})}function nr0(A,Q,B){Q.setJobQueueCallback(async(w)=>{let $=[{type:w.type,data:w.data}];return A.jobs.enqueueBatch($,{priority:5,source:"directory-sync-watcher",rootJobId:F6(),metadata:{operationType:"file_operations",operationTarget:B,pluginId:"directory-sync"}})})}JA();I0();import{access as Ok2,readdir as or0,mkdir as bk2,copyFile as Rk2}from"fs/promises";import{exec as _k2}from"child_process";import{promisify as Pk2}from"util";import{join as rLA,resolve as iLA}from"path";var kk2=Pk2(_k2);async function LAA(A){try{return await Ok2(A),!0}catch{return!1}}async function jk2(A,Q){if(!await LAA(A))return!0;if((await or0(A)).filter(($)=>!$.startsWith(".")&&!$.startsWith("_")).length>0)return!1;if(await xk2(A))return Q.debug("Git repository with remote detected - skipping seed content",{path:A}),!1;return!0}async function xk2(A){let Q=rLA(A,".git");if(!await LAA(Q))return!1;try{let{stdout:B}=await kk2("git remote",{cwd:A});return B.trim().length>0}catch{return!1}}async function sr0(A,Q){let B=await or0(A,{withFileTypes:!0});for(let w of B){let $=rLA(A,w.name),I=rLA(Q,w.name);if(w.isDirectory()){if(!await LAA(I))await bk2(I,{recursive:!0});await sr0($,I)}else await Rk2($,I)}}async function ar0(A,Q,B){let w=iLA(process.cwd(),A);B=B?iLA(B):iLA(process.cwd(),"seed-content");let $=await jk2(w,Q);if($&&await LAA(B))Q.debug("Copying seed content to brain-data directory"),await sr0(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 tr0(A,Q,B,w,$){let I=!1,f=async()=>{if(I)return;I=!0;let D=Q();if(B.seedContent){let Y=B.syncPath??A.dataDir;await ar0(Y,w,B.seedContentPath)}try{if($){w.debug("Git enabled \u2014 pulling before import");let H=await $.pull();if(H.files.length>0)w.info("Pulled changes from remote",{filesChanged:H.files.length})}w.debug("Starting initial sync");let Y=await D.sync();w.debug("Initial sync completed",{imported:Y.import.imported,failed:Y.import.failed,duration:Y.duration}),await A.messaging.send({type:Uz.initialSyncCompleted,payload:{success:!0},...{broadcast:!0}})}catch(Y){w.error("Initial sync failed",Y),await A.messaging.send({type:Uz.initialSyncCompleted,payload:{success:!1,error:h0(Y)},...{broadcast:!0}})}};A.messaging.subscribe(Uz.pluginsRegistered,async()=>{return w.debug("Plugins registered, starting initial sync"),await f(),{success:!0}})}JA();function er0(A,Q,B,w){let $=new wz(()=>{Q.withLock(async()=>{try{await Q.commit(),await Q.push()}catch(D){w.error("Git auto-commit failed",{error:D})}})},B),I=["entity:created","entity:updated","entity:deleted"],f=[];for(let D of I){let Y=A.subscribe(D,async()=>{return $.trigger(),{success:!0}});f.push(Y)}return()=>{$.dispose();for(let D of f)D()}}function Ad0(A,Q,B,w,$){if(w<=0)return()=>{};let I=w*60*1000,f=!1,D=async()=>{if(f)return;f=!0;try{let{files:H,result:W}=await A.withLock(async()=>{let G=await A.pull(),K=await Q.queueSyncBatch(B,"periodic-sync");return{files:G.files,result:K}});if(H.length>0)$.info("Periodic sync: pulled changes",{filesChanged:H.length});if(W)$.debug("Periodic sync: queued imports",{importOperations:W.importOperationsCount,totalFiles:W.totalFiles})}catch(H){$.error("Periodic git sync failed",{error:H})}finally{f=!1}},Y=setInterval(()=>{D()},I);return $.info("Started periodic git sync",{intervalMinutes:w}),()=>{clearInterval(Y)}}import{spawnSync as Bd0}from"child_process";import{cpSync as vk2,existsSync as Qd0,mkdirSync as hk2,mkdtempSync as yk2,rmSync as gk2}from"fs";import{tmpdir as Tk2}from"os";import{fileURLToPath as Sk2}from"url";import{join as mk2,resolve as uk2}from"path";function DZ(A,Q){let B=Bd0("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 ck2(A){return A.startsWith("file://")}function pk2(A){return Sk2(A)}function lk2(A,Q){return Bd0("git",["--git-dir",A,"show-ref","--verify","--quiet",`refs/heads/${Q}`]).status===0}async function wd0(A){if(!A.bootstrapFromSeed)return;if(!A.gitUrl||!ck2(A.gitUrl))return;if(!A.seedContentPath)throw Error("directory-sync git.bootstrapFromSeed requires seedContentPath for local file:// remotes");let Q=A.branch??"main",B=pk2(A.gitUrl),w=uk2(A.seedContentPath);if(!Qd0(w))throw Error(`Seed content path not found: ${w}`);if(!Qd0(B))A.logger.debug("Creating local bare content remote",{remotePath:B,branch:Q}),hk2(B,{recursive:!0}),DZ(process.cwd(),["init","--bare",`--initial-branch=${Q}`,B]);if(lk2(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 $=yk2(mk2(Tk2(),"directory-sync-seed-"));try{DZ($,["init",`--initial-branch=${Q}`]),DZ($,["config","user.name",A.authorName??"Brain"]),DZ($,["config","user.email",A.authorEmail??"brain@localhost"]),vk2(w,$,{recursive:!0}),DZ($,["add","."]),DZ($,["commit","-m","seed content remote"]),DZ($,["remote","add","origin",A.gitUrl]),DZ($,["push","-u","origin",Q])}finally{gk2($,{recursive:!0,force:!0})}}function $d0(A,Q,B,w,$){let{subscribe:I}=A.messaging;I("entity:export:request",async(f)=>{try{return{success:!0,data:await Q().exportEntities(f.payload.entityTypes)}}catch(D){return{success:!1,error:D instanceof Error?D.message:"Export failed"}}}),I("entity:import:request",async(f)=>{try{let D=Q(),Y=f.payload.paths,H=await D.importEntities(Y);if(Y&&Y.length>0)await D.removeOrphanedEntities();return{success:!0,data:H}}catch(D){return{success:!1,error:D instanceof Error?D.message:"Import failed"}}}),I("sync:status:request",async()=>{try{let D=await Q().getStatus();return{success:!0,data:{syncPath:D.syncPath,isInitialized:D.exists,watchEnabled:D.watching}}}catch(f){return{success:!1,error:f instanceof Error?f.message:"Status check failed"}}}),I("sync:configure:request",async(f)=>{try{return await B({syncPath:f.payload.syncPath}),{success:!0,data:{syncPath:f.payload.syncPath,configured:!0}}}catch(D){return{success:!1,error:D instanceof Error?D.message:"Configuration failed"}}}),I("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")}I0();JA();I0();JA();function Id0(A,Q){return jQ(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 I=await Q.show(B.sha,w);return _8({sha:B.sha,entityType:B.entityType,id:B.id,content:I},`Content at ${B.sha.slice(0,7)}`)}let $=await Q.log(w,B.limit);if($.length===0)return _8({commits:[]},`No history found for ${B.entityType}/${B.id}`);return _8({commits:$,entityType:B.entityType,id:B.id},`${$.length} version${$.length===1?"":"s"} found`)}catch($){return N9($ instanceof Error?$.message:"History lookup failed")}})}function fd0(A,Q,B,w){let $=[jQ(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(I,f)=>{try{let D=f.channelId?`${f.interfaceType}:${f.channelId}`:`plugin:${B}`,Y={interfaceType:f.interfaceType,channelId:f.channelId},H=w!==void 0,W=()=>A.queueSyncBatch(Q,D,Y),G=w?await w.withLock(async()=>{return await w.pull(),W()}):await W();if(!G)return _8({gitPulled:H},"No files to sync");return _8({batchId:G.batchId,importOperations:G.importOperationsCount,totalFiles:G.totalFiles,gitPulled:H},`Sync started: ${G.importOperationsCount} import jobs queued for ${G.totalFiles} files${H?" (pulled from git)":""}`)}catch(D){return N9(D instanceof Error?D.message:"Sync failed")}},{cli:{name:"sync"}}),jQ(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 I=await A.getStatus(),f={syncPath:I.syncPath,lastSync:I.lastSync?.toISOString(),watching:I.watching};if(w){let D=await w.getStatus();f.git={isRepo:D.isRepo,branch:D.branch,hasChanges:D.hasChanges,ahead:D.ahead,behind:D.behind,remote:D.remote}}return _8(f)}catch(I){return N9(I instanceof Error?I.message:"Status check failed")}},{visibility:"public"})];if(w)$.push(Id0(B,w));return $}var Dd0={name:"@brains/directory-sync",private:!0,version:"0.2.0-alpha.60",description:"Directory-based entity synchronization plugin for Brains",type:"module",main:"./src/index.ts",types:"./src/index.ts",exports:{".":{types:"./src/index.ts",import:"./src/index.ts"}},scripts:{test:"bun test",typecheck:"tsc --noEmit",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",clean:"rm -rf .turbo"},dependencies:{"@brains/image":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*",chokidar:"^3.5.3","simple-git":"^3.21.0"},devDependencies:{"@types/bun":"latest","@types/node":"^20.0.0",typescript:"^5.3.3"},peerDependencies:{}};class dLA extends Ww{directorySync;gitSync;gitCleanups=[];constructor(A={}){super("directory-sync",Dd0,A,PT)}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:kT,basePrompt:"",formatter:new FAA,requiredPermission:"anchor"}});let w=this.config.syncPath??A.dataDir;this.directorySync=new NT({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(f){throw this.logger.error("Failed to initialize directory",f),f}await this.registerJobHandlers(A);let $=this.requireDirectorySync();if(dr0(A,$,this.logger,this.config.entityTypes),this.config.autoSync)nr0(A,$,this.config.syncPath??A.dataDir);let I=this.config.git!==void 0&&(this.config.git.repo!==void 0||this.config.git.gitUrl!==void 0);if(this.config.git&&!I)this.logger.debug("Git block present but no repo/gitUrl configured \u2014 git sync disabled");if(I&&this.config.git){await wd0({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 f=this.config.syncPath??A.dataDir;if(this.gitSync=new SLA({logger:this.logger.child("GitSync"),dataDir:f,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(er0(A.messaging,this.gitSync,this.config.commitDebounce,this.logger.child("GitAutoCommit"))),this.config.autoSync)this.gitCleanups.push(Ad0(this.gitSync,this.requireDirectorySync(),A,this.config.syncInterval,this.logger.child("GitPeriodicSync")))}if(this.config.initialSync)tr0(A,()=>this.requireDirectorySync(),this.config,this.logger,this.gitSync);$d0(A,()=>this.requireDirectorySync(),(f)=>this.configure(f),this.logger,this.config.git)}async getTools(){let A=this.requireDirectorySync();return fd0(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 NT({...this.config,syncPath:A.syncPath,entityService:Q.entityService,logger:Q.logger}),await this.directorySync.initialize(),this.logger.info("Directory sync reconfigured",{path:A.syncPath})}async registerJobHandlers(A){rr0(A,this.requireDirectorySync(),this.logger)}}function Sq(A={}){return new dLA(A)}I0();import{render as eQ1}from"preact-render-to-string";import{h as ZC}from"preact";function Yd0(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=Yd0(A[Q]))&&(w&&(w+=" "),w+=B)}else for(B in A)A[B]&&(w&&(w+=" "),w+=B);return w}function QR(){for(var A,Q,B=0,w="",$=arguments.length;B<$;B++)(A=arguments[B])&&(Q=Yd0(A))&&(w&&(w+=" "),w+=Q);return w}var rk2=(A)=>{let Q=nk2(A),{conflictingClassGroups:B,conflictingClassGroupModifiers:w}=A;return{getClassGroupId:(f)=>{let D=f.split("-");if(D[0]===""&&D.length!==1)D.shift();return Jd0(D,Q)||dk2(f)},getConflictingClassGroupIds:(f,D)=>{let Y=B[f]||[];if(D&&w[f])return[...Y,...w[f]];return Y}}},Jd0=(A,Q)=>{if(A.length===0)return Q.classGroupId;let B=A[0],w=Q.nextPart.get(B),$=w?Jd0(A.slice(1),w):void 0;if($)return $;if(Q.validators.length===0)return;let I=A.join("-");return Q.validators.find(({validator:f})=>f(I))?.classGroupId},Hd0=/^\[(.+)\]$/,dk2=(A)=>{if(Hd0.test(A)){let Q=Hd0.exec(A)[1],B=Q?.substring(0,Q.indexOf(":"));if(B)return"arbitrary.."+B}},nk2=(A)=>{let{theme:Q,prefix:B}=A,w={nextPart:new Map,validators:[]};return sk2(Object.entries(A.classGroups),B).forEach(([I,f])=>{oLA(f,w,I,Q)}),w},oLA=(A,Q,B,w)=>{A.forEach(($)=>{if(typeof $==="string"){let I=$===""?Q:Xd0(Q,$);I.classGroupId=B;return}if(typeof $==="function"){if(ok2($)){oLA($(w),Q,B,w);return}Q.validators.push({validator:$,classGroupId:B});return}Object.entries($).forEach(([I,f])=>{oLA(f,Xd0(Q,I),B,w)})})},Xd0=(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},ok2=(A)=>A.isThemeGetter,sk2=(A,Q)=>{if(!Q)return A;return A.map(([B,w])=>{let $=w.map((I)=>{if(typeof I==="string")return Q+I;if(typeof I==="object")return Object.fromEntries(Object.entries(I).map(([f,D])=>[Q+f,D]));return I});return[B,$]})},ak2=(A)=>{if(A<1)return{get:()=>{return},set:()=>{}};let Q=0,B=new Map,w=new Map,$=(I,f)=>{if(B.set(I,f),Q++,Q>A)Q=0,w=B,B=new Map};return{get(I){let f=B.get(I);if(f!==void 0)return f;if((f=w.get(I))!==void 0)return $(I,f),f},set(I,f){if(B.has(I))B.set(I,f);else $(I,f)}}};var tk2=(A)=>{let{separator:Q,experimentalParseClassName:B}=A,w=Q.length===1,$=Q[0],I=Q.length,f=(D)=>{let Y=[],H=0,W=0,G;for(let C=0;C<D.length;C++){let R=D[C];if(H===0){if(R===$&&(w||D.slice(C,C+I)===Q)){Y.push(D.slice(W,C)),W=C+I;continue}if(R==="/"){G=C;continue}}if(R==="[")H++;else if(R==="]")H--}let K=Y.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:Y,hasImportantModifier:Z,baseClassName:q,maybePostfixModifierPosition:L}};if(B)return(D)=>B({className:D,parseClassName:f});return f},ek2=(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},Aj2=(A)=>({cache:ak2(A.cacheSize),parseClassName:tk2(A),...rk2(A)}),Qj2=/\s+/,Bj2=(A,Q)=>{let{parseClassName:B,getClassGroupId:w,getConflictingClassGroupIds:$}=Q,I=[],f=A.trim().split(Qj2),D="";for(let Y=f.length-1;Y>=0;Y-=1){let H=f[Y],{modifiers:W,hasImportantModifier:G,baseClassName:K,maybePostfixModifierPosition:Z}=B(H),q=Boolean(Z),L=w(q?K.substring(0,Z):K);if(!L){if(!q){D=H+(D.length>0?" "+D:D);continue}if(L=w(K),!L){D=H+(D.length>0?" "+D:D);continue}q=!1}let C=ek2(W).join(":"),R=G?C+"!":C,j=R+L;if(I.includes(j))continue;I.push(j);let P=$(L,q);for(let o=0;o<P.length;++o){let n=P[o];I.push(R+n)}D=H+(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=Gd0(Q))w&&(w+=" "),w+=B}return w}var Gd0=(A)=>{if(typeof A==="string")return A;let Q,B="";for(let w=0;w<A.length;w++)if(A[w]){if(Q=Gd0(A[w]))B&&(B+=" "),B+=Q}return B};function Wd0(A,...Q){let B,w,$,I=f;function f(Y){let H=Q.reduce((W,G)=>G(W),A());return B=Aj2(H),w=B.cache.get,$=B.cache.set,I=D,D(Y)}function D(Y){let H=w(Y);if(H)return H;let W=Bj2(Y,B);return $(Y,W),W}return function(){return I(wj2.apply(null,arguments))}}var ew=(A)=>{let Q=(B)=>B[A]||[];return Q.isThemeGetter=!0,Q},Fd0=/^\[(?:([a-z-]+):)?(.+)\]$/i,$j2=/^\d+\/\d+$/,Ij2=new Set(["px","full","screen"]),fj2=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,Dj2=/\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$/,Yj2=/^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/,Hj2=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,Xj2=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,RJ=(A)=>BR(A)||Ij2.has(A)||$j2.test(A),YZ=(A)=>wR(A,"length",zj2),BR=(A)=>Boolean(A)&&!Number.isNaN(Number(A)),nLA=(A)=>wR(A,"number",BR),jT=(A)=>Boolean(A)&&Number.isInteger(Number(A)),Wj2=(A)=>A.endsWith("%")&&BR(A.slice(0,-1)),_Q=(A)=>Fd0.test(A),HZ=(A)=>fj2.test(A),Uj2=new Set(["length","size","percentage"]),Jj2=(A)=>wR(A,Uj2,Kd0),Gj2=(A)=>wR(A,"position",Kd0),Fj2=new Set(["image","url"]),Kj2=(A)=>wR(A,Fj2,qj2),Zj2=(A)=>wR(A,"",Nj2),xT=()=>!0,wR=(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},zj2=(A)=>Dj2.test(A)&&!Yj2.test(A),Kd0=()=>!1,Nj2=(A)=>Hj2.test(A),qj2=(A)=>Xj2.test(A);var Ud0=()=>{let A=ew("colors"),Q=ew("spacing"),B=ew("blur"),w=ew("brightness"),$=ew("borderColor"),I=ew("borderRadius"),f=ew("borderSpacing"),D=ew("borderWidth"),Y=ew("contrast"),H=ew("grayscale"),W=ew("hueRotate"),G=ew("invert"),K=ew("gap"),Z=ew("gradientColorStops"),q=ew("gradientColorStopPositions"),L=ew("inset"),C=ew("margin"),R=ew("opacity"),j=ew("padding"),P=ew("saturate"),o=ew("scale"),n=ew("sepia"),S=ew("skew"),v=ew("space"),y=ew("translate"),g=()=>["auto","contain","none"],AA=()=>["auto","hidden","clip","visible","scroll"],c=()=>["auto",_Q,Q],GA=()=>[_Q,Q],YA=()=>["",RJ,YZ],_=()=>["auto",BR,_Q],b=()=>["bottom","center","left","left-bottom","left-top","right","right-bottom","right-top","top"],k=()=>["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"],r=()=>["start","end","center","between","around","evenly","stretch"],BA=()=>["","0",_Q],d=()=>["auto","avoid","all","avoid-page","page","left","right","column"],UA=()=>[BR,_Q];return{cacheSize:500,separator:":",theme:{colors:[xT],spacing:[RJ,YZ],blur:["none","",HZ,_Q],brightness:UA(),borderColor:[A],borderRadius:["none","","full",HZ,_Q],borderSpacing:GA(),borderWidth:YA(),contrast:UA(),grayscale:BA(),hueRotate:UA(),invert:BA(),gap:GA(),gradientColorStops:[A],gradientColorStopPositions:[Wj2,YZ],inset:c(),margin:c(),opacity:UA(),padding:GA(),saturate:UA(),scale:UA(),sepia:BA(),skew:UA(),space:GA(),translate:GA()},classGroups:{aspect:[{aspect:["auto","square","video",_Q]}],container:["container"],columns:[{columns:[HZ]}],"break-after":[{"break-after":d()}],"break-before":[{"break-before":d()}],"break-inside":[{"break-inside":["auto","avoid","avoid-page","avoid-column"]}],"box-decoration":[{"box-decoration":["slice","clone"]}],box:[{box:["border","content"]}],display:["block","inline-block","inline","flex","inline-flex","table","inline-table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row-group","table-row","flow-root","grid","inline-grid","contents","list-item","hidden"],float:[{float:["right","left","none","start","end"]}],clear:[{clear:["left","right","both","none","start","end"]}],isolation:["isolate","isolation-auto"],"object-fit":[{object:["contain","cover","fill","none","scale-down"]}],"object-position":[{object:[...b(),_Q]}],overflow:[{overflow:AA()}],"overflow-x":[{"overflow-x":AA()}],"overflow-y":[{"overflow-y":AA()}],overscroll:[{overscroll:g()}],"overscroll-x":[{"overscroll-x":g()}],"overscroll-y":[{"overscroll-y":g()}],position:["static","fixed","absolute","relative","sticky"],inset:[{inset:[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",jT,_Q]}],basis:[{basis:c()}],"flex-direction":[{flex:["row","row-reverse","col","col-reverse"]}],"flex-wrap":[{flex:["wrap","wrap-reverse","nowrap"]}],flex:[{flex:["1","auto","initial","none",_Q]}],grow:[{grow:BA()}],shrink:[{shrink:BA()}],order:[{order:["first","last","none",jT,_Q]}],"grid-cols":[{"grid-cols":[xT]}],"col-start-end":[{col:["auto",{span:["full",jT,_Q]},_Q]}],"col-start":[{"col-start":_()}],"col-end":[{"col-end":_()}],"grid-rows":[{"grid-rows":[xT]}],"row-start-end":[{row:["auto",{span:[jT,_Q]},_Q]}],"row-start":[{"row-start":_()}],"row-end":[{"row-end":_()}],"grid-flow":[{"grid-flow":["row","col","dense","row-dense","col-dense"]}],"auto-cols":[{"auto-cols":["auto","min","max","fr",_Q]}],"auto-rows":[{"auto-rows":["auto","min","max","fr",_Q]}],gap:[{gap:[K]}],"gap-x":[{"gap-x":[K]}],"gap-y":[{"gap-y":[K]}],"justify-content":[{justify:["normal",...r()]}],"justify-items":[{"justify-items":["start","end","center","stretch"]}],"justify-self":[{"justify-self":["auto","start","end","center","stretch"]}],"align-content":[{content:["normal",...r(),"baseline"]}],"align-items":[{items:["start","end","center","baseline","stretch"]}],"align-self":[{self:["auto","start","end","center","stretch","baseline"]}],"place-content":[{"place-content":[...r(),"baseline"]}],"place-items":[{"place-items":["start","end","center","baseline","stretch"]}],"place-self":[{"place-self":["auto","start","end","center","stretch"]}],p:[{p:[j]}],px:[{px:[j]}],py:[{py:[j]}],ps:[{ps:[j]}],pe:[{pe:[j]}],pt:[{pt:[j]}],pr:[{pr:[j]}],pb:[{pb:[j]}],pl:[{pl:[j]}],m:[{m:[C]}],mx:[{mx:[C]}],my:[{my:[C]}],ms:[{ms:[C]}],me:[{me:[C]}],mt:[{mt:[C]}],mr:[{mr:[C]}],mb:[{mb:[C]}],ml:[{ml:[C]}],"space-x":[{"space-x":[v]}],"space-x-reverse":["space-x-reverse"],"space-y":[{"space-y":[v]}],"space-y-reverse":["space-y-reverse"],w:[{w:["auto","min","max","fit","svw","lvw","dvw",_Q,Q]}],"min-w":[{"min-w":[_Q,Q,"min","max","fit"]}],"max-w":[{"max-w":[_Q,Q,"none","full","min","max","fit","prose",{screen:[HZ]},HZ]}],h:[{h:[_Q,Q,"auto","min","max","fit","svh","lvh","dvh"]}],"min-h":[{"min-h":[_Q,Q,"min","max","fit","svh","lvh","dvh"]}],"max-h":[{"max-h":[_Q,Q,"min","max","fit","svh","lvh","dvh"]}],size:[{size:[_Q,Q,"auto","min","max","fit"]}],"font-size":[{text:["base",HZ,YZ]}],"font-smoothing":["antialiased","subpixel-antialiased"],"font-style":["italic","not-italic"],"font-weight":[{font:["thin","extralight","light","normal","medium","semibold","bold","extrabold","black",nLA]}],"font-family":[{font:[xT]}],"fvn-normal":["normal-nums"],"fvn-ordinal":["ordinal"],"fvn-slashed-zero":["slashed-zero"],"fvn-figure":["lining-nums","oldstyle-nums"],"fvn-spacing":["proportional-nums","tabular-nums"],"fvn-fraction":["diagonal-fractions","stacked-fractions"],tracking:[{tracking:["tighter","tight","normal","wide","wider","widest",_Q]}],"line-clamp":[{"line-clamp":["none",BR,nLA]}],leading:[{leading:["none","tight","snug","normal","relaxed","loose",RJ,_Q]}],"list-image":[{"list-image":["none",_Q]}],"list-style-type":[{list:["none","disc","decimal",_Q]}],"list-style-position":[{list:["inside","outside"]}],"placeholder-color":[{placeholder:[A]}],"placeholder-opacity":[{"placeholder-opacity":[R]}],"text-alignment":[{text:["left","center","right","justify","start","end"]}],"text-color":[{text:[A]}],"text-opacity":[{"text-opacity":[R]}],"text-decoration":["underline","overline","line-through","no-underline"],"text-decoration-style":[{decoration:[...k(),"wavy"]}],"text-decoration-thickness":[{decoration:["auto","from-font",RJ,YZ]}],"underline-offset":[{"underline-offset":["auto",RJ,_Q]}],"text-decoration-color":[{decoration:[A]}],"text-transform":["uppercase","lowercase","capitalize","normal-case"],"text-overflow":["truncate","text-ellipsis","text-clip"],"text-wrap":[{text:["wrap","nowrap","balance","pretty"]}],indent:[{indent:GA()}],"vertical-align":[{align:["baseline","top","middle","bottom","text-top","text-bottom","sub","super",_Q]}],whitespace:[{whitespace:["normal","nowrap","pre","pre-line","pre-wrap","break-spaces"]}],break:[{break:["normal","words","all","keep"]}],hyphens:[{hyphens:["none","manual","auto"]}],content:[{content:["none",_Q]}],"bg-attachment":[{bg:["fixed","local","scroll"]}],"bg-clip":[{"bg-clip":["border","padding","content","text"]}],"bg-opacity":[{"bg-opacity":[R]}],"bg-origin":[{"bg-origin":["border","padding","content"]}],"bg-position":[{bg:[...b(),Gj2]}],"bg-repeat":[{bg:["no-repeat",{repeat:["","x","y","round","space"]}]}],"bg-size":[{bg:["auto","cover","contain",Jj2]}],"bg-image":[{bg:["none",{"gradient-to":["t","tr","r","br","b","bl","l","tl"]},Kj2]}],"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:[I]}],"rounded-s":[{"rounded-s":[I]}],"rounded-e":[{"rounded-e":[I]}],"rounded-t":[{"rounded-t":[I]}],"rounded-r":[{"rounded-r":[I]}],"rounded-b":[{"rounded-b":[I]}],"rounded-l":[{"rounded-l":[I]}],"rounded-ss":[{"rounded-ss":[I]}],"rounded-se":[{"rounded-se":[I]}],"rounded-ee":[{"rounded-ee":[I]}],"rounded-es":[{"rounded-es":[I]}],"rounded-tl":[{"rounded-tl":[I]}],"rounded-tr":[{"rounded-tr":[I]}],"rounded-br":[{"rounded-br":[I]}],"rounded-bl":[{"rounded-bl":[I]}],"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:[...k(),"hidden"]}],"divide-x":[{"divide-x":[D]}],"divide-x-reverse":["divide-x-reverse"],"divide-y":[{"divide-y":[D]}],"divide-y-reverse":["divide-y-reverse"],"divide-opacity":[{"divide-opacity":[R]}],"divide-style":[{divide:k()}],"border-color":[{border:[$]}],"border-color-x":[{"border-x":[$]}],"border-color-y":[{"border-y":[$]}],"border-color-s":[{"border-s":[$]}],"border-color-e":[{"border-e":[$]}],"border-color-t":[{"border-t":[$]}],"border-color-r":[{"border-r":[$]}],"border-color-b":[{"border-b":[$]}],"border-color-l":[{"border-l":[$]}],"divide-color":[{divide:[$]}],"outline-style":[{outline:["",...k()]}],"outline-offset":[{"outline-offset":[RJ,_Q]}],"outline-w":[{outline:[RJ,YZ]}],"outline-color":[{outline:[A]}],"ring-w":[{ring:YA()}],"ring-w-inset":["ring-inset"],"ring-color":[{ring:[A]}],"ring-opacity":[{"ring-opacity":[R]}],"ring-offset-w":[{"ring-offset":[RJ,YZ]}],"ring-offset-color":[{"ring-offset":[A]}],shadow:[{shadow:["","inner","none",HZ,Zj2]}],"shadow-color":[{shadow:[xT]}],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:[Y]}],"drop-shadow":[{"drop-shadow":["","none",HZ,_Q]}],grayscale:[{grayscale:[H]}],"hue-rotate":[{"hue-rotate":[W]}],invert:[{invert:[G]}],saturate:[{saturate:[P]}],sepia:[{sepia:[n]}],"backdrop-filter":[{"backdrop-filter":["","none"]}],"backdrop-blur":[{"backdrop-blur":[B]}],"backdrop-brightness":[{"backdrop-brightness":[w]}],"backdrop-contrast":[{"backdrop-contrast":[Y]}],"backdrop-grayscale":[{"backdrop-grayscale":[H]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[W]}],"backdrop-invert":[{"backdrop-invert":[G]}],"backdrop-opacity":[{"backdrop-opacity":[R]}],"backdrop-saturate":[{"backdrop-saturate":[P]}],"backdrop-sepia":[{"backdrop-sepia":[n]}],"border-collapse":[{border:["collapse","separate"]}],"border-spacing":[{"border-spacing":[f]}],"border-spacing-x":[{"border-spacing-x":[f]}],"border-spacing-y":[{"border-spacing-y":[f]}],"table-layout":[{table:["auto","fixed"]}],caption:[{caption:["top","bottom"]}],transition:[{transition:["none","all","","colors","opacity","shadow","transform",_Q]}],duration:[{duration:UA()}],ease:[{ease:["linear","in","out","in-out",_Q]}],delay:[{delay:UA()}],animate:[{animate:["none","spin","ping","pulse","bounce",_Q]}],transform:[{transform:["","gpu","none"]}],scale:[{scale:[o]}],"scale-x":[{"scale-x":[o]}],"scale-y":[{"scale-y":[o]}],rotate:[{rotate:[jT,_Q]}],"translate-x":[{"translate-x":[y]}],"translate-y":[{"translate-y":[y]}],"skew-x":[{"skew-x":[S]}],"skew-y":[{"skew-y":[S]}],"transform-origin":[{origin:["center","top","top-right","right","bottom-right","bottom","bottom-left","left","top-left",_Q]}],accent:[{accent:["auto",A]}],appearance:[{appearance:["none","auto"]}],cursor:[{cursor:["auto","default","pointer","wait","text","move","help","not-allowed","none","context-menu","progress","cell","crosshair","vertical-text","alias","copy","no-drop","grab","grabbing","all-scroll","col-resize","row-resize","n-resize","e-resize","s-resize","w-resize","ne-resize","nw-resize","se-resize","sw-resize","ew-resize","ns-resize","nesw-resize","nwse-resize","zoom-in","zoom-out",_Q]}],"caret-color":[{caret:[A]}],"pointer-events":[{"pointer-events":["none","auto"]}],resize:[{resize:["none","y","x",""]}],"scroll-behavior":[{scroll:["auto","smooth"]}],"scroll-m":[{"scroll-m":GA()}],"scroll-mx":[{"scroll-mx":GA()}],"scroll-my":[{"scroll-my":GA()}],"scroll-ms":[{"scroll-ms":GA()}],"scroll-me":[{"scroll-me":GA()}],"scroll-mt":[{"scroll-mt":GA()}],"scroll-mr":[{"scroll-mr":GA()}],"scroll-mb":[{"scroll-mb":GA()}],"scroll-ml":[{"scroll-ml":GA()}],"scroll-p":[{"scroll-p":GA()}],"scroll-px":[{"scroll-px":GA()}],"scroll-py":[{"scroll-py":GA()}],"scroll-ps":[{"scroll-ps":GA()}],"scroll-pe":[{"scroll-pe":GA()}],"scroll-pt":[{"scroll-pt":GA()}],"scroll-pr":[{"scroll-pr":GA()}],"scroll-pb":[{"scroll-pb":GA()}],"scroll-pl":[{"scroll-pl":GA()}],"snap-align":[{snap:["start","end","center","align-none"]}],"snap-stop":[{snap:["normal","always"]}],"snap-type":[{snap:["none","x","y","both"]}],"snap-strictness":[{snap:["mandatory","proximity"]}],touch:[{touch:["auto","none","manipulation"]}],"touch-x":[{"touch-pan":["x","left","right"]}],"touch-y":[{"touch-pan":["y","up","down"]}],"touch-pz":["touch-pinch-zoom"],select:[{select:["none","text","all","auto"]}],"will-change":[{"will-change":["auto","scroll","contents","transform",_Q]}],fill:[{fill:[A,"none"]}],"stroke-w":[{stroke:[RJ,YZ,nLA]}],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"]}}},Cj2=(A,{cacheSize:Q,prefix:B,separator:w,experimentalParseClassName:$,extend:I={},override:f={}})=>{vT(A,"cacheSize",Q),vT(A,"prefix",B),vT(A,"separator",w),vT(A,"experimentalParseClassName",$);for(let D in f)Ej2(A[D],f[D]);for(let D in I)Lj2(A[D],I[D]);return A},vT=(A,Q,B)=>{if(B!==void 0)A[Q]=B},Ej2=(A,Q)=>{if(Q)for(let B in Q)vT(A,B,Q[B])},Lj2=(A,Q)=>{if(Q)for(let B in Q){let w=Q[B];if(w!==void 0)A[B]=(A[B]||[]).concat(w)}},MAA=(A,...Q)=>typeof A==="function"?Wd0(Ud0,A,...Q):Wd0(()=>Cj2(Ud0(),A),...Q);var Mj2=MAA({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 Mj2(QR(A))}var Zd0=(A)=>typeof A==="boolean"?`${A}`:A===0?"0":A,zd0=QR,Kw=(A,Q)=>(B)=>{var w;if((Q===null||Q===void 0?void 0:Q.variants)==null)return zd0(A,B===null||B===void 0?void 0:B.class,B===null||B===void 0?void 0:B.className);let{variants:$,defaultVariants:I}=Q,f=Object.keys($).map((H)=>{let W=B===null||B===void 0?void 0:B[H],G=I===null||I===void 0?void 0:I[H];if(W===null)return null;let K=Zd0(W)||Zd0(G);return $[H][K]}),D=B&&Object.entries(B).reduce((H,W)=>{let[G,K]=W;if(K===void 0)return H;return H[G]=K,H},{}),Y=Q===null||Q===void 0?void 0:(w=Q.compoundVariants)===null||w===void 0?void 0:w.reduce((H,W)=>{let{class:G,className:K,...Z}=W;return Object.entries(Z).every((q)=>{let[L,C]=q;return Array.isArray(C)?C.includes({...I,...D}[L]):{...I,...D}[L]===C})?[...H,G,K]:H},[]);return zd0(A,f,Y,B===null||B===void 0?void 0:B.class,B===null||B===void 0?void 0:B.className)};import{jsxDEV as sLA}from"preact/jsx-dev-runtime";var Nd0=Kw("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 aLA({variant:A,title:Q,children:B,className:w}){return sLA("div",{className:s1(Nd0({variant:A}),w),role:"alert",children:[Q&&sLA("p",{className:"font-medium text-current opacity-90",children:Q},void 0,!1,void 0,this),sLA("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 qd0=Kw("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 mq({variant:A,size:Q,className:B,children:w,ssrOnClick:$,type:I="button",...f}){return Vj2("button",{type:I,className:s1(qd0({variant:A,size:Q}),B),...f,...$&&{onclick:$},children:w},void 0,!1,void 0,this)}import{jsxDEV as Oj2}from"preact/jsx-dev-runtime";var Cd0=Kw("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 V5({href:A,children:Q,variant:B,size:w,external:$=!1,className:I,"aria-label":f}){let D=$?{target:"_blank",rel:"noopener noreferrer"}:{};return Oj2("a",{href:A,className:s1(Cd0({variant:B,size:w}),I),"aria-label":f,...D,children:Q},void 0,!1,void 0,this)}import{jsxDEV as VAA}from"preact/jsx-dev-runtime";var Ed0=Kw("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"}}),bj2={sm:"w-4 h-4",md:"w-5 h-5",lg:"w-6 h-6"};function $R({variant:A,size:Q,className:B}){let w=bj2[Q??"md"];return VAA("button",{onclick:"toggleTheme()",type:"button",className:s1(Ed0({variant:A,size:Q}),B),"aria-label":"Toggle dark mode",children:VAA("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:[VAA("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),VAA("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 tLA}from"preact/jsx-dev-runtime";var Ld0=Kw("flex flex-wrap",{variants:{orientation:{horizontal:"justify-center gap-6 items-center",vertical:"flex-col gap-2.5"}},defaultVariants:{orientation:"horizontal"}});function OAA({items:A,className:Q,linkClassName:B="hover:text-accent transition-colors",orientation:w,children:$}){if(A.length===0&&!$)return null;let I=[...A].sort((f,D)=>f.priority-D.priority);return tLA("ul",{className:s1(Ld0({orientation:w}),Q),children:[I.map((f)=>tLA("li",{children:tLA("a",{href:f.href,className:B,children:f.label},void 0,!1,void 0,this)},f.href,!1,void 0,this)),$]},void 0,!0,void 0,this)}import{jsxDEV as RpB}from"preact/jsx-dev-runtime";import{jsxDEV as kpB}from"preact/jsx-dev-runtime";JA();JA();import{createContext as Rj2,h as _j2}from"preact";import{useContext as Pj2}from"preact/hooks";var Md0=Rj2(null);function bAA({imageRenderer:A,children:Q}){return _j2(Md0.Provider,{value:A??null},Q)}function Vd0(){return Pj2(Md0)}function uq(){let A=Vd0();return(Q)=>zp(Q,A?{imageRenderer:A}:void 0)}import{jsxDEV as _J}from"preact/jsx-dev-runtime";var eLA=({markdown:A})=>{let Q=uq(),w=A.split(/^---$/gm).map((f)=>f.trim()).map((f)=>{let{attributes:D,markdown:Y}=mp(f),H=up(Y),W;if(H)W=`<div class="slide-columns">${H.map((K)=>`<div class="slide-column">${Vk(Q(K.trim()))}</div>`).join("")}</div>`;else W=Vk(Q(Y));return{attributes:D,htmlContent:W}}),$=w.some((f)=>f.htmlContent.includes('class="mermaid"')),I=w.map(({attributes:f,htmlContent:D},Y)=>_J("section",{...f,dangerouslySetInnerHTML:{__html:D}},Y,!1,void 0,this));return _J("section",{className:"presentation-section",children:[_J("link",{rel:"stylesheet",href:"https://cdn.jsdelivr.net/npm/reveal.js@5.1.0/dist/reveal.min.css"},void 0,!1,void 0,this),_J("div",{className:"reveal",children:_J("div",{className:"slides",children:I},void 0,!1,void 0,this)},void 0,!1,void 0,this),_J("script",{src:"https://cdn.jsdelivr.net/npm/reveal.js@5.1.0/dist/reveal.min.js",defer:!0},void 0,!1,void 0,this),$&&_J("script",{src:"https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js",defer:!0},void 0,!1,void 0,this),_J("script",{dangerouslySetInnerHTML:{__html:`
|
|
2419
|
+
`)}}I0();class KAA extends tB{directorySync;constructor(A,Q,B){super(A,{schema:cLA,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}}}I0();class ZAA extends tB{directorySync;constructor(A,Q,B){super(A,{schema:uLA,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}}}I0();class zAA extends tB{directorySync;context;constructor(A,Q,B){super(A,{schema:mLA,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 I={imported:0,skipped:0,failed:0,quarantined:0,quarantinedFiles:[],errors:[],jobIds:[]},f={exported:0,failed:0,errors:[]};if($!=="export")if(await B.report({progress:10,message:"Scanning directory for changes"}),I=await this.importWithProgress(A.paths,B),$==="import")await this.waitForImportJobs(I.jobIds,B),await B.report({progress:100,message:`Import complete: ${I.imported} imported`});else await B.report({progress:50,message:`Imported ${I.imported} entities`}),await this.waitForImportJobs(I.jobIds,B),await B.report({progress:56,message:"Processing complete, starting export"});if($!=="import"){let Y=$==="export"?10:60;await B.report({progress:Y,message:"Exporting entities to directory"}),f=await this.exportWithProgress(A.entityTypes,B),await B.report({progress:100,message:$==="export"?`Export complete: ${f.exported} exported`:`Sync complete: ${I.imported} imported, ${f.exported} exported`})}let D=Date.now()-w;return this.logger.info("Directory sync job completed",{jobId:Q,duration:D,imported:I.imported,exported:f.exported}),{import:I,export:f,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,I=Date.now(),f=async()=>{let Y=(await Promise.all(A.map((W)=>B.getAsyncJobStatus(W)))).filter((W)=>W&&(W.status==="completed"||W.status==="failed")).length;if(Y===A.length){this.logger.debug("All import jobs completed");return}if(Date.now()-I>w){this.logger.warn(`Timeout waiting for import jobs (${Y}/${A.length} completed)`);return}let H=Math.round(Y/A.length*100);return await Q.report({progress:50+Math.round(H*0.05),message:`Processing ${Y}/${A.length} entities`}),await new Promise((W)=>setTimeout(W,$)),f()};return f()}summarizeDataForLog(A){return{operation:A.operation,syncDirection:A.syncDirection}}}I0();class NAA extends tB{context;constructor(A,Q,B){super(A,{schema:GAA,jobTypeName:"directory-delete"});this.context=Q}async process(A,Q,B){let w=GAA.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}}}I0();JA();var zk2=F.object({});class qAA extends tB{directorySync;constructor(A,Q){super(A,{schema:zk2,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}}I0();JA();import{readFile as Nk2,writeFile as qk2}from"fs/promises";var Ck2=pLA;class CAA extends tB{context;fetcher;constructor(A,Q,B=m7){super(Q,{schema:Ck2,jobTypeName:"cover-image-convert"});this.context=A,this.fetcher=B}async process(A,Q,B){let{filePath:w,sourceUrl:$,postTitle:I,postSlug:f,customAlt:D}=A;this.logger.debug("Starting image conversion job",{jobId:Q,filePath:w,sourceUrl:$,postSlug:f});try{await this.reportProgress(B,{progress:v2.INIT,message:`Reading file: ${w}`});let Y;try{Y=await Nk2(w,"utf-8")}catch(L){return this.logger.error("Failed to read file",{filePath:w,error:h0(L)}),r8.failure(L)}let H;try{H=S4(Y)}catch(L){return this.logger.warn("Failed to parse markdown",{filePath:w,error:h0(L)}),r8.failure(L)}let W=H.frontmatter;if(W.coverImageId)return this.logger.debug("File already has coverImageId, skipping",{filePath:w}),await this.reportProgress(B,{progress:v2.COMPLETE,message:"Already converted"}),{success:!0,skipped:!0};await this.reportProgress(B,{progress:v2.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:v2.EXTRACT,message:`Reusing existing image: ${K}`});else{await this.reportProgress(B,{progress:v2.PROCESS,message:`Fetching image from ${$}`});let L;try{L=await this.fetcher($)}catch(n){return this.logger.error("Failed to fetch image",{sourceUrl:$,error:h0(n)}),r8.failure(n)}await this.reportProgress(B,{progress:v2.GENERATE,message:"Creating image entity"});let{base64:C}=pF(L),R=QN(C),j=lF(C);if(!R||!j)return this.logger.error("Could not detect image format or dimensions",{sourceUrl:$}),r8.failure(Error("Could not detect image format or dimensions"));K=`${f}-cover`;let P=`Cover image for ${I}`,o=D??P;await this.context.entityService.createEntity({entity:{id:K,entityType:"image",content:L,metadata:{title:P,alt:o,format:R,width:j.width,height:j.height,sourceUrl:$}}}),this.logger.debug("Created image entity",{imageId:K,sourceUrl:$}),await this.reportProgress(B,{progress:v2.EXTRACT,message:`Created image: ${K}`})}await this.reportProgress(B,{progress:v2.SAVE,message:"Updating file"});let Z={...W};delete Z.coverImageUrl,delete Z.coverImageAlt,Z.coverImageId=K;let q=e3(Z,H.content);try{await qk2(w,q,"utf-8")}catch(L){return this.logger.error("Failed to write file",{filePath:w,error:h0(L)}),r8.failure(L)}return await this.reportProgress(B,{progress:v2.COMPLETE,message:"Conversion complete"}),this.logger.info("Image conversion complete",{filePath:w,imageId:K,sourceUrl:$}),{success:!0,imageId:K}}catch(Y){return this.logger.error("Image conversion job failed",{jobId:Q,filePath:w,error:h0(Y)}),r8.failure(Y)}}summarizeDataForLog(A){return{filePath:A.filePath,sourceUrl:A.sourceUrl,postSlug:A.postSlug}}}I0();JA();import{readFile as Ek2,writeFile as Lk2}from"fs/promises";class EAA extends tB{converter;constructor(A,Q,B=m7){super(Q,{schema:lLA,jobTypeName:"inline-image-convert"});this.converter=new zT(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:v2.INIT,message:`Reading file: ${w}`});let I;try{I=await Ek2(w,"utf-8")}catch(Y){let H=h0(Y);return this.logger.error("Failed to read file",{filePath:w,error:H}),{success:!1,error:H}}await this.reportProgress(B,{progress:v2.FETCH,message:"Detecting inline images"});let f=this.converter.detectInlineImages(I,$);if(f.length===0)return this.logger.debug("No inline images to convert",{filePath:w}),await this.reportProgress(B,{progress:v2.COMPLETE,message:"No images to convert"}),{success:!0,skipped:!0,convertedCount:0};this.logger.debug("Found inline images to convert",{filePath:w,count:f.length}),await this.reportProgress(B,{progress:v2.PROCESS,message:`Converting ${f.length} images`});let D=await this.converter.convert(I,$);if(!D.converted)return this.logger.debug("No images were converted",{filePath:w}),await this.reportProgress(B,{progress:v2.COMPLETE,message:"No images converted"}),{success:!0,skipped:!0,convertedCount:0};await this.reportProgress(B,{progress:v2.SAVE,message:"Writing updated file"});try{await Lk2(w,D.content,"utf-8")}catch(Y){let H=h0(Y);return this.logger.error("Failed to write file",{filePath:w,error:H}),{success:!1,error:H}}return await this.reportProgress(B,{progress:v2.COMPLETE,message:"Conversion complete"}),this.logger.info("Inline image conversion complete",{filePath:w,convertedCount:D.convertedCount}),{success:!0,convertedCount:D.convertedCount}}catch(I){let f=h0(I);return this.logger.error("Inline image conversion job failed",{jobId:Q,filePath:w,error:f}),{success:!1,error:f}}}summarizeDataForLog(A){return{filePath:A.filePath,postSlug:A.postSlug}}}function rr0(A,Q,B){let w=($)=>B.child($);A.jobs.registerHandler("directory-sync",new zAA(w("DirectorySyncJobHandler"),A,Q)),A.jobs.registerHandler("directory-export",new KAA(w("DirectoryExportJobHandler"),A,Q)),A.jobs.registerHandler("directory-import",new ZAA(w("DirectoryImportJobHandler"),A,Q)),A.jobs.registerHandler("directory-delete",new NAA(w("DirectoryDeleteJobHandler"),A,Q)),A.jobs.registerHandler("directory-cleanup",new qAA(w("DirectoryCleanupJobHandler"),Q)),A.jobs.registerHandler("cover-image-convert",new CAA(A,w("CoverImageConversionJobHandler"))),A.jobs.registerHandler("inline-image-convert",new EAA(A,w("InlineImageConversionJobHandler"))),B.debug("Registered async job handlers")}I0();import{unlink as Mk2,access as Vk2}from"fs/promises";function dr0(A,Q,B,w){let{subscribe:$}=A.messaging,{entityService:I}=A;$("entity:created",async(f)=>{let{entity:D}=f.payload;try{await Q.fileOps.writeEntity(D),B.debug("Auto-exported created entity",{id:D.id,entityType:D.entityType})}catch(Y){B.error("Auto-export FAILED for created entity",{id:D.id,entityType:D.entityType,error:Y instanceof Error?Y.message:String(Y),stack:Y instanceof Error?Y.stack:void 0})}return{success:!0}}),$("entity:updated",async(f)=>{let{entityType:D,entityId:Y}=f.payload;try{let H=await I.getEntity({entityType:D,id:Y});if(!H)return B.debug("Entity not found in DB, skipping export",{entityType:D,entityId:Y}),{success:!1};await Q.fileOps.writeEntity(H),B.debug("Auto-exported updated entity",{id:H.id,entityType:H.entityType})}catch(H){B.error("Auto-export FAILED for updated entity",{entityType:D,entityId:Y,error:H instanceof Error?H.message:String(H),stack:H instanceof Error?H.stack:void 0})}return{success:!0}}),$("entity:deleted",async(f)=>{let{entityId:D,entityType:Y}=f.payload,H=Q.fileOps.getFilePath(D,Y);if(await Vk2(H).then(()=>!0,()=>!1))await Mk2(H),B.debug("Auto-deleted entity file",{id:D,entityType:Y,path:H});return{success:!0}}),B.debug("Setup auto-sync for entity events",{entityTypes:w})}function nr0(A,Q,B){Q.setJobQueueCallback(async(w)=>{let $=[{type:w.type,data:w.data}];return A.jobs.enqueueBatch($,{priority:5,source:"directory-sync-watcher",rootJobId:F6(),metadata:{operationType:"file_operations",operationTarget:B,pluginId:"directory-sync"}})})}JA();I0();import{access as Ok2,readdir as or0,mkdir as bk2,copyFile as Rk2}from"fs/promises";import{exec as _k2}from"child_process";import{promisify as Pk2}from"util";import{join as rLA,resolve as iLA}from"path";var kk2=Pk2(_k2);async function LAA(A){try{return await Ok2(A),!0}catch{return!1}}async function jk2(A,Q){if(!await LAA(A))return!0;if((await or0(A)).filter(($)=>!$.startsWith(".")&&!$.startsWith("_")).length>0)return!1;if(await xk2(A))return Q.debug("Git repository with remote detected - skipping seed content",{path:A}),!1;return!0}async function xk2(A){let Q=rLA(A,".git");if(!await LAA(Q))return!1;try{let{stdout:B}=await kk2("git remote",{cwd:A});return B.trim().length>0}catch{return!1}}async function sr0(A,Q){let B=await or0(A,{withFileTypes:!0});for(let w of B){let $=rLA(A,w.name),I=rLA(Q,w.name);if(w.isDirectory()){if(!await LAA(I))await bk2(I,{recursive:!0});await sr0($,I)}else await Rk2($,I)}}async function ar0(A,Q,B){let w=iLA(process.cwd(),A);B=B?iLA(B):iLA(process.cwd(),"seed-content");let $=await jk2(w,Q);if($&&await LAA(B))Q.debug("Copying seed content to brain-data directory"),await sr0(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 tr0(A,Q,B,w,$){let I=!1,f=async()=>{if(I)return;I=!0;let D=Q();if(B.seedContent){let Y=B.syncPath??A.dataDir;await ar0(Y,w,B.seedContentPath)}try{if($){w.debug("Git enabled \u2014 pulling before import");let H=await $.pull();if(H.files.length>0)w.info("Pulled changes from remote",{filesChanged:H.files.length})}w.debug("Starting initial sync");let Y=await D.sync();w.debug("Initial sync completed",{imported:Y.import.imported,failed:Y.import.failed,duration:Y.duration}),await A.messaging.send({type:Uz.initialSyncCompleted,payload:{success:!0},...{broadcast:!0}})}catch(Y){w.error("Initial sync failed",Y),await A.messaging.send({type:Uz.initialSyncCompleted,payload:{success:!1,error:h0(Y)},...{broadcast:!0}})}};A.messaging.subscribe(Uz.pluginsRegistered,async()=>{return w.debug("Plugins registered, starting initial sync"),await f(),{success:!0}})}JA();function er0(A,Q,B,w){let $=new wz(()=>{Q.withLock(async()=>{try{await Q.commit(),await Q.push()}catch(D){w.error("Git auto-commit failed",{error:D})}})},B),I=["entity:created","entity:updated","entity:deleted"],f=[];for(let D of I){let Y=A.subscribe(D,async()=>{return $.trigger(),{success:!0}});f.push(Y)}return()=>{$.dispose();for(let D of f)D()}}function Ad0(A,Q,B,w,$){if(w<=0)return()=>{};let I=w*60*1000,f=!1,D=async()=>{if(f)return;f=!0;try{let{files:H,result:W}=await A.withLock(async()=>{let G=await A.pull(),K=await Q.queueSyncBatch(B,"periodic-sync");return{files:G.files,result:K}});if(H.length>0)$.info("Periodic sync: pulled changes",{filesChanged:H.length});if(W)$.debug("Periodic sync: queued imports",{importOperations:W.importOperationsCount,totalFiles:W.totalFiles})}catch(H){$.error("Periodic git sync failed",{error:H})}finally{f=!1}},Y=setInterval(()=>{D()},I);return $.info("Started periodic git sync",{intervalMinutes:w}),()=>{clearInterval(Y)}}import{spawnSync as Bd0}from"child_process";import{cpSync as vk2,existsSync as Qd0,mkdirSync as hk2,mkdtempSync as yk2,rmSync as gk2}from"fs";import{tmpdir as Tk2}from"os";import{fileURLToPath as Sk2}from"url";import{join as mk2,resolve as uk2}from"path";function DZ(A,Q){let B=Bd0("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 ck2(A){return A.startsWith("file://")}function pk2(A){return Sk2(A)}function lk2(A,Q){return Bd0("git",["--git-dir",A,"show-ref","--verify","--quiet",`refs/heads/${Q}`]).status===0}async function wd0(A){if(!A.bootstrapFromSeed)return;if(!A.gitUrl||!ck2(A.gitUrl))return;if(!A.seedContentPath)throw Error("directory-sync git.bootstrapFromSeed requires seedContentPath for local file:// remotes");let Q=A.branch??"main",B=pk2(A.gitUrl),w=uk2(A.seedContentPath);if(!Qd0(w))throw Error(`Seed content path not found: ${w}`);if(!Qd0(B))A.logger.debug("Creating local bare content remote",{remotePath:B,branch:Q}),hk2(B,{recursive:!0}),DZ(process.cwd(),["init","--bare",`--initial-branch=${Q}`,B]);if(lk2(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 $=yk2(mk2(Tk2(),"directory-sync-seed-"));try{DZ($,["init",`--initial-branch=${Q}`]),DZ($,["config","user.name",A.authorName??"Brain"]),DZ($,["config","user.email",A.authorEmail??"brain@localhost"]),vk2(w,$,{recursive:!0}),DZ($,["add","."]),DZ($,["commit","-m","seed content remote"]),DZ($,["remote","add","origin",A.gitUrl]),DZ($,["push","-u","origin",Q])}finally{gk2($,{recursive:!0,force:!0})}}function $d0(A,Q,B,w,$){let{subscribe:I}=A.messaging;I("entity:export:request",async(f)=>{try{return{success:!0,data:await Q().exportEntities(f.payload.entityTypes)}}catch(D){return{success:!1,error:D instanceof Error?D.message:"Export failed"}}}),I("entity:import:request",async(f)=>{try{let D=Q(),Y=f.payload.paths,H=await D.importEntities(Y);if(Y&&Y.length>0)await D.removeOrphanedEntities();return{success:!0,data:H}}catch(D){return{success:!1,error:D instanceof Error?D.message:"Import failed"}}}),I("sync:status:request",async()=>{try{let D=await Q().getStatus();return{success:!0,data:{syncPath:D.syncPath,isInitialized:D.exists,watchEnabled:D.watching}}}catch(f){return{success:!1,error:f instanceof Error?f.message:"Status check failed"}}}),I("sync:configure:request",async(f)=>{try{return await B({syncPath:f.payload.syncPath}),{success:!0,data:{syncPath:f.payload.syncPath,configured:!0}}}catch(D){return{success:!1,error:D instanceof Error?D.message:"Configuration failed"}}}),I("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")}I0();JA();I0();JA();function Id0(A,Q){return jQ(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 I=await Q.show(B.sha,w);return _8({sha:B.sha,entityType:B.entityType,id:B.id,content:I},`Content at ${B.sha.slice(0,7)}`)}let $=await Q.log(w,B.limit);if($.length===0)return _8({commits:[]},`No history found for ${B.entityType}/${B.id}`);return _8({commits:$,entityType:B.entityType,id:B.id},`${$.length} version${$.length===1?"":"s"} found`)}catch($){return N9($ instanceof Error?$.message:"History lookup failed")}})}function fd0(A,Q,B,w){let $=[jQ(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(I,f)=>{try{let D=f.channelId?`${f.interfaceType}:${f.channelId}`:`plugin:${B}`,Y={interfaceType:f.interfaceType,channelId:f.channelId},H=w!==void 0,W=()=>A.queueSyncBatch(Q,D,Y),G=w?await w.withLock(async()=>{return await w.pull(),W()}):await W();if(!G)return _8({gitPulled:H},"No files to sync");return _8({batchId:G.batchId,importOperations:G.importOperationsCount,totalFiles:G.totalFiles,gitPulled:H},`Sync started: ${G.importOperationsCount} import jobs queued for ${G.totalFiles} files${H?" (pulled from git)":""}`)}catch(D){return N9(D instanceof Error?D.message:"Sync failed")}},{cli:{name:"sync"}}),jQ(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 I=await A.getStatus(),f={syncPath:I.syncPath,lastSync:I.lastSync?.toISOString(),watching:I.watching};if(w){let D=await w.getStatus();f.git={isRepo:D.isRepo,branch:D.branch,hasChanges:D.hasChanges,ahead:D.ahead,behind:D.behind,remote:D.remote}}return _8(f)}catch(I){return N9(I instanceof Error?I.message:"Status check failed")}},{visibility:"public"})];if(w)$.push(Id0(B,w));return $}var Dd0={name:"@brains/directory-sync",private:!0,version:"0.2.0-alpha.61",description:"Directory-based entity synchronization plugin for Brains",type:"module",main:"./src/index.ts",types:"./src/index.ts",exports:{".":{types:"./src/index.ts",import:"./src/index.ts"}},scripts:{test:"bun test",typecheck:"tsc --noEmit",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",clean:"rm -rf .turbo"},dependencies:{"@brains/image":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*",chokidar:"^3.5.3","simple-git":"^3.21.0"},devDependencies:{"@types/bun":"latest","@types/node":"^20.0.0",typescript:"^5.3.3"},peerDependencies:{}};class dLA extends Ww{directorySync;gitSync;gitCleanups=[];constructor(A={}){super("directory-sync",Dd0,A,PT)}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:kT,basePrompt:"",formatter:new FAA,requiredPermission:"anchor"}});let w=this.config.syncPath??A.dataDir;this.directorySync=new NT({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(f){throw this.logger.error("Failed to initialize directory",f),f}await this.registerJobHandlers(A);let $=this.requireDirectorySync();if(dr0(A,$,this.logger,this.config.entityTypes),this.config.autoSync)nr0(A,$,this.config.syncPath??A.dataDir);let I=this.config.git!==void 0&&(this.config.git.repo!==void 0||this.config.git.gitUrl!==void 0);if(this.config.git&&!I)this.logger.debug("Git block present but no repo/gitUrl configured \u2014 git sync disabled");if(I&&this.config.git){await wd0({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 f=this.config.syncPath??A.dataDir;if(this.gitSync=new SLA({logger:this.logger.child("GitSync"),dataDir:f,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(er0(A.messaging,this.gitSync,this.config.commitDebounce,this.logger.child("GitAutoCommit"))),this.config.autoSync)this.gitCleanups.push(Ad0(this.gitSync,this.requireDirectorySync(),A,this.config.syncInterval,this.logger.child("GitPeriodicSync")))}if(this.config.initialSync)tr0(A,()=>this.requireDirectorySync(),this.config,this.logger,this.gitSync);$d0(A,()=>this.requireDirectorySync(),(f)=>this.configure(f),this.logger,this.config.git)}async getTools(){let A=this.requireDirectorySync();return fd0(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 NT({...this.config,syncPath:A.syncPath,entityService:Q.entityService,logger:Q.logger}),await this.directorySync.initialize(),this.logger.info("Directory sync reconfigured",{path:A.syncPath})}async registerJobHandlers(A){rr0(A,this.requireDirectorySync(),this.logger)}}function Sq(A={}){return new dLA(A)}I0();import{render as eQ1}from"preact-render-to-string";import{h as ZC}from"preact";function Yd0(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=Yd0(A[Q]))&&(w&&(w+=" "),w+=B)}else for(B in A)A[B]&&(w&&(w+=" "),w+=B);return w}function QR(){for(var A,Q,B=0,w="",$=arguments.length;B<$;B++)(A=arguments[B])&&(Q=Yd0(A))&&(w&&(w+=" "),w+=Q);return w}var rk2=(A)=>{let Q=nk2(A),{conflictingClassGroups:B,conflictingClassGroupModifiers:w}=A;return{getClassGroupId:(f)=>{let D=f.split("-");if(D[0]===""&&D.length!==1)D.shift();return Jd0(D,Q)||dk2(f)},getConflictingClassGroupIds:(f,D)=>{let Y=B[f]||[];if(D&&w[f])return[...Y,...w[f]];return Y}}},Jd0=(A,Q)=>{if(A.length===0)return Q.classGroupId;let B=A[0],w=Q.nextPart.get(B),$=w?Jd0(A.slice(1),w):void 0;if($)return $;if(Q.validators.length===0)return;let I=A.join("-");return Q.validators.find(({validator:f})=>f(I))?.classGroupId},Hd0=/^\[(.+)\]$/,dk2=(A)=>{if(Hd0.test(A)){let Q=Hd0.exec(A)[1],B=Q?.substring(0,Q.indexOf(":"));if(B)return"arbitrary.."+B}},nk2=(A)=>{let{theme:Q,prefix:B}=A,w={nextPart:new Map,validators:[]};return sk2(Object.entries(A.classGroups),B).forEach(([I,f])=>{oLA(f,w,I,Q)}),w},oLA=(A,Q,B,w)=>{A.forEach(($)=>{if(typeof $==="string"){let I=$===""?Q:Xd0(Q,$);I.classGroupId=B;return}if(typeof $==="function"){if(ok2($)){oLA($(w),Q,B,w);return}Q.validators.push({validator:$,classGroupId:B});return}Object.entries($).forEach(([I,f])=>{oLA(f,Xd0(Q,I),B,w)})})},Xd0=(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},ok2=(A)=>A.isThemeGetter,sk2=(A,Q)=>{if(!Q)return A;return A.map(([B,w])=>{let $=w.map((I)=>{if(typeof I==="string")return Q+I;if(typeof I==="object")return Object.fromEntries(Object.entries(I).map(([f,D])=>[Q+f,D]));return I});return[B,$]})},ak2=(A)=>{if(A<1)return{get:()=>{return},set:()=>{}};let Q=0,B=new Map,w=new Map,$=(I,f)=>{if(B.set(I,f),Q++,Q>A)Q=0,w=B,B=new Map};return{get(I){let f=B.get(I);if(f!==void 0)return f;if((f=w.get(I))!==void 0)return $(I,f),f},set(I,f){if(B.has(I))B.set(I,f);else $(I,f)}}};var tk2=(A)=>{let{separator:Q,experimentalParseClassName:B}=A,w=Q.length===1,$=Q[0],I=Q.length,f=(D)=>{let Y=[],H=0,W=0,G;for(let C=0;C<D.length;C++){let R=D[C];if(H===0){if(R===$&&(w||D.slice(C,C+I)===Q)){Y.push(D.slice(W,C)),W=C+I;continue}if(R==="/"){G=C;continue}}if(R==="[")H++;else if(R==="]")H--}let K=Y.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:Y,hasImportantModifier:Z,baseClassName:q,maybePostfixModifierPosition:L}};if(B)return(D)=>B({className:D,parseClassName:f});return f},ek2=(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},Aj2=(A)=>({cache:ak2(A.cacheSize),parseClassName:tk2(A),...rk2(A)}),Qj2=/\s+/,Bj2=(A,Q)=>{let{parseClassName:B,getClassGroupId:w,getConflictingClassGroupIds:$}=Q,I=[],f=A.trim().split(Qj2),D="";for(let Y=f.length-1;Y>=0;Y-=1){let H=f[Y],{modifiers:W,hasImportantModifier:G,baseClassName:K,maybePostfixModifierPosition:Z}=B(H),q=Boolean(Z),L=w(q?K.substring(0,Z):K);if(!L){if(!q){D=H+(D.length>0?" "+D:D);continue}if(L=w(K),!L){D=H+(D.length>0?" "+D:D);continue}q=!1}let C=ek2(W).join(":"),R=G?C+"!":C,j=R+L;if(I.includes(j))continue;I.push(j);let P=$(L,q);for(let o=0;o<P.length;++o){let n=P[o];I.push(R+n)}D=H+(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=Gd0(Q))w&&(w+=" "),w+=B}return w}var Gd0=(A)=>{if(typeof A==="string")return A;let Q,B="";for(let w=0;w<A.length;w++)if(A[w]){if(Q=Gd0(A[w]))B&&(B+=" "),B+=Q}return B};function Wd0(A,...Q){let B,w,$,I=f;function f(Y){let H=Q.reduce((W,G)=>G(W),A());return B=Aj2(H),w=B.cache.get,$=B.cache.set,I=D,D(Y)}function D(Y){let H=w(Y);if(H)return H;let W=Bj2(Y,B);return $(Y,W),W}return function(){return I(wj2.apply(null,arguments))}}var ew=(A)=>{let Q=(B)=>B[A]||[];return Q.isThemeGetter=!0,Q},Fd0=/^\[(?:([a-z-]+):)?(.+)\]$/i,$j2=/^\d+\/\d+$/,Ij2=new Set(["px","full","screen"]),fj2=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,Dj2=/\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$/,Yj2=/^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/,Hj2=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,Xj2=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,RJ=(A)=>BR(A)||Ij2.has(A)||$j2.test(A),YZ=(A)=>wR(A,"length",zj2),BR=(A)=>Boolean(A)&&!Number.isNaN(Number(A)),nLA=(A)=>wR(A,"number",BR),jT=(A)=>Boolean(A)&&Number.isInteger(Number(A)),Wj2=(A)=>A.endsWith("%")&&BR(A.slice(0,-1)),_Q=(A)=>Fd0.test(A),HZ=(A)=>fj2.test(A),Uj2=new Set(["length","size","percentage"]),Jj2=(A)=>wR(A,Uj2,Kd0),Gj2=(A)=>wR(A,"position",Kd0),Fj2=new Set(["image","url"]),Kj2=(A)=>wR(A,Fj2,qj2),Zj2=(A)=>wR(A,"",Nj2),xT=()=>!0,wR=(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},zj2=(A)=>Dj2.test(A)&&!Yj2.test(A),Kd0=()=>!1,Nj2=(A)=>Hj2.test(A),qj2=(A)=>Xj2.test(A);var Ud0=()=>{let A=ew("colors"),Q=ew("spacing"),B=ew("blur"),w=ew("brightness"),$=ew("borderColor"),I=ew("borderRadius"),f=ew("borderSpacing"),D=ew("borderWidth"),Y=ew("contrast"),H=ew("grayscale"),W=ew("hueRotate"),G=ew("invert"),K=ew("gap"),Z=ew("gradientColorStops"),q=ew("gradientColorStopPositions"),L=ew("inset"),C=ew("margin"),R=ew("opacity"),j=ew("padding"),P=ew("saturate"),o=ew("scale"),n=ew("sepia"),S=ew("skew"),v=ew("space"),y=ew("translate"),g=()=>["auto","contain","none"],AA=()=>["auto","hidden","clip","visible","scroll"],c=()=>["auto",_Q,Q],GA=()=>[_Q,Q],YA=()=>["",RJ,YZ],_=()=>["auto",BR,_Q],b=()=>["bottom","center","left","left-bottom","left-top","right","right-bottom","right-top","top"],k=()=>["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"],r=()=>["start","end","center","between","around","evenly","stretch"],BA=()=>["","0",_Q],d=()=>["auto","avoid","all","avoid-page","page","left","right","column"],UA=()=>[BR,_Q];return{cacheSize:500,separator:":",theme:{colors:[xT],spacing:[RJ,YZ],blur:["none","",HZ,_Q],brightness:UA(),borderColor:[A],borderRadius:["none","","full",HZ,_Q],borderSpacing:GA(),borderWidth:YA(),contrast:UA(),grayscale:BA(),hueRotate:UA(),invert:BA(),gap:GA(),gradientColorStops:[A],gradientColorStopPositions:[Wj2,YZ],inset:c(),margin:c(),opacity:UA(),padding:GA(),saturate:UA(),scale:UA(),sepia:BA(),skew:UA(),space:GA(),translate:GA()},classGroups:{aspect:[{aspect:["auto","square","video",_Q]}],container:["container"],columns:[{columns:[HZ]}],"break-after":[{"break-after":d()}],"break-before":[{"break-before":d()}],"break-inside":[{"break-inside":["auto","avoid","avoid-page","avoid-column"]}],"box-decoration":[{"box-decoration":["slice","clone"]}],box:[{box:["border","content"]}],display:["block","inline-block","inline","flex","inline-flex","table","inline-table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row-group","table-row","flow-root","grid","inline-grid","contents","list-item","hidden"],float:[{float:["right","left","none","start","end"]}],clear:[{clear:["left","right","both","none","start","end"]}],isolation:["isolate","isolation-auto"],"object-fit":[{object:["contain","cover","fill","none","scale-down"]}],"object-position":[{object:[...b(),_Q]}],overflow:[{overflow:AA()}],"overflow-x":[{"overflow-x":AA()}],"overflow-y":[{"overflow-y":AA()}],overscroll:[{overscroll:g()}],"overscroll-x":[{"overscroll-x":g()}],"overscroll-y":[{"overscroll-y":g()}],position:["static","fixed","absolute","relative","sticky"],inset:[{inset:[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",jT,_Q]}],basis:[{basis:c()}],"flex-direction":[{flex:["row","row-reverse","col","col-reverse"]}],"flex-wrap":[{flex:["wrap","wrap-reverse","nowrap"]}],flex:[{flex:["1","auto","initial","none",_Q]}],grow:[{grow:BA()}],shrink:[{shrink:BA()}],order:[{order:["first","last","none",jT,_Q]}],"grid-cols":[{"grid-cols":[xT]}],"col-start-end":[{col:["auto",{span:["full",jT,_Q]},_Q]}],"col-start":[{"col-start":_()}],"col-end":[{"col-end":_()}],"grid-rows":[{"grid-rows":[xT]}],"row-start-end":[{row:["auto",{span:[jT,_Q]},_Q]}],"row-start":[{"row-start":_()}],"row-end":[{"row-end":_()}],"grid-flow":[{"grid-flow":["row","col","dense","row-dense","col-dense"]}],"auto-cols":[{"auto-cols":["auto","min","max","fr",_Q]}],"auto-rows":[{"auto-rows":["auto","min","max","fr",_Q]}],gap:[{gap:[K]}],"gap-x":[{"gap-x":[K]}],"gap-y":[{"gap-y":[K]}],"justify-content":[{justify:["normal",...r()]}],"justify-items":[{"justify-items":["start","end","center","stretch"]}],"justify-self":[{"justify-self":["auto","start","end","center","stretch"]}],"align-content":[{content:["normal",...r(),"baseline"]}],"align-items":[{items:["start","end","center","baseline","stretch"]}],"align-self":[{self:["auto","start","end","center","stretch","baseline"]}],"place-content":[{"place-content":[...r(),"baseline"]}],"place-items":[{"place-items":["start","end","center","baseline","stretch"]}],"place-self":[{"place-self":["auto","start","end","center","stretch"]}],p:[{p:[j]}],px:[{px:[j]}],py:[{py:[j]}],ps:[{ps:[j]}],pe:[{pe:[j]}],pt:[{pt:[j]}],pr:[{pr:[j]}],pb:[{pb:[j]}],pl:[{pl:[j]}],m:[{m:[C]}],mx:[{mx:[C]}],my:[{my:[C]}],ms:[{ms:[C]}],me:[{me:[C]}],mt:[{mt:[C]}],mr:[{mr:[C]}],mb:[{mb:[C]}],ml:[{ml:[C]}],"space-x":[{"space-x":[v]}],"space-x-reverse":["space-x-reverse"],"space-y":[{"space-y":[v]}],"space-y-reverse":["space-y-reverse"],w:[{w:["auto","min","max","fit","svw","lvw","dvw",_Q,Q]}],"min-w":[{"min-w":[_Q,Q,"min","max","fit"]}],"max-w":[{"max-w":[_Q,Q,"none","full","min","max","fit","prose",{screen:[HZ]},HZ]}],h:[{h:[_Q,Q,"auto","min","max","fit","svh","lvh","dvh"]}],"min-h":[{"min-h":[_Q,Q,"min","max","fit","svh","lvh","dvh"]}],"max-h":[{"max-h":[_Q,Q,"min","max","fit","svh","lvh","dvh"]}],size:[{size:[_Q,Q,"auto","min","max","fit"]}],"font-size":[{text:["base",HZ,YZ]}],"font-smoothing":["antialiased","subpixel-antialiased"],"font-style":["italic","not-italic"],"font-weight":[{font:["thin","extralight","light","normal","medium","semibold","bold","extrabold","black",nLA]}],"font-family":[{font:[xT]}],"fvn-normal":["normal-nums"],"fvn-ordinal":["ordinal"],"fvn-slashed-zero":["slashed-zero"],"fvn-figure":["lining-nums","oldstyle-nums"],"fvn-spacing":["proportional-nums","tabular-nums"],"fvn-fraction":["diagonal-fractions","stacked-fractions"],tracking:[{tracking:["tighter","tight","normal","wide","wider","widest",_Q]}],"line-clamp":[{"line-clamp":["none",BR,nLA]}],leading:[{leading:["none","tight","snug","normal","relaxed","loose",RJ,_Q]}],"list-image":[{"list-image":["none",_Q]}],"list-style-type":[{list:["none","disc","decimal",_Q]}],"list-style-position":[{list:["inside","outside"]}],"placeholder-color":[{placeholder:[A]}],"placeholder-opacity":[{"placeholder-opacity":[R]}],"text-alignment":[{text:["left","center","right","justify","start","end"]}],"text-color":[{text:[A]}],"text-opacity":[{"text-opacity":[R]}],"text-decoration":["underline","overline","line-through","no-underline"],"text-decoration-style":[{decoration:[...k(),"wavy"]}],"text-decoration-thickness":[{decoration:["auto","from-font",RJ,YZ]}],"underline-offset":[{"underline-offset":["auto",RJ,_Q]}],"text-decoration-color":[{decoration:[A]}],"text-transform":["uppercase","lowercase","capitalize","normal-case"],"text-overflow":["truncate","text-ellipsis","text-clip"],"text-wrap":[{text:["wrap","nowrap","balance","pretty"]}],indent:[{indent:GA()}],"vertical-align":[{align:["baseline","top","middle","bottom","text-top","text-bottom","sub","super",_Q]}],whitespace:[{whitespace:["normal","nowrap","pre","pre-line","pre-wrap","break-spaces"]}],break:[{break:["normal","words","all","keep"]}],hyphens:[{hyphens:["none","manual","auto"]}],content:[{content:["none",_Q]}],"bg-attachment":[{bg:["fixed","local","scroll"]}],"bg-clip":[{"bg-clip":["border","padding","content","text"]}],"bg-opacity":[{"bg-opacity":[R]}],"bg-origin":[{"bg-origin":["border","padding","content"]}],"bg-position":[{bg:[...b(),Gj2]}],"bg-repeat":[{bg:["no-repeat",{repeat:["","x","y","round","space"]}]}],"bg-size":[{bg:["auto","cover","contain",Jj2]}],"bg-image":[{bg:["none",{"gradient-to":["t","tr","r","br","b","bl","l","tl"]},Kj2]}],"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:[I]}],"rounded-s":[{"rounded-s":[I]}],"rounded-e":[{"rounded-e":[I]}],"rounded-t":[{"rounded-t":[I]}],"rounded-r":[{"rounded-r":[I]}],"rounded-b":[{"rounded-b":[I]}],"rounded-l":[{"rounded-l":[I]}],"rounded-ss":[{"rounded-ss":[I]}],"rounded-se":[{"rounded-se":[I]}],"rounded-ee":[{"rounded-ee":[I]}],"rounded-es":[{"rounded-es":[I]}],"rounded-tl":[{"rounded-tl":[I]}],"rounded-tr":[{"rounded-tr":[I]}],"rounded-br":[{"rounded-br":[I]}],"rounded-bl":[{"rounded-bl":[I]}],"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:[...k(),"hidden"]}],"divide-x":[{"divide-x":[D]}],"divide-x-reverse":["divide-x-reverse"],"divide-y":[{"divide-y":[D]}],"divide-y-reverse":["divide-y-reverse"],"divide-opacity":[{"divide-opacity":[R]}],"divide-style":[{divide:k()}],"border-color":[{border:[$]}],"border-color-x":[{"border-x":[$]}],"border-color-y":[{"border-y":[$]}],"border-color-s":[{"border-s":[$]}],"border-color-e":[{"border-e":[$]}],"border-color-t":[{"border-t":[$]}],"border-color-r":[{"border-r":[$]}],"border-color-b":[{"border-b":[$]}],"border-color-l":[{"border-l":[$]}],"divide-color":[{divide:[$]}],"outline-style":[{outline:["",...k()]}],"outline-offset":[{"outline-offset":[RJ,_Q]}],"outline-w":[{outline:[RJ,YZ]}],"outline-color":[{outline:[A]}],"ring-w":[{ring:YA()}],"ring-w-inset":["ring-inset"],"ring-color":[{ring:[A]}],"ring-opacity":[{"ring-opacity":[R]}],"ring-offset-w":[{"ring-offset":[RJ,YZ]}],"ring-offset-color":[{"ring-offset":[A]}],shadow:[{shadow:["","inner","none",HZ,Zj2]}],"shadow-color":[{shadow:[xT]}],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:[Y]}],"drop-shadow":[{"drop-shadow":["","none",HZ,_Q]}],grayscale:[{grayscale:[H]}],"hue-rotate":[{"hue-rotate":[W]}],invert:[{invert:[G]}],saturate:[{saturate:[P]}],sepia:[{sepia:[n]}],"backdrop-filter":[{"backdrop-filter":["","none"]}],"backdrop-blur":[{"backdrop-blur":[B]}],"backdrop-brightness":[{"backdrop-brightness":[w]}],"backdrop-contrast":[{"backdrop-contrast":[Y]}],"backdrop-grayscale":[{"backdrop-grayscale":[H]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[W]}],"backdrop-invert":[{"backdrop-invert":[G]}],"backdrop-opacity":[{"backdrop-opacity":[R]}],"backdrop-saturate":[{"backdrop-saturate":[P]}],"backdrop-sepia":[{"backdrop-sepia":[n]}],"border-collapse":[{border:["collapse","separate"]}],"border-spacing":[{"border-spacing":[f]}],"border-spacing-x":[{"border-spacing-x":[f]}],"border-spacing-y":[{"border-spacing-y":[f]}],"table-layout":[{table:["auto","fixed"]}],caption:[{caption:["top","bottom"]}],transition:[{transition:["none","all","","colors","opacity","shadow","transform",_Q]}],duration:[{duration:UA()}],ease:[{ease:["linear","in","out","in-out",_Q]}],delay:[{delay:UA()}],animate:[{animate:["none","spin","ping","pulse","bounce",_Q]}],transform:[{transform:["","gpu","none"]}],scale:[{scale:[o]}],"scale-x":[{"scale-x":[o]}],"scale-y":[{"scale-y":[o]}],rotate:[{rotate:[jT,_Q]}],"translate-x":[{"translate-x":[y]}],"translate-y":[{"translate-y":[y]}],"skew-x":[{"skew-x":[S]}],"skew-y":[{"skew-y":[S]}],"transform-origin":[{origin:["center","top","top-right","right","bottom-right","bottom","bottom-left","left","top-left",_Q]}],accent:[{accent:["auto",A]}],appearance:[{appearance:["none","auto"]}],cursor:[{cursor:["auto","default","pointer","wait","text","move","help","not-allowed","none","context-menu","progress","cell","crosshair","vertical-text","alias","copy","no-drop","grab","grabbing","all-scroll","col-resize","row-resize","n-resize","e-resize","s-resize","w-resize","ne-resize","nw-resize","se-resize","sw-resize","ew-resize","ns-resize","nesw-resize","nwse-resize","zoom-in","zoom-out",_Q]}],"caret-color":[{caret:[A]}],"pointer-events":[{"pointer-events":["none","auto"]}],resize:[{resize:["none","y","x",""]}],"scroll-behavior":[{scroll:["auto","smooth"]}],"scroll-m":[{"scroll-m":GA()}],"scroll-mx":[{"scroll-mx":GA()}],"scroll-my":[{"scroll-my":GA()}],"scroll-ms":[{"scroll-ms":GA()}],"scroll-me":[{"scroll-me":GA()}],"scroll-mt":[{"scroll-mt":GA()}],"scroll-mr":[{"scroll-mr":GA()}],"scroll-mb":[{"scroll-mb":GA()}],"scroll-ml":[{"scroll-ml":GA()}],"scroll-p":[{"scroll-p":GA()}],"scroll-px":[{"scroll-px":GA()}],"scroll-py":[{"scroll-py":GA()}],"scroll-ps":[{"scroll-ps":GA()}],"scroll-pe":[{"scroll-pe":GA()}],"scroll-pt":[{"scroll-pt":GA()}],"scroll-pr":[{"scroll-pr":GA()}],"scroll-pb":[{"scroll-pb":GA()}],"scroll-pl":[{"scroll-pl":GA()}],"snap-align":[{snap:["start","end","center","align-none"]}],"snap-stop":[{snap:["normal","always"]}],"snap-type":[{snap:["none","x","y","both"]}],"snap-strictness":[{snap:["mandatory","proximity"]}],touch:[{touch:["auto","none","manipulation"]}],"touch-x":[{"touch-pan":["x","left","right"]}],"touch-y":[{"touch-pan":["y","up","down"]}],"touch-pz":["touch-pinch-zoom"],select:[{select:["none","text","all","auto"]}],"will-change":[{"will-change":["auto","scroll","contents","transform",_Q]}],fill:[{fill:[A,"none"]}],"stroke-w":[{stroke:[RJ,YZ,nLA]}],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"]}}},Cj2=(A,{cacheSize:Q,prefix:B,separator:w,experimentalParseClassName:$,extend:I={},override:f={}})=>{vT(A,"cacheSize",Q),vT(A,"prefix",B),vT(A,"separator",w),vT(A,"experimentalParseClassName",$);for(let D in f)Ej2(A[D],f[D]);for(let D in I)Lj2(A[D],I[D]);return A},vT=(A,Q,B)=>{if(B!==void 0)A[Q]=B},Ej2=(A,Q)=>{if(Q)for(let B in Q)vT(A,B,Q[B])},Lj2=(A,Q)=>{if(Q)for(let B in Q){let w=Q[B];if(w!==void 0)A[B]=(A[B]||[]).concat(w)}},MAA=(A,...Q)=>typeof A==="function"?Wd0(Ud0,A,...Q):Wd0(()=>Cj2(Ud0(),A),...Q);var Mj2=MAA({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 Mj2(QR(A))}var Zd0=(A)=>typeof A==="boolean"?`${A}`:A===0?"0":A,zd0=QR,Kw=(A,Q)=>(B)=>{var w;if((Q===null||Q===void 0?void 0:Q.variants)==null)return zd0(A,B===null||B===void 0?void 0:B.class,B===null||B===void 0?void 0:B.className);let{variants:$,defaultVariants:I}=Q,f=Object.keys($).map((H)=>{let W=B===null||B===void 0?void 0:B[H],G=I===null||I===void 0?void 0:I[H];if(W===null)return null;let K=Zd0(W)||Zd0(G);return $[H][K]}),D=B&&Object.entries(B).reduce((H,W)=>{let[G,K]=W;if(K===void 0)return H;return H[G]=K,H},{}),Y=Q===null||Q===void 0?void 0:(w=Q.compoundVariants)===null||w===void 0?void 0:w.reduce((H,W)=>{let{class:G,className:K,...Z}=W;return Object.entries(Z).every((q)=>{let[L,C]=q;return Array.isArray(C)?C.includes({...I,...D}[L]):{...I,...D}[L]===C})?[...H,G,K]:H},[]);return zd0(A,f,Y,B===null||B===void 0?void 0:B.class,B===null||B===void 0?void 0:B.className)};import{jsxDEV as sLA}from"preact/jsx-dev-runtime";var Nd0=Kw("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 aLA({variant:A,title:Q,children:B,className:w}){return sLA("div",{className:s1(Nd0({variant:A}),w),role:"alert",children:[Q&&sLA("p",{className:"font-medium text-current opacity-90",children:Q},void 0,!1,void 0,this),sLA("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 qd0=Kw("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 mq({variant:A,size:Q,className:B,children:w,ssrOnClick:$,type:I="button",...f}){return Vj2("button",{type:I,className:s1(qd0({variant:A,size:Q}),B),...f,...$&&{onclick:$},children:w},void 0,!1,void 0,this)}import{jsxDEV as Oj2}from"preact/jsx-dev-runtime";var Cd0=Kw("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 V5({href:A,children:Q,variant:B,size:w,external:$=!1,className:I,"aria-label":f}){let D=$?{target:"_blank",rel:"noopener noreferrer"}:{};return Oj2("a",{href:A,className:s1(Cd0({variant:B,size:w}),I),"aria-label":f,...D,children:Q},void 0,!1,void 0,this)}import{jsxDEV as VAA}from"preact/jsx-dev-runtime";var Ed0=Kw("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"}}),bj2={sm:"w-4 h-4",md:"w-5 h-5",lg:"w-6 h-6"};function $R({variant:A,size:Q,className:B}){let w=bj2[Q??"md"];return VAA("button",{onclick:"toggleTheme()",type:"button",className:s1(Ed0({variant:A,size:Q}),B),"aria-label":"Toggle dark mode",children:VAA("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:[VAA("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),VAA("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 tLA}from"preact/jsx-dev-runtime";var Ld0=Kw("flex flex-wrap",{variants:{orientation:{horizontal:"justify-center gap-6 items-center",vertical:"flex-col gap-2.5"}},defaultVariants:{orientation:"horizontal"}});function OAA({items:A,className:Q,linkClassName:B="hover:text-accent transition-colors",orientation:w,children:$}){if(A.length===0&&!$)return null;let I=[...A].sort((f,D)=>f.priority-D.priority);return tLA("ul",{className:s1(Ld0({orientation:w}),Q),children:[I.map((f)=>tLA("li",{children:tLA("a",{href:f.href,className:B,children:f.label},void 0,!1,void 0,this)},f.href,!1,void 0,this)),$]},void 0,!0,void 0,this)}import{jsxDEV as RpB}from"preact/jsx-dev-runtime";import{jsxDEV as kpB}from"preact/jsx-dev-runtime";JA();JA();import{createContext as Rj2,h as _j2}from"preact";import{useContext as Pj2}from"preact/hooks";var Md0=Rj2(null);function bAA({imageRenderer:A,children:Q}){return _j2(Md0.Provider,{value:A??null},Q)}function Vd0(){return Pj2(Md0)}function uq(){let A=Vd0();return(Q)=>zp(Q,A?{imageRenderer:A}:void 0)}import{jsxDEV as _J}from"preact/jsx-dev-runtime";var eLA=({markdown:A})=>{let Q=uq(),w=A.split(/^---$/gm).map((f)=>f.trim()).map((f)=>{let{attributes:D,markdown:Y}=mp(f),H=up(Y),W;if(H)W=`<div class="slide-columns">${H.map((K)=>`<div class="slide-column">${Vk(Q(K.trim()))}</div>`).join("")}</div>`;else W=Vk(Q(Y));return{attributes:D,htmlContent:W}}),$=w.some((f)=>f.htmlContent.includes('class="mermaid"')),I=w.map(({attributes:f,htmlContent:D},Y)=>_J("section",{...f,dangerouslySetInnerHTML:{__html:D}},Y,!1,void 0,this));return _J("section",{className:"presentation-section",children:[_J("link",{rel:"stylesheet",href:"https://cdn.jsdelivr.net/npm/reveal.js@5.1.0/dist/reveal.min.css"},void 0,!1,void 0,this),_J("div",{className:"reveal",children:_J("div",{className:"slides",children:I},void 0,!1,void 0,this)},void 0,!1,void 0,this),_J("script",{src:"https://cdn.jsdelivr.net/npm/reveal.js@5.1.0/dist/reveal.min.js",defer:!0},void 0,!1,void 0,this),$&&_J("script",{src:"https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js",defer:!0},void 0,!1,void 0,this),_J("script",{dangerouslySetInnerHTML:{__html:`
|
|
2420
2420
|
window.addEventListener('DOMContentLoaded', () => {
|
|
2421
2421
|
if (window.Reveal) {
|
|
2422
2422
|
window.Reveal.initialize({
|
|
@@ -3257,13 +3257,13 @@ ${A.map((I)=>({url:`${Q}${I.path}`,lastmod:B,changefreq:I.path==="/"?"daily":"we
|
|
|
3257
3257
|
`+$:B,f=wW(this.outputDir,"styles","main.css");await this.cssProcessor.process(I,f,this.workingDir,this.outputDir,this.logger);let D=await g9.readFile(f,"utf-8"),Y=w.length>0?w:Q;if(Y.length>0){let H=Y.join(`
|
|
3258
3258
|
`)+`
|
|
3259
3259
|
|
|
3260
|
-
`+D;await g9.writeFile(f,H,"utf-8")}this.logger.debug("CSS processed successfully with font imports")}async copyStaticAssets(){this.logger.debug("Copying static assets from public/ directory");let A=wW(process.cwd(),"public");try{await g9.access(A)}catch{this.logger.debug("No public/ directory found, skipping static assets");return}let Q=await g9.readdir(A,{withFileTypes:!0});for(let B of Q){let w=wW(A,B.name),$=wW(this.outputDir,B.name);if(B.isDirectory())await this.copyDirectory(w,$);else await g9.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,I=wW(this.outputDir,$);await g9.mkdir(qs2(I),{recursive:!0}),await g9.writeFile(I,w,"utf-8"),this.logger.debug(`Wrote inline static asset: ${$}`)}))}async copyDirectory(A,Q){await g9.mkdir(Q,{recursive:!0});let B=await g9.readdir(A,{withFileTypes:!0});for(let w of B){let $=wW(A,w.name),I=wW(Q,w.name);if(w.isDirectory())await this.copyDirectory($,I);else await g9.copyFile($,I)}}}function WbA(A){return new AB1(A)}JA();JA();JA();s7();var QB1=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:Hf,layouts:F.record(F.any()),themeCSS:F.string().optional()}),WAw=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 BB1(A){let Q=A.list(),B=Q.length===0?["No routes registered for site build"]:[];return{routes:Q,warnings:B}}function wB1(A,Q,B){let w=Q.getProfile(),$=B.getNavigationItems("primary"),I=B.getNavigationItems("secondary");return{...A,...w.socialLinks!==void 0&&{socialLinks:w.socialLinks},navigation:{primary:$,secondary:I},copyright:A.copyright??"Powered by Rizom"}}JA();JA();var Cs2=F.object({id:F.string(),entityType:F.string(),content:F.string(),metadata:F.object({slug:F.string()}).passthrough()}).passthrough(),Es2=F.object({content:F.string(),metadata:F.object({width:F.number().optional(),height:F.number().optional()}).passthrough()});async function u1A(A,Q){let B=Q.urlGenerator??z9.getInstance();if(A===null||A===void 0)return A;if(Array.isArray(A))return Promise.all(A.map((P)=>u1A(P,{...Q,urlGenerator:B})));if(typeof A!=="object")return A;let w={},$=Object.entries(A),I=await Promise.all($.map(([,P])=>u1A(P,{...Q,urlGenerator:B})));for(let P=0;P<$.length;P++){let o=$[P];if(o)w[o[0]]=I[P]}let f=Cs2.safeParse(A);if(!f.success)return w;let D=f.data,Y=D.entityType,H=D.metadata.slug,W=Q.pipelineContext.entityDisplay?.[Y],G=W?W.label:Y.charAt(0).toUpperCase()+Y.slice(1),K=W?W.pluralName??W.label.toLowerCase()+"s":dI(Y),Z=`/${K}`,q=K.charAt(0).toUpperCase()+K.slice(1),L=Wk(D)??void 0,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 P=await Ls2(L,Q.pipelineContext.services.entityService);if(P)R={coverImageUrl:P.url,...P.width&&{coverImageWidth:P.width},...P.height&&{coverImageHeight:P.height}}}return{...w,...D,url:B.generateUrl(Y,H),typeLabel:G,listUrl:Z,listLabel:q,...R}}async function Ls2(A,Q){if(!A)return;let B=await Q.getEntity({entityType:"image",id:A}),w=Es2.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 $B1(A,Q){let B=new Set;try{let w=A.getEntityTypes();for(let $ of w){if($==="image")continue;let I=await A.listEntities({entityType:$});for(let f of I){let D=Wk(f);if(D)B.add(D)}}}catch(w){Q.warn("Failed to collect image IDs for pre-resolution",{error:h0(w)})}return[...B]}async function IB1(A,Q,B,w){if(!A.template)return A.content??null;let $=A.template,I=A.dataQuery?{dataParams:A.dataQuery,fallback:A.content,publishedOnly:B}:{savedContent:{entityType:"site-content",entityId:`${Q.id}:${A.id}`},fallback:A.content},f=await w.pipelineContext.services.resolveTemplateContent($,I);if(!f)return null;return u1A(f,{pipelineContext:w.pipelineContext,imageBuildService:w.imageBuildService,urlGenerator:z9.getInstance()})}function fB1(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 IB1(B,Q,w,{pipelineContext:A.pipelineContext,imageBuildService:A.imageBuildService})},getViewTemplate:(Q)=>{return A.pipelineContext.services.getViewTemplate(Q)},layouts:A.parsedOptions.layouts,getSiteLayoutInfo:async()=>{return wB1(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 Ms2}from"path";async function DB1(A){let Q=A.parsedOptions.workingDir??Ms2(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 YB1(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 HB1(A){let Q=new T1A(A.pipelineContext.services.entityService,A.pipelineContext.logger,A.sharedImagesDir),B=await $B1(A.pipelineContext.services.entityService,A.pipelineContext.logger);if(B.length>0)await Q.resolveAll(B);return Q}async function XB1(A){let Q=A.reporter?.createSub({scale:{start:85,end:95}});await A.staticSiteBuilder.build(A.buildContext,(B)=>{Q?.report(B).catch(()=>{})})}function WB1(A){return{success:!0,outputDir:A.outputDir,filesGenerated:A.routesBuilt+1,routesBuilt:A.routesBuilt,...A.warnings.length>0&&{warnings:A.warnings}}}function UB1(A){return{success:!1,outputDir:A.outputDir,filesGenerated:0,routesBuilt:0,errors:[A.errorMessage]}}async function JB1(A){let Q=QB1.parse(A.buildOptions),B=G6.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 YB1({pipelineContext:A.pipelineContext});let $=await DB1({logger:A.pipelineContext.logger,parsedOptions:Q,staticSiteBuilderFactory:A.staticSiteBuilderFactory}),I=BB1(A.pipelineContext.routeRegistry);w.push(...I.warnings);let{routes:f}=I;await B?.report({message:`Building ${f.length} routes`,progress:20,total:100}),await B?.report({message:"Resolving images",progress:25,total:100});let D=await HB1({pipelineContext:A.pipelineContext,sharedImagesDir:Q.sharedImagesDir}),Y=fB1({routes:f,parsedOptions:Q,buildOptions:A.buildOptions,pipelineContext:A.pipelineContext,imageBuildService:D,siteMetadata:Q.siteConfig});return await XB1({staticSiteBuilder:$,buildContext:Y,reporter:B}),await B?.report({message:"Site build complete",progress:100,total:100}),WB1({outputDir:Q.outputDir,routesBuilt:f.length,warnings:w})}catch($){let I=Error("Site build process failed");return A.pipelineContext.logger.error("Site build failed",{error:I,originalError:$}),UB1({outputDir:Q.outputDir,errorMessage:I.message})}}class hf{static instance=null;static defaultStaticSiteBuilderFactory=WbA;pipelineContext;staticSiteBuilderFactory;static setDefaultStaticSiteBuilderFactory(A){hf.defaultStaticSiteBuilderFactory=A}static getInstance(A,Q,B,w,$=void 0){return hf.instance??=new hf(A,hf.defaultStaticSiteBuilderFactory,Q,B,w,$),hf.instance}static resetInstance(){hf.instance=null}static createFresh(A,Q,B,w,$,I=void 0){return new hf(A,$??hf.defaultStaticSiteBuilderFactory,Q,B,w,I)}constructor(A,Q,B,w,$,I){this.pipelineContext={logger:A,services:B,routeRegistry:w,profileService:$,entityDisplay:I},this.staticSiteBuilderFactory=Q,z9.getInstance().configure(I)}async build(A,Q){return JB1({buildOptions:A,progress:Q,pipelineContext:this.pipelineContext,staticSiteBuilderFactory:this.staticSiteBuilderFactory})}}JA();class UbA{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 wz(()=>{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})}}}s7();function Vs2(A,Q){return A.map((B)=>({...B,template:B.template.includes(":")?B.template:`${Q}:${B.template}`}))}function c1A(A,Q,B){for(let w of A)B.register({...w,pluginId:Q,sections:w.sections?Vs2(w.sections,Q):[]})}function GB1(A,Q,B){A.messaging.subscribe("plugin:site-builder:route:register",async(w)=>{try{let $=iWA.parse(w.payload),{routes:I,pluginId:f}=$;return c1A(I,f,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 $=rWA.parse(w.payload),{paths:I,pluginId:f}=$;if(I)for(let D of I)Q.unregister(D);else if(f)Q.unregisterByPlugin(f);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 $=dWA.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 $=nWA.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 FB1}from"fs";import{join as KB1}from"path";async function Os2(A,Q,B){let w=A.siteConfig.url??"https://example.com",$=Q.list(),I=HbA(w,A.environment);await FB1.writeFile(KB1(A.outputDir,"robots.txt"),I,"utf-8"),B.info(`Generated robots.txt for ${A.environment} environment`);let f=XbA($,w);await FB1.writeFile(KB1(A.outputDir,"sitemap.xml"),f,"utf-8"),B.info(`Generated sitemap.xml with ${$.length} URLs`)}function ZB1(A){let{context:Q,routeRegistry:B,logger:w}=A;Q.messaging.subscribe("site:build:completed",async($)=>{try{let I=$.payload;return w.info(`Received site:build:completed event for ${I.environment} environment - generating SEO files`),await Os2(I,B,w),{success:!0}}catch(I){return w.error("Failed to generate SEO files",I),{success:!1}}})}I0();JA();s7();var zB1=F.object({environment:F.enum(["preview","production"]).optional(),outputDir:F.string(),workingDir:F.string().optional(),enableContentGeneration:F.boolean().optional(),siteConfig:Hf.optional()});JA();s7();async function oS(A,Q){try{let B=await A({type:qv,payload:void 0});if("success"in B&&B.success&&B.data){let w=Hf.safeParse(B.data);if(w.success)return Hf.parse({...Q,...w.data})}}catch{}return Q}class JbA extends tB{sendMessage;cfg;constructor(A,Q,B){super(A,{schema:zB1,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 I=B.createSub({scale:{start:10,end:90}}),f=await oS(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:f,layouts:this.cfg.layouts,themeCSS:this.cfg.themeCSS,slots:this.cfg.slots,headScripts:this.cfg.getHeadScripts?.(),...this.cfg.staticAssets&&{staticAssets:this.cfg.staticAssets}},I.toCallback());if(await B.report({progress:100,total:100,message:`Site build completed: ${D.routesBuilt} routes built`}),this.logger.debug("Site build job completed",{jobId:Q,environment:w,routesBuilt:D.routesBuilt,success:D.success}),D.success){this.logger.info(`Emitting site:build:completed event for ${w} environment`);let Y=w==="preview"?this.cfg.previewUrl??this.cfg.siteUrl:this.cfg.siteUrl;await this.sendMessage({type:"site:build:completed",payload:{outputDir:A.outputDir,environment:w,routesBuilt:D.routesBuilt,siteConfig:{...f,url:Y},generateEntityUrl:(H,W)=>z9.getInstance().generateUrl(H,W)},broadcast:!0})}return{success:D.success,routesBuilt:D.routesBuilt,outputDir:A.outputDir,environment:w,...D.errors&&{errors:D.errors},...D.warnings&&{warnings:D.warnings}}}catch(I){throw this.logger.error("Site build job failed",I),I}}summarizeDataForLog(A){return{environment:A.environment,outputDir:A.outputDir}}}JA();s7();var bs2=F.object({slot:F.enum(JV).optional().default("primary"),limit:F.number().optional()});class GbA{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=bs2.parse(A??{});this.logger.debug("NavigationDataSource fetch called",{params:w});let $=this.routeRegistry.getNavigationItems(w.slot),I=w.limit?$.slice(0,w.limit):$,f=I.map((Y)=>({label:Y.label,href:Y.href}));this.logger.debug("NavigationDataSource returning",{slot:w.slot,itemCount:I.length,items:f});let D={navigation:f};return Q.parse(D)}}s7();I0();JA();var Rs2=F.object({environment:F.enum(["preview","production"]).optional().describe("Build environment (defaults to production, or preview if configured)")});function NB1(A,Q){return[jQ(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'.",Rs2,async(B)=>{return Q(B.environment),{success:!0,message:`Site build requested${B.environment?` for ${B.environment}`:""} (debounced)`,data:{}}},{cli:{name:"build"}})]}JA();s7();var qB1=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:Hf.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(GV).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(JV).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 CB1={name:"@brains/site-builder-plugin",private:!0,version:"0.2.0-alpha.60",description:"Static site generation plugin for Brain system",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint .",clean:"rm -rf dist"},dependencies:{"@brains/plugins":"workspace:*","@brains/site-composition":"workspace:*","@brains/site-engine":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*","@tailwindcss/typography":"^0.5.19",preact:"^10.27.2","preact-render-to-string":"^6.3.1"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14",eslint:"^8.56.0",typescript:"^5.3.3"}};class FbA 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",CB1,{...A,layouts:Q},qB1);this.layouts=Q}async onRegister(A){if(this.pluginContext=A,this._routeRegistry=new m1A(A.logger),this._slotRegistry=new z1A,A.messaging.subscribe("plugin:site-builder:slot:register",async(B)=>{let{slotName:w,pluginId:$,render:I,priority:f}=B.payload;return this._slotRegistry?.register(w,{pluginId:$,render:I,...f!==void 0&&{priority:f}}),{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 GbA(this._routeRegistry,A.logger.child("NavigationDataSource"))),this.profileService=a$.getInstance(A.entityService,A.logger),GB1(A,this._routeRegistry,this.logger),this.config.templates)A.templates.register(this.config.templates);if(this.config.routes)c1A(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=hf.getInstance(A.logger.child("SiteBuilder"),Q,this.routeRegistry,this.profileService,this.config.entityDisplay),A.jobs.registerHandler("site-build",new JbA(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 UbA(this.config,A,this.id,this.logger),this.config.autoRebuild)this.logger.debug("Auto-rebuild enabled"),this.rebuildManager.setupAutoRebuild();A.messaging.subscribe(Cv,async()=>{let B=await this.getInstructions();if(B)A.registerInstructions(B);return{success:!0}}),ZB1({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 NB1(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 oS(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 oS(A.messaging.send,this.config.siteInfo);return`## Your Site
|
|
3260
|
+
`+D;await g9.writeFile(f,H,"utf-8")}this.logger.debug("CSS processed successfully with font imports")}async copyStaticAssets(){this.logger.debug("Copying static assets from public/ directory");let A=wW(process.cwd(),"public");try{await g9.access(A)}catch{this.logger.debug("No public/ directory found, skipping static assets");return}let Q=await g9.readdir(A,{withFileTypes:!0});for(let B of Q){let w=wW(A,B.name),$=wW(this.outputDir,B.name);if(B.isDirectory())await this.copyDirectory(w,$);else await g9.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,I=wW(this.outputDir,$);await g9.mkdir(qs2(I),{recursive:!0}),await g9.writeFile(I,w,"utf-8"),this.logger.debug(`Wrote inline static asset: ${$}`)}))}async copyDirectory(A,Q){await g9.mkdir(Q,{recursive:!0});let B=await g9.readdir(A,{withFileTypes:!0});for(let w of B){let $=wW(A,w.name),I=wW(Q,w.name);if(w.isDirectory())await this.copyDirectory($,I);else await g9.copyFile($,I)}}}function WbA(A){return new AB1(A)}JA();JA();JA();s7();var QB1=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:Hf,layouts:F.record(F.any()),themeCSS:F.string().optional()}),WAw=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 BB1(A){let Q=A.list(),B=Q.length===0?["No routes registered for site build"]:[];return{routes:Q,warnings:B}}function wB1(A,Q,B){let w=Q.getProfile(),$=B.getNavigationItems("primary"),I=B.getNavigationItems("secondary");return{...A,...w.socialLinks!==void 0&&{socialLinks:w.socialLinks},navigation:{primary:$,secondary:I},copyright:A.copyright??"Powered by Rizom"}}JA();JA();var Cs2=F.object({id:F.string(),entityType:F.string(),content:F.string(),metadata:F.object({slug:F.string()}).passthrough()}).passthrough(),Es2=F.object({content:F.string(),metadata:F.object({width:F.number().optional(),height:F.number().optional()}).passthrough()});async function u1A(A,Q){let B=Q.urlGenerator??z9.getInstance();if(A===null||A===void 0)return A;if(Array.isArray(A))return Promise.all(A.map((P)=>u1A(P,{...Q,urlGenerator:B})));if(typeof A!=="object")return A;let w={},$=Object.entries(A),I=await Promise.all($.map(([,P])=>u1A(P,{...Q,urlGenerator:B})));for(let P=0;P<$.length;P++){let o=$[P];if(o)w[o[0]]=I[P]}let f=Cs2.safeParse(A);if(!f.success)return w;let D=f.data,Y=D.entityType,H=D.metadata.slug,W=Q.pipelineContext.entityDisplay?.[Y],G=W?W.label:Y.charAt(0).toUpperCase()+Y.slice(1),K=W?W.pluralName??W.label.toLowerCase()+"s":dI(Y),Z=`/${K}`,q=K.charAt(0).toUpperCase()+K.slice(1),L=Wk(D)??void 0,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 P=await Ls2(L,Q.pipelineContext.services.entityService);if(P)R={coverImageUrl:P.url,...P.width&&{coverImageWidth:P.width},...P.height&&{coverImageHeight:P.height}}}return{...w,...D,url:B.generateUrl(Y,H),typeLabel:G,listUrl:Z,listLabel:q,...R}}async function Ls2(A,Q){if(!A)return;let B=await Q.getEntity({entityType:"image",id:A}),w=Es2.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 $B1(A,Q){let B=new Set;try{let w=A.getEntityTypes();for(let $ of w){if($==="image")continue;let I=await A.listEntities({entityType:$});for(let f of I){let D=Wk(f);if(D)B.add(D)}}}catch(w){Q.warn("Failed to collect image IDs for pre-resolution",{error:h0(w)})}return[...B]}async function IB1(A,Q,B,w){if(!A.template)return A.content??null;let $=A.template,I=A.dataQuery?{dataParams:A.dataQuery,fallback:A.content,publishedOnly:B}:{savedContent:{entityType:"site-content",entityId:`${Q.id}:${A.id}`},fallback:A.content},f=await w.pipelineContext.services.resolveTemplateContent($,I);if(!f)return null;return u1A(f,{pipelineContext:w.pipelineContext,imageBuildService:w.imageBuildService,urlGenerator:z9.getInstance()})}function fB1(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 IB1(B,Q,w,{pipelineContext:A.pipelineContext,imageBuildService:A.imageBuildService})},getViewTemplate:(Q)=>{return A.pipelineContext.services.getViewTemplate(Q)},layouts:A.parsedOptions.layouts,getSiteLayoutInfo:async()=>{return wB1(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 Ms2}from"path";async function DB1(A){let Q=A.parsedOptions.workingDir??Ms2(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 YB1(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 HB1(A){let Q=new T1A(A.pipelineContext.services.entityService,A.pipelineContext.logger,A.sharedImagesDir),B=await $B1(A.pipelineContext.services.entityService,A.pipelineContext.logger);if(B.length>0)await Q.resolveAll(B);return Q}async function XB1(A){let Q=A.reporter?.createSub({scale:{start:85,end:95}});await A.staticSiteBuilder.build(A.buildContext,(B)=>{Q?.report(B).catch(()=>{})})}function WB1(A){return{success:!0,outputDir:A.outputDir,filesGenerated:A.routesBuilt+1,routesBuilt:A.routesBuilt,...A.warnings.length>0&&{warnings:A.warnings}}}function UB1(A){return{success:!1,outputDir:A.outputDir,filesGenerated:0,routesBuilt:0,errors:[A.errorMessage]}}async function JB1(A){let Q=QB1.parse(A.buildOptions),B=G6.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 YB1({pipelineContext:A.pipelineContext});let $=await DB1({logger:A.pipelineContext.logger,parsedOptions:Q,staticSiteBuilderFactory:A.staticSiteBuilderFactory}),I=BB1(A.pipelineContext.routeRegistry);w.push(...I.warnings);let{routes:f}=I;await B?.report({message:`Building ${f.length} routes`,progress:20,total:100}),await B?.report({message:"Resolving images",progress:25,total:100});let D=await HB1({pipelineContext:A.pipelineContext,sharedImagesDir:Q.sharedImagesDir}),Y=fB1({routes:f,parsedOptions:Q,buildOptions:A.buildOptions,pipelineContext:A.pipelineContext,imageBuildService:D,siteMetadata:Q.siteConfig});return await XB1({staticSiteBuilder:$,buildContext:Y,reporter:B}),await B?.report({message:"Site build complete",progress:100,total:100}),WB1({outputDir:Q.outputDir,routesBuilt:f.length,warnings:w})}catch($){let I=Error("Site build process failed");return A.pipelineContext.logger.error("Site build failed",{error:I,originalError:$}),UB1({outputDir:Q.outputDir,errorMessage:I.message})}}class hf{static instance=null;static defaultStaticSiteBuilderFactory=WbA;pipelineContext;staticSiteBuilderFactory;static setDefaultStaticSiteBuilderFactory(A){hf.defaultStaticSiteBuilderFactory=A}static getInstance(A,Q,B,w,$=void 0){return hf.instance??=new hf(A,hf.defaultStaticSiteBuilderFactory,Q,B,w,$),hf.instance}static resetInstance(){hf.instance=null}static createFresh(A,Q,B,w,$,I=void 0){return new hf(A,$??hf.defaultStaticSiteBuilderFactory,Q,B,w,I)}constructor(A,Q,B,w,$,I){this.pipelineContext={logger:A,services:B,routeRegistry:w,profileService:$,entityDisplay:I},this.staticSiteBuilderFactory=Q,z9.getInstance().configure(I)}async build(A,Q){return JB1({buildOptions:A,progress:Q,pipelineContext:this.pipelineContext,staticSiteBuilderFactory:this.staticSiteBuilderFactory})}}JA();class UbA{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 wz(()=>{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})}}}s7();function Vs2(A,Q){return A.map((B)=>({...B,template:B.template.includes(":")?B.template:`${Q}:${B.template}`}))}function c1A(A,Q,B){for(let w of A)B.register({...w,pluginId:Q,sections:w.sections?Vs2(w.sections,Q):[]})}function GB1(A,Q,B){A.messaging.subscribe("plugin:site-builder:route:register",async(w)=>{try{let $=iWA.parse(w.payload),{routes:I,pluginId:f}=$;return c1A(I,f,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 $=rWA.parse(w.payload),{paths:I,pluginId:f}=$;if(I)for(let D of I)Q.unregister(D);else if(f)Q.unregisterByPlugin(f);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 $=dWA.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 $=nWA.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 FB1}from"fs";import{join as KB1}from"path";async function Os2(A,Q,B){let w=A.siteConfig.url??"https://example.com",$=Q.list(),I=HbA(w,A.environment);await FB1.writeFile(KB1(A.outputDir,"robots.txt"),I,"utf-8"),B.info(`Generated robots.txt for ${A.environment} environment`);let f=XbA($,w);await FB1.writeFile(KB1(A.outputDir,"sitemap.xml"),f,"utf-8"),B.info(`Generated sitemap.xml with ${$.length} URLs`)}function ZB1(A){let{context:Q,routeRegistry:B,logger:w}=A;Q.messaging.subscribe("site:build:completed",async($)=>{try{let I=$.payload;return w.info(`Received site:build:completed event for ${I.environment} environment - generating SEO files`),await Os2(I,B,w),{success:!0}}catch(I){return w.error("Failed to generate SEO files",I),{success:!1}}})}I0();JA();s7();var zB1=F.object({environment:F.enum(["preview","production"]).optional(),outputDir:F.string(),workingDir:F.string().optional(),enableContentGeneration:F.boolean().optional(),siteConfig:Hf.optional()});JA();s7();async function oS(A,Q){try{let B=await A({type:qv,payload:void 0});if("success"in B&&B.success&&B.data){let w=Hf.safeParse(B.data);if(w.success)return Hf.parse({...Q,...w.data})}}catch{}return Q}class JbA extends tB{sendMessage;cfg;constructor(A,Q,B){super(A,{schema:zB1,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 I=B.createSub({scale:{start:10,end:90}}),f=await oS(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:f,layouts:this.cfg.layouts,themeCSS:this.cfg.themeCSS,slots:this.cfg.slots,headScripts:this.cfg.getHeadScripts?.(),...this.cfg.staticAssets&&{staticAssets:this.cfg.staticAssets}},I.toCallback());if(await B.report({progress:100,total:100,message:`Site build completed: ${D.routesBuilt} routes built`}),this.logger.debug("Site build job completed",{jobId:Q,environment:w,routesBuilt:D.routesBuilt,success:D.success}),D.success){this.logger.info(`Emitting site:build:completed event for ${w} environment`);let Y=w==="preview"?this.cfg.previewUrl??this.cfg.siteUrl:this.cfg.siteUrl;await this.sendMessage({type:"site:build:completed",payload:{outputDir:A.outputDir,environment:w,routesBuilt:D.routesBuilt,siteConfig:{...f,url:Y},generateEntityUrl:(H,W)=>z9.getInstance().generateUrl(H,W)},broadcast:!0})}return{success:D.success,routesBuilt:D.routesBuilt,outputDir:A.outputDir,environment:w,...D.errors&&{errors:D.errors},...D.warnings&&{warnings:D.warnings}}}catch(I){throw this.logger.error("Site build job failed",I),I}}summarizeDataForLog(A){return{environment:A.environment,outputDir:A.outputDir}}}JA();s7();var bs2=F.object({slot:F.enum(JV).optional().default("primary"),limit:F.number().optional()});class GbA{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=bs2.parse(A??{});this.logger.debug("NavigationDataSource fetch called",{params:w});let $=this.routeRegistry.getNavigationItems(w.slot),I=w.limit?$.slice(0,w.limit):$,f=I.map((Y)=>({label:Y.label,href:Y.href}));this.logger.debug("NavigationDataSource returning",{slot:w.slot,itemCount:I.length,items:f});let D={navigation:f};return Q.parse(D)}}s7();I0();JA();var Rs2=F.object({environment:F.enum(["preview","production"]).optional().describe("Build environment (defaults to production, or preview if configured)")});function NB1(A,Q){return[jQ(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'.",Rs2,async(B)=>{return Q(B.environment),{success:!0,message:`Site build requested${B.environment?` for ${B.environment}`:""} (debounced)`,data:{}}},{cli:{name:"build"}})]}JA();s7();var qB1=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:Hf.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(GV).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(JV).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 CB1={name:"@brains/site-builder-plugin",private:!0,version:"0.2.0-alpha.61",description:"Static site generation plugin for Brain system",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint .",clean:"rm -rf dist"},dependencies:{"@brains/plugins":"workspace:*","@brains/site-composition":"workspace:*","@brains/site-engine":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*","@tailwindcss/typography":"^0.5.19",preact:"^10.27.2","preact-render-to-string":"^6.3.1"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14",eslint:"^8.56.0",typescript:"^5.3.3"}};class FbA 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",CB1,{...A,layouts:Q},qB1);this.layouts=Q}async onRegister(A){if(this.pluginContext=A,this._routeRegistry=new m1A(A.logger),this._slotRegistry=new z1A,A.messaging.subscribe("plugin:site-builder:slot:register",async(B)=>{let{slotName:w,pluginId:$,render:I,priority:f}=B.payload;return this._slotRegistry?.register(w,{pluginId:$,render:I,...f!==void 0&&{priority:f}}),{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 GbA(this._routeRegistry,A.logger.child("NavigationDataSource"))),this.profileService=a$.getInstance(A.entityService,A.logger),GB1(A,this._routeRegistry,this.logger),this.config.templates)A.templates.register(this.config.templates);if(this.config.routes)c1A(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=hf.getInstance(A.logger.child("SiteBuilder"),Q,this.routeRegistry,this.profileService,this.config.entityDisplay),A.jobs.registerHandler("site-build",new JbA(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 UbA(this.config,A,this.id,this.logger),this.config.autoRebuild)this.logger.debug("Auto-rebuild enabled"),this.rebuildManager.setupAutoRebuild();A.messaging.subscribe(Cv,async()=>{let B=await this.getInstructions();if(B)A.registerInstructions(B);return{success:!0}}),ZB1({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 NB1(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 oS(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 oS(A.messaging.send,this.config.siteInfo);return`## Your Site
|
|
3261
3261
|
${[`**Title:** ${B.title}`,`**Description:** ${B.description}`,A.domain&&`**Domain:** ${A.domain}`,A.siteUrl&&`**URL:** ${A.siteUrl}`].filter(Boolean).join(`
|
|
3262
3262
|
`)}
|
|
3263
3263
|
|
|
3264
3264
|
## Site Builder Actions
|
|
3265
3265
|
- When the user asks to build, rebuild, publish, or build the website/site again, call \`site-builder_build-site\` immediately.
|
|
3266
|
-
- 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(),hf.resetInstance(),this.logger.debug("Cleaned up all event subscriptions")}}function zC(A={}){return new FbA(A)}I0();s7();JA();I0();s7();var EB1=F.object({}),sS=I2.extend({id:F.literal("site-info"),entityType:F.literal("site-info"),metadata:EB1}),KbA=Dn,mR=Hf.omit({url:!0,analyticsScript:!0});I0();class $W extends W2{constructor(){super({entityType:"site-info",schema:sS,frontmatterSchema:mR,isSingleton:!0,hasBody:!1})}createSiteInfoContent(A){let Q=mR.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 IW{static instance=null;logger;entityService;adapter;defaultSiteInfo;static getDefaultSiteInfo(){return{title:"Brain",description:"A knowledge management system"}}static getInstance(A,Q,B){return IW.instance??=new IW(A,Q,B),IW.instance}static resetInstance(){IW.instance=null}static createFresh(A,Q,B){return new IW(A,Q,B)}constructor(A,Q,B){this.entityService=A,this.logger=Q.child("SiteInfoService"),this.adapter=new $W;let w=IW.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 Ps2=new $W;class p1A{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?Ps2.parseSiteInfoBody(D.content):{title:"Brain",description:"A knowledge management system"}}catch{$={title:"Brain",description:"A knowledge management system"}}let I;try{let D=await w.getEntity({entityType:"anchor-profile",id:"anchor-profile"});if(D)I=D.metadata.socialLinks}catch{}let f={...$,socialLinks:I,copyright:$.copyright??"Powered by Rizom"};return this.logger.debug("SiteInfoDataSource returning",{title:f.title,hasSocialLinks:!!f.socialLinks}),Q.parse(f)}}var LB1={name:"@brains/site-info",private:!0,version:"0.2.0-alpha.
|
|
3266
|
+
- 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(),hf.resetInstance(),this.logger.debug("Cleaned up all event subscriptions")}}function zC(A={}){return new FbA(A)}I0();s7();JA();I0();s7();var EB1=F.object({}),sS=I2.extend({id:F.literal("site-info"),entityType:F.literal("site-info"),metadata:EB1}),KbA=Dn,mR=Hf.omit({url:!0,analyticsScript:!0});I0();class $W extends W2{constructor(){super({entityType:"site-info",schema:sS,frontmatterSchema:mR,isSingleton:!0,hasBody:!1})}createSiteInfoContent(A){let Q=mR.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 IW{static instance=null;logger;entityService;adapter;defaultSiteInfo;static getDefaultSiteInfo(){return{title:"Brain",description:"A knowledge management system"}}static getInstance(A,Q,B){return IW.instance??=new IW(A,Q,B),IW.instance}static resetInstance(){IW.instance=null}static createFresh(A,Q,B){return new IW(A,Q,B)}constructor(A,Q,B){this.entityService=A,this.logger=Q.child("SiteInfoService"),this.adapter=new $W;let w=IW.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 Ps2=new $W;class p1A{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?Ps2.parseSiteInfoBody(D.content):{title:"Brain",description:"A knowledge management system"}}catch{$={title:"Brain",description:"A knowledge management system"}}let I;try{let D=await w.getEntity({entityType:"anchor-profile",id:"anchor-profile"});if(D)I=D.metadata.socialLinks}catch{}let f={...$,socialLinks:I,copyright:$.copyright??"Powered by Rizom"};return this.logger.debug("SiteInfoDataSource returning",{title:f.title,hasSocialLinks:!!f.socialLinks}),Q.parse(f)}}var LB1={name:"@brains/site-info",private:!0,version:"0.2.0-alpha.61",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 js2=new $W;class ZbA extends FQ{entityType="site-info";schema=sS;adapter=js2;defaultSiteInfo;constructor(A){super("site-info",LB1);this.defaultSiteInfo=A?.siteInfo??{}}getEntityTypeConfig(){return{embeddable:!1}}getDataSources(){return[new p1A(this.logger.child("SiteInfoDataSource"))]}async onRegister(A){let Q=IW.createFresh(A.entityService,this.logger,this.defaultSiteInfo);A.messaging.subscribe(qv,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:Cv,payload:$,broadcast:!0})}return{success:!0}}),A.messaging.subscribe("sync:initial:completed",async()=>{return await Q.initialize(),{success:!0}})}}function NC(A){return new ZbA(A)}var xs2=new $W;async function zbA(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 xs2.parseSiteInfoBody(B.content)}JA();var vs2=mR.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")});I0();fW();eS();JA();var NbA=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)});I0();JA();var gs2=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()}),P1w=u7.extend({title:F.string().optional(),slug:F.string().optional()});class qbA extends w${constructor(A,Q){super(A,Q,{schema:gs2,jobTypeName:"blog-generation",entityType:"post"})}async generate(A,Q){let{prompt:B,coverImageId:w,seriesName:$,seriesIndex:I,skipAi:f}=A,{title:D,content:Y,excerpt:H}=A;if(f){if(!D)this.failEarly("Title is required when skipAi is true");Y=Y??`## Introduction
|
|
3267
3267
|
|
|
3268
3268
|
Add your introduction here.
|
|
3269
3269
|
|
|
@@ -3308,7 +3308,7 @@ The excerpt should be clear, concise, and compelling.`});JA();R8();fW();import{j
|
|
|
3308
3308
|
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=ts2.parse(Q);return A.ai.generate({prompt:`Title: ${B.title}
|
|
3309
3309
|
|
|
3310
3310
|
Content:
|
|
3311
|
-
${B.content}`,templateName:"blog:excerpt"})})}var TB1={name:"@brains/blog",private:!0,version:"0.2.0-alpha.
|
|
3311
|
+
${B.content}`,templateName:"blog:excerpt"})})}var TB1={name:"@brains/blog",private:!0,version:"0.2.0-alpha.61",description:"AI-powered blog post generation from existing brain content",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class MbA extends FQ{entityType=qC.entityType;schema=uR;adapter=qC;constructor(A={}){super("blog",TB1,A,NbA)}getEntityTypeConfig(){return{weight:2}}createGenerationHandler(A){return new qbA(this.logger.child("BlogGenerationJobHandler"),A)}getTemplates(){return jB1()}getDataSources(){return[new EbA(this.logger.child("BlogDataSource"))]}async onRegister(A){let{RSSDataSource:Q}=await Promise.resolve().then(() => (uB1(),mB1));A.entities.registerDataSource(new Q(this.logger.child("RSSDataSource"))),await xB1(A,this.logger),vB1(A,this.logger),yB1(A,this.logger),gB1(A),this.logger.info("Blog plugin registered (routes auto-generated at /posts/)")}}function VbA(A={}){return new MbA(A)}fW();eS();I0();JA();JA();Ow();var B4=F.object({title:F.string(),slug:F.string(),coverImageId:F.string().optional()}),cB1=B4.pick({title:!0,slug:!0}),lR=I2.extend({metadata:cB1}),d1A=lR.extend({frontmatter:B4}),n1A=d1A.extend({description:F.string().optional(),postCount:F.number(),coverImageUrl:F.string().optional(),coverImageWidth:F.number().optional(),coverImageHeight:F.number().optional()}),pB1=F.object({description:F.string().optional()});function CC(A){return new NB(pB1,{title:A,mappings:[{key:"description",label:"Description",type:"string"}]})}Ow();class ObA extends W2{constructor(){super({entityType:"series",schema:lR,frontmatterSchema:B4,supportsCoverImage:!0,bodyFormatter:CC("")})}toMarkdown(A){let Q,B={};try{Q=this.parseFrontMatter(A.content,B4).coverImageId,B=CC(A.metadata.title).parse(this.extractBody(A.content))}catch{}let w={title:A.metadata.title,slug:A.metadata.slug,...Q&&{coverImageId:Q}},I=CC(A.metadata.title).format(B);return this.buildMarkdown(I,w)}fromMarkdown(A){let Q=this.parseFrontMatter(A,B4);return{content:A,entityType:"series",metadata:{title:Q.title,slug:Q.slug}}}parseBody(A){try{let Q=this.parseFrontMatter(A,B4);return CC(Q.title).parse(this.extractBody(A))}catch{return{}}}generateFrontMatter(){return""}}var iR=new ObA;I0();JA();KD();class bbA{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 I=F2($);w.add(I);let f=B.get(I),D=f?.content??this.createSeriesContent($),Y=xB(D);if(f?.contentHash===Y)continue;let H={id:I,entityType:"series",content:D,contentHash:Y,created:f?.created??new Date().toISOString(),updated:new Date().toISOString(),metadata:{title:$,slug:F2($)}};await this.entityService.upsertEntity({entity:H}),this.logger.debug(`Upserted series: ${$}`)}for(let $ of Q)if(!w.has($.id))await this.entityService.deleteEntity({entityType:"series",id:$.id}),this.logger.debug(`Deleted orphaned series: ${$.id}`)}async handleEntityChange(A,Q){let B=this.getSeriesName(A);if(B)await this.ensureSeriesExists(B);if(Q&&Q!==B)await this.cleanupOrphanedSeries(Q)}async handleEntityDeleted(){await this.syncAllSeries()}getSeriesName(A){let B=A.metadata.seriesName;return typeof B==="string"?B:void 0}async ensureSeriesExists(A){let Q=F2(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:F2(A)}};await this.entityService.upsertEntity({entity:$}),this.logger.debug(`Created series: ${A}`)}async cleanupOrphanedSeries(A){let Q=F2(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 I=this.getSeriesName($);if(I)A.add(I)}}return A}createSeriesContent(A){let Q={title:A,slug:F2(A)};return Q$("",Q)}}I0();JA();var Qa2=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()}),Ba2=F.object({type:F.enum(["list","detail"]),seriesName:F.string().optional()});function wa2(A){let Q=Ba2.safeParse(A);if(Q.success)return{type:Q.data.type,seriesName:Q.data.seriesName};let B=Qa2.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 lB1(A){let Q=l2(A.content,B4);return d1A.parse({...A,frontmatter:Q.metadata})}class RbA{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=wa2(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((I)=>{let f=lB1(I),D=iR.parseBody(I.content);return{...f,description:D.description,postCount:w.get(I.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 $=lB1(w),I=iR.parseBody(w.content),f=await this.getSeriesMembers(A,B);return this.logger.debug(`Found ${f.length} entities in series "${A}"`),Q.parse({seriesName:A,posts:f,series:{...$,description:I.description,postCount:f.length},description:I.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 I of $){let f=this.getSeriesName(I);if(f)Q.set(f,(Q.get(f)??0)+1)}}return Q}async getSeriesMembers(A,Q){let B=[],w=Q.getEntityTypes();for(let $ of w){if($==="series")continue;let I=await Q.listEntities({entityType:$,options:{filter:{metadata:{seriesName:A}}}});B.push(...I)}return B.sort(($,I)=>{let f=$.metadata.seriesIndex,D=I.metadata.seriesIndex;return(typeof f==="number"?f:999)-(typeof D==="number"?D:999)}),B}getSeriesName(A){let B=A.metadata.seriesName;return typeof B==="string"?B:void 0}}I0();JA();KD();var $a2=F.object({prompt:F.string().optional(),title:F.string().optional(),seriesId:F.string().optional()});class o1A{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}
|
|
3312
3312
|
|
|
3313
3313
|
Content in this series:
|
|
3314
3314
|
${w.join(`
|
|
@@ -3320,7 +3320,7 @@ Your task is to write a series description (2-3 sentences) that:
|
|
|
3320
3320
|
3. Is engaging and makes readers want to explore the content
|
|
3321
3321
|
4. Works well as a series overview on a website
|
|
3322
3322
|
|
|
3323
|
-
Be concise and focus on what makes this series unique and valuable.`});var aB1={name:"@brains/series",private:!0,version:"0.2.0-alpha.
|
|
3323
|
+
Be concise and focus on what makes this series unique and valuable.`});var aB1={name:"@brains/series",private:!0,version:"0.2.0-alpha.61",description:"Cross-content series \u2014 auto-derived from entities with seriesName metadata",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint src test --ext .ts,.tsx","lint:fix":"eslint src test --ext .ts,.tsx --fix"},dependencies:{"@brains/entity-service":"workspace:*","@brains/job-queue":"workspace:*","@brains/plugins":"workspace:*","@brains/templates":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var tB1=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 _bA extends FQ{entityType="series";schema=lR;adapter=iR;manager;constructor(){super("series",aB1)}getEntityTypeConfig(){return{weight:0.5}}createGenerationHandler(A){return new o1A(this.logger.child("SeriesGenerationHandler"),A)}getTemplates(){return{...oB1(),description:sB1}}getDataSources(){return[new RbA(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 bbA(A.entityService,this.logger.child("SeriesManager"))}createSeriesProjectionHandler(A){return{process:async(Q)=>{let B=tB1.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=tB1.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 o1A(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 PbA(){return new _bA}I0();JA();I0();JA();JA();I0();var Ha2=F.enum(["draft","queued","published"]),_Z=F.object({title:F.string(),slug:F.string().optional(),description:F.string().optional(),author:F.string().optional(),status:Ha2,publishedAt:F.string().datetime().optional(),event:F.string().optional(),coverImageId:F.string().optional()}),Xa2=_Z.pick({title:!0,description:!0,status:!0,publishedAt:!0,coverImageId:!0}).extend({slug:F.string()}),s1A=I2.extend({entityType:F.literal("deck"),metadata:Xa2}),a1A=s1A.extend({frontmatter:_Z,body:F.string()}),Bm=a1A.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 kbA extends W2{constructor(){super({entityType:"deck",schema:s1A,frontmatterSchema:_Z,supportsCoverImage:!0})}validateSlideStructure(A){if(!/^---$/gm.test(A))throw Error("Invalid deck: markdown must contain slide separators (---) to be a valid presentation")}toMarkdown(A){let Q=this.extractBody(A.content);this.validateSlideStructure(Q);try{let B=this.parseFrontMatter(A.content,_Z),w={...B,slug:B.slug??A.metadata.slug};return this.buildMarkdown(Q,w)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontmatter(A),B=this.extractBody(A);this.validateSlideStructure(B);let w=Q.slug??F2(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 wm=new kbA;JA();R8();var Wa2=F.object({markdown:F.string().describe("Markdown content with slide separators (---)")}),jbA=b1({name:"deck-detail",description:"Render a presentation deck as Reveal.js slides",schema:Wa2,dataSourceId:"decks:entities",requiredPermission:"public",layout:{component:eLA,fullscreen:!0}});R8();JA();var xbA=F.object({decks:F.array(a1A)}),vbA=F.object({decks:F.array(Bm),pageTitle:F.string().optional()});import{jsxDEV as hbA}from"preact/jsx-dev-runtime";var ybA=({decks:A,pageTitle:Q})=>{let B=A.map((w)=>({id:w.id,url:w.url,title:w.frontmatter.title,date:w.frontmatter.publishedAt??w.created,description:w.frontmatter.description}));return hbA("div",{className:"deck-list bg-theme",children:hbA("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:hbA(gT,{title:Q??"Presentations",items:B},void 0,!1,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)};JA();class t1A extends NB{constructor(){super(xbA,{title:"Deck List",mappings:[{key:"decks",label:"Decks",type:"array",itemType:"object"}]})}}var gbA=b1({name:"deck-list",description:"List view of all presentation decks",schema:vbA,dataSourceId:"decks:entities",requiredPermission:"public",formatter:new t1A,layout:{component:ybA}});JA();I0();var Ua2=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")}),eB1=b1({name:"decks:generation",description:"Template for AI to generate complete slide decks from prompts",schema:Ua2,dataSourceId:"shell:ai-content",requiredPermission:"public",useKnowledgeContext:!0,basePrompt:`You are creating slide decks in a distinctive voice that blends philosophy, technology, and culture.
|
|
3324
3324
|
|
|
3325
3325
|
Your task is to generate a complete slide deck based on the user's prompt.
|
|
3326
3326
|
|
|
@@ -3389,7 +3389,7 @@ Add your conclusion here`,Y=Y??`Presentation: ${f}`,await this.reportProgress(Q,
|
|
|
3389
3389
|
Note: This presentation is for "${$}".`:""}`,R=await this.context.ai.generate({prompt:C,templateName:"decks:generation"});f=f??R.title,D=D??R.content,Y=Y??R.description,await this.reportProgress(Q,{progress:50,message:`Generated deck: "${f}"`})}else if(!Y)await this.reportProgress(Q,{progress:30,message:"Generating description with AI"}),Y=(await this.context.ai.generate({prompt:`Title: ${f}
|
|
3390
3390
|
|
|
3391
3391
|
Content:
|
|
3392
|
-
${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(!f||!D)this.failEarly("Title and content are required");let W={slug:F2(f),title:f,status:"draft"},G=await ZU({entityType:"deck",title:f,deriveId:(q)=>q,regeneratePrompt:"Generate a different presentation deck title on the same topic.",context:this.context});if(G!==f)W.title=G,W.slug=F2(G);let K={title:W.title,status:W.status,slug:W.slug,description:Y,author:w,event:$},Z=Q$(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 Qw1={name:"@brains/decks",private:!0,version:"0.2.0-alpha.
|
|
3392
|
+
${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(!f||!D)this.failEarly("Title and content are required");let W={slug:F2(f),title:f,status:"draft"},G=await ZU({entityType:"deck",title:f,deriveId:(q)=>q,regeneratePrompt:"Generate a different presentation deck title on the same topic.",context:this.context});if(G!==f)W.title=G,W.slug=F2(G);let K={title:W.title,status:W.status,slug:W.slug,description:Y,author:w,event:$},Z=Q$(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 Qw1={name:"@brains/decks",private:!0,version:"0.2.0-alpha.61",description:"Presentation decks plugin for creating and viewing slide presentations",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/image":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class mbA extends FQ{entityType=wm.entityType;schema=wm.schema;adapter=wm;constructor(){super("decks",Qw1)}createGenerationHandler(A){return new SbA(this.logger.child("DeckGenerationJobHandler"),A)}getTemplates(){return{"deck-detail":jbA,"deck-list":gbA,generation:eB1,description:Aw1}}getDataSources(){return[new TbA(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 I=new Date().toISOString(),f={...$,metadata:{...$.metadata,status:"published",publishedAt:I}};await A.entityService.updateEntity({entity:{...f,content:this.adapter.toMarkdown(f)}}),await A.messaging.send({type:"publish:report:success",payload:{entityType:B,entityId:w,result:{id:w}}})}catch($){await A.messaging.send({type:"publish:report:failure",payload:{entityType:B,entityId:w,error:h0($)}})}return{success:!0}})}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?`
|
|
3393
3393
|
|
|
3394
3394
|
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}
|
|
3395
3395
|
|
|
@@ -3404,7 +3404,7 @@ Guidelines:
|
|
|
3404
3404
|
3. Depth: Provide enough detail to be useful as a reference, but stay focused on the topic.
|
|
3405
3405
|
4. Style: Informative and educational. Write as if explaining to yourself for future reference.
|
|
3406
3406
|
5. Length: Adjust based on topic complexity - concise for simple topics, more detailed for complex ones.
|
|
3407
|
-
6. No meta-commentary: Just provide the content directly without phrases like "Here is..." or "This note covers..."`});I0();JA();var $w1=F.object({prompt:F.string(),title:F.string().optional()}),Za2=u7.extend({title:F.string().optional()});class e1A extends w${constructor(A,Q){super(A,Q,{schema:$w1,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:dR.createNoteContent(w,B.body),metadata:{title:w},title:w,resultExtras:{title:w}}}summarizeDataForLog(A){return{prompt:A.prompt,title:A.title}}}var Iw1={name:"@brains/note",private:!0,version:"0.2.0-alpha.
|
|
3407
|
+
6. No meta-commentary: Just provide the content directly without phrases like "Here is..." or "This note covers..."`});I0();JA();var $w1=F.object({prompt:F.string(),title:F.string().optional()}),Za2=u7.extend({title:F.string().optional()});class e1A extends w${constructor(A,Q){super(A,Q,{schema:$w1,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:dR.createNoteContent(w,B.body),metadata:{title:w},title:w,resultExtras:{title:w}}}summarizeDataForLog(A){return{prompt:A.prompt,title:A.title}}}var Iw1={name:"@brains/note",private:!0,version:"0.2.0-alpha.61",description:"Personal knowledge capture with markdown-first workflow",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class lbA extends FQ{entityType=dR.entityType;schema=rR;adapter=dR;constructor(A={}){super("note",Iw1,A,cbA)}createGenerationHandler(A){return new e1A(this.logger.child("NoteGenerationJobHandler"),A)}getTemplates(){return{generation:pbA}}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 EC(A={}){return new lbA(A)}I0();JA();JA();I0();var fw1=F.object({ref:F.string(),label:F.string()}),Dw1=F.enum(["pending","draft","published"]),sJ=F.object({status:Dw1,title:F.string(),url:F.string().url(),description:F.string().optional(),domain:F.string(),capturedAt:F.string().datetime(),source:fw1}),Yw1=sJ.pick({title:!0,status:!0}),fm=I2.extend({entityType:F.literal("link"),metadata:Yw1}),ibA=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)")});I0();class kZ extends W2{constructor(){super({entityType:"link",schema:fm,frontmatterSchema:sJ})}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,sJ),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 rbA=new kZ;I0();JA();var Na2=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.")}),Hw1=b1({name:"link:extraction",description:"Extract structured content from webpage markdown",dataSourceId:"shell:ai-content",schema:Na2,basePrompt:`You are an expert at extracting key information from webpage content.
|
|
3408
3408
|
|
|
3409
3409
|
You will receive webpage content in markdown format. Your job is to extract structured information from it.
|
|
3410
3410
|
|
|
@@ -3426,7 +3426,7 @@ Accuracy rules:
|
|
|
3426
3426
|
|
|
3427
3427
|
`))return{success:!1,error:f.trim(),errorType:"fetch_failed"};return{success:!0,content:f}}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 La2}from"crypto";class LC{static URL_PATTERN=/https?:\/\/[^\s<>"{}|\\^`[\]]+?(?=[,;:\s]|$)/gi;static extractUrls(A){let Q=A.match(LC.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=La2("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}}}I0();JA();var Ma2=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()}),o8w=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 Q2A extends tB{context;linkAdapter;urlFetcher;constructor(A,Q,B){super(A,{schema:Ma2,jobTypeName:"link-capture"});this.context=Q,this.linkAdapter=new kZ,this.urlFetcher=new nR(B?.jinaApiKey?{jinaApiKey:B.jinaApiKey}:void 0)}async process(A,Q,B){let{url:w,metadata:$}=A;try{await B.report({progress:v2.START,total:100,message:"Starting link capture"});let I=LC.generateEntityId(w);await B.report({progress:v2.INIT,total:100,message:"Checking for existing link"});let f=await this.context.entityService.getEntity({entityType:"link",id:I});if(f){this.logger.info("Link already captured, returning existing",{url:w,entityId:I});let{frontmatter:Z}=this.linkAdapter.parseLinkContent(f.content);return{success:!0,entityId:f.id,title:Z.title,url:w,status:f.metadata.status}}await B.report({progress:v2.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:v2.PROCESS,total:100,message:"Extracting content with AI"});let Y=await this.context.ai.generate({templateName:"link:extraction",prompt:D.success?`Extract structured information from this webpage content:
|
|
3428
3428
|
|
|
3429
|
-
${D.content}`:`The URL ${w} could not be fetched. Return success: false with error: "${D.error}"`,data:{url:w,hasContent:D.success},interfacePermissionGrant:"public"});this.logger.debug("AI extraction result",{result:Y}),await B.report({progress:v2.EXTRACT,total:100,message:"Processing extraction results"});let H=this.resolveSource($),W=new Date().toISOString();if(Y.success===!1||!Y.title||!Y.description||!Y.summary){let Z=Y.title||new URL(w).hostname;this.logger.info("Incomplete extraction, saving as pending",{url:w}),await B.report({progress:v2.SAVE,total:100,message:"Saving link as pending"});let q=this.linkAdapter.createLinkContent({status:"pending",title:Z,url:w,description:Y.description,summary:Y.summary,domain:new URL(w).hostname,capturedAt:W,source:H}),L=await this.context.entityService.createEntity({entity:{id:I,entityType:"link",content:q,metadata:{status:"pending",title:Z}}});return await B.report({progress:v2.COMPLETE,total:100,message:"Link saved (pending)"}),{success:!0,entityId:L.entityId,title:Z,url:w,status:"pending"}}await B.report({progress:v2.SAVE,total:100,message:`Saving link: "${Y.title}"`});let G=this.linkAdapter.createLinkContent({status:"draft",title:Y.title,url:w,description:Y.description,summary:Y.summary,domain:new URL(w).hostname,capturedAt:W,source:H}),K=await this.context.entityService.createEntity({entity:{id:I,entityType:"link",content:G,metadata:{status:"draft",title:Y.title}}});return await B.report({progress:v2.COMPLETE,total:100,message:`Link captured: "${Y.title}"`}),{success:!0,entityId:K.entityId,title:Y.title,url:w,status:"draft"}}catch(I){return this.logger.error("Link capture job failed",{error:I,jobId:Q,data:A}),r8.failure(I)}}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 Uw1={name:"@brains/link",private:!0,version:"0.2.0-alpha.
|
|
3429
|
+
${D.content}`:`The URL ${w} could not be fetched. Return success: false with error: "${D.error}"`,data:{url:w,hasContent:D.success},interfacePermissionGrant:"public"});this.logger.debug("AI extraction result",{result:Y}),await B.report({progress:v2.EXTRACT,total:100,message:"Processing extraction results"});let H=this.resolveSource($),W=new Date().toISOString();if(Y.success===!1||!Y.title||!Y.description||!Y.summary){let Z=Y.title||new URL(w).hostname;this.logger.info("Incomplete extraction, saving as pending",{url:w}),await B.report({progress:v2.SAVE,total:100,message:"Saving link as pending"});let q=this.linkAdapter.createLinkContent({status:"pending",title:Z,url:w,description:Y.description,summary:Y.summary,domain:new URL(w).hostname,capturedAt:W,source:H}),L=await this.context.entityService.createEntity({entity:{id:I,entityType:"link",content:q,metadata:{status:"pending",title:Z}}});return await B.report({progress:v2.COMPLETE,total:100,message:"Link saved (pending)"}),{success:!0,entityId:L.entityId,title:Z,url:w,status:"pending"}}await B.report({progress:v2.SAVE,total:100,message:`Saving link: "${Y.title}"`});let G=this.linkAdapter.createLinkContent({status:"draft",title:Y.title,url:w,description:Y.description,summary:Y.summary,domain:new URL(w).hostname,capturedAt:W,source:H}),K=await this.context.entityService.createEntity({entity:{id:I,entityType:"link",content:G,metadata:{status:"draft",title:Y.title}}});return await B.report({progress:v2.COMPLETE,total:100,message:`Link captured: "${Y.title}"`}),{success:!0,entityId:K.entityId,title:Y.title,url:w,status:"draft"}}catch(I){return this.logger.error("Link capture job failed",{error:I,jobId:Q,data:A}),r8.failure(I)}}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 Uw1={name:"@brains/link",private:!0,version:"0.2.0-alpha.61",description:"Web content capture plugin with AI-powered extraction and structured storage",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class tbA extends FQ{entityType=rbA.entityType;schema=fm;adapter=rbA;shell;constructor(A={}){super("link",Uw1,A,ibA)}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 Q2A(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 I=this.adapter.fromMarkdown(A.content).metadata,f=typeof I?.title==="string"?I.title:void 0,D=typeof I?.status==="string"?I.status:void 0,Y=this.extractFirstUrl(A.content);if(f&&D&&Y){let H=F2(Y)||F2(f)||`${A.entityType}-${Date.now()}`,W=new Date().toISOString();return{kind:"handled",result:{success:!0,data:{entityId:(await B.entityService.createEntity({entity:{id:H,entityType:A.entityType,content:A.content,metadata:{title:f,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 Q2A(this.logger.child("LinkCaptureJobHandler"),A,this.config.jinaApiKey?{jinaApiKey:this.config.jinaApiKey}:void 0)}getTemplates(){return{extraction:Hw1,"link-list":Xw1,"link-detail":Ww1}}getDataSources(){return[new abA(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 nR(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:
|
|
3430
3430
|
|
|
3431
3431
|
${$.content}`,data:{url:B,hasContent:!0},interfacePermissionGrant:"public"})})}extractFirstUrl(...A){for(let Q of A){if(!Q)continue;let[B]=LC.extractUrls(Q);if(B)return B}return}}function Jw1(A={}){return new tbA(A)}var MC=Jw1;JA();var F6w=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()});I0();JA();R8();JA();I0();var Gw1=F.enum(["draft","published"]),w4=F.object({title:F.string(),slug:F.string().optional(),status:Gw1,publishedAt:F.string().datetime().optional(),description:F.string(),year:F.number(),coverImageId:F.string().optional(),url:F.string().url().optional()}),Fw1=w4.pick({title:!0,status:!0,publishedAt:!0,year:!0}).extend({slug:F.string()}),oR=I2.extend({entityType:F.literal("project"),metadata:Fw1}),B2A=F.object({context:F.string(),problem:F.string(),solution:F.string(),outcome:F.string()}),Ym=oR.extend({frontmatter:w4,body:F.string(),structuredContent:B2A.optional(),coverImageUrl:F.string().optional()}),sR=Ym.extend({url:F.string().optional(),typeLabel:F.string().optional(),coverImageUrl:F.string().optional(),coverImageWidth:F.number().optional(),coverImageHeight:F.number().optional()}),Oa2=Ym.extend({url:F.string(),typeLabel:F.string(),coverImageUrl:F.string().optional(),coverImageWidth:F.number().optional(),coverImageHeight:F.number().optional()});I0();JA();JA();class ebA extends NB{constructor(){super(B2A,{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 ARA=new ebA;class QRA extends W2{constructor(){super({entityType:"project",schema:oR,frontmatterSchema:w4,supportsCoverImage:!0,bodyFormatter:ARA})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,w4),w={...B,slug:B.slug??A.metadata.slug};return this.buildMarkdown(Q,w)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,w4),B=Q.slug??F2(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,w4)}parseStructuredContent(A){return ARA.parse(this.extractBody(A.content))}createProjectContent(A,Q){let B=ARA.format(Q);return this.buildMarkdown(B,A)}}var jZ=new QRA;JA();var BRA=F.object({});import{jsxDEV as gf,Fragment as Ra2}from"preact/jsx-dev-runtime";var ba2=({project:A})=>{let{frontmatter:Q,url:B,coverImageUrl:w}=A;return gf(xQ,{href:B,children:[w&&gf("img",{src:w,alt:Q.title,className:"w-full h-56 object-cover rounded-md mb-4"},void 0,!1,void 0,this),gf(Q9,{children:Q.title},void 0,!1,void 0,this),gf("p",{className:"text-theme leading-relaxed",children:Q.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},wRA=({projects:A,pageTitle:Q,pagination:B,baseUrl:w="/projects"})=>{let $=Q??"Projects",I=B?.totalItems??A.length,f=`Browse all ${I} ${I===1?"project":"projects"}`;return gf(Ra2,{children:[gf(YQ,{title:$,description:f},void 0,!1,void 0,this),gf("div",{className:"project-list bg-theme",children:gf("div",{className:"container mx-auto px-6 md:px-12 max-w-5xl py-16 md:py-24",children:[gf("h1",{className:"text-4xl font-bold text-heading mb-12",children:$},void 0,!1,void 0,this),gf("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-8",children:A.map((D)=>gf(ba2,{project:D},D.id,!1,void 0,this))},void 0,!1,void 0,this),B&&B.totalPages>1&&gf("div",{className:"mt-12",children:gf(uY,{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 SB,Fragment as Kw1}from"preact/jsx-dev-runtime";var _a2=({prevProject:A,nextProject:Q})=>{if(!A&&!Q)return null;return SB("nav",{className:"pt-12 mt-12 border-t border-theme-muted",children:SB("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[A?SB(xQ,{href:A.url,variant:"compact",children:[SB("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Previous"},void 0,!1,void 0,this),SB("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):SB("div",{},void 0,!1,void 0,this),Q&&SB(xQ,{href:Q.url,variant:"compact",className:"md:text-right",children:[SB("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Next"},void 0,!1,void 0,this),SB("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)},w2A=({title:A,content:Q})=>{if(!Q)return null;return SB("section",{className:"mb-12",children:[SB("h2",{className:"text-2xl font-bold text-heading mb-4",children:A},void 0,!1,void 0,this),SB(jf,{markdown:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},$RA=({project:A,prevProject:Q,nextProject:B})=>{let{frontmatter:w,structuredContent:$,metadata:I,coverImageUrl:f}=A;return SB(Kw1,{children:[SB(YQ,{title:w.title,description:w.description,...f&&{ogImage:f},ogType:"article"},void 0,!1,void 0,this),SB("article",{className:"project-detail",children:SB("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:SB("div",{className:"max-w-3xl mx-auto",children:[f&&A.coverImageWidth&&A.coverImageHeight&&SB(PJ,{src:f,alt:w.title,width:A.coverImageWidth,height:A.coverImageHeight,className:"mb-8 shadow-lg"},void 0,!1,void 0,this),SB("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),SB("div",{className:"flex flex-wrap items-center gap-4 text-theme-muted mb-8",children:[SB("span",{className:"text-sm",children:I.year},void 0,!1,void 0,this),w.url&&SB(Kw1,{children:[SB("span",{className:"text-theme-muted",children:"|"},void 0,!1,void 0,this),SB("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),SB("p",{className:"text-lg text-theme mb-12 leading-relaxed",children:w.description},void 0,!1,void 0,this),$&&SB("div",{className:"case-study",children:[SB(w2A,{title:"Context",content:$.context},void 0,!1,void 0,this),SB(w2A,{title:"Problem",content:$.problem},void 0,!1,void 0,this),SB(w2A,{title:"Solution",content:$.solution},void 0,!1,void 0,this),SB(w2A,{title:"Outcome",content:$.outcome},void 0,!1,void 0,this)]},void 0,!0,void 0,this),SB(_a2,{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)};JA();I0();var Pa2=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)")}),IRA=b1({name:"portfolio:generation",description:"Template for AI to generate portfolio project case studies",schema:Pa2,dataSourceId:"shell:ai-content",requiredPermission:"public",useKnowledgeContext:!0,basePrompt:`You are helping to create a professional portfolio case study based on REAL project information.
|
|
3432
3432
|
|
|
@@ -3450,7 +3450,7 @@ ${A.prompt}
|
|
|
3450
3450
|
|
|
3451
3451
|
Project year: ${A.year}
|
|
3452
3452
|
|
|
3453
|
-
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 $2A extends w${constructor(A,Q){super(A,Q,{schema:ka2,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:fRA(A),templateName:"portfolio:generation"}),$=A.title??w.title,I=F2($);await this.reportProgress(Q,{progress:50,message:`Generated project: "${$}"`});let f={title:$,slug:I,status:"draft",description:w.description,year:B},D={context:w.context,problem:w.problem,solution:w.solution,outcome:w.outcome};return{id:I,content:jZ.createProjectContent(f,D),metadata:{title:$,slug:I,status:"draft",year:B},title:$,resultExtras:{title:$}}}summarizeDataForLog(A){return{prompt:A.prompt.substring(0,100),year:A.year,title:A.title}}}I0();I0();function ja2(A){let Q=l2(A.content,w4),B=jZ.parseStructuredContent(A);return Ym.parse({...A,frontmatter:Q.metadata,body:Q.content,structuredContent:B})}class I2A extends d6{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 ja2(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 Zw1={name:"@brains/portfolio",private:!0,version:"0.2.0-alpha.
|
|
3453
|
+
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 $2A extends w${constructor(A,Q){super(A,Q,{schema:ka2,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:fRA(A),templateName:"portfolio:generation"}),$=A.title??w.title,I=F2($);await this.reportProgress(Q,{progress:50,message:`Generated project: "${$}"`});let f={title:$,slug:I,status:"draft",description:w.description,year:B},D={context:w.context,problem:w.problem,solution:w.solution,outcome:w.outcome};return{id:I,content:jZ.createProjectContent(f,D),metadata:{title:$,slug:I,status:"draft",year:B},title:$,resultExtras:{title:$}}}summarizeDataForLog(A){return{prompt:A.prompt.substring(0,100),year:A.year,title:A.title}}}I0();I0();function ja2(A){let Q=l2(A.content,w4),B=jZ.parseStructuredContent(A);return Ym.parse({...A,frontmatter:Q.metadata,body:Q.content,structuredContent:B})}class I2A extends d6{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 ja2(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 Zw1={name:"@brains/portfolio",private:!0,version:"0.2.0-alpha.61",description:"Portfolio showcase for projects and case studies",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/plugins":"workspace:*","@brains/templates":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest",typescript:"^5.3.3"}};var va2=F.object({projects:F.array(sR),pageTitle:F.string().optional(),pagination:B$.nullable(),baseUrl:F.string().optional()});function ha2(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 DRA extends FQ{entityType=jZ.entityType;schema=oR;adapter=jZ;constructor(A={}){super("portfolio",Zw1,A,BRA)}async interceptCreate(A,Q,B){if(!A.prompt||A.content)return{kind:"continue",input:A};let w=ha2(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 $2A(this.logger.child("ProjectGenerationJobHandler"),A)}getTemplates(){return{"project-list":b1({name:"project-list",description:"Portfolio project list page template",schema:va2,dataSourceId:"portfolio:entities",requiredPermission:"public",layout:{component:wRA}}),"project-detail":b1({name:"project-detail",description:"Individual project case study template",schema:F.object({project:sR,prevProject:sR.nullable(),nextProject:sR.nullable()}),dataSourceId:"portfolio:entities",requiredPermission:"public",layout:{component:$RA}}),generation:IRA}}getDataSources(){return[new I2A(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:fRA(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 I=l2($.content,w4),f=new Date().toISOString(),D=Q$(I.content,{...I.metadata,status:"published",publishedAt:f});await A.entityService.updateEntity({entity:{...$,content:D,metadata:{...$.metadata,status:"published",publishedAt:f}}}),await A.messaging.send({type:"publish:report:success",payload:{entityType:B,entityId:w,publishedAt:f}})}catch($){await A.messaging.send({type:"publish:report:failure",payload:{entityType:B,entityId:w,error:h0($)}})}return{success:!0}})}}function YRA(A={}){return new DRA(A)}I0();JA();var zw1=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)});I0();JA();I0();var ya2=F.object({aliases:F.array(F.string()).optional()}),f2A=I2.extend({entityType:F.literal("topic"),metadata:ya2}),_5w=F.object({content:F.string()}),Nw1=F.object({title:F.string().describe("Topic title")});var aJ="topics",mB="topic",HRA="topics-projection",qw1="topic:project",aR="topics-plugin";class tJ extends W2{constructor(){super({entityType:mB,schema:f2A,frontmatterSchema:Nw1})}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:mB}}extractMetadata(A){return{aliases:A.metadata.aliases??[]}}generateFrontMatter(A){let Q=this.parseTopicBody(A.content),w=this.buildMarkdown("",this.buildFrontmatter(Q.title)).match(/^---\n[\s\S]*?\n---/);return w?w[0]:""}parseTopicBody(A){if(A.startsWith("---"))try{let Q=this.parseFrontmatter(A);return{content:this.extractBody(A).replace(/\n*## Sources[\s\S]*$/,"").trim(),formatted:A,title:Q.title}}catch{return{content:A,formatted:A,title:"Unknown Topic"}}return{content:A,formatted:A,title:"Unknown Topic"}}createTopicBody(A){return this.buildMarkdown(A.content,this.buildFrontmatter(A.title))}}I0();JA();var ga2=new tJ;class XRA{context;logger;constructor(A,Q){this.context=A;this.logger=Q}async synthesize(A){let Q=ga2.parseTopicBody(A.existingTopic.content);return this.logger.debug("Synthesizing merged topic",{existingTitle:Q.title,incomingTitle:A.incomingTopic.title}),this.context.ai.generate({templateName:"topics:merge-synthesis",prompt:`Canonical topic candidate:
|
|
3454
3454
|
Title: ${Q.title}
|
|
3455
3455
|
Content:
|
|
3456
3456
|
${Q.content}
|
|
@@ -3553,13 +3553,13 @@ ${A.content}`}class Jm{context;logger;constructor(A,Q){this.context=A;this.logge
|
|
|
3553
3553
|
|
|
3554
3554
|
${Q.content}`}).join(`
|
|
3555
3555
|
|
|
3556
|
-
`)}async function Gm(A,Q,B){if(A.length===0)return{created:0,skipped:0,batches:0};let w=Tw1(A),$=new Tf(Q.entityService,B),I=0,f=0;for(let D of w){B.info(`Processing batch of ${D.length} entities`);let Y=aa2(D),H=await W2A(Q.entityService),W=U2A({entityTitle:`Batch of ${D.length} entities`,entityType:"batch",content:Y,existingTopicTitles:H});try{let G=await Q.ai.generate({prompt:W,templateName:"topics:extraction"});for(let K of G.topics){let Z=YU(K.title);if(await $.getTopic(Z)){f++;continue}await $.createTopic({title:K.title,content:K.content}),I++}}catch(G){B.error("Batch topic extraction failed",{batchSize:D.length,promptChars:W.length,error:h0(G)})}}return{created:I,skipped:f,batches:w.length}}JA();I0();JA();var ta2=F.object({entityId:F.string(),entityType:F.string(),contentHash:F.string(),minRelevanceScore:F.number().min(0).max(1),autoMerge:F.boolean(),mergeSimilarityThreshold:F.number().min(0).max(1)});class FRA extends tB{topicExtractor;context;constructor(A,Q){super(Q,{schema:ta2,jobTypeName:"topic-extraction"});this.context=A,this.topicExtractor=new Jm(A,Q)}async process(A,Q,B){let{entityId:w,entityType:$,contentHash:I,minRelevanceScore:f,autoMerge:D,mergeSimilarityThreshold:Y}=A;this.logger.debug("Starting topic extraction job",{jobId:Q,entityId:w,entityType:$,contentHash:I});try{await B.report({progress:v2.INIT,message:`Extracting topics from ${$}: ${w}`});let H=await this.context.entityService.getEntity({entityType:$,id:w});if(!H)return this.logger.warn("Entity no longer exists, skipping topic extraction",{jobId:Q,entityId:w,entityType:$}),{success:!0,topicsExtracted:0};if(H.contentHash!==I)return this.logger.info("Entity content changed since job created, skipping stale extraction",{jobId:Q,entityId:w,entityType:$,jobContentHash:I,currentContentHash:H.contentHash}),{success:!0,topicsExtracted:0};let W=await this.topicExtractor.extractFromEntity(H,f);if(await B.report({progress:v2.EXTRACT,message:`Extracted ${W.length} topics`}),W.length===0)return this.logger.debug("No topics found in entity",{entityId:w,entityType:$}),await B.report({progress:v2.COMPLETE,message:"No topics found"}),{success:!0,topicsExtracted:0};let G=W.map((q)=>({type:"topics:process-single",data:{topic:q,sourceEntityId:w,sourceEntityType:$,autoMerge:D,mergeSimilarityThreshold:Y},metadata:{operationType:"data_processing",operationTarget:q.title}})),K=F6(),Z=await this.context.jobs.enqueueBatch(G,{priority:5,source:aR,rootJobId:K,metadata:{operationType:"batch_processing",operationTarget:`process topics for ${$}:${w}`,pluginId:aJ}});return await B.report({progress:v2.COMPLETE,message:`Queued ${W.length} topics for processing`}),this.logger.debug("Queued topic processing batch",{batchId:Z,entityId:w,entityType:$,topicsExtracted:W.length}),{success:!0,topicsExtracted:W.length,batchId:Z}}catch(H){return this.logger.error("Topic extraction job failed",{jobId:Q,entityId:w,entityType:$,error:h0(H)}),{...r8.failure(H),topicsExtracted:0}}}summarizeDataForLog(A){return{entityId:A.entityId,entityType:A.entityType,contentHash:A.contentHash}}}var ea2=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"),entityId:F.string(),entityType:F.string(),contentHash:F.string().optional(),minRelevanceScore:F.number().min(0).max(1).optional(),autoMerge:F.boolean().optional(),mergeSimilarityThreshold:F.number().min(0).max(1).optional()})]);function Sw1(A){let{context:Q,logger:B,config:w}=A,$=new FRA(Q,B),I=G6.from(async()=>{});if(!I)throw Error("Failed to create progress reporter");return{process:async(f)=>{if(f.mode==="derive")return await A.extractAllTopics(),{success:!0};if(f.mode==="rebuild")return await A.rebuildAllTopics(),{success:!0};let D=await Q.entityService.getEntity({entityType:f.entityType,id:f.entityId});if(!D)return{success:!1,topicsExtracted:0};return $.process({entityId:f.entityId,entityType:f.entityType,contentHash:f.contentHash??D.contentHash,minRelevanceScore:f.minRelevanceScore??w.minRelevanceScore,autoMerge:f.autoMerge??w.autoMerge,mergeSimilarityThreshold:f.mergeSimilarityThreshold??w.mergeSimilarityThreshold},`topic-projection:${f.entityType}:${f.entityId}`,I)},validateAndParse:(f)=>{let D=ea2.safeParse(f??{});return D.success?D.data:null}}}function mw1(){return{priority:5,source:aR,deduplication:"coalesce",deduplicationKey:"topics-initial-derivation",metadata:{operationType:"data_processing",operationTarget:"topics-initial-derivation",pluginId:aJ}}}async function uw1(A){let Q=await pw1(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 Gm(Q,A.context,A.logger);A.logger.info("Batch topic extraction complete",B)}async function cw1(A){let Q=await pw1(A),B=await KRA(Q,A.context,A.logger);A.logger.info("Topic rebuild complete",B)}async function KRA(A,Q,B){let w=new Tf(Q.entityService,B),$=await w.listTopics();for(let f of $)await w.deleteTopic(f.id);if(A.length===0)return{deleted:$.length,created:0,skipped:0,batches:0};let I=await Gm(A,Q,B);return{deleted:$.length,...I}}async function pw1(A){let Q=At2(A),B=[];for(let w of Q){let $=await A.context.entityService.listEntities({entityType:w});for(let I of $){if(!A.isEntityPublished(I))continue;B.push(I)}}return B}function At2(A){return A.context.entityService.getEntityTypes().filter((B)=>A.shouldProcessEntityType(B))}var eR=F.object({entityType:F.string(),content:F.string(),metadata:F.record(F.unknown()).optional()}),Qt2=eR.extend({minRelevanceScore:F.number().optional()}),Bt2=F.object({contentA:eR,contentB:eR,minRelevanceScore:F.number().optional()}),Km=F.object({title:F.string(),content:F.string()}),wt2=F.object({existingTopics:F.array(Km),incomingTopic:Km,threshold:F.number().optional()}),$t2=F.object({existingAliases:F.array(F.string()).optional(),canonicalTitle:F.string(),candidateAliases:F.array(F.string())}),It2=F.object({existingTopics:F.array(Km.extend({aliases:F.array(F.string()).optional()})).default([]),incomingTopic:Km.extend({relevanceScore:F.number().min(0).max(1).optional()}),threshold:F.number().optional()}),ft2=F.object({entities:F.array(eR).min(1),minRelevanceScore:F.number().optional()}),Dt2=F.object({existingTopics:F.array(Km).optional(),entities:F.array(eR)}),Yt2=F.object({entities:F.array(eR)});function Fm(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 lw1(A){return{title:A.title,relevanceScore:A.relevanceScore}}function Ht2(A){let Q=A.metadata.title;return typeof Q==="string"?Q:A.id}function Xt2(A,Q){return{...A,sources:[{id:Q.id,type:Q.entityType,title:Ht2(Q)}]}}async function VC(A){let Q=await A.entityService.listEntities({entityType:mB});await Promise.all(Q.map((B)=>A.entityService.deleteEntity({entityType:mB,id:B.id})))}function iw1(A){let{context:Q,logger:B,config:w}=A,$=new Jm(Q,B),I=async(f,D,Y="")=>{let H=Fm(f,Y);return $.extractFromEntity(H,D)};Q.eval.registerHandler("extractFromEntity",async(f)=>{await VC(Q);let D=Qt2.parse(f),Y=D.minRelevanceScore??w.minRelevanceScore,H=Fm(D);return(await $.extractFromEntity(H,Y)).map((G)=>Xt2(G,H))}),Q.eval.registerHandler("checkMergeSimilarity",async(f)=>{await VC(Q);let D=Bt2.parse(f),Y=D.minRelevanceScore??w.minRelevanceScore,[H,W]=await Promise.all([I(D.contentA,Y,"-a"),I(D.contentB,Y,"-b")]),G=H.map((q)=>q.title.toLowerCase()),K=W.map((q)=>q.title.toLowerCase()),Z=G.filter((q)=>K.includes(q));return{topicsA:H.map(lw1),topicsB:W.map(lw1),matchingTitles:Z,wouldMerge:Z.length>0}}),Q.eval.registerHandler("detectMergeCandidate",async(f)=>{await VC(Q);let D=wt2.parse(f),Y=D.threshold??w.mergeSimilarityThreshold,H=new Tf(Q.entityService,B);for(let G of D.existingTopics)await H.createTopic(G);let W=await H.findMergeCandidate({title:D.incomingTopic.title},Y);return{found:W!==null,candidateTitle:W?.title,candidateScore:W?.score}}),Q.eval.registerHandler("mergeAliases",async(f)=>{let D=$t2.parse(f);return{aliases:new Tf(Q.entityService,B).mergeAliases(D.existingAliases,D.canonicalTitle,D.candidateAliases)}}),Q.eval.registerHandler("processTopicWithAutoMerge",async(f)=>{await VC(Q);let D=It2.parse(f),Y=new Tf(Q.entityService,B);for(let Z of D.existingTopics)await Y.createTopic({title:Z.title,content:Z.content,metadata:{aliases:Z.aliases??[]}});let H=new Hm(Q,B),W=G6.from(async()=>{});if(!W)throw Error("Failed to create progress reporter");let G=await H.process({topic:{title:D.incomingTopic.title,content:D.incomingTopic.content,relevanceScore:D.incomingTopic.relevanceScore??0.9},sourceEntityId:"eval-source",sourceEntityType:"post",autoMerge:!0,mergeSimilarityThreshold:D.threshold??w.mergeSimilarityThreshold},`eval-job-${Date.now()}`,W),K=await Q.entityService.listEntities({entityType:mB});return{...G,topicCount:K.length,topics:K.map(JRA)}}),Q.eval.registerHandler("rebuildTopics",async(f)=>{await VC(Q);let D=Dt2.parse(f),Y=new Tf(Q.entityService,B);for(let K of D.existingTopics??[])await Y.createTopic(K);let H=D.entities.map((K,Z)=>Fm(K,`-rebuild-${Z}`)),W=await KRA(H,Q,B),G=await Q.entityService.listEntities({entityType:mB});return{...W,topicCount:G.length,topics:G.map(JRA)}}),Q.eval.registerHandler("extractSequentially",async(f)=>{await VC(Q);let D=ft2.parse(f),Y=D.minRelevanceScore??w.minRelevanceScore,H=new Tf(Q.entityService,B),W=[];for(let[K,Z]of D.entities.entries()){let q=Fm(Z,`-sequential-${K}`),L=await $.extractFromEntity(q,Y);for(let C of L)await H.createTopic({title:C.title,content:C.content});W.push({extractedTitles:L.map((C)=>C.title)})}let G=await Q.entityService.listEntities({entityType:mB});return{totalTopics:G.length,perEntity:W,topics:G.map(tR)}}),Q.eval.registerHandler("batchExtract",async(f)=>{await VC(Q);let Y=Yt2.parse(f).entities.map((G,K)=>Fm(G,`-batch-${K}`)),H=await Gm(Y,Q,B),W=await Q.entityService.listEntities({entityType:mB});return{...H,topics:W.map(tR)}})}var rw1={name:"@brains/topics",private:!0,version:"0.2.0-alpha.60",description:"Extract and manage topics from conversations",type:"module",main:"./src/index.ts",types:"./src/index.ts",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/plugins":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","@types/node":"^20.0.0",typescript:"^5.3.3"}};var Ut2=new tJ;class dw1 extends FQ{entityType=mB;schema=f2A;adapter=Ut2;constructor(A={}){super(aJ,rw1,A,zw1)}getEntityTypeConfig(){return{weight:0.5}}getTemplates(){return{extraction:bw1,"merge-synthesis":Rw1,"topic-list":_w1,"topic-detail":Pw1}}getDataSources(){return[new GRA(this.logger.child("TopicsDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableAutoExtraction)return[];return[{id:HRA,targetType:mB,job:{type:qw1,handler:Sw1({context:A,logger:this.logger,config:this.config,extractAllTopics:()=>this.extractAllTopics(A),rebuildAllTopics:()=>this.rebuildAllTopics(A)})},initialSync:{shouldEnqueue:async()=>!await Wz(A,mB),jobData:{mode:"derive",reason:"initial-sync"},jobOptions:mw1()},sourceChange:{sourceTypes:this.config.includeEntityTypes,requireInitialSync:!0,jobData:(Q)=>{let B=Q.entity;if(!B)return null;if(!this.shouldProcessEntityType(B.entityType))return null;if(!this.isEntityPublished(B))return null;return{mode:"source",entityId:B.id,entityType:B.entityType,contentHash:B.contentHash,minRelevanceScore:this.config.minRelevanceScore,autoMerge:this.config.autoMerge,mergeSimilarityThreshold:this.config.mergeSimilarityThreshold}},jobOptions:(Q)=>({priority:5,source:aR,deduplication:"coalesce",deduplicationKey:`topics-source:${Q.entityType}:${Q.entityId}:${Q.entity?.contentHash??"unknown"}`,metadata:{operationType:"data_processing",operationTarget:`topic-projection:${Q.entityType}:${Q.entityId}`,pluginId:aJ}})}}]}async onRegister(A){let Q=new Hm(A,this.logger);A.jobs.registerHandler("process-single",Q),A.insights.register("topic-distribution",xw1()),vw1({context:A,pluginId:this.id}),iw1({context:A,logger:this.logger,config:this.config})}hasRunInitialDerivation(){return this.getDerivedEntityProjectionController(HRA)?.hasQueuedInitialSync()??!1}shouldProcessEntityType(A){if(A===mB)return!1;return this.config.includeEntityTypes.includes(A)}isEntityPublished(A){let B=A.metadata.status;if(B===void 0||B===null)return!0;if(typeof B!=="string")return!1;return this.config.extractableStatuses.includes(B)}async extractAllTopics(A){await uw1({context:A,logger:this.logger,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}async rebuildAllTopics(A){await cw1({context:A,logger:this.logger,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}}function J2A(A){return new dw1(A)}I0();JA();I0();var nw1=F.enum(["linkedin"]),ow1=F.enum(["draft","queued","published","failed"]),sw1=F.enum(["post","deck"]),$4=F.object({title:F.string().describe("Short descriptive title (3-6 words) for file naming"),platform:nw1.describe("Target platform"),status:ow1,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:sw1.optional().describe("Source entity type (post, deck)")}),aw1=$4.pick({title:!0,platform:!0,status:!0,publishedAt:!0,platformPostId:!0}).extend({slug:F.string().describe("URL-friendly identifier: {platform}-{title}")}),A_=I2.extend({entityType:F.literal("social-post"),metadata:aw1}),G2A=A_.extend({frontmatter:$4,body:F.string()}),F2A=G2A.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()});I0();JA();class ZRA extends W2{constructor(){super({entityType:"social-post",schema:A_,frontmatterSchema:$4,supportsCoverImage:!0})}toMarkdown(A){let Q="",B={};try{B=this.parseFrontMatter(A.content,$4),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,$4),B=`${Q.platform}-${F2(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,$4)}getPostContent(A){return this.extractBody(A.content)}createPostContent(A,Q){return this.buildMarkdown(Q,A)}}var qI=new ZRA;I0();I0();JA();var Jt2=nH.extend({platform:F.enum(["linkedin"]).optional(),status:F.enum(["draft","queued","published","failed"]).optional(),sortByQueue:F.boolean().optional(),nextInQueue:F.boolean().optional()}),Gt2=oH.extend({query:Jt2.optional()});function tw1(A){let Q=l2(A.content,$4);return G2A.parse({...A,frontmatter:Q.metadata,body:Q.content})}class K2A extends d6{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=Gt2.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}transformEntity(A){return tw1(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 I={};if(w.platform)I.platform=w.platform;if(w.status)I.status=w.status;let f=Object.keys(I).length>0,D=w.sortByQueue?[{field:"queueOrder",direction:"asc"}]:this.config.defaultSort,{items:Y,pagination:H}=await this.fetchList(w,$,{...f&&{filter:{metadata:I}},sortFields:D});return Q.parse(this.buildListResult(Y,H,w))}async fetchNextInQueue(A,Q){let w=(await Q.listEntities({entityType:this.config.entityType,options:{filter:{metadata:{status:"queued"}},sortFields:[{field:"queueOrder",direction:"asc"}],limit:1}}))[0],$=w?tw1(w):null;return A.parse({post:$})}}JA();var ew1=F.object({accessToken:F.string().optional(),refreshToken:F.string().optional(),organizationId:F.string().optional()}),zRA=F.object({linkedin:ew1.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)});I0();JA();qRA();import{jsxDEV as b6,Fragment as Zt2}from"preact/jsx-dev-runtime";function Ft2(A,Q){if(A.length<=Q)return A;return A.slice(0,Q).trim()+"..."}function Kt2(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"})}var z2A=({posts:A,pageTitle:Q,pagination:B,baseUrl:w="/social-posts"})=>{let $=Q??"Social Posts",I=B?.totalItems??A.length,f=`Browse all ${I} social ${I===1?"post":"posts"}`;return b6(Zt2,{children:[b6(YQ,{title:$,description:f},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(xQ,{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:Kt2(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(KI,{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:Ft2(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(uY,{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 R6,Fragment as zt2}from"preact/jsx-dev-runtime";function A81(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric",hour:"numeric",minute:"2-digit"})}var N2A=({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 R6(zt2,{children:[R6(YQ,{title:Q,description:B},void 0,!1,void 0,this),R6("section",{className:"social-post-detail",children:R6("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:R6("div",{className:"max-w-3xl mx-auto",children:[R6(tD,{items:w},void 0,!1,void 0,this),R6("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-4",children:A.frontmatter.title},void 0,!1,void 0,this),R6("div",{className:"flex flex-wrap items-center gap-3 mb-6",children:[R6(KI,{status:A.frontmatter.status},void 0,!1,void 0,this),R6("span",{className:"text-sm text-theme-muted uppercase",children:A.frontmatter.platform},void 0,!1,void 0,this),R6("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&&R6(PJ,{src:A.coverImageUrl,alt:A.frontmatter.title,width:A.coverImageWidth,height:A.coverImageHeight,className:"mb-8"},void 0,!1,void 0,this),R6(xQ,{className:"p-8 mb-8",children:R6("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),R6("div",{className:"space-y-4 text-sm text-theme-muted",children:[R6("div",{children:[R6("span",{className:"font-medium",children:"Created:"},void 0,!1,void 0,this)," ",A81(A.created)]},void 0,!0,void 0,this),A.frontmatter.publishedAt&&R6("div",{children:[R6("span",{className:"font-medium",children:"Published:"},void 0,!1,void 0,this)," ",A81(A.frontmatter.publishedAt)]},void 0,!0,void 0,this),A.frontmatter.platformPostId&&R6("div",{children:R6("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 Zm(A){return`social-media:${A}`}var 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")}),Nt2=u7.extend({slug:F.string().optional()});class OC extends w${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:I,sourceEntityId:f}=A,{content:D,title:Y}=A;if(D&&Y)await this.reportProgress(Q,{progress:50,message:"Using provided content"});else if(D&&!Y){await this.reportProgress(Q,{progress:10,message:"Shaping content with AI"});let C=await this.context.ai.generate({prompt:D,templateName:Zm(B)});Y=C.title,D=C.content,await this.reportProgress(Q,{progress:50,message:"Social post shaped from content"})}else if(f&&I){await this.reportProgress(Q,{progress:10,message:`Fetching source ${I}`});let C=await this.context.entityService.getEntity({entityType:I,id:f});if(!C)this.failEarly(`Source entity not found: ${I}/${f}`);await this.reportProgress(Q,{progress:30,message:"Generating social post from source content"});let j=F.object({slug:F.string()}).safeParse(C.metadata),P=j.success?j.data.slug:f,o=await this.context.ai.generate({prompt:`Create an engaging ${B} post to promote this ${I}:
|
|
3556
|
+
`)}async function Gm(A,Q,B){if(A.length===0)return{created:0,skipped:0,batches:0};let w=Tw1(A),$=new Tf(Q.entityService,B),I=0,f=0;for(let D of w){B.info(`Processing batch of ${D.length} entities`);let Y=aa2(D),H=await W2A(Q.entityService),W=U2A({entityTitle:`Batch of ${D.length} entities`,entityType:"batch",content:Y,existingTopicTitles:H});try{let G=await Q.ai.generate({prompt:W,templateName:"topics:extraction"});for(let K of G.topics){let Z=YU(K.title);if(await $.getTopic(Z)){f++;continue}await $.createTopic({title:K.title,content:K.content}),I++}}catch(G){B.error("Batch topic extraction failed",{batchSize:D.length,promptChars:W.length,error:h0(G)})}}return{created:I,skipped:f,batches:w.length}}JA();I0();JA();var ta2=F.object({entityId:F.string(),entityType:F.string(),contentHash:F.string(),minRelevanceScore:F.number().min(0).max(1),autoMerge:F.boolean(),mergeSimilarityThreshold:F.number().min(0).max(1)});class FRA extends tB{topicExtractor;context;constructor(A,Q){super(Q,{schema:ta2,jobTypeName:"topic-extraction"});this.context=A,this.topicExtractor=new Jm(A,Q)}async process(A,Q,B){let{entityId:w,entityType:$,contentHash:I,minRelevanceScore:f,autoMerge:D,mergeSimilarityThreshold:Y}=A;this.logger.debug("Starting topic extraction job",{jobId:Q,entityId:w,entityType:$,contentHash:I});try{await B.report({progress:v2.INIT,message:`Extracting topics from ${$}: ${w}`});let H=await this.context.entityService.getEntity({entityType:$,id:w});if(!H)return this.logger.warn("Entity no longer exists, skipping topic extraction",{jobId:Q,entityId:w,entityType:$}),{success:!0,topicsExtracted:0};if(H.contentHash!==I)return this.logger.info("Entity content changed since job created, skipping stale extraction",{jobId:Q,entityId:w,entityType:$,jobContentHash:I,currentContentHash:H.contentHash}),{success:!0,topicsExtracted:0};let W=await this.topicExtractor.extractFromEntity(H,f);if(await B.report({progress:v2.EXTRACT,message:`Extracted ${W.length} topics`}),W.length===0)return this.logger.debug("No topics found in entity",{entityId:w,entityType:$}),await B.report({progress:v2.COMPLETE,message:"No topics found"}),{success:!0,topicsExtracted:0};let G=W.map((q)=>({type:"topics:process-single",data:{topic:q,sourceEntityId:w,sourceEntityType:$,autoMerge:D,mergeSimilarityThreshold:Y},metadata:{operationType:"data_processing",operationTarget:q.title}})),K=F6(),Z=await this.context.jobs.enqueueBatch(G,{priority:5,source:aR,rootJobId:K,metadata:{operationType:"batch_processing",operationTarget:`process topics for ${$}:${w}`,pluginId:aJ}});return await B.report({progress:v2.COMPLETE,message:`Queued ${W.length} topics for processing`}),this.logger.debug("Queued topic processing batch",{batchId:Z,entityId:w,entityType:$,topicsExtracted:W.length}),{success:!0,topicsExtracted:W.length,batchId:Z}}catch(H){return this.logger.error("Topic extraction job failed",{jobId:Q,entityId:w,entityType:$,error:h0(H)}),{...r8.failure(H),topicsExtracted:0}}}summarizeDataForLog(A){return{entityId:A.entityId,entityType:A.entityType,contentHash:A.contentHash}}}var ea2=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"),entityId:F.string(),entityType:F.string(),contentHash:F.string().optional(),minRelevanceScore:F.number().min(0).max(1).optional(),autoMerge:F.boolean().optional(),mergeSimilarityThreshold:F.number().min(0).max(1).optional()})]);function Sw1(A){let{context:Q,logger:B,config:w}=A,$=new FRA(Q,B),I=G6.from(async()=>{});if(!I)throw Error("Failed to create progress reporter");return{process:async(f)=>{if(f.mode==="derive")return await A.extractAllTopics(),{success:!0};if(f.mode==="rebuild")return await A.rebuildAllTopics(),{success:!0};let D=await Q.entityService.getEntity({entityType:f.entityType,id:f.entityId});if(!D)return{success:!1,topicsExtracted:0};return $.process({entityId:f.entityId,entityType:f.entityType,contentHash:f.contentHash??D.contentHash,minRelevanceScore:f.minRelevanceScore??w.minRelevanceScore,autoMerge:f.autoMerge??w.autoMerge,mergeSimilarityThreshold:f.mergeSimilarityThreshold??w.mergeSimilarityThreshold},`topic-projection:${f.entityType}:${f.entityId}`,I)},validateAndParse:(f)=>{let D=ea2.safeParse(f??{});return D.success?D.data:null}}}function mw1(){return{priority:5,source:aR,deduplication:"coalesce",deduplicationKey:"topics-initial-derivation",metadata:{operationType:"data_processing",operationTarget:"topics-initial-derivation",pluginId:aJ}}}async function uw1(A){let Q=await pw1(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 Gm(Q,A.context,A.logger);A.logger.info("Batch topic extraction complete",B)}async function cw1(A){let Q=await pw1(A),B=await KRA(Q,A.context,A.logger);A.logger.info("Topic rebuild complete",B)}async function KRA(A,Q,B){let w=new Tf(Q.entityService,B),$=await w.listTopics();for(let f of $)await w.deleteTopic(f.id);if(A.length===0)return{deleted:$.length,created:0,skipped:0,batches:0};let I=await Gm(A,Q,B);return{deleted:$.length,...I}}async function pw1(A){let Q=At2(A),B=[];for(let w of Q){let $=await A.context.entityService.listEntities({entityType:w});for(let I of $){if(!A.isEntityPublished(I))continue;B.push(I)}}return B}function At2(A){return A.context.entityService.getEntityTypes().filter((B)=>A.shouldProcessEntityType(B))}var eR=F.object({entityType:F.string(),content:F.string(),metadata:F.record(F.unknown()).optional()}),Qt2=eR.extend({minRelevanceScore:F.number().optional()}),Bt2=F.object({contentA:eR,contentB:eR,minRelevanceScore:F.number().optional()}),Km=F.object({title:F.string(),content:F.string()}),wt2=F.object({existingTopics:F.array(Km),incomingTopic:Km,threshold:F.number().optional()}),$t2=F.object({existingAliases:F.array(F.string()).optional(),canonicalTitle:F.string(),candidateAliases:F.array(F.string())}),It2=F.object({existingTopics:F.array(Km.extend({aliases:F.array(F.string()).optional()})).default([]),incomingTopic:Km.extend({relevanceScore:F.number().min(0).max(1).optional()}),threshold:F.number().optional()}),ft2=F.object({entities:F.array(eR).min(1),minRelevanceScore:F.number().optional()}),Dt2=F.object({existingTopics:F.array(Km).optional(),entities:F.array(eR)}),Yt2=F.object({entities:F.array(eR)});function Fm(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 lw1(A){return{title:A.title,relevanceScore:A.relevanceScore}}function Ht2(A){let Q=A.metadata.title;return typeof Q==="string"?Q:A.id}function Xt2(A,Q){return{...A,sources:[{id:Q.id,type:Q.entityType,title:Ht2(Q)}]}}async function VC(A){let Q=await A.entityService.listEntities({entityType:mB});await Promise.all(Q.map((B)=>A.entityService.deleteEntity({entityType:mB,id:B.id})))}function iw1(A){let{context:Q,logger:B,config:w}=A,$=new Jm(Q,B),I=async(f,D,Y="")=>{let H=Fm(f,Y);return $.extractFromEntity(H,D)};Q.eval.registerHandler("extractFromEntity",async(f)=>{await VC(Q);let D=Qt2.parse(f),Y=D.minRelevanceScore??w.minRelevanceScore,H=Fm(D);return(await $.extractFromEntity(H,Y)).map((G)=>Xt2(G,H))}),Q.eval.registerHandler("checkMergeSimilarity",async(f)=>{await VC(Q);let D=Bt2.parse(f),Y=D.minRelevanceScore??w.minRelevanceScore,[H,W]=await Promise.all([I(D.contentA,Y,"-a"),I(D.contentB,Y,"-b")]),G=H.map((q)=>q.title.toLowerCase()),K=W.map((q)=>q.title.toLowerCase()),Z=G.filter((q)=>K.includes(q));return{topicsA:H.map(lw1),topicsB:W.map(lw1),matchingTitles:Z,wouldMerge:Z.length>0}}),Q.eval.registerHandler("detectMergeCandidate",async(f)=>{await VC(Q);let D=wt2.parse(f),Y=D.threshold??w.mergeSimilarityThreshold,H=new Tf(Q.entityService,B);for(let G of D.existingTopics)await H.createTopic(G);let W=await H.findMergeCandidate({title:D.incomingTopic.title},Y);return{found:W!==null,candidateTitle:W?.title,candidateScore:W?.score}}),Q.eval.registerHandler("mergeAliases",async(f)=>{let D=$t2.parse(f);return{aliases:new Tf(Q.entityService,B).mergeAliases(D.existingAliases,D.canonicalTitle,D.candidateAliases)}}),Q.eval.registerHandler("processTopicWithAutoMerge",async(f)=>{await VC(Q);let D=It2.parse(f),Y=new Tf(Q.entityService,B);for(let Z of D.existingTopics)await Y.createTopic({title:Z.title,content:Z.content,metadata:{aliases:Z.aliases??[]}});let H=new Hm(Q,B),W=G6.from(async()=>{});if(!W)throw Error("Failed to create progress reporter");let G=await H.process({topic:{title:D.incomingTopic.title,content:D.incomingTopic.content,relevanceScore:D.incomingTopic.relevanceScore??0.9},sourceEntityId:"eval-source",sourceEntityType:"post",autoMerge:!0,mergeSimilarityThreshold:D.threshold??w.mergeSimilarityThreshold},`eval-job-${Date.now()}`,W),K=await Q.entityService.listEntities({entityType:mB});return{...G,topicCount:K.length,topics:K.map(JRA)}}),Q.eval.registerHandler("rebuildTopics",async(f)=>{await VC(Q);let D=Dt2.parse(f),Y=new Tf(Q.entityService,B);for(let K of D.existingTopics??[])await Y.createTopic(K);let H=D.entities.map((K,Z)=>Fm(K,`-rebuild-${Z}`)),W=await KRA(H,Q,B),G=await Q.entityService.listEntities({entityType:mB});return{...W,topicCount:G.length,topics:G.map(JRA)}}),Q.eval.registerHandler("extractSequentially",async(f)=>{await VC(Q);let D=ft2.parse(f),Y=D.minRelevanceScore??w.minRelevanceScore,H=new Tf(Q.entityService,B),W=[];for(let[K,Z]of D.entities.entries()){let q=Fm(Z,`-sequential-${K}`),L=await $.extractFromEntity(q,Y);for(let C of L)await H.createTopic({title:C.title,content:C.content});W.push({extractedTitles:L.map((C)=>C.title)})}let G=await Q.entityService.listEntities({entityType:mB});return{totalTopics:G.length,perEntity:W,topics:G.map(tR)}}),Q.eval.registerHandler("batchExtract",async(f)=>{await VC(Q);let Y=Yt2.parse(f).entities.map((G,K)=>Fm(G,`-batch-${K}`)),H=await Gm(Y,Q,B),W=await Q.entityService.listEntities({entityType:mB});return{...H,topics:W.map(tR)}})}var rw1={name:"@brains/topics",private:!0,version:"0.2.0-alpha.61",description:"Extract and manage topics from conversations",type:"module",main:"./src/index.ts",types:"./src/index.ts",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/plugins":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","@types/node":"^20.0.0",typescript:"^5.3.3"}};var Ut2=new tJ;class dw1 extends FQ{entityType=mB;schema=f2A;adapter=Ut2;constructor(A={}){super(aJ,rw1,A,zw1)}getEntityTypeConfig(){return{weight:0.5}}getTemplates(){return{extraction:bw1,"merge-synthesis":Rw1,"topic-list":_w1,"topic-detail":Pw1}}getDataSources(){return[new GRA(this.logger.child("TopicsDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableAutoExtraction)return[];return[{id:HRA,targetType:mB,job:{type:qw1,handler:Sw1({context:A,logger:this.logger,config:this.config,extractAllTopics:()=>this.extractAllTopics(A),rebuildAllTopics:()=>this.rebuildAllTopics(A)})},initialSync:{shouldEnqueue:async()=>!await Wz(A,mB),jobData:{mode:"derive",reason:"initial-sync"},jobOptions:mw1()},sourceChange:{sourceTypes:this.config.includeEntityTypes,requireInitialSync:!0,jobData:(Q)=>{let B=Q.entity;if(!B)return null;if(!this.shouldProcessEntityType(B.entityType))return null;if(!this.isEntityPublished(B))return null;return{mode:"source",entityId:B.id,entityType:B.entityType,contentHash:B.contentHash,minRelevanceScore:this.config.minRelevanceScore,autoMerge:this.config.autoMerge,mergeSimilarityThreshold:this.config.mergeSimilarityThreshold}},jobOptions:(Q)=>({priority:5,source:aR,deduplication:"coalesce",deduplicationKey:`topics-source:${Q.entityType}:${Q.entityId}:${Q.entity?.contentHash??"unknown"}`,metadata:{operationType:"data_processing",operationTarget:`topic-projection:${Q.entityType}:${Q.entityId}`,pluginId:aJ}})}}]}async onRegister(A){let Q=new Hm(A,this.logger);A.jobs.registerHandler("process-single",Q),A.insights.register("topic-distribution",xw1()),vw1({context:A,pluginId:this.id}),iw1({context:A,logger:this.logger,config:this.config})}hasRunInitialDerivation(){return this.getDerivedEntityProjectionController(HRA)?.hasQueuedInitialSync()??!1}shouldProcessEntityType(A){if(A===mB)return!1;return this.config.includeEntityTypes.includes(A)}isEntityPublished(A){let B=A.metadata.status;if(B===void 0||B===null)return!0;if(typeof B!=="string")return!1;return this.config.extractableStatuses.includes(B)}async extractAllTopics(A){await uw1({context:A,logger:this.logger,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}async rebuildAllTopics(A){await cw1({context:A,logger:this.logger,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}}function J2A(A){return new dw1(A)}I0();JA();I0();var nw1=F.enum(["linkedin"]),ow1=F.enum(["draft","queued","published","failed"]),sw1=F.enum(["post","deck"]),$4=F.object({title:F.string().describe("Short descriptive title (3-6 words) for file naming"),platform:nw1.describe("Target platform"),status:ow1,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:sw1.optional().describe("Source entity type (post, deck)")}),aw1=$4.pick({title:!0,platform:!0,status:!0,publishedAt:!0,platformPostId:!0}).extend({slug:F.string().describe("URL-friendly identifier: {platform}-{title}")}),A_=I2.extend({entityType:F.literal("social-post"),metadata:aw1}),G2A=A_.extend({frontmatter:$4,body:F.string()}),F2A=G2A.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()});I0();JA();class ZRA extends W2{constructor(){super({entityType:"social-post",schema:A_,frontmatterSchema:$4,supportsCoverImage:!0})}toMarkdown(A){let Q="",B={};try{B=this.parseFrontMatter(A.content,$4),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,$4),B=`${Q.platform}-${F2(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,$4)}getPostContent(A){return this.extractBody(A.content)}createPostContent(A,Q){return this.buildMarkdown(Q,A)}}var qI=new ZRA;I0();I0();JA();var Jt2=nH.extend({platform:F.enum(["linkedin"]).optional(),status:F.enum(["draft","queued","published","failed"]).optional(),sortByQueue:F.boolean().optional(),nextInQueue:F.boolean().optional()}),Gt2=oH.extend({query:Jt2.optional()});function tw1(A){let Q=l2(A.content,$4);return G2A.parse({...A,frontmatter:Q.metadata,body:Q.content})}class K2A extends d6{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=Gt2.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}transformEntity(A){return tw1(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 I={};if(w.platform)I.platform=w.platform;if(w.status)I.status=w.status;let f=Object.keys(I).length>0,D=w.sortByQueue?[{field:"queueOrder",direction:"asc"}]:this.config.defaultSort,{items:Y,pagination:H}=await this.fetchList(w,$,{...f&&{filter:{metadata:I}},sortFields:D});return Q.parse(this.buildListResult(Y,H,w))}async fetchNextInQueue(A,Q){let w=(await Q.listEntities({entityType:this.config.entityType,options:{filter:{metadata:{status:"queued"}},sortFields:[{field:"queueOrder",direction:"asc"}],limit:1}}))[0],$=w?tw1(w):null;return A.parse({post:$})}}JA();var ew1=F.object({accessToken:F.string().optional(),refreshToken:F.string().optional(),organizationId:F.string().optional()}),zRA=F.object({linkedin:ew1.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)});I0();JA();qRA();import{jsxDEV as b6,Fragment as Zt2}from"preact/jsx-dev-runtime";function Ft2(A,Q){if(A.length<=Q)return A;return A.slice(0,Q).trim()+"..."}function Kt2(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"})}var z2A=({posts:A,pageTitle:Q,pagination:B,baseUrl:w="/social-posts"})=>{let $=Q??"Social Posts",I=B?.totalItems??A.length,f=`Browse all ${I} social ${I===1?"post":"posts"}`;return b6(Zt2,{children:[b6(YQ,{title:$,description:f},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(xQ,{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:Kt2(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(KI,{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:Ft2(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(uY,{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 R6,Fragment as zt2}from"preact/jsx-dev-runtime";function A81(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric",hour:"numeric",minute:"2-digit"})}var N2A=({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 R6(zt2,{children:[R6(YQ,{title:Q,description:B},void 0,!1,void 0,this),R6("section",{className:"social-post-detail",children:R6("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:R6("div",{className:"max-w-3xl mx-auto",children:[R6(tD,{items:w},void 0,!1,void 0,this),R6("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-4",children:A.frontmatter.title},void 0,!1,void 0,this),R6("div",{className:"flex flex-wrap items-center gap-3 mb-6",children:[R6(KI,{status:A.frontmatter.status},void 0,!1,void 0,this),R6("span",{className:"text-sm text-theme-muted uppercase",children:A.frontmatter.platform},void 0,!1,void 0,this),R6("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&&R6(PJ,{src:A.coverImageUrl,alt:A.frontmatter.title,width:A.coverImageWidth,height:A.coverImageHeight,className:"mb-8"},void 0,!1,void 0,this),R6(xQ,{className:"p-8 mb-8",children:R6("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),R6("div",{className:"space-y-4 text-sm text-theme-muted",children:[R6("div",{children:[R6("span",{className:"font-medium",children:"Created:"},void 0,!1,void 0,this)," ",A81(A.created)]},void 0,!0,void 0,this),A.frontmatter.publishedAt&&R6("div",{children:[R6("span",{className:"font-medium",children:"Published:"},void 0,!1,void 0,this)," ",A81(A.frontmatter.publishedAt)]},void 0,!0,void 0,this),A.frontmatter.platformPostId&&R6("div",{children:R6("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 Zm(A){return`social-media:${A}`}var 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")}),Nt2=u7.extend({slug:F.string().optional()});class OC extends w${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:I,sourceEntityId:f}=A,{content:D,title:Y}=A;if(D&&Y)await this.reportProgress(Q,{progress:50,message:"Using provided content"});else if(D&&!Y){await this.reportProgress(Q,{progress:10,message:"Shaping content with AI"});let C=await this.context.ai.generate({prompt:D,templateName:Zm(B)});Y=C.title,D=C.content,await this.reportProgress(Q,{progress:50,message:"Social post shaped from content"})}else if(f&&I){await this.reportProgress(Q,{progress:10,message:`Fetching source ${I}`});let C=await this.context.entityService.getEntity({entityType:I,id:f});if(!C)this.failEarly(`Source entity not found: ${I}/${f}`);await this.reportProgress(Q,{progress:30,message:"Generating social post from source content"});let j=F.object({slug:F.string()}).safeParse(C.metadata),P=j.success?j.data.slug:f,o=await this.context.ai.generate({prompt:`Create an engaging ${B} post to promote this ${I}:
|
|
3557
3557
|
|
|
3558
3558
|
Source: ${I}/${P}
|
|
3559
3559
|
|
|
3560
3560
|
${C.content}`,templateName:Zm(B)});Y=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:Zm(B)});Y=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||!Y)this.failEarly("Content or title was not generated");let W={title:Y,platform:B,status:w?"queued":"draft",...f&&{sourceEntityId:f},...I&&{sourceEntityType:I}},G=qI.createPostContent(W,D),Z=qI.fromMarkdown(G).metadata;if(!Z)this.failEarly("Failed to parse social post metadata");let q=await ZU({entityType:"social-post",title:Y,deriveId:(C)=>`${B}-${F2(C)}`,regeneratePrompt:"Generate a different social media post title on the same topic.",context:this.context}),L=G;if(q!==Y){Z.title=q,Z.slug=`${B}-${F2(q)}`;let C={...W,title:q};L=qI.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}}}class ERA{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 I={shareCommentary:{text:A},shareMediaCategory:$?"IMAGE":"NONE",...$&&{media:[{status:"READY",media:$}]}},f=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":I},visibility:{"com.linkedin.ugc.MemberNetworkVisibility":"PUBLIC"}})});if(!f.ok){let H=await f.text();throw this.logger.error("LinkedIn API error",{status:f.status,error:H}),Error(`LinkedIn API error: ${f.status} - ${H}`)}let D=f.headers.get("X-RestLi-Id")??"";this.logger.info("LinkedIn post created",{postId:D,hasImage:!!$});let Y={id:D};if(D)Y.url=`https://www.linkedin.com/feed/update/${D}`;return Y}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,I=w.value.asset,f=await fetch($,{method:"PUT",headers:{Authorization:`Bearer ${this.config.accessToken}`,"Content-Type":Q.mimeType},body:new Uint8Array(Q.data)});if(!f.ok)return this.logger.warn("LinkedIn image binary upload failed",{status:f.status}),null;return this.logger.info("LinkedIn image uploaded",{assetUrn:I}),I}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 ERA(A,Q)}I0();JA();R8();qRA();var qt2=F.object({posts:F.array(F2A),totalCount:F.number().optional(),pagination:B$.nullable(),baseUrl:F.string().optional()}),Ct2=F.object({post:F2A});function Q81(){return{linkedin:Z2A,"social-post-list":b1({name:"social-post-list",description:"Social post list page template",schema:qt2,dataSourceId:"social-media:posts",requiredPermission:"public",layout:{component:z2A}}),"social-post-detail":b1({name:"social-post-detail",description:"Individual social post template",schema:Ct2,dataSourceId:"social-media:posts",requiredPermission:"public",layout:{component:N2A}})}}JA();var Et2=F.object({prompt:F.string().optional(),content:F.string().optional(),platform:F.enum(["linkedin"]).default("linkedin")}),Lt2=F.object({prompt:F.string().optional(),content:F.string().optional(),title:F.string().optional(),platform:F.enum(["linkedin"]).optional()});function B81(A){A.eval.registerHandler("generation",async(Q)=>{let B=Et2.parse(Q),w=B.content?`Create an engaging LinkedIn post to share this content:
|
|
3561
3561
|
|
|
3562
|
-
${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=Lt2.parse(Q),w=[],$=G6.from(async(H)=>{let W={progress:H.progress};if(H.message!==void 0)W.message=H.message;w.push(W)});if(!$)throw Error("Failed to create progress reporter");let f=await new OC(A.logger,A).process(B,`eval-${Date.now()}`,$),D=!1,Y;if(f.success&&f.entityId){let H=await A.entityService.getEntity({entityType:"social-post",id:f.entityId});D=!!H,Y=H?.content.slice(0,300)}return{...f,entityExists:D,entityPreview:Y,progressSteps:w}})}JA();I0();class zm{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,I=this.providers.get($);if(!I){await this.reportFailure(Q,B,`No provider configured for platform: ${$}`);return}let f=l2(w.content,$4),D;if(f.metadata.coverImageId)D=await this.fetchImageData(f.metadata.coverImageId);try{let Y=await I.publish(f.content,w.metadata,D),H=new Date().toISOString(),W=Y.id||void 0,G={...f.metadata,status:"published",publishedAt:H,...W&&{platformPostId:W}},K=qI.createPostContent(G,f.content);await this.entityService.updateEntity({entity:{...w,content:K,metadata:{...w.metadata,status:"published",publishedAt:H,platformPostId:W}}}),await this.reportSuccess(Q,B,Y.id),this.logger.info(`Post published successfully: ${B}`,{platform:$,platformPostId:W})}catch(Y){let H=Y instanceof Error?Y.message:String(Y),W={...f.metadata,status:"failed"},G=qI.createPostContent(W,f.content);await this.entityService.updateEntity({entity:{...w,content:G,metadata:{...w.metadata,status:"failed"}}}),await this.reportFailure(Q,B,H),this.logger.error(`Post publish failed: ${B}`,{platform:$,error:H})}}catch(w){let $=h0(w);this.logger.error("Unexpected error in publish handler",{entityId:B,error:$}),await this.reportFailure(Q,B,$)}}async reportSuccess(A,Q,B){await this.sendMessage({type:"publish:report:success",payload:{entityType:A,entityId:Q,result:{id:B}}})}async reportFailure(A,Q,B){await this.sendMessage({type:"publish:report:failure",payload:{entityType:A,entityId:Q,error:B}})}async 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],I=w[2];return{data:Buffer.from(I,"base64"),mimeType:$}}catch(Q){this.logger.warn("Failed to fetch cover image",{imageId:A,error:Q});return}}}function w81(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 $81(A,Q,B){let w=new zm({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")}JA();function I81(A,Q){A.messaging.subscribe("entity:updated",async(B)=>{let{entityType:w,entityId:$,entity:I}=B.payload;if(w!=="post")return{success:!0};if(I.metadata?.status!=="queued")return{success:!0};try{if((await A.entityService.listEntities({entityType:"social-post",options:{filter:{metadata:{sourceEntityType:"post",sourceEntityId:$}},limit:1}})).length>0)return Q.debug(`Social post already exists for ${$}, skipping auto-generate`),{success:!0};return await A.messaging.send({type:"social:auto-generate",payload:{sourceEntityType:w,sourceEntityId:$,platform:"linkedin"}}),Q.info(`Auto-generate social post triggered for queued post ${$}`),{success:!0}}catch(D){let Y=h0(D);return Q.error(`Failed to trigger auto-generate for ${$}:`,{error:Y}),{success:!0}}}),Q.debug("Subscribed to entity:updated for auto-generation")}function f81(A,Q){A.messaging.subscribe("social:auto-generate",async(B)=>{let{sourceEntityType:w,sourceEntityId:$,platform:I}=B.payload;try{let f=await A.jobs.enqueue({type:`${qI.entityType}:generation`,data:{sourceEntityType:w,sourceEntityId:$,platform:I,addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}});return Q.info(`Social post generation job enqueued for ${w}/${$}`,{jobId:f}),{success:!0,jobId:f}}catch(f){let D=h0(f);return Q.error(`Failed to enqueue social post generation for ${$}:`,{error:D}),{success:!1}}}),Q.debug("Subscribed to social:auto-generate messages")}function D81(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 I=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){I=D;break}if(!I)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 f=await A.jobs.enqueue({type:`${qI.entityType}:generation`,data:{sourceEntityType:"post",sourceEntityId:I.id,platform:"linkedin",addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}});return Q.info("Social post generation job queued",{jobId:f,sourcePostId:I.id}),{success:!0}}catch($){let I=h0($);return Q.error("Failed to handle generate:execute:",{error:I}),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:I}}),{success:!0}}}),Q.debug("Subscribed to generate:execute messages")}var Y81={name:"@brains/social-media",private:!0,version:"0.2.0-alpha.60",description:"Multi-provider social media posting with queue-based publishing",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class MRA extends FQ{entityType=qI.entityType;schema=A_;adapter=qI;providers=new Map;constructor(A){super("social-media",Y81,A,zRA)}createGenerationHandler(A){return new OC(this.logger.child("GenerationJobHandler"),A)}getTemplates(){return Q81()}getDataSources(){return[new K2A(this.logger.child("SocialPostDataSource"))]}async onRegister(A){if(this.initializeProviders(),w81(A,this.providers,this.logger),$81(A,this.providers,this.logger),this.config.autoGenerateOnBlogPublish)I81(A,this.logger),f81(A,this.logger),this.logger.info("Auto-generate on blog publish enabled");D81(A,this.logger),B81(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 Nm(A){return new MRA(A)}JA();var Vt2=F.enum(["draft","queued","published","failed"]),CIw=F.object({status:Vt2.default("draft"),queueOrder:F.number().optional().describe("Position in publish queue (lower = sooner)"),publishedAt:F.string().datetime().optional()});class VRA{name="internal";async publish(A,Q){return{id:"internal"}}}var M$={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"},xZ={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"};JA();var Ot2=F.object({skipIfDraftExists:F.boolean().optional(),minSourceEntities:F.number().optional(),maxUnpublishedDrafts:F.number().optional(),sourceEntityType:F.string().optional()}),H81=F.object({entitySchedules:F.record(F.string(),F.string()).optional(),generationSchedules:F.record(F.string(),F.string()).optional(),generationConditions:F.record(F.string(),Ot2).optional(),maxRetries:F.number().optional().default(3),retryBaseDelayMs:F.number().optional().default(5000)});class YW{static instance=null;queues=new Map;static getInstance(){return YW.instance??=new YW,YW.instance}static resetInstance(){YW.instance=null}static createFresh(){return new YW}constructor(){}async add(A,Q){let B=this.getOrCreateQueue(A),w=B.find((f)=>f.entityId===Q);if(w)return{position:w.position};let $=B.length+1,I={entityId:Q,entityType:A,position:$,queuedAt:new Date().toISOString()};return B.push(I),{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[I]=w.splice($,1);if(!I)return;let f=Math.max(0,Math.min(B-1,w.length));w.splice(f,0,I),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 HW{static instance=null;providers=new Map;defaultProvider=new VRA;static getInstance(){return HW.instance??=new HW,HW.instance}static resetInstance(){HW.instance=null}static createFresh(){return new HW}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())}}JA();JA();async function X81(A,Q){let B={entityType:A.entityType,entityId:A.entityId};if(Q.messageBus)await Q.messageBus.send({type:M$.EXECUTE,payload:B,sender:"publish-service"});Q.onExecute?.(B)}async function W81(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 I=h0($);Q.retryTracker.recordFailure(A.entityId,I);let f=Q.retryTracker.getRetryInfo(A.entityId);Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:I,retryCount:f?.retryCount??1,willRetry:f?.willRetry??!1})}}function U81(A,Q,B,w){if(w.retryTracker.clearRetries(Q),w.messageBus)w.messageBus.send({type:M$.COMPLETED,payload:{entityType:A,entityId:Q,result:B},sender:"publish-service"});w.onPublish?.({entityType:A,entityId:Q,result:B})}function J81(A,Q,B,w){w.retryTracker.recordFailure(Q,B);let $=w.retryTracker.getRetryInfo(Q),I={entityType:A,entityId:Q,error:B,retryCount:$?.retryCount??1,willRetry:$?.willRetry??!1};if(w.messageBus)w.messageBus.send({type:M$.FAILED,payload:I,sender:"publish-service"});w.onFailed?.(I)}async function G81(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:xZ.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:xZ.EXECUTE,payload:w,sender:"content-pipeline"});Q.onGenerate?.(w)}function F81(A,Q,B){if(B)B.send({type:xZ.COMPLETED,payload:{entityType:A,entityId:Q},sender:"content-pipeline"})}function K81(A,Q,B){if(B)B.send({type:xZ.FAILED,payload:{entityType:A,error:Q},sender:"content-pipeline"})}var bt2=1000;class ORA{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(bt2,()=>this.processUnscheduledTypes())}stop(){if(Rt2(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 X81(A,this.deps.getPublishDeps());else await W81(A,this.deps.getPublishDeps())}get entitySchedules(){return this.deps.config.entitySchedules}}function Rt2(A){for(let Q of A.values())Q.stop();A.clear()}class bRA{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(){_t2(this.generationJobs)}async handleTriggerGeneration(A){if(!this.deps.isRunning())return;try{await G81(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 _t2(A){for(let Q of A.values())Q.stop();A.clear()}class QH{static instance=null;config;publishRunner;generationRunner;running=!1;static getInstance(A){return QH.instance??=new QH(A),QH.instance}static resetInstance(){if(QH.instance)QH.instance.stop();QH.instance=null}static createFresh(A){return new QH(A)}constructor(A){this.config={...A,entitySchedules:A.entitySchedules??{},generationSchedules:A.generationSchedules??{},generationConditions:A.generationConditions??{}},this.validateCronExpressions(),this.publishRunner=new ORA({config:this.config,getPublishDeps:()=>this.publishDeps,isRunning:()=>this.running}),this.generationRunner=new bRA({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){U81(A,Q,B,this.publishDeps)}failPublish(A,Q,B){J81(A,Q,B,this.publishDeps)}async publishDirect(A,Q,B,w){return this.config.providerRegistry.get(A).publish(B,w)}completeGeneration(A,Q){F81(A,Q,this.config.messageBus)}failGeneration(A,Q){K81(A,Q,this.config.messageBus)}get entitySchedules(){return this.config.entitySchedules}get generationSchedules(){return this.config.generationSchedules}get publishDeps(){return{providerRegistry:this.config.providerRegistry,retryTracker:this.config.retryTracker,messageBus:this.config.messageBus,entityService:this.config.entityService,onExecute:this.config.onExecute,onPublish:this.config.onPublish,onFailed:this.config.onFailed}}get generationDeps(){return{logger:this.config.logger,messageBus:this.config.messageBus,generationConditions:this.config.generationConditions,onCheckGenerationConditions:this.config.onCheckGenerationConditions,onGenerate:this.config.onGenerate}}validateCronExpressions(){for(let[A,Q]of Object.entries(this.entitySchedules))this.validateCronExpression(A,Q,"publish");for(let[A,Q]of Object.entries(this.generationSchedules))this.validateCronExpression(A,Q,"generation")}validateCronExpression(A,Q,B){try{this.config.backend.validateCron(Q)}catch(w){throw Error(`Invalid ${B} cron expression for ${A}: "${Q}" - ${h0(w)}`)}}}var Z81={maxRetries:3,baseDelayMs:5000};class XW{static instance=null;retries=new Map;config;static getInstance(A){return XW.instance??=new XW(A??Z81),XW.instance}static resetInstance(){XW.instance=null}static createFresh(A){return new XW(A??Z81)}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),I=Date.now()+$;this.retries.set(A,{entityId:A,retryCount:w,lastError:Q,nextRetryAt:I})}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 V$(A,Q,B,w,$,I,f,D){return V$.fromTZ(V$.tp(A,Q,B,w,$,I,f),D)}V$.fromTZISO=(A,Q,B)=>V$.fromTZ(Pt2(A,Q),B);V$.fromTZ=function(A,Q){let B=new Date(Date.UTC(A.y,A.m-1,A.d,A.h,A.i,A.s)),w=RRA(A.tz,B),$=new Date(B.getTime()-w),I=RRA(A.tz,$);if(I-w===0)return $;{let f=new Date(B.getTime()-I),D=RRA(A.tz,f);if(D-I===0)return f;if(!Q&&D-I>0)return f;if(Q)throw Error("Invalid date passed to fromTZ()");return $}};V$.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}};V$.tp=(A,Q,B,w,$,I,f)=>({y:A,m:Q,d:B,h:w,i:$,s:I,tz:f});function RRA(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 Pt2(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("+")?V$.tp(B.getUTCFullYear(),B.getUTCMonth()+1,B.getUTCDate(),B.getUTCHours(),B.getUTCMinutes(),B.getUTCSeconds(),"Etc/UTC"):V$.tp(B.getFullYear(),B.getMonth()+1,B.getDate(),B.getHours(),B.getMinutes(),B.getSeconds(),Q)}V$.minitz=V$;var _RA=32,Cm=31|_RA,C81=[1,2,4,8,16],z81=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 I4(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,Cm),this.dayOfWeek[7]&&(this.dayOfWeek[0]=this.dayOfWeek[7])}partToArray(A,Q,B,w){let $=this[A],I=A==="day"&&this.lastDayOfMonth;if(Q===""&&!I)throw TypeError("CronPattern: configuration entry "+A+" ("+Q+") is empty, check for trailing spaces.");if(Q==="*")return $.fill(w);let f=Q.split(",");if(f.length>1)for(let D=0;D<f.length;D++)this.partToArray(A,f[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),I=parseInt($[0],10)+B;if(isNaN(I))throw TypeError("CronPattern: "+Q+" is not a number: '"+A+"'");this.setPart(Q,I,$[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),I=$[0].match(/^(\d+)-(\d+)\/(\d+)$/);if(I===null)throw TypeError("CronPattern: Syntax error, illegal range with stepping: '"+A+"'");let[,f,D,Y]=I,H=parseInt(f,10)+B,W=parseInt(D,10)+B,G=parseInt(Y,10);if(isNaN(H))throw TypeError("CronPattern: Syntax error, illegal lower range (NaN)");if(isNaN(W))throw TypeError("CronPattern: Syntax error, illegal upper range (NaN)");if(isNaN(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(H>W)throw TypeError("CronPattern: From value is larger than to value: '"+A+"'");for(let K=H;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),I=$[0].split("-");if(I.length!==2)throw TypeError("CronPattern: Syntax error, illegal range: '"+A+"'");let f=parseInt(I[0],10)+B,D=parseInt(I[1],10)+B;if(isNaN(f))throw TypeError("CronPattern: Syntax error, illegal lower range (NaN)");if(isNaN(D))throw TypeError("CronPattern: Syntax error, illegal upper range (NaN)");if(f>D)throw TypeError("CronPattern: From value is larger than to value: '"+A+"'");for(let Y=f;Y<=D;Y++)this.setPart(Q,Y,$[1]||w)}handleStepping(A,Q,B,w){let $=this.extractNth(A,Q),I=$[0].split("/");if(I.length!==2)throw TypeError("CronPattern: Syntax error, illegal stepping: '"+A+"'");I[0]===""&&(I[0]="*");let f=0;I[0]!=="*"&&(f=parseInt(I[0],10)+B);let D=parseInt(I[1],10);if(isNaN(D))throw TypeError("CronPattern: Syntax error, illegal stepping: (NaN)");if(D===0)throw TypeError("CronPattern: Syntax error, illegal stepping: 0");if(D>this[Q].length)throw TypeError("CronPattern: Syntax error, max steps for part is ("+this[Q].length+")");for(let Y=f;Y<this[Q].length;Y+=D)this.setPart(Q,Y,$[1]||w)}replaceAlphaDays(A){return A.replace(/-sun/gi,"-7").replace(/sun/gi,"0").replace(/mon/gi,"1").replace(/tue/gi,"2").replace(/wed/gi,"3").replace(/thu/gi,"4").replace(/fri/gi,"5").replace(/sat/gi,"6")}replaceAlphaMonths(A){return A.replace(/jan/gi,"1").replace(/feb/gi,"2").replace(/mar/gi,"3").replace(/apr/gi,"4").replace(/may/gi,"5").replace(/jun/gi,"6").replace(/jul/gi,"7").replace(/aug/gi,"8").replace(/sep/gi,"9").replace(/oct/gi,"10").replace(/nov/gi,"11").replace(/dec/gi,"12")}handleNicknames(A){let Q=A.trim().toLowerCase();return Q==="@yearly"||Q==="@annually"?"0 0 1 1 *":Q==="@monthly"?"0 0 1 * *":Q==="@weekly"?"0 0 * * 0":Q==="@daily"?"0 0 * * *":Q==="@hourly"?"0 * * * *":A}setNthWeekdayOfMonth(A,Q){if(typeof Q!="number"&&Q==="L")this.dayOfWeek[A]=this.dayOfWeek[A]|_RA;else if(Q===Cm)this.dayOfWeek[A]=Cm;else if(Q<6&&Q>0)this.dayOfWeek[A]=this.dayOfWeek[A]|C81[Q-1];else throw TypeError(`CronPattern: nth weekday out of range, should be 1-5 or L. Value: ${Q}, Type: ${typeof Q}`)}},N81=[31,28,31,30,31,30,31,31,30,31,30,31],eJ=[["month","year",0],["day","month",-1],["hour","day",0],["minute","hour",0],["second","minute",0]],I4=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 I=new Date(Date.UTC(Q,B,w)).getUTCDay(),f=0;for(let D=1;D<=w;D++)new Date(Date.UTC(Q,B,D)).getUTCDay()===I&&f++;if($&Cm&&C81[f-1]&$)return!0;if($&_RA){let D=new Date(Date.UTC(Q,B+1,0)).getUTCDate();for(let Y=w+1;Y<=D;Y++)if(new Date(Date.UTC(Q,B,Y)).getUTCDay()===I)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=V$.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>N81[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=V$.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(V$.fromTZISO(Q,this.tz))}findNext(Q,B,w,$){let I=this[B],f;w.lastDayOfMonth&&(this.month!==1?f=N81[this.month]:f=new Date(Date.UTC(this.year,this.month+1,0,0,0,0,0)).getUTCDate());let D=!w.starDOW&&B=="day"?new Date(Date.UTC(this.year,this.month,1,0,0,0,0)).getUTCDay():void 0;for(let Y=this[B]+$;Y<w[B].length;Y++){let H=w[B][Y];if(B==="day"&&w.lastDayOfMonth&&Y-$==f&&(H=1),B==="day"&&!w.starDOW){let W=w.dayOfWeek[(D+(Y-$-1))%7];if(W&&W&Cm)W=this.isNthWeekdayOfMonth(this.year,this.month,Y-$,W)?1:0;else if(W)throw Error(`CronDate: Invalid value for dayOfWeek encountered. ${W}`);Q.legacyMode&&!w.starDOM?H=H||W:H=H&&W}if(H)return this[B]=Y-$,I!==this[B]?2:1}return 3}recurse(Q,B,w){let $=this.findNext(B,eJ[w][0],Q,eJ[w][2]);if($>1){let I=w+1;for(;I<eJ.length;)this[eJ[I][0]]=-eJ[I][2],I++;if($===3)return this[eJ[w][1]]++,this[eJ[w][0]]=-eJ[w][2],this.apply(),this.recurse(Q,B,0);if(this.apply())return this.recurse(Q,B,w-1)}return w+=1,w>=eJ.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)):V$.fromTZ(V$.tp(this.year,this.month+1,this.day,this.hour,this.minute,this.second,this.tz),!1)}getTime(){return this.getDate(!1).getTime()}};function kt2(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 I4(A.startAt,A.timezone)),A.stopAt&&(A.stopAt=new I4(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 qm(A){return Object.prototype.toString.call(A)==="[object Function]"||typeof A=="function"||A instanceof Function}function jt2(A){return qm(A)}function xt2(A){typeof Deno<"u"&&typeof Deno.unrefTimer<"u"?Deno.unrefTimer(A):A&&typeof A.unref<"u"&&A.unref()}var q81=30000,q2A=[],PRA=class{name;options;_states;fn;constructor(A,Q,B){let w,$;if(qm(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(qm(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=kt2(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 z81("* * * * *")},A&&(A instanceof Date||typeof A=="string"&&A.indexOf(":")>0)?this._states.once=new I4(A,this.options.timezone||this.options.utcOffset):this._states.pattern=new z81(A,this.options.timezone),this.name){if(q2A.find((I)=>I.name===this.name))throw Error("Cron: Tried to initialize new named job '"+this.name+"', but name already taken.");q2A.push(this)}return $!==void 0&&jt2($)&&(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 I4||A instanceof Date?Q.getTime()-A.getTime():Q.getTime()-new I4(A).getTime():null}stop(){this._states.kill=!0,this._states.currentTimeout&&clearTimeout(this._states.currentTimeout);let A=q2A.indexOf(this);A>=0&&q2A.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>q81&&(Q=q81),this._states.currentTimeout=setTimeout(()=>this._checkTrigger(B),Q),this._states.currentTimeout&&this.options.unref&&xt2(this._states.currentTimeout),this)}async _trigger(A){if(this._states.blocking=!0,this._states.currentRun=new I4(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){qm(this.options.catch)&&this.options.catch(Q,this)}else this.fn!==void 0&&await this.fn(this,this.options.context);this._states.previousRun=new I4(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&&qm(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 I4(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 I4(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 I4(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 I4(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 C2A{scheduleCron(A,Q){let B=new PRA(A,()=>{Q()});return{stop:()=>B.stop()}}scheduleInterval(A,Q){let B=setInterval(()=>{Q()},A);return{stop:()=>clearInterval(B)}}validateCron(A){new PRA(A).stop()}}I0();JA();var kRA=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)")}),jRA=F.object({position:F.number(),entityType:F.string(),entityId:F.string(),queuedAt:F.string()}),vt2=F.object({success:F.literal(!0),message:F.string().optional(),data:F.object({queue:F.array(jRA).optional(),entityType:F.string().optional(),entityId:F.string().optional(),position:F.number().optional()}).optional()}),ht2=F.object({success:F.literal(!1),error:F.string(),code:F.string().optional()}),xRA=F.union([vt2,ht2]);function E2A(A,Q,B){return{...jQ(Q,"queue","Manage the publish queue for all entity types (list, add, remove, reorder)",kRA,async($)=>{let{action:I,entityType:f,entityId:D,position:Y}=$;switch(I){case"list":return yt2(B,f);case"add":return gt2(B,f,D);case"remove":return Tt2(B,f,D);case"reorder":return St2(B,f,D,Y);default:return{success:!1,error:`Unknown action: ${I}`}}}),outputSchema:xRA}}async function yt2(A,Q){let B=[];if(Q)B=await A.list(Q);else{let $=A.getRegisteredTypes();for(let I of $){let f=await A.list(I);B.push(...f)}B.sort((I,f)=>new Date(I.queuedAt).getTime()-new Date(f.queuedAt).getTime())}if(B.length===0)return{success:!0,data:{queue:[]},message:"No items in queue"};return{success:!0,data:{queue:B.map(($,I)=>({position:I+1,entityType:$.entityType,entityId:$.entityId,queuedAt:$.queuedAt}))},message:`${B.length} items in queue`}}async function gt2(A,Q,B){let w=vRA("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 Tt2(A,Q,B){let w=vRA("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 St2(A,Q,B,w){let $=vRA("reorder",Q,B);if(!$.success)return $.error;let I=mt2(w);if(!I.success)return I.error;return await A.reorder($.entityType,$.entityId,I.position),{success:!0,data:{entityType:$.entityType,entityId:$.entityId,position:I.position},message:`Moved to position ${I.position}`}}function vRA(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 mt2(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}}I0();JA();I0();JA();async function E81(A,Q){let{bodyContent:B,coverImageId:w}=ut2(Q.content),$=w?await ct2(A,w):void 0,I={bodyContent:B};if($)I.imageData=$;return I}function ut2(A){try{let Q=l2(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 ct2(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 hRA=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")}),pt2=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()}),lt2=F.object({success:F.literal(!1),error:F.string(),code:F.string().optional()}),yRA=F.union([pt2,lt2]);function L2A(A,Q,B){return{...jQ(Q,"publish","Publish an entity directly to its platform. Works with any registered entity type (social-post, post, deck, etc.)",hRA,async($)=>{let{entityType:I,id:f,slug:D}=$;if(!f&&!D)return{success:!1,error:"Either 'id' or 'slug' must be provided"};let Y=await it2(A,I,f,D);if(!Y)return{success:!1,error:`Entity not found: ${I}:${f??D}`};if(Y.metadata.status==="published")return{success:!1,error:"Entity is already published"};if(!B.has(I))return{success:!1,error:`No publish provider registered for ${I}. Check that the required credentials are configured.`};let H=B.get(I),{bodyContent:W,imageData:G}=await E81(A,Y),K=await H.publish(W,Y.metadata,G);return await A.entityService.updateEntity({entity:{...Y,metadata:{...Y.metadata,status:"published",publishedAt:new Date().toISOString(),platformId:K.id}}}),{success:!0,data:{entityType:I,entityId:Y.id,platformId:K.id,url:K.url},message:`Published ${I}:${Y.id}`}}),outputSchema:yRA}}async function it2(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}I0();JA();function L81(A,Q){rt2(A,Q),dt2(A,Q)}function rt2(A,Q){A.messaging.subscribe(M$.REGISTER,async(B)=>nt2(Q,B.payload)),A.messaging.subscribe(M$.QUEUE,async(B)=>ot2(A,Q,B.payload)),A.messaging.subscribe(M$.DIRECT,async(B)=>st2(A,Q,B.payload)),A.messaging.subscribe(M$.REMOVE,async(B)=>at2(Q,B.payload)),A.messaging.subscribe(M$.REORDER,async(B)=>tt2(Q,B.payload)),A.messaging.subscribe(M$.LIST,async(B)=>et2(A,Q,B.payload)),A.messaging.subscribe(M$.REPORT_SUCCESS,async(B)=>Ae2(Q,B.payload)),A.messaging.subscribe(M$.REPORT_FAILURE,async(B)=>Qe2(Q,B.payload)),Q.logger.debug("Subscribed to publish messages")}function dt2(A,Q){A.messaging.subscribe(xZ.REPORT_SUCCESS,async(B)=>Be2(Q,B.payload)),A.messaging.subscribe(xZ.REPORT_FAILURE,async(B)=>we2(Q,B.payload)),Q.logger.debug("Subscribed to generation messages")}async function nt2(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 I=h0($);return A.logger.error(`Failed to register provider: ${I}`),{success:!1}}}async function ot2(A,Q,B){let{entityType:w,entityId:$}=B;try{let I=await Q.queueManager.add(w,$);return await A.messaging.send({type:M$.QUEUED,payload:{entityType:w,entityId:$,position:I.position}}),Q.logger.debug(`Entity queued: ${$}`,{entityType:w,position:I.position}),{success:!0}}catch(I){let f=h0(I);return Q.logger.error(`Failed to queue entity: ${f}`),{success:!1}}}async function st2(A,Q,B){let{entityType:w,entityId:$}=B;return await A.messaging.send({type:M$.EXECUTE,payload:{entityType:w,entityId:$}}),Q.logger.debug(`Direct publish requested: ${$}`,{entityType:w}),{success:!0}}async function at2(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 I=h0($);return A.logger.error(`Failed to remove entity: ${I}`),{success:!1}}}async function tt2(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(I){let f=h0(I);return A.logger.error(`Failed to reorder entity: ${f}`),{success:!1}}}async function et2(A,Q,B){let{entityType:w}=B;try{let $=await Q.queueManager.list(w);return await A.messaging.send({type:M$.LIST_RESPONSE,payload:{entityType:w,queue:$.map((I)=>({entityId:I.entityId,position:I.position,queuedAt:I.queuedAt}))}}),{success:!0}}catch($){let I=h0($);return Q.logger.error(`Failed to list queue: ${I}`),{success:!1}}}async function Ae2(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 Qe2(A,Q){let{entityType:B,entityId:w,error:$}=Q;A.scheduler.failPublish(B,w,$);let I=A.retryTracker.getRetryInfo(w);return A.logger.info(`Publish reported failure: ${w}`,{entityType:B,error:$,retryCount:I?.retryCount,willRetry:I?.willRetry}),{success:!0}}async function Be2(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 we2(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}}JA();async function M81(A,Q,B,w){try{if(w.skipIfDraftExists!==!1){if((await A.listEntities({entityType:B,options:{filter:{metadata:{status:"draft"}},limit:1}})).length>0)return{shouldGenerate:!1,reason:"Draft already exists"}}if(w.maxUnpublishedDrafts!==void 0){let $=await A.listEntities({entityType:B,options:{filter:{metadata:{status:"draft"}},limit:w.maxUnpublishedDrafts+1}});if($.length>=w.maxUnpublishedDrafts)return{shouldGenerate:!1,reason:`Max unpublished drafts reached (${$.length}/${w.maxUnpublishedDrafts})`}}if(w.minSourceEntities!==void 0&&w.sourceEntityType){let $=await A.listEntities({entityType:w.sourceEntityType,options:{publishedOnly:!0,limit:w.minSourceEntities}});if($.length<w.minSourceEntities)return{shouldGenerate:!1,reason:`Not enough source entities (${$.length}/${w.minSourceEntities} ${w.sourceEntityType})`}}return{shouldGenerate:!0}}catch($){return Q.error("Failed to check generation conditions",{entityType:B,error:h0($)}),{shouldGenerate:!1,reason:`Condition check failed: ${h0($)}`}}}function V81(A){let{context:Q,config:B,queueManager:w,providerRegistry:$,retryTracker:I,logger:f}=A,D=$e2(Q);return QH.createFresh({queueManager:w,providerRegistry:$,retryTracker:I,logger:f,backend:new C2A,...B.entitySchedules&&{entitySchedules:B.entitySchedules},...B.generationSchedules&&{generationSchedules:B.generationSchedules},...B.generationConditions&&{generationConditions:B.generationConditions},messageBus:D,entityService:Q.entityService,onCheckGenerationConditions:(Y,H)=>M81(Q.entityService,f,Y,H)})}function $e2(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 O81(A,Q,B){let w=A.getEntityTypes();for(let I of w){let f=await A.listEntities({entityType:I,options:{filter:{metadata:{status:"queued"}}}});for(let D of f)await Q.add(D.entityType,D.id)}let $=0;for(let I of w){let f=await Q.list(I);$+=f.length}if($>0)B.info(`Rebuilt queue with ${$} queued entities`)}var Ie2=["draft","queued","published","failed"];async function b81(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:"operator",dataProvider:()=>fe2(A)}})}async function fe2(A){let Q=A.entityService.getEntityTypes(),B=[],w={draft:0,queued:0,published:0,failed:0};for(let $ of Q){let I=await A.entityService.listEntities({entityType:$});for(let f of I){let D=De2(f.metadata.status);if(!D)continue;w[D]++,B.push({id:f.id,title:Ye2(f.id,f.metadata.title),type:$,status:D})}}return{summary:w,items:B}}function De2(A){return Ie2.find((Q)=>Q===A)}function Ye2(A,Q){return typeof Q==="string"?Q:A}var R81={name:"@brains/content-pipeline",private:!0,version:"0.2.0-alpha.60",description:"Content pipeline plugin for managing entity publishing queues, scheduling, and generation",type:"module",main:"src/index.ts",types:"src/index.ts",scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*",croner:"^9.1.0"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14",typescript:"^5.3.3"},exports:{".":{types:"./src/index.ts",default:"./src/index.ts"}},files:["src"]};class gRA extends Ww{pluginContext;queueManager;providerRegistry;retryTracker;scheduler;constructor(A){super("content-pipeline",R81,A??{},H81)}async onRegister(A){this.pluginContext=A,this.queueManager=YW.createFresh(),this.providerRegistry=HW.createFresh(),this.retryTracker=XW.createFresh({maxRetries:this.config.maxRetries,baseDelayMs:this.config.retryBaseDelayMs}),this.scheduler=V81({context:A,config:this.config,queueManager:this.queueManager,providerRegistry:this.providerRegistry,retryTracker:this.retryTracker,logger:this.logger}),L81(A,{queueManager:this.queueManager,providerRegistry:this.providerRegistry,retryTracker:this.retryTracker,scheduler:this.scheduler,logger:this.logger})}async onReady(A){await O81(A.entityService,this.queueManager,this.logger),await b81(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[E2A(this.pluginContext,this.id,this.queueManager),L2A(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(),YW.resetInstance(),HW.resetInstance(),XW.resetInstance()}}function TRA(A){return new gRA(A)}I0();JA();var _81=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")}),SRA=F.object({cloudflare:_81.optional()});I0();JA();var Xe2=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 We2(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 P81(A,Q,B){let w=[];if(!B)return w;return w.push(jQ(A,"query",`Query website analytics from Cloudflare.
|
|
3562
|
+
${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=Lt2.parse(Q),w=[],$=G6.from(async(H)=>{let W={progress:H.progress};if(H.message!==void 0)W.message=H.message;w.push(W)});if(!$)throw Error("Failed to create progress reporter");let f=await new OC(A.logger,A).process(B,`eval-${Date.now()}`,$),D=!1,Y;if(f.success&&f.entityId){let H=await A.entityService.getEntity({entityType:"social-post",id:f.entityId});D=!!H,Y=H?.content.slice(0,300)}return{...f,entityExists:D,entityPreview:Y,progressSteps:w}})}JA();I0();class zm{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,I=this.providers.get($);if(!I){await this.reportFailure(Q,B,`No provider configured for platform: ${$}`);return}let f=l2(w.content,$4),D;if(f.metadata.coverImageId)D=await this.fetchImageData(f.metadata.coverImageId);try{let Y=await I.publish(f.content,w.metadata,D),H=new Date().toISOString(),W=Y.id||void 0,G={...f.metadata,status:"published",publishedAt:H,...W&&{platformPostId:W}},K=qI.createPostContent(G,f.content);await this.entityService.updateEntity({entity:{...w,content:K,metadata:{...w.metadata,status:"published",publishedAt:H,platformPostId:W}}}),await this.reportSuccess(Q,B,Y.id),this.logger.info(`Post published successfully: ${B}`,{platform:$,platformPostId:W})}catch(Y){let H=Y instanceof Error?Y.message:String(Y),W={...f.metadata,status:"failed"},G=qI.createPostContent(W,f.content);await this.entityService.updateEntity({entity:{...w,content:G,metadata:{...w.metadata,status:"failed"}}}),await this.reportFailure(Q,B,H),this.logger.error(`Post publish failed: ${B}`,{platform:$,error:H})}}catch(w){let $=h0(w);this.logger.error("Unexpected error in publish handler",{entityId:B,error:$}),await this.reportFailure(Q,B,$)}}async reportSuccess(A,Q,B){await this.sendMessage({type:"publish:report:success",payload:{entityType:A,entityId:Q,result:{id:B}}})}async reportFailure(A,Q,B){await this.sendMessage({type:"publish:report:failure",payload:{entityType:A,entityId:Q,error:B}})}async 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],I=w[2];return{data:Buffer.from(I,"base64"),mimeType:$}}catch(Q){this.logger.warn("Failed to fetch cover image",{imageId:A,error:Q});return}}}function w81(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 $81(A,Q,B){let w=new zm({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")}JA();function I81(A,Q){A.messaging.subscribe("entity:updated",async(B)=>{let{entityType:w,entityId:$,entity:I}=B.payload;if(w!=="post")return{success:!0};if(I.metadata?.status!=="queued")return{success:!0};try{if((await A.entityService.listEntities({entityType:"social-post",options:{filter:{metadata:{sourceEntityType:"post",sourceEntityId:$}},limit:1}})).length>0)return Q.debug(`Social post already exists for ${$}, skipping auto-generate`),{success:!0};return await A.messaging.send({type:"social:auto-generate",payload:{sourceEntityType:w,sourceEntityId:$,platform:"linkedin"}}),Q.info(`Auto-generate social post triggered for queued post ${$}`),{success:!0}}catch(D){let Y=h0(D);return Q.error(`Failed to trigger auto-generate for ${$}:`,{error:Y}),{success:!0}}}),Q.debug("Subscribed to entity:updated for auto-generation")}function f81(A,Q){A.messaging.subscribe("social:auto-generate",async(B)=>{let{sourceEntityType:w,sourceEntityId:$,platform:I}=B.payload;try{let f=await A.jobs.enqueue({type:`${qI.entityType}:generation`,data:{sourceEntityType:w,sourceEntityId:$,platform:I,addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}});return Q.info(`Social post generation job enqueued for ${w}/${$}`,{jobId:f}),{success:!0,jobId:f}}catch(f){let D=h0(f);return Q.error(`Failed to enqueue social post generation for ${$}:`,{error:D}),{success:!1}}}),Q.debug("Subscribed to social:auto-generate messages")}function D81(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 I=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){I=D;break}if(!I)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 f=await A.jobs.enqueue({type:`${qI.entityType}:generation`,data:{sourceEntityType:"post",sourceEntityId:I.id,platform:"linkedin",addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}});return Q.info("Social post generation job queued",{jobId:f,sourcePostId:I.id}),{success:!0}}catch($){let I=h0($);return Q.error("Failed to handle generate:execute:",{error:I}),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:I}}),{success:!0}}}),Q.debug("Subscribed to generate:execute messages")}var Y81={name:"@brains/social-media",private:!0,version:"0.2.0-alpha.61",description:"Multi-provider social media posting with queue-based publishing",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class MRA extends FQ{entityType=qI.entityType;schema=A_;adapter=qI;providers=new Map;constructor(A){super("social-media",Y81,A,zRA)}createGenerationHandler(A){return new OC(this.logger.child("GenerationJobHandler"),A)}getTemplates(){return Q81()}getDataSources(){return[new K2A(this.logger.child("SocialPostDataSource"))]}async onRegister(A){if(this.initializeProviders(),w81(A,this.providers,this.logger),$81(A,this.providers,this.logger),this.config.autoGenerateOnBlogPublish)I81(A,this.logger),f81(A,this.logger),this.logger.info("Auto-generate on blog publish enabled");D81(A,this.logger),B81(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 Nm(A){return new MRA(A)}JA();var Vt2=F.enum(["draft","queued","published","failed"]),CIw=F.object({status:Vt2.default("draft"),queueOrder:F.number().optional().describe("Position in publish queue (lower = sooner)"),publishedAt:F.string().datetime().optional()});class VRA{name="internal";async publish(A,Q){return{id:"internal"}}}var M$={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"},xZ={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"};JA();var Ot2=F.object({skipIfDraftExists:F.boolean().optional(),minSourceEntities:F.number().optional(),maxUnpublishedDrafts:F.number().optional(),sourceEntityType:F.string().optional()}),H81=F.object({entitySchedules:F.record(F.string(),F.string()).optional(),generationSchedules:F.record(F.string(),F.string()).optional(),generationConditions:F.record(F.string(),Ot2).optional(),maxRetries:F.number().optional().default(3),retryBaseDelayMs:F.number().optional().default(5000)});class YW{static instance=null;queues=new Map;static getInstance(){return YW.instance??=new YW,YW.instance}static resetInstance(){YW.instance=null}static createFresh(){return new YW}constructor(){}async add(A,Q){let B=this.getOrCreateQueue(A),w=B.find((f)=>f.entityId===Q);if(w)return{position:w.position};let $=B.length+1,I={entityId:Q,entityType:A,position:$,queuedAt:new Date().toISOString()};return B.push(I),{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[I]=w.splice($,1);if(!I)return;let f=Math.max(0,Math.min(B-1,w.length));w.splice(f,0,I),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 HW{static instance=null;providers=new Map;defaultProvider=new VRA;static getInstance(){return HW.instance??=new HW,HW.instance}static resetInstance(){HW.instance=null}static createFresh(){return new HW}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())}}JA();JA();async function X81(A,Q){let B={entityType:A.entityType,entityId:A.entityId};if(Q.messageBus)await Q.messageBus.send({type:M$.EXECUTE,payload:B,sender:"publish-service"});Q.onExecute?.(B)}async function W81(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 I=h0($);Q.retryTracker.recordFailure(A.entityId,I);let f=Q.retryTracker.getRetryInfo(A.entityId);Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:I,retryCount:f?.retryCount??1,willRetry:f?.willRetry??!1})}}function U81(A,Q,B,w){if(w.retryTracker.clearRetries(Q),w.messageBus)w.messageBus.send({type:M$.COMPLETED,payload:{entityType:A,entityId:Q,result:B},sender:"publish-service"});w.onPublish?.({entityType:A,entityId:Q,result:B})}function J81(A,Q,B,w){w.retryTracker.recordFailure(Q,B);let $=w.retryTracker.getRetryInfo(Q),I={entityType:A,entityId:Q,error:B,retryCount:$?.retryCount??1,willRetry:$?.willRetry??!1};if(w.messageBus)w.messageBus.send({type:M$.FAILED,payload:I,sender:"publish-service"});w.onFailed?.(I)}async function G81(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:xZ.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:xZ.EXECUTE,payload:w,sender:"content-pipeline"});Q.onGenerate?.(w)}function F81(A,Q,B){if(B)B.send({type:xZ.COMPLETED,payload:{entityType:A,entityId:Q},sender:"content-pipeline"})}function K81(A,Q,B){if(B)B.send({type:xZ.FAILED,payload:{entityType:A,error:Q},sender:"content-pipeline"})}var bt2=1000;class ORA{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(bt2,()=>this.processUnscheduledTypes())}stop(){if(Rt2(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 X81(A,this.deps.getPublishDeps());else await W81(A,this.deps.getPublishDeps())}get entitySchedules(){return this.deps.config.entitySchedules}}function Rt2(A){for(let Q of A.values())Q.stop();A.clear()}class bRA{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(){_t2(this.generationJobs)}async handleTriggerGeneration(A){if(!this.deps.isRunning())return;try{await G81(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 _t2(A){for(let Q of A.values())Q.stop();A.clear()}class QH{static instance=null;config;publishRunner;generationRunner;running=!1;static getInstance(A){return QH.instance??=new QH(A),QH.instance}static resetInstance(){if(QH.instance)QH.instance.stop();QH.instance=null}static createFresh(A){return new QH(A)}constructor(A){this.config={...A,entitySchedules:A.entitySchedules??{},generationSchedules:A.generationSchedules??{},generationConditions:A.generationConditions??{}},this.validateCronExpressions(),this.publishRunner=new ORA({config:this.config,getPublishDeps:()=>this.publishDeps,isRunning:()=>this.running}),this.generationRunner=new bRA({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){U81(A,Q,B,this.publishDeps)}failPublish(A,Q,B){J81(A,Q,B,this.publishDeps)}async publishDirect(A,Q,B,w){return this.config.providerRegistry.get(A).publish(B,w)}completeGeneration(A,Q){F81(A,Q,this.config.messageBus)}failGeneration(A,Q){K81(A,Q,this.config.messageBus)}get entitySchedules(){return this.config.entitySchedules}get generationSchedules(){return this.config.generationSchedules}get publishDeps(){return{providerRegistry:this.config.providerRegistry,retryTracker:this.config.retryTracker,messageBus:this.config.messageBus,entityService:this.config.entityService,onExecute:this.config.onExecute,onPublish:this.config.onPublish,onFailed:this.config.onFailed}}get generationDeps(){return{logger:this.config.logger,messageBus:this.config.messageBus,generationConditions:this.config.generationConditions,onCheckGenerationConditions:this.config.onCheckGenerationConditions,onGenerate:this.config.onGenerate}}validateCronExpressions(){for(let[A,Q]of Object.entries(this.entitySchedules))this.validateCronExpression(A,Q,"publish");for(let[A,Q]of Object.entries(this.generationSchedules))this.validateCronExpression(A,Q,"generation")}validateCronExpression(A,Q,B){try{this.config.backend.validateCron(Q)}catch(w){throw Error(`Invalid ${B} cron expression for ${A}: "${Q}" - ${h0(w)}`)}}}var Z81={maxRetries:3,baseDelayMs:5000};class XW{static instance=null;retries=new Map;config;static getInstance(A){return XW.instance??=new XW(A??Z81),XW.instance}static resetInstance(){XW.instance=null}static createFresh(A){return new XW(A??Z81)}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),I=Date.now()+$;this.retries.set(A,{entityId:A,retryCount:w,lastError:Q,nextRetryAt:I})}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 V$(A,Q,B,w,$,I,f,D){return V$.fromTZ(V$.tp(A,Q,B,w,$,I,f),D)}V$.fromTZISO=(A,Q,B)=>V$.fromTZ(Pt2(A,Q),B);V$.fromTZ=function(A,Q){let B=new Date(Date.UTC(A.y,A.m-1,A.d,A.h,A.i,A.s)),w=RRA(A.tz,B),$=new Date(B.getTime()-w),I=RRA(A.tz,$);if(I-w===0)return $;{let f=new Date(B.getTime()-I),D=RRA(A.tz,f);if(D-I===0)return f;if(!Q&&D-I>0)return f;if(Q)throw Error("Invalid date passed to fromTZ()");return $}};V$.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}};V$.tp=(A,Q,B,w,$,I,f)=>({y:A,m:Q,d:B,h:w,i:$,s:I,tz:f});function RRA(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 Pt2(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("+")?V$.tp(B.getUTCFullYear(),B.getUTCMonth()+1,B.getUTCDate(),B.getUTCHours(),B.getUTCMinutes(),B.getUTCSeconds(),"Etc/UTC"):V$.tp(B.getFullYear(),B.getMonth()+1,B.getDate(),B.getHours(),B.getMinutes(),B.getSeconds(),Q)}V$.minitz=V$;var _RA=32,Cm=31|_RA,C81=[1,2,4,8,16],z81=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 I4(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,Cm),this.dayOfWeek[7]&&(this.dayOfWeek[0]=this.dayOfWeek[7])}partToArray(A,Q,B,w){let $=this[A],I=A==="day"&&this.lastDayOfMonth;if(Q===""&&!I)throw TypeError("CronPattern: configuration entry "+A+" ("+Q+") is empty, check for trailing spaces.");if(Q==="*")return $.fill(w);let f=Q.split(",");if(f.length>1)for(let D=0;D<f.length;D++)this.partToArray(A,f[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),I=parseInt($[0],10)+B;if(isNaN(I))throw TypeError("CronPattern: "+Q+" is not a number: '"+A+"'");this.setPart(Q,I,$[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),I=$[0].match(/^(\d+)-(\d+)\/(\d+)$/);if(I===null)throw TypeError("CronPattern: Syntax error, illegal range with stepping: '"+A+"'");let[,f,D,Y]=I,H=parseInt(f,10)+B,W=parseInt(D,10)+B,G=parseInt(Y,10);if(isNaN(H))throw TypeError("CronPattern: Syntax error, illegal lower range (NaN)");if(isNaN(W))throw TypeError("CronPattern: Syntax error, illegal upper range (NaN)");if(isNaN(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(H>W)throw TypeError("CronPattern: From value is larger than to value: '"+A+"'");for(let K=H;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),I=$[0].split("-");if(I.length!==2)throw TypeError("CronPattern: Syntax error, illegal range: '"+A+"'");let f=parseInt(I[0],10)+B,D=parseInt(I[1],10)+B;if(isNaN(f))throw TypeError("CronPattern: Syntax error, illegal lower range (NaN)");if(isNaN(D))throw TypeError("CronPattern: Syntax error, illegal upper range (NaN)");if(f>D)throw TypeError("CronPattern: From value is larger than to value: '"+A+"'");for(let Y=f;Y<=D;Y++)this.setPart(Q,Y,$[1]||w)}handleStepping(A,Q,B,w){let $=this.extractNth(A,Q),I=$[0].split("/");if(I.length!==2)throw TypeError("CronPattern: Syntax error, illegal stepping: '"+A+"'");I[0]===""&&(I[0]="*");let f=0;I[0]!=="*"&&(f=parseInt(I[0],10)+B);let D=parseInt(I[1],10);if(isNaN(D))throw TypeError("CronPattern: Syntax error, illegal stepping: (NaN)");if(D===0)throw TypeError("CronPattern: Syntax error, illegal stepping: 0");if(D>this[Q].length)throw TypeError("CronPattern: Syntax error, max steps for part is ("+this[Q].length+")");for(let Y=f;Y<this[Q].length;Y+=D)this.setPart(Q,Y,$[1]||w)}replaceAlphaDays(A){return A.replace(/-sun/gi,"-7").replace(/sun/gi,"0").replace(/mon/gi,"1").replace(/tue/gi,"2").replace(/wed/gi,"3").replace(/thu/gi,"4").replace(/fri/gi,"5").replace(/sat/gi,"6")}replaceAlphaMonths(A){return A.replace(/jan/gi,"1").replace(/feb/gi,"2").replace(/mar/gi,"3").replace(/apr/gi,"4").replace(/may/gi,"5").replace(/jun/gi,"6").replace(/jul/gi,"7").replace(/aug/gi,"8").replace(/sep/gi,"9").replace(/oct/gi,"10").replace(/nov/gi,"11").replace(/dec/gi,"12")}handleNicknames(A){let Q=A.trim().toLowerCase();return Q==="@yearly"||Q==="@annually"?"0 0 1 1 *":Q==="@monthly"?"0 0 1 * *":Q==="@weekly"?"0 0 * * 0":Q==="@daily"?"0 0 * * *":Q==="@hourly"?"0 * * * *":A}setNthWeekdayOfMonth(A,Q){if(typeof Q!="number"&&Q==="L")this.dayOfWeek[A]=this.dayOfWeek[A]|_RA;else if(Q===Cm)this.dayOfWeek[A]=Cm;else if(Q<6&&Q>0)this.dayOfWeek[A]=this.dayOfWeek[A]|C81[Q-1];else throw TypeError(`CronPattern: nth weekday out of range, should be 1-5 or L. Value: ${Q}, Type: ${typeof Q}`)}},N81=[31,28,31,30,31,30,31,31,30,31,30,31],eJ=[["month","year",0],["day","month",-1],["hour","day",0],["minute","hour",0],["second","minute",0]],I4=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 I=new Date(Date.UTC(Q,B,w)).getUTCDay(),f=0;for(let D=1;D<=w;D++)new Date(Date.UTC(Q,B,D)).getUTCDay()===I&&f++;if($&Cm&&C81[f-1]&$)return!0;if($&_RA){let D=new Date(Date.UTC(Q,B+1,0)).getUTCDate();for(let Y=w+1;Y<=D;Y++)if(new Date(Date.UTC(Q,B,Y)).getUTCDay()===I)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=V$.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>N81[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=V$.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(V$.fromTZISO(Q,this.tz))}findNext(Q,B,w,$){let I=this[B],f;w.lastDayOfMonth&&(this.month!==1?f=N81[this.month]:f=new Date(Date.UTC(this.year,this.month+1,0,0,0,0,0)).getUTCDate());let D=!w.starDOW&&B=="day"?new Date(Date.UTC(this.year,this.month,1,0,0,0,0)).getUTCDay():void 0;for(let Y=this[B]+$;Y<w[B].length;Y++){let H=w[B][Y];if(B==="day"&&w.lastDayOfMonth&&Y-$==f&&(H=1),B==="day"&&!w.starDOW){let W=w.dayOfWeek[(D+(Y-$-1))%7];if(W&&W&Cm)W=this.isNthWeekdayOfMonth(this.year,this.month,Y-$,W)?1:0;else if(W)throw Error(`CronDate: Invalid value for dayOfWeek encountered. ${W}`);Q.legacyMode&&!w.starDOM?H=H||W:H=H&&W}if(H)return this[B]=Y-$,I!==this[B]?2:1}return 3}recurse(Q,B,w){let $=this.findNext(B,eJ[w][0],Q,eJ[w][2]);if($>1){let I=w+1;for(;I<eJ.length;)this[eJ[I][0]]=-eJ[I][2],I++;if($===3)return this[eJ[w][1]]++,this[eJ[w][0]]=-eJ[w][2],this.apply(),this.recurse(Q,B,0);if(this.apply())return this.recurse(Q,B,w-1)}return w+=1,w>=eJ.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)):V$.fromTZ(V$.tp(this.year,this.month+1,this.day,this.hour,this.minute,this.second,this.tz),!1)}getTime(){return this.getDate(!1).getTime()}};function kt2(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 I4(A.startAt,A.timezone)),A.stopAt&&(A.stopAt=new I4(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 qm(A){return Object.prototype.toString.call(A)==="[object Function]"||typeof A=="function"||A instanceof Function}function jt2(A){return qm(A)}function xt2(A){typeof Deno<"u"&&typeof Deno.unrefTimer<"u"?Deno.unrefTimer(A):A&&typeof A.unref<"u"&&A.unref()}var q81=30000,q2A=[],PRA=class{name;options;_states;fn;constructor(A,Q,B){let w,$;if(qm(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(qm(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=kt2(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 z81("* * * * *")},A&&(A instanceof Date||typeof A=="string"&&A.indexOf(":")>0)?this._states.once=new I4(A,this.options.timezone||this.options.utcOffset):this._states.pattern=new z81(A,this.options.timezone),this.name){if(q2A.find((I)=>I.name===this.name))throw Error("Cron: Tried to initialize new named job '"+this.name+"', but name already taken.");q2A.push(this)}return $!==void 0&&jt2($)&&(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 I4||A instanceof Date?Q.getTime()-A.getTime():Q.getTime()-new I4(A).getTime():null}stop(){this._states.kill=!0,this._states.currentTimeout&&clearTimeout(this._states.currentTimeout);let A=q2A.indexOf(this);A>=0&&q2A.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>q81&&(Q=q81),this._states.currentTimeout=setTimeout(()=>this._checkTrigger(B),Q),this._states.currentTimeout&&this.options.unref&&xt2(this._states.currentTimeout),this)}async _trigger(A){if(this._states.blocking=!0,this._states.currentRun=new I4(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){qm(this.options.catch)&&this.options.catch(Q,this)}else this.fn!==void 0&&await this.fn(this,this.options.context);this._states.previousRun=new I4(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&&qm(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 I4(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 I4(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 I4(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 I4(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 C2A{scheduleCron(A,Q){let B=new PRA(A,()=>{Q()});return{stop:()=>B.stop()}}scheduleInterval(A,Q){let B=setInterval(()=>{Q()},A);return{stop:()=>clearInterval(B)}}validateCron(A){new PRA(A).stop()}}I0();JA();var kRA=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)")}),jRA=F.object({position:F.number(),entityType:F.string(),entityId:F.string(),queuedAt:F.string()}),vt2=F.object({success:F.literal(!0),message:F.string().optional(),data:F.object({queue:F.array(jRA).optional(),entityType:F.string().optional(),entityId:F.string().optional(),position:F.number().optional()}).optional()}),ht2=F.object({success:F.literal(!1),error:F.string(),code:F.string().optional()}),xRA=F.union([vt2,ht2]);function E2A(A,Q,B){return{...jQ(Q,"queue","Manage the publish queue for all entity types (list, add, remove, reorder)",kRA,async($)=>{let{action:I,entityType:f,entityId:D,position:Y}=$;switch(I){case"list":return yt2(B,f);case"add":return gt2(B,f,D);case"remove":return Tt2(B,f,D);case"reorder":return St2(B,f,D,Y);default:return{success:!1,error:`Unknown action: ${I}`}}}),outputSchema:xRA}}async function yt2(A,Q){let B=[];if(Q)B=await A.list(Q);else{let $=A.getRegisteredTypes();for(let I of $){let f=await A.list(I);B.push(...f)}B.sort((I,f)=>new Date(I.queuedAt).getTime()-new Date(f.queuedAt).getTime())}if(B.length===0)return{success:!0,data:{queue:[]},message:"No items in queue"};return{success:!0,data:{queue:B.map(($,I)=>({position:I+1,entityType:$.entityType,entityId:$.entityId,queuedAt:$.queuedAt}))},message:`${B.length} items in queue`}}async function gt2(A,Q,B){let w=vRA("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 Tt2(A,Q,B){let w=vRA("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 St2(A,Q,B,w){let $=vRA("reorder",Q,B);if(!$.success)return $.error;let I=mt2(w);if(!I.success)return I.error;return await A.reorder($.entityType,$.entityId,I.position),{success:!0,data:{entityType:$.entityType,entityId:$.entityId,position:I.position},message:`Moved to position ${I.position}`}}function vRA(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 mt2(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}}I0();JA();I0();JA();async function E81(A,Q){let{bodyContent:B,coverImageId:w}=ut2(Q.content),$=w?await ct2(A,w):void 0,I={bodyContent:B};if($)I.imageData=$;return I}function ut2(A){try{let Q=l2(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 ct2(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 hRA=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")}),pt2=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()}),lt2=F.object({success:F.literal(!1),error:F.string(),code:F.string().optional()}),yRA=F.union([pt2,lt2]);function L2A(A,Q,B){return{...jQ(Q,"publish","Publish an entity directly to its platform. Works with any registered entity type (social-post, post, deck, etc.)",hRA,async($)=>{let{entityType:I,id:f,slug:D}=$;if(!f&&!D)return{success:!1,error:"Either 'id' or 'slug' must be provided"};let Y=await it2(A,I,f,D);if(!Y)return{success:!1,error:`Entity not found: ${I}:${f??D}`};if(Y.metadata.status==="published")return{success:!1,error:"Entity is already published"};if(!B.has(I))return{success:!1,error:`No publish provider registered for ${I}. Check that the required credentials are configured.`};let H=B.get(I),{bodyContent:W,imageData:G}=await E81(A,Y),K=await H.publish(W,Y.metadata,G);return await A.entityService.updateEntity({entity:{...Y,metadata:{...Y.metadata,status:"published",publishedAt:new Date().toISOString(),platformId:K.id}}}),{success:!0,data:{entityType:I,entityId:Y.id,platformId:K.id,url:K.url},message:`Published ${I}:${Y.id}`}}),outputSchema:yRA}}async function it2(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}I0();JA();function L81(A,Q){rt2(A,Q),dt2(A,Q)}function rt2(A,Q){A.messaging.subscribe(M$.REGISTER,async(B)=>nt2(Q,B.payload)),A.messaging.subscribe(M$.QUEUE,async(B)=>ot2(A,Q,B.payload)),A.messaging.subscribe(M$.DIRECT,async(B)=>st2(A,Q,B.payload)),A.messaging.subscribe(M$.REMOVE,async(B)=>at2(Q,B.payload)),A.messaging.subscribe(M$.REORDER,async(B)=>tt2(Q,B.payload)),A.messaging.subscribe(M$.LIST,async(B)=>et2(A,Q,B.payload)),A.messaging.subscribe(M$.REPORT_SUCCESS,async(B)=>Ae2(Q,B.payload)),A.messaging.subscribe(M$.REPORT_FAILURE,async(B)=>Qe2(Q,B.payload)),Q.logger.debug("Subscribed to publish messages")}function dt2(A,Q){A.messaging.subscribe(xZ.REPORT_SUCCESS,async(B)=>Be2(Q,B.payload)),A.messaging.subscribe(xZ.REPORT_FAILURE,async(B)=>we2(Q,B.payload)),Q.logger.debug("Subscribed to generation messages")}async function nt2(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 I=h0($);return A.logger.error(`Failed to register provider: ${I}`),{success:!1}}}async function ot2(A,Q,B){let{entityType:w,entityId:$}=B;try{let I=await Q.queueManager.add(w,$);return await A.messaging.send({type:M$.QUEUED,payload:{entityType:w,entityId:$,position:I.position}}),Q.logger.debug(`Entity queued: ${$}`,{entityType:w,position:I.position}),{success:!0}}catch(I){let f=h0(I);return Q.logger.error(`Failed to queue entity: ${f}`),{success:!1}}}async function st2(A,Q,B){let{entityType:w,entityId:$}=B;return await A.messaging.send({type:M$.EXECUTE,payload:{entityType:w,entityId:$}}),Q.logger.debug(`Direct publish requested: ${$}`,{entityType:w}),{success:!0}}async function at2(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 I=h0($);return A.logger.error(`Failed to remove entity: ${I}`),{success:!1}}}async function tt2(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(I){let f=h0(I);return A.logger.error(`Failed to reorder entity: ${f}`),{success:!1}}}async function et2(A,Q,B){let{entityType:w}=B;try{let $=await Q.queueManager.list(w);return await A.messaging.send({type:M$.LIST_RESPONSE,payload:{entityType:w,queue:$.map((I)=>({entityId:I.entityId,position:I.position,queuedAt:I.queuedAt}))}}),{success:!0}}catch($){let I=h0($);return Q.logger.error(`Failed to list queue: ${I}`),{success:!1}}}async function Ae2(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 Qe2(A,Q){let{entityType:B,entityId:w,error:$}=Q;A.scheduler.failPublish(B,w,$);let I=A.retryTracker.getRetryInfo(w);return A.logger.info(`Publish reported failure: ${w}`,{entityType:B,error:$,retryCount:I?.retryCount,willRetry:I?.willRetry}),{success:!0}}async function Be2(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 we2(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}}JA();async function M81(A,Q,B,w){try{if(w.skipIfDraftExists!==!1){if((await A.listEntities({entityType:B,options:{filter:{metadata:{status:"draft"}},limit:1}})).length>0)return{shouldGenerate:!1,reason:"Draft already exists"}}if(w.maxUnpublishedDrafts!==void 0){let $=await A.listEntities({entityType:B,options:{filter:{metadata:{status:"draft"}},limit:w.maxUnpublishedDrafts+1}});if($.length>=w.maxUnpublishedDrafts)return{shouldGenerate:!1,reason:`Max unpublished drafts reached (${$.length}/${w.maxUnpublishedDrafts})`}}if(w.minSourceEntities!==void 0&&w.sourceEntityType){let $=await A.listEntities({entityType:w.sourceEntityType,options:{publishedOnly:!0,limit:w.minSourceEntities}});if($.length<w.minSourceEntities)return{shouldGenerate:!1,reason:`Not enough source entities (${$.length}/${w.minSourceEntities} ${w.sourceEntityType})`}}return{shouldGenerate:!0}}catch($){return Q.error("Failed to check generation conditions",{entityType:B,error:h0($)}),{shouldGenerate:!1,reason:`Condition check failed: ${h0($)}`}}}function V81(A){let{context:Q,config:B,queueManager:w,providerRegistry:$,retryTracker:I,logger:f}=A,D=$e2(Q);return QH.createFresh({queueManager:w,providerRegistry:$,retryTracker:I,logger:f,backend:new C2A,...B.entitySchedules&&{entitySchedules:B.entitySchedules},...B.generationSchedules&&{generationSchedules:B.generationSchedules},...B.generationConditions&&{generationConditions:B.generationConditions},messageBus:D,entityService:Q.entityService,onCheckGenerationConditions:(Y,H)=>M81(Q.entityService,f,Y,H)})}function $e2(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 O81(A,Q,B){let w=A.getEntityTypes();for(let I of w){let f=await A.listEntities({entityType:I,options:{filter:{metadata:{status:"queued"}}}});for(let D of f)await Q.add(D.entityType,D.id)}let $=0;for(let I of w){let f=await Q.list(I);$+=f.length}if($>0)B.info(`Rebuilt queue with ${$} queued entities`)}var Ie2=["draft","queued","published","failed"];async function b81(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:"operator",dataProvider:()=>fe2(A)}})}async function fe2(A){let Q=A.entityService.getEntityTypes(),B=[],w={draft:0,queued:0,published:0,failed:0};for(let $ of Q){let I=await A.entityService.listEntities({entityType:$});for(let f of I){let D=De2(f.metadata.status);if(!D)continue;w[D]++,B.push({id:f.id,title:Ye2(f.id,f.metadata.title),type:$,status:D})}}return{summary:w,items:B}}function De2(A){return Ie2.find((Q)=>Q===A)}function Ye2(A,Q){return typeof Q==="string"?Q:A}var R81={name:"@brains/content-pipeline",private:!0,version:"0.2.0-alpha.61",description:"Content pipeline plugin for managing entity publishing queues, scheduling, and generation",type:"module",main:"src/index.ts",types:"src/index.ts",scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*",croner:"^9.1.0"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14",typescript:"^5.3.3"},exports:{".":{types:"./src/index.ts",default:"./src/index.ts"}},files:["src"]};class gRA extends Ww{pluginContext;queueManager;providerRegistry;retryTracker;scheduler;constructor(A){super("content-pipeline",R81,A??{},H81)}async onRegister(A){this.pluginContext=A,this.queueManager=YW.createFresh(),this.providerRegistry=HW.createFresh(),this.retryTracker=XW.createFresh({maxRetries:this.config.maxRetries,baseDelayMs:this.config.retryBaseDelayMs}),this.scheduler=V81({context:A,config:this.config,queueManager:this.queueManager,providerRegistry:this.providerRegistry,retryTracker:this.retryTracker,logger:this.logger}),L81(A,{queueManager:this.queueManager,providerRegistry:this.providerRegistry,retryTracker:this.retryTracker,scheduler:this.scheduler,logger:this.logger})}async onReady(A){await O81(A.entityService,this.queueManager,this.logger),await b81(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[E2A(this.pluginContext,this.id,this.queueManager),L2A(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(),YW.resetInstance(),HW.resetInstance(),XW.resetInstance()}}function TRA(A){return new gRA(A)}I0();JA();var _81=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")}),SRA=F.object({cloudflare:_81.optional()});I0();JA();var Xe2=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 We2(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 P81(A,Q,B){let w=[];if(!B)return w;return w.push(jQ(A,"query",`Query website analytics from Cloudflare.
|
|
3563
3563
|
|
|
3564
3564
|
Date range options (use only one):
|
|
3565
3565
|
- No params: yesterday only
|
|
@@ -3697,7 +3697,7 @@ Returns pageviews, visitors, top pages, referrers, devices, and countries.`,Xe2,
|
|
|
3697
3697
|
}
|
|
3698
3698
|
}
|
|
3699
3699
|
}
|
|
3700
|
-
`,variables:B})});if(!w.ok){let f=await w.text();throw Error(`Cloudflare API error: ${w.status} - ${f}`)}let $=await w.json();if($.errors&&$.errors.length>0)throw Error(`Cloudflare GraphQL error: ${$.errors.map((f)=>f.message).join(", ")}`);return($.data.viewer.accounts[0]?.rumPageloadEventsAdaptiveGroups??[]).map((f)=>({country:f.dimensions.countryName,visits:f.sum.visits}))}}JA();var uRA=7,Ue2=10;function j81(A){return async()=>{if(!A)return{unavailable:!0,reason:"Cloudflare analytics not configured"};let Q=LL(),B=gp(uRA),w=UF(B),$=UF(Q);try{let[I,f]=await Promise.all([A.getWebsiteStats({startDate:w,endDate:$}),A.getTopPages({startDate:w,endDate:$,limit:Ue2})]);return{days:uRA,startDate:w,endDate:$,pageviews:I.pageviews,visitors:I.visitors,topPages:f}}catch(I){return{error:I instanceof Error?I.message:"Failed to fetch analytics",days:uRA}}}}var x81={name:"@brains/analytics",private:!0,version:"0.2.0-alpha.
|
|
3700
|
+
`,variables:B})});if(!w.ok){let f=await w.text();throw Error(`Cloudflare API error: ${w.status} - ${f}`)}let $=await w.json();if($.errors&&$.errors.length>0)throw Error(`Cloudflare GraphQL error: ${$.errors.map((f)=>f.message).join(", ")}`);return($.data.viewer.accounts[0]?.rumPageloadEventsAdaptiveGroups??[]).map((f)=>({country:f.dimensions.countryName,visits:f.sum.visits}))}}JA();var uRA=7,Ue2=10;function j81(A){return async()=>{if(!A)return{unavailable:!0,reason:"Cloudflare analytics not configured"};let Q=LL(),B=gp(uRA),w=UF(B),$=UF(Q);try{let[I,f]=await Promise.all([A.getWebsiteStats({startDate:w,endDate:$}),A.getTopPages({startDate:w,endDate:$,limit:Ue2})]);return{days:uRA,startDate:w,endDate:$,pageviews:I.pageviews,visitors:I.visitors,topPages:f}}catch(I){return{error:I instanceof Error?I.message:"Failed to fetch analytics",days:uRA}}}}var x81={name:"@brains/analytics",private:!0,version:"0.2.0-alpha.61",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 v81 extends Ww{cloudflareClient;constructor(A={}){super("analytics",x81,A,SRA)}async onRegister(A){this.cloudflareClient=this.config.cloudflare?new mRA(this.config.cloudflare):void 0,A.insights.register("traffic-overview",j81(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:k81(Q)}})}async getTools(){return P81(this.id,this.getContext(),this.cloudflareClient)}}function Ge2(A={}){return new v81(A)}var M2A=Ge2;I0();JA();Ow();var Fe2=new Set(["description","excerpt","summary","tagline","story"]);function Ke2(A){if(A.endsWith("s"))return A;return dI(A)}function cRA(A,Q=!1,B){let w=A._def.typeName;if(w==="ZodOptional"||w==="ZodNullable")return cRA(A._def.innerType,!0,B);if(w==="ZodDefault")return cRA(A._def.innerType,Q,A._def.defaultValue());return{inner:A,isOptional:Q,defaultValue:B}}function pRA(A,Q){let{inner:B,isOptional:w,defaultValue:$}=cRA(Q),I=B._def.typeName,f={name:A,label:mH(A),widget:"string",...w&&{required:!1},...$!==void 0&&{default:$}};switch(I){case"ZodString":{if((B._def.checks??[]).some((Y)=>Y.kind==="datetime"))return{...f,widget:"datetime"};if(Fe2.has(A))return{...f,widget:"text"};return{...f,widget:"string"}}case"ZodNumber":return{...f,widget:"number"};case"ZodBoolean":return{...f,widget:"boolean"};case"ZodEnum":{let D=B._def.values;return{...f,widget:"select",options:D}}case"ZodArray":{let D=B._def.type,Y=pRA("item",D);if(Y.widget==="object"&&Y.fields)return{...f,widget:"list",fields:Y.fields};return{...f,widget:"list",field:{name:A,label:mH(A),widget:Y.widget}}}case"ZodObject":{let D=B.shape,Y=Object.entries(D).map(([H,W])=>pRA(H,W));return{...f,widget:"object",fields:Y}}default:return{...f,widget:"string"}}}function h81(A,Q){let B=Object.entries(A.shape).map(([w,$])=>pRA(w,$));if(Q)B.push({name:"body",label:"Body",widget:"markdown"});return B}function y81(A){let Q=[],B=[];for(let w of A.entityTypes){let $=A.getFrontmatterSchema(w);if(!$)continue;let I=A.getAdapter(w),f=I?.hasBody!==!1,D=A.entityDisplay?.[w],Y=w===Ol?"Note":mH(w),H=D?.label??Y,W=D?.pluralName??Ke2(H);if(I?.isSingleton){B.push({name:w,label:H,file:`${w}/${w}.md`,fields:h81($,f)});continue}if(w===Ol){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:h81($,f)})}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 lRA(A){return`<!doctype html>
|
|
3701
3701
|
<html>
|
|
3702
3702
|
<head>
|
|
3703
3703
|
<meta charset="utf-8" />
|
|
@@ -3708,7 +3708,7 @@ Returns pageviews, visitors, top pages, referrers, devices, and countries.`,Xe2,
|
|
|
3708
3708
|
</head>
|
|
3709
3709
|
<body></body>
|
|
3710
3710
|
</html>
|
|
3711
|
-
`}JA();var g81={name:"@brains/cms",private:!0,version:"0.2.0-alpha.
|
|
3711
|
+
`}JA();var g81={name:"@brains/cms",private:!0,version:"0.2.0-alpha.61",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 ze2=F.object({label:F.string().optional(),pluralName:F.string().optional()}).passthrough(),Ne2=F.object({entityDisplay:F.record(ze2).optional(),routePath:F.string().default("/cms")});function qe2(A){return`${A.endsWith("/")?A:`${A}/`}config.yml`}function Ce2(A,Q){let B=A.entityDisplay??Q?.entityDisplay;return B?{entityDisplay:B}:{}}async function Ee2(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 Le2(A,Q={}){let{repo:B,branch:w}=await Ee2(A);return y81({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 T81(A,Q={}){return SH(await Le2(A,Q))}class iRA extends Ww{constructor(A={}){super("cms",g81,A,Ne2)}async onRegister(A){await super.onRegister(A),A.endpoints.register({label:"CMS",url:this.config.routePath,priority:40})}getWebRoutes(){let A=qe2(this.config.routePath);return[{path:this.config.routePath,method:"GET",public:!0,handler:async()=>{return new Response(lRA({cmsConfigPath:A}),{headers:{"Content-Type":"text/html; charset=utf-8"}})}},{path:A,method:"GET",public:!0,handler:async()=>{try{let Q=await T81(this.getContext(),Ce2(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 bC(A){return new iRA(A)}I0();JA();JA();var V2A=["StatsWidget","ListWidget","CustomWidget","PipelineWidget","IdentityWidget","ProfileWidget","SystemWidget"],Me2=new Set(V2A);function rRA(A){return Me2.has(A)}var S81=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:F.enum(["public","operator"]).default("public")});class O2A{widgets=new Map;logger;constructor(A){this.logger=A.child("DashboardWidgetRegistry")}register(A){let Q={...A,...S81.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;return Array.from(this.widgets.values()).filter((B)=>!Q.section||B.section===Q.section).filter((B)=>(Q.includeOperator??!1)||B.visibility!=="operator").sort((B,w)=>B.priority-w.priority)}get size(){return this.widgets.size}}JA();class b2A{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=this.registry.list({...A.includeOperator!==void 0&&{includeOperator:A.includeOperator}}),w=await Promise.allSettled(B.map(async($)=>{let I=await $.dataProvider(),{dataProvider:f,component:D,clientScript:Y,visibility:H="public",...W}=$;return{key:`${$.pluginId}:${$.id}`,widget:{...W,visibility:H},data:I}}));for(let $=0;$<w.length;$++){let I=w[$],f=B[$];if(!I||!f)continue;if(I.status==="fulfilled")Q[I.value.key]={widget:I.value.widget,data:I.value.data};else this.logger.error("Widget data provider failed",{widgetId:f.id,pluginId:f.pluginId,error:h0(I.reason)})}return{widgets:Q}}async fetch(A,Q,B){return await this.getDashboardData()}}import{render as se2}from"preact-render-to-string";var m81=`
|
|
3712
3712
|
:root {
|
|
3713
3713
|
--ink: #0a0819;
|
|
3714
3714
|
--ink-raised: #14112b;
|
|
@@ -4685,7 +4685,7 @@ body::after {
|
|
|
4685
4685
|
}
|
|
4686
4686
|
});
|
|
4687
4687
|
})();`;function QAQ({input:A}){let Q=A.entityCounts.reduce((f,{count:D})=>f+D,0),B=te2(A.widgets),w=Boolean(A.character.role)||Boolean(A.character.purpose)||A.character.values.length>0,$=A.appInfo.endpoints.length>0,I=A.operatorAccess&&!A.operatorAccess.isOperator&&A.operatorAccess.hiddenWidgetCount>0;return PB("html",{lang:"en","data-theme":"dark",children:[PB("head",{children:[PB("meta",{charSet:"utf-8"},void 0,!1,void 0,this),PB("meta",{name:"viewport",content:"width=device-width, initial-scale=1.0"},void 0,!1,void 0,this),PB("title",{children:A.title},void 0,!1,void 0,this),PB("link",{rel:"preconnect",href:"https://fonts.googleapis.com"},void 0,!1,void 0,this),PB("link",{rel:"preconnect",href:"https://fonts.gstatic.com",crossOrigin:"anonymous"},void 0,!1,void 0,this),PB("link",{href:ae2,rel:"stylesheet"},void 0,!1,void 0,this),PB("style",{dangerouslySetInnerHTML:{__html:m81}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),PB("body",{children:[PB("main",{class:"console","data-component":"dashboard:dashboard",children:[PB(c81,{title:A.title,tagline:A.profile.description,appInfo:A.appInfo,now:new Date,operatorAccess:A.operatorAccess},void 0,!1,void 0,this),PB("section",{class:"layout",children:[PB("div",{class:"main-column",children:[PB(p81,{total:Q,entityCounts:A.entityCounts},void 0,!1,void 0,this),I&&A.operatorAccess&&PB("section",{class:"card operator-gate",children:[PB("div",{children:[PB("div",{class:"card-title",children:"Operator layer"},void 0,!1,void 0,this),PB("p",{children:[A.operatorAccess.hiddenWidgetCount===1?"1 operator widget is hidden.":`${A.operatorAccess.hiddenWidgetCount} operator widgets are hidden.`," ","","Sign in with your passkey to unlock private console data."]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),PB("a",{class:"operator-gate-link",href:A.operatorAccess.loginUrl,children:"Sign in"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),B.primary.map((f)=>PB(R2A,{widget:f},`${f.widget.pluginId}:${f.widget.id}`,!1,void 0,this)),B.secondary.map((f)=>PB(R2A,{widget:f},`${f.widget.pluginId}:${f.widget.id}`,!1,void 0,this))]},void 0,!0,void 0,this),(w||B.sidebar.length>0||$)&&PB("div",{class:"sidebar-column",children:[PB(l81,{character:A.character},void 0,!1,void 0,this),B.sidebar.map((f)=>PB(R2A,{widget:f},`${f.widget.pluginId}:${f.widget.id}`,!1,void 0,this)),PB(i81,{endpoints:A.appInfo.endpoints,baseUrl:A.baseUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),PB(o81,{title:A.title,appInfo:A.appInfo},void 0,!1,void 0,this)]},void 0,!0,void 0,this),PB("button",{class:"theme-toggle",id:"themeToggle","aria-label":"Toggle theme",children:"Light mode"},void 0,!1,void 0,this),PB("script",{dangerouslySetInnerHTML:{__html:ee2}},void 0,!1,void 0,this),PB("script",{dangerouslySetInnerHTML:{__html:AAQ}},void 0,!1,void 0,this),A.widgetScripts.map((f,D)=>PB("script",{dangerouslySetInnerHTML:{__html:f}},`widget-script:${D}`,!1,void 0,this))]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}function s81(A){return`<!doctype html>
|
|
4688
|
-
${se2(PB(QAQ,{input:A},void 0,!1,void 0,this))}`}function a81(A,Q){let B={},w=new Set;for(let[$,I]of Object.entries(A)){let f=Q?.get(I.widget.pluginId,I.widget.id);if(B[$]={...I,...f?.component?{component:f.component}:{}},f?.clientScript)w.add(f.clientScript)}return{widgets:B,widgetScripts:Array.from(w)}}var t81={name:"@brains/dashboard",private:!0,version:"0.2.0-alpha.
|
|
4688
|
+
${se2(PB(QAQ,{input:A},void 0,!1,void 0,this))}`}function a81(A,Q){let B={},w=new Set;for(let[$,I]of Object.entries(A)){let f=Q?.get(I.widget.pluginId,I.widget.id);if(B[$]={...I,...f?.component?{component:f.component}:{}},f?.clientScript)w.add(f.clientScript)}return{widgets:B,widgetScripts:Array.from(w)}}var t81={name:"@brains/dashboard",private:!0,version:"0.2.0-alpha.61",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 wAQ=F.object({version:F.string().default("1.0.0"),routePath:F.string().default("/dashboard")}),$AQ=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:F.enum(["public","operator"]).default("public"),component:F.custom().optional(),clientScript:F.string().optional(),dataProvider:F.function().returns(F.promise(F.unknown()))}).superRefine((A,Q)=>{if(!rRA(A.rendererName)&&!A.component)Q.addIssue({code:F.ZodIssueCode.custom,message:"Custom dashboard widgets must register a Preact component.",path:["component"]})}),IAQ=F.object({pluginId:F.string(),widgetId:F.string().optional()});function fAQ(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 oRA extends Ww{widgetRegistry=null;datasource=null;siteUrl;ctx;constructor(A){super("dashboard",t81,A??{},wAQ)}async onRegister(A){this.siteUrl=A.siteUrl,this.ctx=A,this.widgetRegistry=new O2A(this.logger),this.datasource=new b2A(this.widgetRegistry,this.logger),A.entities.registerDataSource(this.datasource),A.messaging.subscribe("dashboard:register-widget",async(Q)=>{try{let B=$AQ.parse(Q.payload),w=fAQ(B);return this.widgetRegistry?.register(w),this.logger.debug("Widget registered via messaging",{widgetId:B.id,pluginId:B.pluginId,rendererName:B.rendererName,builtIn:V2A.includes(B.rendererName)}),{success:!0}}catch(B){return this.logger.error("Failed to register widget",{error:h0(B),payload:Q.payload}),{success:!1,error:"Widget registration failed"}}}),A.messaging.subscribe("dashboard:unregister-widget",async(Q)=>{let B=IAQ.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 hO()?.getOperatorSession(A),w=Boolean(B),$=w?0:this.widgetRegistry?.list({includeOperator:!0}).filter((R)=>R.visibility==="operator").length??0,[I,f,D]=await Promise.all([this.datasource.getDashboardData({includeOperator:w}),Q.appInfo(),Q.entityService.getEntityCounts()]),Y=Q.identity.get(),H=Q.identity.getProfile(),W=this.siteUrl??(()=>{try{return new URL(A.url).origin}catch{return}})(),G=H.name||f.model||"Brain Dashboard",K=new URL(A.url),Z=`${K.pathname}${K.search}`,q=encodeURIComponent(Z),L=a81(I.widgets,this.widgetRegistry),C={title:G,baseUrl:W,widgets:L.widgets,widgetScripts:L.widgetScripts,character:Y,profile:H,appInfo:f,entityCounts:D,operatorAccess:{isOperator:w,hiddenWidgetCount:$,loginUrl:`/login?return_to=${q}`,logoutUrl:`/logout?return_to=${q}`}};return new Response(s81(C),{headers:{"Content-Type":"text/html; charset=utf-8"}})}}]}async getTools(){return[]}getWidgetRegistry(){return this.widgetRegistry}}function hZ(A){return new oRA(A)}JA();var DAQ=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:F.enum(["public","operator"]),component:F.custom().optional()}),YAQ=F.object({widget:DAQ,data:F.unknown()}),HAQ=F.object({widgets:F.record(YAQ)});JA();I0();JA();import{h as LAQ}from"preact";JA();KD();I0();var Q_=F.enum(["draft","queued","published","failed"]),Em=F.object({subject:F.string(),status:Q_,entityIds:F.array(F.string()).optional(),scheduledFor:F.string().datetime().optional(),sentAt:F.string().datetime().optional(),buttondownId:F.string().optional(),sourceEntityType:F.string().optional()}),e81=Em.pick({subject:!0,status:!0,entityIds:!0,scheduledFor:!0,sentAt:!0,buttondownId:!0,sourceEntityType:!0}),Lm=I2.extend({entityType:F.literal("newsletter"),metadata:e81});I0();class A61 extends W2{constructor(){super({entityType:"newsletter",schema:Lm,frontmatterSchema:Em})}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 Q61=new A61;I0();I0();JA();var XAQ=nH.extend({status:F.enum(["draft","queued","published","failed"]).optional()}),WAQ=oH.extend({query:XAQ.optional()});function B61(A){try{let{content:Q}=l2(A.content,Em);return Q}catch{return A.content}}class sRA extends d6{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=WAQ.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}transformEntity(A){let Q=B61(A),B={id:A.id,subject:A.metadata.subject,status:A.metadata.status,excerpt:WF(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 I=w.status,f=I?{filter:{metadata:{status:I}}}:void 0,{items:D,pagination:Y}=await this.fetchList(w,$,f);return Q.parse(this.buildListResult(D,Y,w))}async fetchSingleNewsletter(A,Q,B){let w=await B.getEntity({entityType:this.config.entityType,id:A});if(!w)throw Error(`Newsletter not found: ${A}`);let $=await this.resolveNavigation(w,B),I=[];if(w.metadata.entityIds?.length){let Y=w.metadata.sourceEntityType??"post";I=(await Promise.all(w.metadata.entityIds.map(async(W)=>{let G=await B.getEntity({entityType:Y,id:W});if(G){let K=G.metadata;return{id:W,title:K.title??W,url:`/${Y}s/${K.slug??W}`}}return null}))).filter((W)=>W!==null)}let f=B61(w),D={id:w.id,subject:w.metadata.subject,status:w.metadata.status,content:f,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:I.length>0?I:void 0};return Q.parse(D)}}I0();JA();var UAQ=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 aRA extends w${constructor(A,Q){super(A,Q,{schema:UAQ,jobTypeName:"newsletter:generation",entityType:"newsletter"})}async generate(A,Q){let B=A.addToQueue??!1,{prompt:w,sourceEntityIds:$,sourceEntityType:I}=A,{content:f,subject:D}=A;if(f){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=I??"post";await this.reportProgress(Q,{progress:10,message:`Fetching ${$.length} source entities`});let q=(await Promise.all($.map((P)=>this.context.entityService.getEntity({entityType:K,id:P})))).filter((P)=>P!=null);if(q.length===0)this.failEarly(`No source entities found for IDs: ${$.join(", ")}`);await this.reportProgress(Q,{progress:30,message:`Generating newsletter from ${q.length} posts`});let C=`Create an engaging newsletter that highlights these blog posts:
|
|
4689
4689
|
|
|
4690
4690
|
${q.map((P)=>`## ${P.metadata.title}
|
|
4691
4691
|
|
|
@@ -4754,14 +4754,14 @@ Newsletter-specific guidelines:
|
|
|
4754
4754
|
- "Reply and let me know..."
|
|
4755
4755
|
- "Until next time..."
|
|
4756
4756
|
|
|
4757
|
-
The goal is to build a relationship with readers through valuable, authentic content.`});JA();I0();import{jsxDEV as V7,Fragment as ZAQ}from"preact/jsx-dev-runtime";var GAQ=F.object({id:F.string(),subject:F.string(),status:Q_,excerpt:F.string(),created:F.string(),sentAt:F.string().optional(),url:F.string()}),FAQ=F.object({newsletters:F.array(GAQ),totalCount:F.number(),pagination:B$.nullable()}),KAQ=({newsletters:A,totalCount:Q,pageTitle:B,pagination:w,baseUrl:$="/newsletters"})=>{let I=B??"Newsletters",f=`Browse all ${Q} ${Q===1?"newsletter":"newsletters"}`;return V7(ZAQ,{children:[V7(YQ,{title:I,description:f},void 0,!1,void 0,this),V7("div",{className:"newsletter-list bg-theme",children:V7("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[V7("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:I},void 0,!1,void 0,this),A.length===0?V7("p",{className:"text-theme-muted italic",children:"No newsletters yet."},void 0,!1,void 0,this):V7("div",{className:"space-y-4",children:A.map((D)=>V7(xQ,{href:D.url,children:[V7(Q9,{className:"text-lg",children:D.subject},void 0,!1,void 0,this),V7(k9,{children:V7("div",{className:"flex items-center gap-3",children:[V7(KI,{status:D.status},void 0,!1,void 0,this),V7("span",{className:"text-sm text-theme-muted",children:Z8(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&&V7("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&&V7(uY,{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)},$61=b1({name:"newsletter-list",description:"Newsletter list page template",schema:FAQ,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:KAQ}});JA();I0();import{jsxDEV as hw,Fragment as CAQ}from"preact/jsx-dev-runtime";var zAQ=F.object({id:F.string(),title:F.string(),url:F.string()}),I61=F.object({id:F.string(),subject:F.string(),url:F.string()}),NAQ=F.object({id:F.string(),subject:F.string(),status:Q_,content:F.string(),created:F.string(),updated:F.string(),sentAt:F.string().optional(),scheduledFor:F.string().optional(),sourceEntities:F.array(zAQ).optional(),prevNewsletter:I61.nullable().optional(),nextNewsletter:I61.nullable().optional()}),qAQ=({subject:A,status:Q,content:B,created:w,sentAt:$,scheduledFor:I,sourceEntities:f,prevNewsletter:D,nextNewsletter:Y})=>{let H=[{label:"Home",href:"/"},{label:"Newsletters",href:"/newsletters"},{label:A}],W=$??w,G=$?"Sent":"Created";return hw(CAQ,{children:[hw(YQ,{title:A,description:`Newsletter: ${A}`},void 0,!1,void 0,this),hw("section",{className:"newsletter-detail-section",children:hw("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:hw("div",{className:"max-w-3xl mx-auto",children:[hw(tD,{items:H},void 0,!1,void 0,this),hw("h1",{className:"text-3xl md:text-4xl font-bold text-heading leading-tight tracking-tight mb-4",children:A},void 0,!1,void 0,this),hw("div",{className:"flex flex-wrap items-center gap-3 mb-8 text-sm text-theme-muted",children:[hw(KI,{status:Q},void 0,!1,void 0,this),hw("span",{children:[G,": ",Z8(W,{style:"long"})]},void 0,!0,void 0,this),I&&Q==="queued"&&hw("span",{children:["Scheduled for: ",Z8(I,{style:"long"})]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),f&&f.length>0&&hw(xQ,{variant:"compact",className:"mb-8",children:[hw("h3",{className:"text-sm font-medium text-heading mb-2",children:"Related Content"},void 0,!1,void 0,this),hw("ul",{className:"space-y-1",children:f.map((K)=>hw("li",{children:hw("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),hw(jf,{markdown:B},void 0,!1,void 0,this),(D??Y)&&hw("nav",{className:"mt-12 pt-8 border-t border-theme",children:hw("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[D?hw(xQ,{href:D.url,variant:"compact",children:[hw("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Newer"},void 0,!1,void 0,this),hw("span",{className:"block mt-1 font-medium text-heading group-hover:text-brand transition-colors truncate",children:D.subject},void 0,!1,void 0,this)]},void 0,!0,void 0,this):hw("div",{},void 0,!1,void 0,this),Y&&hw(xQ,{href:Y.url,variant:"compact",className:"md:text-right",children:[hw("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Older"},void 0,!1,void 0,this),hw("span",{className:"block mt-1 font-medium text-heading group-hover:text-brand transition-colors truncate",children:Y.subject},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},f61=b1({name:"newsletter-detail",description:"Individual newsletter detail template",schema:NAQ,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:qAQ}});var D61={name:"@brains/newsletter-entity",private:!0,version:"0.2.0-alpha.
|
|
4757
|
+
The goal is to build a relationship with readers through valuable, authentic content.`});JA();I0();import{jsxDEV as V7,Fragment as ZAQ}from"preact/jsx-dev-runtime";var GAQ=F.object({id:F.string(),subject:F.string(),status:Q_,excerpt:F.string(),created:F.string(),sentAt:F.string().optional(),url:F.string()}),FAQ=F.object({newsletters:F.array(GAQ),totalCount:F.number(),pagination:B$.nullable()}),KAQ=({newsletters:A,totalCount:Q,pageTitle:B,pagination:w,baseUrl:$="/newsletters"})=>{let I=B??"Newsletters",f=`Browse all ${Q} ${Q===1?"newsletter":"newsletters"}`;return V7(ZAQ,{children:[V7(YQ,{title:I,description:f},void 0,!1,void 0,this),V7("div",{className:"newsletter-list bg-theme",children:V7("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[V7("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:I},void 0,!1,void 0,this),A.length===0?V7("p",{className:"text-theme-muted italic",children:"No newsletters yet."},void 0,!1,void 0,this):V7("div",{className:"space-y-4",children:A.map((D)=>V7(xQ,{href:D.url,children:[V7(Q9,{className:"text-lg",children:D.subject},void 0,!1,void 0,this),V7(k9,{children:V7("div",{className:"flex items-center gap-3",children:[V7(KI,{status:D.status},void 0,!1,void 0,this),V7("span",{className:"text-sm text-theme-muted",children:Z8(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&&V7("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&&V7(uY,{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)},$61=b1({name:"newsletter-list",description:"Newsletter list page template",schema:FAQ,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:KAQ}});JA();I0();import{jsxDEV as hw,Fragment as CAQ}from"preact/jsx-dev-runtime";var zAQ=F.object({id:F.string(),title:F.string(),url:F.string()}),I61=F.object({id:F.string(),subject:F.string(),url:F.string()}),NAQ=F.object({id:F.string(),subject:F.string(),status:Q_,content:F.string(),created:F.string(),updated:F.string(),sentAt:F.string().optional(),scheduledFor:F.string().optional(),sourceEntities:F.array(zAQ).optional(),prevNewsletter:I61.nullable().optional(),nextNewsletter:I61.nullable().optional()}),qAQ=({subject:A,status:Q,content:B,created:w,sentAt:$,scheduledFor:I,sourceEntities:f,prevNewsletter:D,nextNewsletter:Y})=>{let H=[{label:"Home",href:"/"},{label:"Newsletters",href:"/newsletters"},{label:A}],W=$??w,G=$?"Sent":"Created";return hw(CAQ,{children:[hw(YQ,{title:A,description:`Newsletter: ${A}`},void 0,!1,void 0,this),hw("section",{className:"newsletter-detail-section",children:hw("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:hw("div",{className:"max-w-3xl mx-auto",children:[hw(tD,{items:H},void 0,!1,void 0,this),hw("h1",{className:"text-3xl md:text-4xl font-bold text-heading leading-tight tracking-tight mb-4",children:A},void 0,!1,void 0,this),hw("div",{className:"flex flex-wrap items-center gap-3 mb-8 text-sm text-theme-muted",children:[hw(KI,{status:Q},void 0,!1,void 0,this),hw("span",{children:[G,": ",Z8(W,{style:"long"})]},void 0,!0,void 0,this),I&&Q==="queued"&&hw("span",{children:["Scheduled for: ",Z8(I,{style:"long"})]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),f&&f.length>0&&hw(xQ,{variant:"compact",className:"mb-8",children:[hw("h3",{className:"text-sm font-medium text-heading mb-2",children:"Related Content"},void 0,!1,void 0,this),hw("ul",{className:"space-y-1",children:f.map((K)=>hw("li",{children:hw("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),hw(jf,{markdown:B},void 0,!1,void 0,this),(D??Y)&&hw("nav",{className:"mt-12 pt-8 border-t border-theme",children:hw("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[D?hw(xQ,{href:D.url,variant:"compact",children:[hw("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Newer"},void 0,!1,void 0,this),hw("span",{className:"block mt-1 font-medium text-heading group-hover:text-brand transition-colors truncate",children:D.subject},void 0,!1,void 0,this)]},void 0,!0,void 0,this):hw("div",{},void 0,!1,void 0,this),Y&&hw(xQ,{href:Y.url,variant:"compact",className:"md:text-right",children:[hw("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Older"},void 0,!1,void 0,this),hw("span",{className:"block mt-1 font-medium text-heading group-hover:text-brand transition-colors truncate",children:Y.subject},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},f61=b1({name:"newsletter-detail",description:"Individual newsletter detail template",schema:NAQ,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:qAQ}});var D61={name:"@brains/newsletter-entity",private:!0,version:"0.2.0-alpha.61",description:"Newsletter entity type with AI generation and publish pipeline",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint src test --ext .ts,.tsx","lint:fix":"eslint src test --ext .ts,.tsx --fix"},dependencies:{"@brains/entity-service":"workspace:*","@brains/plugins":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var MAQ=F.object({});class tRA extends FQ{entityType="newsletter";schema=Lm;adapter=Q61;constructor(A={}){super("newsletter",D61,A,MAQ)}createGenerationHandler(A){return new aRA(this.logger,A)}getTemplates(){return{generation:w61,"newsletter-list":$61,"newsletter-detail":f61}}getDataSources(){return[new sRA(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:()=>LAQ(NMA,{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 I=await A.messaging.send({type:"buttondown:send",payload:{entityId:w,subject:$.metadata.subject,content:$.content}}),f=new Date().toISOString(),D=!("noop"in I)&&I.data?I.data.emailId:void 0;return await A.entityService.updateEntity({entity:{...$,metadata:{...$.metadata,status:"published",sentAt:f,buttondownId:D}}}),await A.messaging.send({type:"publish:report:success",payload:{entityType:B,entityId:w,sentAt:f}}),this.logger.info(`Published newsletter: ${w}`),{success:!0}}catch($){let I=h0($);return await A.messaging.send({type:"publish:report:failure",payload:{entityType:B,entityId:w,error:I}}),{success:!0}}})}subscribeToGenerateExecute(A){A.messaging.subscribe("generate:execute",async(Q)=>{if(Q.payload.entityType!=="newsletter")return{success:!0};try{let B=await A.entityService.listEntities({entityType:"post",options:{filter:{metadata:{status:"published"}},limit:10}});if(B.length===0)return await A.messaging.send({type:"generate:report:failure",payload:{entityType:"newsletter",error:"No published posts available for newsletter"}}),{success:!0};return await A.jobs.enqueue({type:"newsletter:generation",data:{sourceEntityIds:B.map((w)=>w.id),sourceEntityType:"post",addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}}),{success:!0}}catch(B){return await A.messaging.send({type:"generate:report:failure",payload:{entityType:"newsletter",error:h0(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:
|
|
4758
4758
|
|
|
4759
|
-
${w.content}`:w.prompt??"Write an engaging newsletter";return A.ai.generate({prompt:$,templateName:"newsletter:generation"})})}}function eRA(A={}){return new tRA(A)}I0();JA();class B_{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(()=>({})),I=$.detail??$.message??`HTTP ${w.status}`;throw this.logger.error("Buttondown API error",{endpoint:A,status:w.status,error:I}),Error(`Buttondown API error: ${I}`)}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}}}I0();JA();var VAQ=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)")}),OAQ=F.object({email:F.string().email().describe("Email address to unsubscribe")}),bAQ=F.object({type:F.enum(["unactivated","regular","unsubscribed"]).optional().describe("Filter by subscriber status"),limit:F.number().optional().describe("Maximum number of results")});function Y61(A,Q,B){let w=new B_(Q,B);return[jQ(A,"subscribe","Subscribe an email address to the newsletter. Uses double opt-in by default.",VAQ,async($)=>{try{let I=await w.createSubscriber({email:$.email,...$.name&&{name:$.name},...$.tags&&{tags:$.tags}}),f=I.subscriber_type==="already_subscribed";return _8({subscriberId:I.id,email:I.email,status:I.subscriber_type,message:f?"already_subscribed":"subscribed"},f?`${$.email} is already subscribed`:`Subscribed ${$.email} successfully`)}catch(I){return N9(h0(I))}}),jQ(A,"unsubscribe","Unsubscribe an email address from the newsletter.",OAQ,async($)=>{try{return await w.unsubscribe($.email),_8({email:$.email},`Unsubscribed ${$.email} successfully`)}catch(I){return N9(h0(I))}}),jQ(A,"list_subscribers","List newsletter subscribers with optional filtering by status.",bAQ,async($)=>{try{let I=await w.listSubscribers({...$.type&&{type:$.type},...$.limit&&{limit:$.limit}});return _8({subscribers:I.results.map((f)=>({id:f.id,email:f.email,status:f.subscriber_type})),count:I.count},`Found ${I.count} subscribers`)}catch(I){return N9(h0(I))}})]}JA();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 I=await Q.createEmail({subject:$.metadata.title,body:$.content,status:"about_to_send"});return w.info("Newsletter sent for post",{postId:$.id,emailId:I.id}),{success:!0,emailId:I.id}}catch(I){let f=h0(I);return w.error("Failed to send newsletter for post",{postId:$.id,error:f}),{success:!1,error:f}}}var X61={name:"@brains/buttondown",private:!0,version:"0.2.0-alpha.
|
|
4759
|
+
${w.content}`:w.prompt??"Write an engaging newsletter";return A.ai.generate({prompt:$,templateName:"newsletter:generation"})})}}function eRA(A={}){return new tRA(A)}I0();JA();class B_{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(()=>({})),I=$.detail??$.message??`HTTP ${w.status}`;throw this.logger.error("Buttondown API error",{endpoint:A,status:w.status,error:I}),Error(`Buttondown API error: ${I}`)}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}}}I0();JA();var VAQ=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)")}),OAQ=F.object({email:F.string().email().describe("Email address to unsubscribe")}),bAQ=F.object({type:F.enum(["unactivated","regular","unsubscribed"]).optional().describe("Filter by subscriber status"),limit:F.number().optional().describe("Maximum number of results")});function Y61(A,Q,B){let w=new B_(Q,B);return[jQ(A,"subscribe","Subscribe an email address to the newsletter. Uses double opt-in by default.",VAQ,async($)=>{try{let I=await w.createSubscriber({email:$.email,...$.name&&{name:$.name},...$.tags&&{tags:$.tags}}),f=I.subscriber_type==="already_subscribed";return _8({subscriberId:I.id,email:I.email,status:I.subscriber_type,message:f?"already_subscribed":"subscribed"},f?`${$.email} is already subscribed`:`Subscribed ${$.email} successfully`)}catch(I){return N9(h0(I))}}),jQ(A,"unsubscribe","Unsubscribe an email address from the newsletter.",OAQ,async($)=>{try{return await w.unsubscribe($.email),_8({email:$.email},`Unsubscribed ${$.email} successfully`)}catch(I){return N9(h0(I))}}),jQ(A,"list_subscribers","List newsletter subscribers with optional filtering by status.",bAQ,async($)=>{try{let I=await w.listSubscribers({...$.type&&{type:$.type},...$.limit&&{limit:$.limit}});return _8({subscribers:I.results.map((f)=>({id:f.id,email:f.email,status:f.subscriber_type})),count:I.count},`Found ${I.count} subscribers`)}catch(I){return N9(h0(I))}})]}JA();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 I=await Q.createEmail({subject:$.metadata.title,body:$.content,status:"about_to_send"});return w.info("Newsletter sent for post",{postId:$.id,emailId:I.id}),{success:!0,emailId:I.id}}catch(I){let f=h0(I);return w.error("Failed to send newsletter for post",{postId:$.id,error:f}),{success:!1,error:f}}}var X61={name:"@brains/buttondown",private:!0,version:"0.2.0-alpha.61",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 _AQ=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 A_A extends Ww{constructor(A={}){super("buttondown",X61,A,_AQ)}async onRegister(A){if(A.messaging.subscribe("buttondown:is-configured",async()=>{return{success:!!this.config.apiKey}}),this.config.apiKey){let Q=new B_({apiKey:this.config.apiKey,doubleOptIn:this.config.doubleOptIn},this.logger);if(A.messaging.subscribe("buttondown:send",async(B)=>{try{return{success:!0,data:{emailId:(await Q.createEmail({subject:B.payload.subject,body:B.payload.content,status:"about_to_send"})).id}}}catch(w){return this.logger.error("Buttondown send failed",{error:h0(w)}),{success:!1}}}),this.config.autoSendOnPublish)A.messaging.subscribe("publish:completed",async(B)=>{return await 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 Y61(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 Q_A(A={}){return new A_A(A)}var PAQ=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 W61(A={}){let Q=PAQ.parse(A);return[eRA({}),Q_A({...Q.apiKey!==void 0&&{apiKey:Q.apiKey},...Q.doubleOptIn!==void 0&&{doubleOptIn:Q.doubleOptIn},...Q.autoSendOnPublish!==void 0&&{autoSendOnPublish:Q.autoSendOnPublish}})]}I0();JA();import{existsSync as cAQ,mkdirSync as pAQ,writeFileSync as lAQ}from"fs";import{join as AG}from"path";JA();var B_A=F.object({baseFolder:F.string().default("_obsidian")});JA();function kAQ(A){let Q=A,B=!0,w=void 0,$=!1,I=!0;while(I){if(I=!1,Q instanceof F.ZodOptional)B=!1,Q=Q._def.innerType,I=!0;if(Q instanceof F.ZodDefault)B=!1,$=!0,w=Q._def.defaultValue(),Q=Q._def.innerType,I=!0;if(Q instanceof F.ZodNullable)B=!1,Q=Q._def.innerType,I=!0}let f={inner:Q,required:B};if($)f.defaultValue=w;return f}function jAQ(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 U61(A){let Q=A.shape,B=[];for(let[w,$]of Object.entries(Q)){let{inner:I,required:f,defaultValue:D}=kAQ($),Y=jAQ(I),H={name:w,type:Y.type,required:f},W=D!==void 0?D:Y.defaultValue;if(W!==void 0)H.defaultValue=W;if(Y.enumValues)H.enumValues=Y.enumValues;B.push(H)}return B}function xAQ(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 J61(A,Q,B=""){let w=["---"];for(let $ of Q){let I=xAQ($,A);if(I==="")w.push(`${$.name}:`);else w.push(`${$.name}: ${I}`)}if(w.push("---"),w.push(""),B)w.push(B);else w.push("<!-- Write your content here -->"),w.push("");return w.join(`
|
|
4760
4760
|
`)}JA();var vAQ={string:"Input",number:"Number",boolean:"Boolean",date:"Date",enum:"Select",array:"Multi",unknown:"Input"};function hAQ(A){let Q={name:A.name,id:A.name,type:vAQ[A.type]};if(A.type==="enum"&&A.enumValues){let B={};A.enumValues.forEach((w,$)=>{B[String($)]=w}),Q.options=B}return Q}function G61(A,Q){let B={filesPaths:A,fields:Q.map(hAQ)};return`---
|
|
4761
4761
|
${SH(B)}---
|
|
4762
|
-
`}JA();var yAQ=new Set(["entityType"]),gAQ={base:"Notes"},TAQ=new Set(["base"]);function SAQ(A){let Q=["file.name"];for(let B of A)if(!yAQ.has(B.name))Q.push(B.name);return Q}function mAQ(A){return A.some((Q)=>Q.name==="status"&&Q.type==="enum")}function F61(A,Q){let B=gAQ[A]??xp(A),w=mAQ(Q),$=SAQ(Q),I=[{type:"table",name:`All ${B}`,order:$}];if(w)I.push({type:"table",name:"By Status",groupBy:{property:"status",direction:"ASC"},order:$});let D={filters:{and:[TAQ.has(A)?'file.folder == "/"':`file.inFolder("${A}")`]},views:I};return{filename:`${B}.base`,content:SH(D),hasStatus:w}}function K61(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 SH(B)}function Z61(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 SH(B)}var z61={name:"@brains/obsidian-vault",private:!0,version:"0.2.0-alpha.60",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 iAQ={mkdir:pAQ,writeFile:lAQ,existsFile:cAQ},rAQ=F.object({entityTypes:F.array(F.string()).optional().describe("Entity types to generate templates for (default: all)")});class w_A extends Ww{deps;constructor(A={},Q={}){super("obsidian-vault",z61,A,B_A);this.deps={...iAQ,...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[jQ(this.id,"sync-templates","Generate Obsidian templates, Metadata Menu fileClass definitions, and Bases views for all registered entity types.",rAQ,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,$=AG(A.dataDir,this.config.baseFolder),I=AG($,"templates"),f=AG($,"fileClasses"),D=AG($,"bases");this.deps.mkdir(I,{recursive:!0}),this.deps.mkdir(f,{recursive:!0}),this.deps.mkdir(D,{recursive:!0});let Y=[],H=[],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`),H.push(C);continue}let j=U61(R),P=A.entities.getAdapter(C),o=P?.isSingleton===!0,n=G61(C,j);if(this.deps.writeFile(AG(f,`${C}.md`),n),W.push(C),o){K.push(C),this.logger.debug(`Generated fileClass (singleton): ${C}`);continue}let S=P?.getBodyTemplate()??"",v=J61(C,j,S);this.deps.writeFile(AG(I,`${C}.md`),v),Y.push(C);let y=F61(C,j),g=AG(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:j});this.logger.debug(`Generated template + fileClass: ${C}`)}let q=K61(K);if(q){let C=AG(D,"Settings.base");if(!this.deps.existsFile(C))this.deps.writeFile(C,q),G.push("Settings"),this.logger.debug("Generated Settings.base")}let L=Z61(Z);if(L){let C=AG(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 ${Y.length} templates, ${W.length} fileClasses, ${G.length} bases (${H.length} skipped)`),_8({generated:Y,skipped:H,fileClasses:W,bases:G})}catch(B){return this.logger.error("Failed to sync",{error:B}),N9(B instanceof Error?B.message:"Unknown error")}}}function $_A(A,Q){return new w_A(A,Q)}I0();JA();I0();var I_A=F.enum(["new","planned","in-progress","done","declined"]),f_A=F.enum(["low","medium","high","critical"]),Mm=F.object({title:F.string(),status:I_A,priority:f_A.default("medium"),requested:F.number().int().default(1),declinedReason:F.string().optional()}),N61=F.object({title:F.string(),status:I_A,priority:f_A,requested:F.number().int(),slug:F.string()}),Vm=I2.extend({entityType:F.literal("wish"),metadata:N61}),D_A=F.object({});I0();JA();class Om extends W2{constructor(){super({entityType:"wish",schema:Vm,frontmatterSchema:Mm})}createWishContent(A,Q){return this.buildMarkdown(Q,A)}parseWishContent(A){let Q=this.parseFrontMatter(A,Mm);return{frontmatter:Mm.parse(Q),description:this.extractBody(A).trim()}}fromMarkdown(A){let{frontmatter:Q}=this.parseWishContent(A),B=F2(Q.title);return{content:A,entityType:"wish",metadata:{title:Q.title,status:Q.status,priority:Q.priority,requested:Q.requested,slug:B}}}}var Y_A=new Om;JA();JA();async function q61(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 I=F2(Q.title);return A.getEntity({entityType:"wish",id:I})}class _2A{logger;context;adapter=new Om;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??"",I=await q61({search:(H)=>this.context.entityService.search(H),getEntity:(H)=>this.context.entityService.getEntity(H),similarityThreshold:0.85},{title:w,description:$});if(I){let{frontmatter:H,description:W}=this.adapter.parseWishContent(I.content),G=H.requested+1,K=this.adapter.createWishContent({...H,requested:G},W);return await this.context.entityService.updateEntity({entity:{...I,content:K,metadata:{...I.metadata,requested:G}}}),this.logger.info("Incremented wish request count",{id:I.id,requested:G}),{success:!0,entityId:I.id,existed:!0,requested:G}}let f=F2(w),D=A.options?.priority??"medium",Y=this.adapter.createWishContent({title:w,status:"new",priority:D,requested:1},$);return await this.context.entityService.createEntity({entity:{id:f,entityType:"wish",content:Y,metadata:{title:w,status:"new",priority:D,requested:1,slug:f}}}),this.logger.info("Created new wish",{id:f,title:w}),{success:!0,entityId:f,existed:!1,requested:1}}}var C61={critical:0,high:1,medium:2,low:3};function E61(A){A.sort((Q,B)=>{let w=B.metadata.requested-Q.metadata.requested;if(w!==0)return w;return C61[Q.metadata.priority]-C61[B.metadata.priority]})}var L61={name:"@brains/wishlist",private:!0,version:"0.2.0-alpha.60",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 M61 extends FQ{entityType=Y_A.entityType;schema=Vm;adapter=Y_A;constructor(A={}){super("wishlist",L61,A,D_A)}async interceptCreate(A,Q,B){let w=await new _2A(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 E61(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 _2A(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 nAQ(A={}){return new M61(A)}var P2A=nAQ;I0();JA();I0();var bm=F.object({title:F.string(),target:F.string()}),V61=F.object({title:F.string(),target:F.string(),slug:F.string().optional()}),Rm=I2.extend({entityType:F.literal("prompt"),metadata:V61});I0();JA();class H_A extends W2{constructor(){super({entityType:"prompt",schema:Rm,frontmatterSchema:bm})}toMarkdown(A){let Q=this.extractBody(A.content),B=this.parseFrontMatter(A.content,bm);return this.buildMarkdown(Q,B)}fromMarkdown(A){let Q=this.parseFrontMatter(A,bm),B=F2(Q.target.replace(/:/g,"-"));return{content:A,entityType:"prompt",metadata:{title:Q.title,target:Q.target,slug:B}}}}var k2A=new H_A;var O61={name:"@brains/prompt",private:!0,version:"0.2.0-alpha.60",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 X_A extends FQ{entityType=k2A.entityType;schema=Rm;adapter=k2A;constructor(){super("prompt",O61,{},void 0)}getEntityTypeConfig(){return{embeddable:!1}}}function _C(){return new X_A}I0();JA();class j2A{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(sAQ),total:$.total,totalPages:$.total_pages,page:Q.page}}async triggerDownload(A){try{await this.fetchFn(A,{headers:{Authorization:`Client-ID ${this.apiKey}`}})}catch{}}}function sAQ(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}}JA();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")},R61={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 P61(A,Q){return[aAQ(A,Q),tAQ(A,Q)]}function aAQ(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 tAQ(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:R61,handler:async(B)=>{let w=F.object(R61).safeParse(B);if(!w.success)return{success:!1,error:`Invalid input: ${w.error.message}`};let{photoId:$,downloadLocation:I,photographerName:f,photographerUrl:D,sourceUrl:Y,imageUrl:H,title:W,alt:G,targetEntityType:K,targetEntityId:Z}=w.data,q={photographerName:f,photographerUrl:D,sourceUrl:Y},L=await Q.entityService.listEntities({entityType:"image",options:{limit:1,filter:{metadata:{sourceUrl:H}}}});if(L[0]){let S={imageEntityId:L[0].id,alreadyExisted:!0,attribution:q};if(K&&Z)await _61(Q.entityService,K,Z,L[0].id),S.coverSet=!0;return{success:!0,data:S}}Q.provider.triggerDownload(I).catch(()=>{});let C;try{C=await Q.fetchImage(H)}catch(S){return{success:!1,error:S instanceof Error?S.message:"Image download failed"}}let R=W??`Stock photo ${$}`,j=iF.createImageEntity({dataUrl:C,title:R,alt:G??R}),P={id:$,...j,metadata:{...j.metadata,sourceUrl:H}},{entityId:o}=await Q.entityService.createEntity({entity:P}),n={imageEntityId:o,alreadyExisted:!1,attribution:q};if(K&&Z)await _61(Q.entityService,K,Z,o),n.coverSet=!0;return{success:!0,data:n}}}}async function _61(A,Q,B,w){let $=await A.getEntity({entityType:Q,id:B});if(!$)return;await A.updateEntity({entity:{...$,metadata:{...$.metadata,coverImageId:w}}})}JA();var k61={name:"@brains/stock-photo",private:!0,version:"0.2.0-alpha.60",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 A0Q=F.object({provider:F.enum(["unsplash"]).default("unsplash"),apiKey:F.string().optional().describe("Stock photo provider API key")});class W_A extends Ww{deps;cachedTools=null;constructor(A={},Q={}){super("stock-photo",k61,A,A0Q);this.deps=Q}async getTools(){if(!this.config.apiKey)return[];if(this.cachedTools)return this.cachedTools;let A=this.getContext(),Q=new j2A(this.config.apiKey,this.deps.fetch??globalThis.fetch);return this.cachedTools=P61(this.id,{provider:Q,entityService:A.entityService,fetchImage:this.deps.fetchImage??m7}),this.cachedTools}}function U_A(A={},Q={}){return new W_A(A,Q)}I0();JA();I0();I0();JA();var j61=F.enum(["ai","foundation","work"]),x61=F.object({suffix:j61,title:F.string(),body:F.string(),linkLabel:F.string(),linkHref:F.string()}),_m=F.object({eyebrow:F.string(),headline:F.string(),cards:F.array(x61).min(1)}),x2A=F.object({title:F.string(),slug:F.string(),status:F.enum(["draft","published"])}),Pm=I2.extend({entityType:F.literal("ecosystem-section"),metadata:x2A});class v61 extends W2{constructor(){super({entityType:"ecosystem-section",schema:Pm,frontmatterSchema:x2A})}fromMarkdown(A){return{content:A,entityType:"ecosystem-section",metadata:this.parseFrontmatter(A)}}}var J_A=new v61;JA();function Q0Q(A){return A.replace(/^---\n[\s\S]*?\n---\n?/,"")}function G_A(A,Q){return new RegExp(`(?:^|\\n)## ${Q}\\s*\\n([\\s\\S]*?)(?=\\n## |$)`).exec(A)?.[1]?.trim()??""}function km(A,Q){return new RegExp(`(?:^|\\n)#### ${Q}\\s*\\n([\\s\\S]*?)(?=\\n#### |\\n### |$)`).exec(A)?.[1]?.trim()??""}function v2A(A){let Q=Q0Q(A),w=G_A(Q,"Cards").split(/^### Card \d+\s*$/m).map(($)=>$.trim()).filter(Boolean);return _m.parse({eyebrow:G_A(Q,"Eyebrow"),headline:G_A(Q,"Headline"),cards:w.map(($)=>({suffix:km($,"Suffix"),title:km($,"Title"),body:km($,"Body"),linkLabel:km($,"Link Label"),linkHref:km($,"Link Href")}))})}function h61(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(`
|
|
4762
|
+
`}JA();var yAQ=new Set(["entityType"]),gAQ={base:"Notes"},TAQ=new Set(["base"]);function SAQ(A){let Q=["file.name"];for(let B of A)if(!yAQ.has(B.name))Q.push(B.name);return Q}function mAQ(A){return A.some((Q)=>Q.name==="status"&&Q.type==="enum")}function F61(A,Q){let B=gAQ[A]??xp(A),w=mAQ(Q),$=SAQ(Q),I=[{type:"table",name:`All ${B}`,order:$}];if(w)I.push({type:"table",name:"By Status",groupBy:{property:"status",direction:"ASC"},order:$});let D={filters:{and:[TAQ.has(A)?'file.folder == "/"':`file.inFolder("${A}")`]},views:I};return{filename:`${B}.base`,content:SH(D),hasStatus:w}}function K61(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 SH(B)}function Z61(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 SH(B)}var z61={name:"@brains/obsidian-vault",private:!0,version:"0.2.0-alpha.61",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 iAQ={mkdir:pAQ,writeFile:lAQ,existsFile:cAQ},rAQ=F.object({entityTypes:F.array(F.string()).optional().describe("Entity types to generate templates for (default: all)")});class w_A extends Ww{deps;constructor(A={},Q={}){super("obsidian-vault",z61,A,B_A);this.deps={...iAQ,...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[jQ(this.id,"sync-templates","Generate Obsidian templates, Metadata Menu fileClass definitions, and Bases views for all registered entity types.",rAQ,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,$=AG(A.dataDir,this.config.baseFolder),I=AG($,"templates"),f=AG($,"fileClasses"),D=AG($,"bases");this.deps.mkdir(I,{recursive:!0}),this.deps.mkdir(f,{recursive:!0}),this.deps.mkdir(D,{recursive:!0});let Y=[],H=[],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`),H.push(C);continue}let j=U61(R),P=A.entities.getAdapter(C),o=P?.isSingleton===!0,n=G61(C,j);if(this.deps.writeFile(AG(f,`${C}.md`),n),W.push(C),o){K.push(C),this.logger.debug(`Generated fileClass (singleton): ${C}`);continue}let S=P?.getBodyTemplate()??"",v=J61(C,j,S);this.deps.writeFile(AG(I,`${C}.md`),v),Y.push(C);let y=F61(C,j),g=AG(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:j});this.logger.debug(`Generated template + fileClass: ${C}`)}let q=K61(K);if(q){let C=AG(D,"Settings.base");if(!this.deps.existsFile(C))this.deps.writeFile(C,q),G.push("Settings"),this.logger.debug("Generated Settings.base")}let L=Z61(Z);if(L){let C=AG(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 ${Y.length} templates, ${W.length} fileClasses, ${G.length} bases (${H.length} skipped)`),_8({generated:Y,skipped:H,fileClasses:W,bases:G})}catch(B){return this.logger.error("Failed to sync",{error:B}),N9(B instanceof Error?B.message:"Unknown error")}}}function $_A(A,Q){return new w_A(A,Q)}I0();JA();I0();var I_A=F.enum(["new","planned","in-progress","done","declined"]),f_A=F.enum(["low","medium","high","critical"]),Mm=F.object({title:F.string(),status:I_A,priority:f_A.default("medium"),requested:F.number().int().default(1),declinedReason:F.string().optional()}),N61=F.object({title:F.string(),status:I_A,priority:f_A,requested:F.number().int(),slug:F.string()}),Vm=I2.extend({entityType:F.literal("wish"),metadata:N61}),D_A=F.object({});I0();JA();class Om extends W2{constructor(){super({entityType:"wish",schema:Vm,frontmatterSchema:Mm})}createWishContent(A,Q){return this.buildMarkdown(Q,A)}parseWishContent(A){let Q=this.parseFrontMatter(A,Mm);return{frontmatter:Mm.parse(Q),description:this.extractBody(A).trim()}}fromMarkdown(A){let{frontmatter:Q}=this.parseWishContent(A),B=F2(Q.title);return{content:A,entityType:"wish",metadata:{title:Q.title,status:Q.status,priority:Q.priority,requested:Q.requested,slug:B}}}}var Y_A=new Om;JA();JA();async function q61(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 I=F2(Q.title);return A.getEntity({entityType:"wish",id:I})}class _2A{logger;context;adapter=new Om;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??"",I=await q61({search:(H)=>this.context.entityService.search(H),getEntity:(H)=>this.context.entityService.getEntity(H),similarityThreshold:0.85},{title:w,description:$});if(I){let{frontmatter:H,description:W}=this.adapter.parseWishContent(I.content),G=H.requested+1,K=this.adapter.createWishContent({...H,requested:G},W);return await this.context.entityService.updateEntity({entity:{...I,content:K,metadata:{...I.metadata,requested:G}}}),this.logger.info("Incremented wish request count",{id:I.id,requested:G}),{success:!0,entityId:I.id,existed:!0,requested:G}}let f=F2(w),D=A.options?.priority??"medium",Y=this.adapter.createWishContent({title:w,status:"new",priority:D,requested:1},$);return await this.context.entityService.createEntity({entity:{id:f,entityType:"wish",content:Y,metadata:{title:w,status:"new",priority:D,requested:1,slug:f}}}),this.logger.info("Created new wish",{id:f,title:w}),{success:!0,entityId:f,existed:!1,requested:1}}}var C61={critical:0,high:1,medium:2,low:3};function E61(A){A.sort((Q,B)=>{let w=B.metadata.requested-Q.metadata.requested;if(w!==0)return w;return C61[Q.metadata.priority]-C61[B.metadata.priority]})}var L61={name:"@brains/wishlist",private:!0,version:"0.2.0-alpha.61",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 M61 extends FQ{entityType=Y_A.entityType;schema=Vm;adapter=Y_A;constructor(A={}){super("wishlist",L61,A,D_A)}async interceptCreate(A,Q,B){let w=await new _2A(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 E61(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 _2A(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 nAQ(A={}){return new M61(A)}var P2A=nAQ;I0();JA();I0();var bm=F.object({title:F.string(),target:F.string()}),V61=F.object({title:F.string(),target:F.string(),slug:F.string().optional()}),Rm=I2.extend({entityType:F.literal("prompt"),metadata:V61});I0();JA();class H_A extends W2{constructor(){super({entityType:"prompt",schema:Rm,frontmatterSchema:bm})}toMarkdown(A){let Q=this.extractBody(A.content),B=this.parseFrontMatter(A.content,bm);return this.buildMarkdown(Q,B)}fromMarkdown(A){let Q=this.parseFrontMatter(A,bm),B=F2(Q.target.replace(/:/g,"-"));return{content:A,entityType:"prompt",metadata:{title:Q.title,target:Q.target,slug:B}}}}var k2A=new H_A;var O61={name:"@brains/prompt",private:!0,version:"0.2.0-alpha.61",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 X_A extends FQ{entityType=k2A.entityType;schema=Rm;adapter=k2A;constructor(){super("prompt",O61,{},void 0)}getEntityTypeConfig(){return{embeddable:!1}}}function _C(){return new X_A}I0();JA();class j2A{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(sAQ),total:$.total,totalPages:$.total_pages,page:Q.page}}async triggerDownload(A){try{await this.fetchFn(A,{headers:{Authorization:`Client-ID ${this.apiKey}`}})}catch{}}}function sAQ(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}}JA();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")},R61={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 P61(A,Q){return[aAQ(A,Q),tAQ(A,Q)]}function aAQ(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 tAQ(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:R61,handler:async(B)=>{let w=F.object(R61).safeParse(B);if(!w.success)return{success:!1,error:`Invalid input: ${w.error.message}`};let{photoId:$,downloadLocation:I,photographerName:f,photographerUrl:D,sourceUrl:Y,imageUrl:H,title:W,alt:G,targetEntityType:K,targetEntityId:Z}=w.data,q={photographerName:f,photographerUrl:D,sourceUrl:Y},L=await Q.entityService.listEntities({entityType:"image",options:{limit:1,filter:{metadata:{sourceUrl:H}}}});if(L[0]){let S={imageEntityId:L[0].id,alreadyExisted:!0,attribution:q};if(K&&Z)await _61(Q.entityService,K,Z,L[0].id),S.coverSet=!0;return{success:!0,data:S}}Q.provider.triggerDownload(I).catch(()=>{});let C;try{C=await Q.fetchImage(H)}catch(S){return{success:!1,error:S instanceof Error?S.message:"Image download failed"}}let R=W??`Stock photo ${$}`,j=iF.createImageEntity({dataUrl:C,title:R,alt:G??R}),P={id:$,...j,metadata:{...j.metadata,sourceUrl:H}},{entityId:o}=await Q.entityService.createEntity({entity:P}),n={imageEntityId:o,alreadyExisted:!1,attribution:q};if(K&&Z)await _61(Q.entityService,K,Z,o),n.coverSet=!0;return{success:!0,data:n}}}}async function _61(A,Q,B,w){let $=await A.getEntity({entityType:Q,id:B});if(!$)return;await A.updateEntity({entity:{...$,metadata:{...$.metadata,coverImageId:w}}})}JA();var k61={name:"@brains/stock-photo",private:!0,version:"0.2.0-alpha.61",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 A0Q=F.object({provider:F.enum(["unsplash"]).default("unsplash"),apiKey:F.string().optional().describe("Stock photo provider API key")});class W_A extends Ww{deps;cachedTools=null;constructor(A={},Q={}){super("stock-photo",k61,A,A0Q);this.deps=Q}async getTools(){if(!this.config.apiKey)return[];if(this.cachedTools)return this.cachedTools;let A=this.getContext(),Q=new j2A(this.config.apiKey,this.deps.fetch??globalThis.fetch);return this.cachedTools=P61(this.id,{provider:Q,entityService:A.entityService,fetchImage:this.deps.fetchImage??m7}),this.cachedTools}}function U_A(A={},Q={}){return new W_A(A,Q)}I0();JA();I0();I0();JA();var j61=F.enum(["ai","foundation","work"]),x61=F.object({suffix:j61,title:F.string(),body:F.string(),linkLabel:F.string(),linkHref:F.string()}),_m=F.object({eyebrow:F.string(),headline:F.string(),cards:F.array(x61).min(1)}),x2A=F.object({title:F.string(),slug:F.string(),status:F.enum(["draft","published"])}),Pm=I2.extend({entityType:F.literal("ecosystem-section"),metadata:x2A});class v61 extends W2{constructor(){super({entityType:"ecosystem-section",schema:Pm,frontmatterSchema:x2A})}fromMarkdown(A){return{content:A,entityType:"ecosystem-section",metadata:this.parseFrontmatter(A)}}}var J_A=new v61;JA();function Q0Q(A){return A.replace(/^---\n[\s\S]*?\n---\n?/,"")}function G_A(A,Q){return new RegExp(`(?:^|\\n)## ${Q}\\s*\\n([\\s\\S]*?)(?=\\n## |$)`).exec(A)?.[1]?.trim()??""}function km(A,Q){return new RegExp(`(?:^|\\n)#### ${Q}\\s*\\n([\\s\\S]*?)(?=\\n#### |\\n### |$)`).exec(A)?.[1]?.trim()??""}function v2A(A){let Q=Q0Q(A),w=G_A(Q,"Cards").split(/^### Card \d+\s*$/m).map(($)=>$.trim()).filter(Boolean);return _m.parse({eyebrow:G_A(Q,"Eyebrow"),headline:G_A(Q,"Headline"),cards:w.map(($)=>({suffix:km($,"Suffix"),title:km($,"Title"),body:km($,"Body"),linkLabel:km($,"Link Label"),linkHref:km($,"Link Href")}))})}function h61(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(`
|
|
4763
4763
|
`)}var B0Q=F.object({query:F.object({id:F.string().optional()}).optional()}).passthrough();class h2A{id="rizom-ecosystem:entities";name="Rizom Ecosystem";description="Fetches an ecosystem-section entity for rendering";async fetch(A,Q,B){let $=B0Q.parse(A??{}).query?.id??"rizom-ecosystem",I=await B.entityService.getEntity({entityType:"ecosystem-section",id:$});if(!I)throw Error(`Ecosystem section not found: ${$}`);return Q.parse(v2A(I.content))}}I0();var w0Q=MAA({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 WW(...A){return w0Q(QR(A))}import{jsxDEV as MXw}from"preact/jsx-dev-runtime";import{jsxDEV as RXw}from"preact/jsx-dev-runtime";import{jsxDEV as jXw}from"preact/jsx-dev-runtime";import{jsxDEV as I0Q}from"preact/jsx-dev-runtime";var F_A="px-6 md:px-10 xl:px-20",$0Q=`${F_A} relative z-[1]`,K_A=({id:A,className:Q,children:B})=>I0Q("section",{id:A,className:WW($0Q,Q),children:B},void 0,!1,void 0,this);import{jsxDEV as y2A}from"preact/jsx-dev-runtime";var f0Q={work:"text-accent",foundation:"text-secondary",ai:"text-accent-bright"},jm=({name:A="rizom",brandSuffix:Q,className:B,dotClassName:w,suffixClassName:$})=>{let I=f0Q[Q];return y2A("span",{className:WW("inline-flex items-baseline gap-0 font-display font-medium tracking-[-0.015em] [font-variation-settings:'opsz'_24]",B),children:[y2A("span",{className:"text-theme",children:A},void 0,!1,void 0,this),y2A("span",{className:WW(I??"text-accent",w),children:"."},void 0,!1,void 0,this),y2A("span",{className:WW("italic font-normal text-theme-muted",$),children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as lXw}from"preact/jsx-dev-runtime";import{jsxDEV as nXw}from"preact/jsx-dev-runtime";import{jsxDEV as tXw,Fragment as aXw}from"preact/jsx-dev-runtime";import{jsxDEV as QWw}from"preact/jsx-dev-runtime";import{Fragment as Z_A}from"preact";import{jsxDEV as xm}from"preact/jsx-dev-runtime";var D0Q=/(\*[^*]+\*)/;function z_A(A,Q){let B=A.split(`
|
|
4764
|
-
`);return xm(Z_A,{children:B.map((w,$)=>xm(Z_A,{children:[$>0&&xm("br",{},void 0,!1,void 0,this),w.split(D0Q).map((I,f)=>{if(I.length>=3&&I.startsWith("*")&&I.endsWith("*"))return xm("span",{className:Q,children:I.slice(1,-1)},f,!1,void 0,this);return xm(Z_A,{children:I},f,!1,void 0,this)})]},$,!0,void 0,this))},void 0,!1,void 0,this)}import{jsxDEV as CI,Fragment as z0Q}from"preact/jsx-dev-runtime";var Y0Q="italic text-accent font-normal",H0Q="You are here",X0Q={work:"text-accent",foundation:"text-secondary",ai:"text-accent-bright"},W0Q={work:"border-t-accent/60",foundation:"border-t-secondary/60",ai:"border-t-accent-bright/60"},U0Q={work:"hover:border-t-accent",foundation:"hover:border-t-secondary",ai:"hover:border-t-accent-bright"},J0Q="font-label text-[10.5px] uppercase tracking-[0.26em] mt-1",G0Q="font-body text-[15px] leading-[1.6] text-theme-muted mt-2",F0Q="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",K0Q="font-label text-[10.5px] uppercase tracking-[0.22em] text-accent self-start mt-[18px] pb-1",Z0Q=({card:A})=>{let Q=A.linkLabel===H0Q,B=A.linkHref.trim().length===0,w=CI(z0Q,{children:[CI(jm,{brandSuffix:A.suffix,className:"text-[clamp(28px,3vw,40px)] [font-variation-settings:'opsz'_96]"},void 0,!1,void 0,this),CI("span",{className:`${J0Q} ${X0Q[A.suffix]}`,children:A.title},void 0,!1,void 0,this),CI("p",{className:G0Q,children:A.body},void 0,!1,void 0,this),Q?CI("span",{className:K0Q,children:A.linkLabel},void 0,!1,void 0,this):CI("span",{className:F0Q,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?W0Q[A.suffix]:"border-white/10"}`;return Q||B?CI("div",{className:$,children:w},void 0,!1,void 0,this):CI("a",{href:A.linkHref,className:`${$} text-inherit no-underline transition-colors ${U0Q[A.suffix]}`,children:w},void 0,!1,void 0,this)},N_A=({eyebrow:A,headline:Q,cards:B})=>CI(K_A,{id:"ecosystem",className:"pt-[112px] pb-[144px] border-t border-white/5",children:[CI("div",{className:"mx-auto mb-[88px] max-w-[1180px] text-center",children:[CI("span",{className:"font-label text-[11px] font-semibold uppercase tracking-[0.24em] text-accent",children:A},void 0,!1,void 0,this),CI("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:z_A(Q,Y0Q)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),CI("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)=>CI(Z0Q,{card:w},w.suffix,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this);var N0Q=[{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 y61(A){return{eyebrow:"The Ecosystem",headline:"One practice. *Three faces.*",cards:N0Q.map((Q)=>Q.suffix===A?{...Q,linkLabel:"You are here",linkHref:""}:Q)}}var q0Q=y61();var q_A=b1({name:"ecosystem",description:"Rizom ecosystem sibling-site section",schema:_m,formatter:{parse:v2A,format:h61},dataSourceId:"rizom-ecosystem:entities",requiredPermission:"public",layout:{component:N_A}});var g61={name:"@brains/rizom-ecosystem",private:!0,version:"0.2.0-alpha.
|
|
4764
|
+
`);return xm(Z_A,{children:B.map((w,$)=>xm(Z_A,{children:[$>0&&xm("br",{},void 0,!1,void 0,this),w.split(D0Q).map((I,f)=>{if(I.length>=3&&I.startsWith("*")&&I.endsWith("*"))return xm("span",{className:Q,children:I.slice(1,-1)},f,!1,void 0,this);return xm(Z_A,{children:I},f,!1,void 0,this)})]},$,!0,void 0,this))},void 0,!1,void 0,this)}import{jsxDEV as CI,Fragment as z0Q}from"preact/jsx-dev-runtime";var Y0Q="italic text-accent font-normal",H0Q="You are here",X0Q={work:"text-accent",foundation:"text-secondary",ai:"text-accent-bright"},W0Q={work:"border-t-accent/60",foundation:"border-t-secondary/60",ai:"border-t-accent-bright/60"},U0Q={work:"hover:border-t-accent",foundation:"hover:border-t-secondary",ai:"hover:border-t-accent-bright"},J0Q="font-label text-[10.5px] uppercase tracking-[0.26em] mt-1",G0Q="font-body text-[15px] leading-[1.6] text-theme-muted mt-2",F0Q="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",K0Q="font-label text-[10.5px] uppercase tracking-[0.22em] text-accent self-start mt-[18px] pb-1",Z0Q=({card:A})=>{let Q=A.linkLabel===H0Q,B=A.linkHref.trim().length===0,w=CI(z0Q,{children:[CI(jm,{brandSuffix:A.suffix,className:"text-[clamp(28px,3vw,40px)] [font-variation-settings:'opsz'_96]"},void 0,!1,void 0,this),CI("span",{className:`${J0Q} ${X0Q[A.suffix]}`,children:A.title},void 0,!1,void 0,this),CI("p",{className:G0Q,children:A.body},void 0,!1,void 0,this),Q?CI("span",{className:K0Q,children:A.linkLabel},void 0,!1,void 0,this):CI("span",{className:F0Q,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?W0Q[A.suffix]:"border-white/10"}`;return Q||B?CI("div",{className:$,children:w},void 0,!1,void 0,this):CI("a",{href:A.linkHref,className:`${$} text-inherit no-underline transition-colors ${U0Q[A.suffix]}`,children:w},void 0,!1,void 0,this)},N_A=({eyebrow:A,headline:Q,cards:B})=>CI(K_A,{id:"ecosystem",className:"pt-[112px] pb-[144px] border-t border-white/5",children:[CI("div",{className:"mx-auto mb-[88px] max-w-[1180px] text-center",children:[CI("span",{className:"font-label text-[11px] font-semibold uppercase tracking-[0.24em] text-accent",children:A},void 0,!1,void 0,this),CI("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:z_A(Q,Y0Q)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),CI("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)=>CI(Z0Q,{card:w},w.suffix,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this);var N0Q=[{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 y61(A){return{eyebrow:"The Ecosystem",headline:"One practice. *Three faces.*",cards:N0Q.map((Q)=>Q.suffix===A?{...Q,linkLabel:"You are here",linkHref:""}:Q)}}var q0Q=y61();var q_A=b1({name:"ecosystem",description:"Rizom ecosystem sibling-site section",schema:_m,formatter:{parse:v2A,format:h61},dataSourceId:"rizom-ecosystem:entities",requiredPermission:"public",layout:{component:N_A}});var g61={name:"@brains/rizom-ecosystem",private:!0,version:"0.2.0-alpha.61",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 FQ{entityType="ecosystem-section";schema=Pm;adapter=J_A;constructor(A={}){super("rizom-ecosystem",g61,A,F.object({}).default({}))}getTemplates(){return{ecosystem:q_A}}getDataSources(){return[new h2A]}}function PC(A={}){return new C_A(A)}JA();I0();I0();JA();JA();I0();var T9="agent",T61="agent-discovery",S61="agent:generation",m61="agent-network",u61="AgentNetworkWidget",vm="agent-discovery:entities",E_A="agent-list",L_A="agent-detail",$6="skill",c61="skill",g2A="skill-derivation",p61="skill:project",l61="skill-derivation",i61="skill:skill-derivation",r61="skills";var w_=F.object({name:F.string(),description:F.string(),tags:F.array(F.string())}),f4=F.enum(["discovered","approved"]).describe("Discovered for review or approved for calling"),BH=a4.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:f4,discoveredAt:F.string().datetime().describe("When this agent was first discovered")}),d61=BH.pick({name:!0,url:!0,status:!0}).extend({discoveredAt:F.string().datetime().optional(),slug:F.string()}),$_=I2.extend({entityType:F.literal(T9),metadata:d61}),hm=$_.extend({frontmatter:BH,about:F.string(),skills:F.array(w_),notes:F.string()}),I_=hm.extend({url:F.string().optional(),typeLabel:F.string().optional()}),E0Q=hm.extend({url:F.string(),typeLabel:F.string()});JA();var L0Q=F.array(w_);function n61(A){let Q=L0Q.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(`
|
|
4765
4765
|
`)}function o61(A){if(!A.trim())return[];let Q=[];for(let B of A.split(`
|
|
4766
4766
|
`)){let w=B.match(/^- (.+?): (.+?)(?:\s+\[(.+?)\])?$/);if(!w)continue;let $=w[1]??"",I=w[2]??"",f=w[3],D=f?f.split(",").map((Y)=>Y.trim()).filter(Boolean):[];Q.push({name:$,description:I,tags:D})}return Q}var M0Q=F.object({about:F.string(),skills:F.array(w_),notes:F.string()}),s61=new NB(M0Q,{title:"Agent",mappings:[{key:"about",label:"About",type:"string"},{key:"skills",label:"Skills",type:"custom",formatter:n61,parser:o61},{key:"notes",label:"Notes",type:"string"}]});class D4 extends W2{constructor(){super({entityType:T9,schema:$_,frontmatterSchema:BH})}fromMarkdown(A){let Q=this.parseFrontMatter(A,BH),B=CL(Q.url);return{content:A,entityType:T9,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:f4.parse(A.status),discoveredAt:A.discoveredAt},B=s61.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=s61.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,BH),body:this.parseAgentContent(A.content)}}}I0();var V0Q=new D4,O0Q=nH.extend({status:f4.optional()}),b0Q=oH.extend({query:O0Q.optional()});function R0Q(A){let Q=l2(A.content,BH),B=V0Q.parseAgentContent(A.content);return hm.parse({...A,frontmatter:Q.metadata,about:B.about,skills:B.skills,notes:B.notes})}class T2A extends d6{id=vm;name="Agent Directory DataSource";description="Fetches and transforms agent entities for rendering";config={entityType:T9,defaultSort:[{field:"discoveredAt",direction:"desc"}],defaultLimit:50,lookupField:"slug",enableNavigation:!0};constructor(A){super(A)}transformEntity(A){return R0Q(A)}buildDetailResult(A,Q){return{agent:A,prevAgent:Q?.prev??null,nextAgent:Q?.next??null}}parseQuery(A){let Q=b0Q.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}buildListResult(A,Q,B){let w=f4.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:I}=await this.fetchList(w,B.entityService,w.status?{filter:{metadata:{status:w.status}}}:void 0);return Q.parse(this.buildListResult($,I,w))}}I0();JA();I0();async function a61(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 I=await $.json();return Yj(I)}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""}JA();var _0Q=new D4;function t61(A){return A.trim().toLowerCase().replace(/[_\s]+/g,"-")}function yZ(A){let Q=new Set,B=[];for(let w of A){let $=t61(w);if(!$||Q.has($))continue;Q.add($),B.push($)}return B}function P0Q(A,Q){if(Q.count!==A.count)return Q.count-A.count;return A.tag.localeCompare(Q.tag)}async function e61(A,Q={}){let B=Q.minCount??1,w=Q.topN??12,$=new Map,[I,f]=await Promise.all([A.entityService.listEntities({entityType:$6}),A.entityService.listEntities({entityType:T9})]),D=(Y)=>{for(let H of yZ(Y))$.set(H,($.get(H)??0)+1)};for(let Y of I)D(Y.metadata.tags);for(let Y of f){let H=_0Q.parseAgentContent(Y.content);D(H.skills.flatMap((W)=>W.tags))}return Array.from($.entries()).map(([Y,H])=>({tag:Y,count:H})).filter((Y)=>Y.count>=B).sort(P0Q).slice(0,w)}function A51(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(`
|
|
4767
4767
|
`)}var k0Q=new D4;function Q51(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 I=Q.status??"discovered",f=new Date().toISOString();return{content:k0Q.createAgentContent({name:B,kind:w,...A.anchor?.organization&&{organization:A.anchor.organization},brainName:A.brainName,url:A.url,status:I,discoveredAt:f,about:$.join(`
|
|
@@ -4861,7 +4861,7 @@ ${SH(B)}---
|
|
|
4861
4861
|
setView("agents");
|
|
4862
4862
|
setTagFilter("all");
|
|
4863
4863
|
});
|
|
4864
|
-
})();`;import{jsxDEV as kQ}from"preact/jsx-dev-runtime";function m0Q({item:A}){return kQ("li",{class:"list-item",children:[kQ("div",{class:"list-main",children:[kQ("span",{class:"list-name",children:A.name},void 0,!1,void 0,this),kQ("span",{class:"list-desc",children:A.description},void 0,!1,void 0,this),A.tags.length>0&&kQ("div",{class:"list-tags",children:A.tags.map((Q)=>kQ("span",{class:"tag",children:Q},`${A.id}:${Q}`,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),kQ("div",{class:"list-meta",children:A.status==="discovered"&&kQ("span",{class:"pill pill--warn",children:"review"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function u0Q({item:A}){return kQ("li",{class:"list-item agent-network-skill-row","data-agent-network-skill-row":!0,"data-agent-network-tags":JSON.stringify(A.tags),children:[kQ("div",{class:"list-main",children:kQ("span",{class:"list-name",children:A.name},void 0,!1,void 0,this)},void 0,!1,void 0,this),kQ("div",{class:"list-meta",children:kQ("span",{class:`agent-network-source${A.sourceType==="brain"?" is-brain":""}`,children:A.sourceLabel},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function c0Q({kind:A,items:Q,active:B}){return kQ("div",{class:`agent-network-panel${B?" is-active":""}`,"data-agent-network-panel":A,children:Q.length>0?kQ("ul",{class:"list agent-network-list",children:Q.map((w)=>kQ(m0Q,{item:w},w.id,!1,void 0,this))},void 0,!1,void 0,this):kQ("p",{class:"agent-network-empty",children:"Nothing to show yet."},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function p0Q({skills:A,count:Q,filters:B}){return kQ("div",{class:"agent-network-panel","data-agent-network-panel":"skills",children:[kQ("div",{class:"agent-network-filter-row",role:"tablist","aria-label":"Filter skills by tag",children:[kQ("button",{class:"agent-network-filter is-active",type:"button","data-agent-network-tag-filter":"all","aria-pressed":"true",children:[kQ("span",{class:"count",children:Q},void 0,!1,void 0,this),kQ("span",{class:"label",children:"all"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),B.map((w)=>kQ("button",{class:`agent-network-filter${w.variant==="gap"?" is-gap":""}`,type:"button","data-agent-network-tag-filter":w.tag,"aria-pressed":"false",children:[kQ("span",{class:"count",children:w.count},void 0,!1,void 0,this),kQ("span",{class:"label",children:w.tag},void 0,!1,void 0,this)]},w.tag,!0,void 0,this))]},void 0,!0,void 0,this),A.length>0?kQ("ul",{class:"list agent-network-list agent-network-skills-list",children:A.map((w)=>kQ(u0Q,{item:w},w.id,!1,void 0,this))},void 0,!1,void 0,this):kQ("p",{class:"agent-network-empty",children:"Nothing to show yet."},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function O_A({data:A}){let Q=D51.safeParse(A);if(!Q.success)return kQ("p",{class:"muted",children:"Nothing to show yet."},void 0,!1,void 0,this);let B=Q.data;return kQ("div",{"data-agent-network-widget":!0,"data-agent-network-view":"agents",children:[kQ("div",{class:"agent-network-view-tabs",role:"tablist","aria-label":"Browse the agent network",children:[kQ("button",{class:"agent-network-view-tab is-active",type:"button","data-agent-network-view-tab":"agents","aria-pressed":"true",children:["Agents",kQ("span",{class:"agent-network-view-count",children:B.counts.agents},void 0,!1,void 0,this)]},void 0,!0,void 0,this),kQ("button",{class:"agent-network-view-tab",type:"button","data-agent-network-view-tab":"skills","aria-pressed":"false",children:["Skills",kQ("span",{class:"agent-network-view-count",children:B.counts.skills},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),kQ("div",{class:"agent-network-kind-tabs",role:"tablist","aria-label":"Filter agents by kind",children:V_A.map((w)=>{let $=w==="all";return kQ("button",{class:`agent-network-kind-tab${$?" is-active":""}`,type:"button","data-agent-network-kind-tab":w,"aria-pressed":$?"true":"false",children:[kQ("span",{class:"agent-network-kind-count",children:B.agents[w].length},void 0,!1,void 0,this),kQ("span",{class:"agent-network-kind-label",children:w},void 0,!1,void 0,this)]},w,!0,void 0,this)})},void 0,!1,void 0,this),V_A.map((w)=>kQ(c0Q,{kind:w,items:B.agents[w],active:w==="all"},w,!1,void 0,this)),kQ(p0Q,{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:m61,pluginId:Q,title:"Agent Network",section:"secondary",priority:15,rendererName:u61,component:O_A,clientScript:u2A,dataProvider:async()=>Y51(A)}}),{success:!0}})}function X51(){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.'}I0();R8();JA();import{jsxDEV as W51}from"preact/jsx-dev-runtime";function c2A(A){try{return new URL(A).hostname}catch{return A}}var p2A=({name:A,className:Q=""})=>{let B=A.charAt(0).toUpperCase(),w=0;for(let I=0;I<A.length;I++)w=A.charCodeAt(I)+((w<<5)-w);let $=Math.abs(w)%360;return W51("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)},l2A=({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 W51("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 G2,Fragment as r0Q}from"preact/jsx-dev-runtime";var l0Q=({skills:A})=>{if(A.length===0)return null;return G2("div",{className:"flex gap-1.5 flex-wrap mt-2",children:A.map((Q)=>G2("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 i0Q(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric"})}function U51(A,Q,B){let w=new URLSearchParams({status:Q});if(B>1)w.set("page",String(B));return`${A}?${w.toString()}`}var b_A=({agent:A})=>{let{frontmatter:Q,about:B,skills:w,url:$}=A,I=Q.status==="approved";return G2("a",{href:$,className:`flex items-start gap-5 p-6 rounded-xl border border-theme bg-theme-subtle hover:shadow-lg transition-shadow ${I?"":"opacity-70"}`,children:[G2(p2A,{name:Q.name,className:"w-12 h-12 text-lg"},void 0,!1,void 0,this),G2("div",{className:"flex-1 min-w-0",children:[G2("div",{className:"flex items-center gap-2 mb-1 flex-wrap",children:[G2("span",{className:"text-lg font-semibold text-heading",children:Q.name},void 0,!1,void 0,this),G2(l2A,{kind:Q.kind,size:"sm"},void 0,!1,void 0,this),Q.organization&&G2("span",{className:"text-xs text-theme-muted",children:["\xB7 ",Q.organization]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),G2("div",{className:"text-sm text-theme-muted mb-1",children:Q.brainName},void 0,!1,void 0,this),B&&G2("p",{className:"text-sm text-theme-muted line-clamp-2 mb-0",children:B},void 0,!1,void 0,this),I&&G2(l0Q,{skills:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this),G2("div",{className:"flex flex-col items-end gap-1 flex-shrink-0 text-right",children:[G2("span",{className:"text-xs text-theme-muted",children:c2A(Q.url)},void 0,!1,void 0,this),G2("span",{className:"text-[11px] text-theme-muted opacity-60",children:I?`Discovered ${i0Q(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)},J51=({agents:A,pageTitle:Q,pagination:B,baseUrl:w="/agents",selectedStatus:$})=>{let I=Q??"Agent Directory",f=B?.totalItems??A.length,D=A.filter((K)=>K.frontmatter.status==="approved"),Y=A.filter((K)=>K.frontmatter.status==="discovered"),H=D.length,W=Y.length,G=`Your network of ${f} ${f===1?"brain":"brains"} and their anchors`;return G2(r0Q,{children:[G2(YQ,{title:I,description:G},void 0,!1,void 0,this),G2("div",{className:"agent-list bg-theme",children:G2("div",{className:"container mx-auto px-6 md:px-12 max-w-5xl py-16 md:py-24",children:[G2("div",{className:"mb-8 pb-6 border-b border-theme",children:[G2("h1",{className:"text-4xl font-bold text-heading mb-2",children:I},void 0,!1,void 0,this),G2("p",{className:"text-theme-muted mb-4",children:G},void 0,!1,void 0,this),G2("div",{className:"flex flex-wrap gap-2 text-sm mb-4",children:[G2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-heading",children:[f," total"]},void 0,!0,void 0,this),G2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-status-success",children:[H," approved"]},void 0,!0,void 0,this),G2("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),G2("div",{className:"flex flex-wrap gap-2 text-sm",children:[G2("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),G2("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),G2("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&&G2("section",{className:"mb-10",children:[G2("div",{className:"flex items-center justify-between mb-4",children:[G2("h2",{className:"text-lg font-semibold text-heading",children:"Approved brains"},void 0,!1,void 0,this),G2("span",{className:"text-sm text-theme-muted",children:D.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),G2("div",{className:"flex flex-col gap-4",children:D.map((K)=>G2(b_A,{agent:K},K.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$==="all"&&Y.length>0&&G2("section",{children:[G2("div",{className:"flex items-center justify-between mb-4",children:[G2("div",{children:[G2("h2",{className:"text-lg font-semibold text-heading",children:"Discovered brains"},void 0,!1,void 0,this),G2("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),G2("span",{className:"text-sm text-theme-muted",children:Y.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),G2("div",{className:"flex flex-col gap-4",children:Y.map((K)=>G2(b_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&&G2("section",{children:[G2("div",{className:"flex items-center justify-between mb-4",children:[G2("h2",{className:"text-lg font-semibold text-heading",children:$==="approved"?"Approved brains":"Discovered brains"},void 0,!1,void 0,this),G2("span",{className:"text-sm text-theme-muted",children:A.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),G2("div",{className:"flex flex-col gap-4",children:A.map((K)=>G2(b_A,{agent:K},K.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.length===0&&G2("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"&&G2("div",{className:"mt-12",children:G2(uY,{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"&&G2("nav",{"aria-label":"Pagination",className:"flex items-center justify-center gap-3 mt-12",children:[B.hasPrevPage?G2("a",{href:U51(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):G2("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),G2("span",{className:"text-sm text-theme-muted",children:["Page ",B.currentPage," of ",B.totalPages]},void 0,!0,void 0,this),B.hasNextPage?G2("a",{href:U51(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):G2("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 $2,Fragment as s0Q}from"preact/jsx-dev-runtime";function d0Q(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"})}var ym=({children:A})=>$2("h2",{className:"text-sm font-semibold text-theme-muted uppercase tracking-wide mb-3",children:A},void 0,!1,void 0,this),n0Q=({skill:A})=>$2("div",{className:"flex items-start gap-3 px-4 py-3 bg-theme-subtle rounded-lg",children:[$2("div",{className:"flex-1",children:[$2("div",{className:"text-sm font-semibold text-heading",children:A.name},void 0,!1,void 0,this),$2("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&&$2("div",{className:"flex gap-1 flex-shrink-0",children:A.tags.map((Q)=>$2("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),o0Q=({label:A,value:Q,valueClassName:B})=>$2("div",{className:"flex justify-between text-[13px]",children:[$2("span",{className:"text-theme-muted",children:A},void 0,!1,void 0,this),$2("span",{className:B??"text-heading",children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this),G51=({agent:A,prevAgent:Q,nextAgent:B})=>{let{frontmatter:w,about:$,skills:I,notes:f}=A,D=c2A(w.url),Y=w.status==="approved";return $2(s0Q,{children:[$2(YQ,{title:w.name,description:$||`Agent profile for ${w.name}`},void 0,!1,void 0,this),$2("article",{className:"agent-detail",children:$2("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:[$2("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),$2("div",{className:"flex items-start gap-6 mb-8",children:[$2(p2A,{name:w.name,className:"w-[72px] h-[72px] text-3xl"},void 0,!1,void 0,this),$2("div",{children:[$2("div",{className:"flex items-center gap-3 mb-1",children:[$2("h1",{className:"text-3xl md:text-4xl font-bold text-heading",children:w.name},void 0,!1,void 0,this),$2(l2A,{kind:w.kind},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$2("div",{className:"text-base text-theme-muted mb-2",children:w.brainName},void 0,!1,void 0,this),$2("div",{className:"flex items-center gap-3 text-theme-muted",children:[w.organization&&$2("span",{className:"text-[15px]",children:w.organization},void 0,!1,void 0,this),w.organization&&$2("span",{className:"text-theme-muted opacity-40",children:"\xB7"},void 0,!1,void 0,this),$2("span",{className:"text-sm",children:["Discovered ",d0Q(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),$2("div",{className:"border-b border-theme mb-8"},void 0,!1,void 0,this),!Y&&$2("div",{className:"mb-8 rounded-xl border border-theme bg-theme-subtle px-5 py-4",children:[$2("div",{className:"text-sm font-semibold text-heading mb-1",children:"Saved for review"},void 0,!1,void 0,this),$2("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),$2("div",{className:"flex flex-col md:flex-row gap-12",children:[$2("div",{className:"flex-[2] min-w-0",children:[$&&$2("section",{className:"mb-8",children:[$2(ym,{children:"About"},void 0,!1,void 0,this),$2("p",{className:"text-[15px] text-theme leading-relaxed",children:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this),I.length>0&&$2("section",{className:"mb-8",children:[$2(ym,{children:"Skills"},void 0,!1,void 0,this),$2("div",{className:"flex flex-col gap-2.5",children:I.map((H)=>$2(n0Q,{skill:H},H.name,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),f&&$2("section",{className:"mb-8",children:[$2(ym,{children:"Notes"},void 0,!1,void 0,this),$2("p",{className:"text-[15px] text-theme leading-relaxed",children:f},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),$2("aside",{className:"flex-1 md:pl-8 md:border-l border-theme-muted/20",children:[$2("section",{className:"mb-8",children:[$2(ym,{children:"Brain"},void 0,!1,void 0,this),$2("div",{className:"p-4 bg-theme-subtle rounded-xl",children:[$2("div",{className:"text-[15px] font-semibold text-heading mb-1",children:w.brainName},void 0,!1,void 0,this),w.did&&$2("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),$2("section",{className:"mb-8",children:[$2(ym,{children:"Connection"},void 0,!1,void 0,this),$2("div",{className:"flex flex-col gap-3",children:[$2("div",{children:[$2("div",{className:"text-[13px] text-theme-muted mb-0.5",children:"Endpoint"},void 0,!1,void 0,this),$2("div",{className:"text-xs text-heading font-mono",children:w.url},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$2(o0Q,{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),$2("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)&&$2("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:[$2("div",{className:"min-h-[1px]",children:Q&&$2("a",{href:Q.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[$2("span",{children:"\u2190 Previous"},void 0,!1,void 0,this),$2("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),$2("div",{className:"min-h-[1px] md:text-right",children:B&&$2("a",{href:B.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[$2("span",{children:"Next \u2192"},void 0,!1,void 0,this),$2("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 a0Q=F.object({agents:F.array(I_),pageTitle:F.string().optional(),pagination:B$.nullable(),baseUrl:F.string().optional(),selectedStatus:F.union([F.literal("all"),f4])});function F51(){return{[E_A]:b1({name:E_A,description:"Agent directory list page template",schema:a0Q,dataSourceId:vm,requiredPermission:"public",layout:{component:J51}}),[L_A]:b1({name:L_A,description:"Individual agent profile template",schema:F.object({agent:I_,prevAgent:I_.nullable(),nextAgent:I_.nullable()}),dataSourceId:vm,requiredPermission:"public",layout:{component:G51}})}}var i2A={name:"@brains/agent-discovery",private:!0,version:"0.2.0-alpha.60",description:"Agent discovery \u2014 brain+anchor contacts and skills",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts,.tsx","lint:fix":"eslint . --ext .ts,.tsx --fix"},dependencies:{"@brains/dashboard":"workspace:*","@brains/plugins":"workspace:*","@brains/templates":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var e0Q=new D4;class R_A extends FQ{entityType=T9;schema=$_;adapter=e0Q;constructor(){super(T61,i2A)}interceptCreate(A,Q,B){return B51(A,Q,B,this.id)}createGenerationHandler(A){return new M_A(this.logger.child("AgentGenerationJobHandler"),A)}getTemplates(){return F51()}getDataSources(){return[new T2A(this.logger.child("AgentDataSource"))]}async onRegister(A){H51(A,this.id)}async getInstructions(){return X51()}}function __A(){return new R_A}I0();JA();I0();var f_=Af,K51=Af,gm=I2.extend({entityType:F.literal($6),metadata:K51});I0();class D_ extends W2{constructor(){super({entityType:$6,schema:gm,frontmatterSchema:f_})}fromMarkdown(A){let Q=this.parseFrontMatter(A,f_);return{content:A,entityType:$6,metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}I0();JA();var A1Q=F.object({skills:F.array(f_)}),Z51=b1({name:"skill:skill-derivation",description:"Derive skills from topic titles and brain capabilities",dataSourceId:"shell:ai-content",schema:A1Q,useKnowledgeContext:!0,basePrompt:`You are analyzing a brain's content to identify its high-level capabilities.
|
|
4864
|
+
})();`;import{jsxDEV as kQ}from"preact/jsx-dev-runtime";function m0Q({item:A}){return kQ("li",{class:"list-item",children:[kQ("div",{class:"list-main",children:[kQ("span",{class:"list-name",children:A.name},void 0,!1,void 0,this),kQ("span",{class:"list-desc",children:A.description},void 0,!1,void 0,this),A.tags.length>0&&kQ("div",{class:"list-tags",children:A.tags.map((Q)=>kQ("span",{class:"tag",children:Q},`${A.id}:${Q}`,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),kQ("div",{class:"list-meta",children:A.status==="discovered"&&kQ("span",{class:"pill pill--warn",children:"review"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function u0Q({item:A}){return kQ("li",{class:"list-item agent-network-skill-row","data-agent-network-skill-row":!0,"data-agent-network-tags":JSON.stringify(A.tags),children:[kQ("div",{class:"list-main",children:kQ("span",{class:"list-name",children:A.name},void 0,!1,void 0,this)},void 0,!1,void 0,this),kQ("div",{class:"list-meta",children:kQ("span",{class:`agent-network-source${A.sourceType==="brain"?" is-brain":""}`,children:A.sourceLabel},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function c0Q({kind:A,items:Q,active:B}){return kQ("div",{class:`agent-network-panel${B?" is-active":""}`,"data-agent-network-panel":A,children:Q.length>0?kQ("ul",{class:"list agent-network-list",children:Q.map((w)=>kQ(m0Q,{item:w},w.id,!1,void 0,this))},void 0,!1,void 0,this):kQ("p",{class:"agent-network-empty",children:"Nothing to show yet."},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function p0Q({skills:A,count:Q,filters:B}){return kQ("div",{class:"agent-network-panel","data-agent-network-panel":"skills",children:[kQ("div",{class:"agent-network-filter-row",role:"tablist","aria-label":"Filter skills by tag",children:[kQ("button",{class:"agent-network-filter is-active",type:"button","data-agent-network-tag-filter":"all","aria-pressed":"true",children:[kQ("span",{class:"count",children:Q},void 0,!1,void 0,this),kQ("span",{class:"label",children:"all"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),B.map((w)=>kQ("button",{class:`agent-network-filter${w.variant==="gap"?" is-gap":""}`,type:"button","data-agent-network-tag-filter":w.tag,"aria-pressed":"false",children:[kQ("span",{class:"count",children:w.count},void 0,!1,void 0,this),kQ("span",{class:"label",children:w.tag},void 0,!1,void 0,this)]},w.tag,!0,void 0,this))]},void 0,!0,void 0,this),A.length>0?kQ("ul",{class:"list agent-network-list agent-network-skills-list",children:A.map((w)=>kQ(u0Q,{item:w},w.id,!1,void 0,this))},void 0,!1,void 0,this):kQ("p",{class:"agent-network-empty",children:"Nothing to show yet."},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function O_A({data:A}){let Q=D51.safeParse(A);if(!Q.success)return kQ("p",{class:"muted",children:"Nothing to show yet."},void 0,!1,void 0,this);let B=Q.data;return kQ("div",{"data-agent-network-widget":!0,"data-agent-network-view":"agents",children:[kQ("div",{class:"agent-network-view-tabs",role:"tablist","aria-label":"Browse the agent network",children:[kQ("button",{class:"agent-network-view-tab is-active",type:"button","data-agent-network-view-tab":"agents","aria-pressed":"true",children:["Agents",kQ("span",{class:"agent-network-view-count",children:B.counts.agents},void 0,!1,void 0,this)]},void 0,!0,void 0,this),kQ("button",{class:"agent-network-view-tab",type:"button","data-agent-network-view-tab":"skills","aria-pressed":"false",children:["Skills",kQ("span",{class:"agent-network-view-count",children:B.counts.skills},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),kQ("div",{class:"agent-network-kind-tabs",role:"tablist","aria-label":"Filter agents by kind",children:V_A.map((w)=>{let $=w==="all";return kQ("button",{class:`agent-network-kind-tab${$?" is-active":""}`,type:"button","data-agent-network-kind-tab":w,"aria-pressed":$?"true":"false",children:[kQ("span",{class:"agent-network-kind-count",children:B.agents[w].length},void 0,!1,void 0,this),kQ("span",{class:"agent-network-kind-label",children:w},void 0,!1,void 0,this)]},w,!0,void 0,this)})},void 0,!1,void 0,this),V_A.map((w)=>kQ(c0Q,{kind:w,items:B.agents[w],active:w==="all"},w,!1,void 0,this)),kQ(p0Q,{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:m61,pluginId:Q,title:"Agent Network",section:"secondary",priority:15,rendererName:u61,component:O_A,clientScript:u2A,dataProvider:async()=>Y51(A)}}),{success:!0}})}function X51(){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.'}I0();R8();JA();import{jsxDEV as W51}from"preact/jsx-dev-runtime";function c2A(A){try{return new URL(A).hostname}catch{return A}}var p2A=({name:A,className:Q=""})=>{let B=A.charAt(0).toUpperCase(),w=0;for(let I=0;I<A.length;I++)w=A.charCodeAt(I)+((w<<5)-w);let $=Math.abs(w)%360;return W51("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)},l2A=({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 W51("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 G2,Fragment as r0Q}from"preact/jsx-dev-runtime";var l0Q=({skills:A})=>{if(A.length===0)return null;return G2("div",{className:"flex gap-1.5 flex-wrap mt-2",children:A.map((Q)=>G2("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 i0Q(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric"})}function U51(A,Q,B){let w=new URLSearchParams({status:Q});if(B>1)w.set("page",String(B));return`${A}?${w.toString()}`}var b_A=({agent:A})=>{let{frontmatter:Q,about:B,skills:w,url:$}=A,I=Q.status==="approved";return G2("a",{href:$,className:`flex items-start gap-5 p-6 rounded-xl border border-theme bg-theme-subtle hover:shadow-lg transition-shadow ${I?"":"opacity-70"}`,children:[G2(p2A,{name:Q.name,className:"w-12 h-12 text-lg"},void 0,!1,void 0,this),G2("div",{className:"flex-1 min-w-0",children:[G2("div",{className:"flex items-center gap-2 mb-1 flex-wrap",children:[G2("span",{className:"text-lg font-semibold text-heading",children:Q.name},void 0,!1,void 0,this),G2(l2A,{kind:Q.kind,size:"sm"},void 0,!1,void 0,this),Q.organization&&G2("span",{className:"text-xs text-theme-muted",children:["\xB7 ",Q.organization]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),G2("div",{className:"text-sm text-theme-muted mb-1",children:Q.brainName},void 0,!1,void 0,this),B&&G2("p",{className:"text-sm text-theme-muted line-clamp-2 mb-0",children:B},void 0,!1,void 0,this),I&&G2(l0Q,{skills:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this),G2("div",{className:"flex flex-col items-end gap-1 flex-shrink-0 text-right",children:[G2("span",{className:"text-xs text-theme-muted",children:c2A(Q.url)},void 0,!1,void 0,this),G2("span",{className:"text-[11px] text-theme-muted opacity-60",children:I?`Discovered ${i0Q(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)},J51=({agents:A,pageTitle:Q,pagination:B,baseUrl:w="/agents",selectedStatus:$})=>{let I=Q??"Agent Directory",f=B?.totalItems??A.length,D=A.filter((K)=>K.frontmatter.status==="approved"),Y=A.filter((K)=>K.frontmatter.status==="discovered"),H=D.length,W=Y.length,G=`Your network of ${f} ${f===1?"brain":"brains"} and their anchors`;return G2(r0Q,{children:[G2(YQ,{title:I,description:G},void 0,!1,void 0,this),G2("div",{className:"agent-list bg-theme",children:G2("div",{className:"container mx-auto px-6 md:px-12 max-w-5xl py-16 md:py-24",children:[G2("div",{className:"mb-8 pb-6 border-b border-theme",children:[G2("h1",{className:"text-4xl font-bold text-heading mb-2",children:I},void 0,!1,void 0,this),G2("p",{className:"text-theme-muted mb-4",children:G},void 0,!1,void 0,this),G2("div",{className:"flex flex-wrap gap-2 text-sm mb-4",children:[G2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-heading",children:[f," total"]},void 0,!0,void 0,this),G2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-status-success",children:[H," approved"]},void 0,!0,void 0,this),G2("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),G2("div",{className:"flex flex-wrap gap-2 text-sm",children:[G2("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),G2("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),G2("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&&G2("section",{className:"mb-10",children:[G2("div",{className:"flex items-center justify-between mb-4",children:[G2("h2",{className:"text-lg font-semibold text-heading",children:"Approved brains"},void 0,!1,void 0,this),G2("span",{className:"text-sm text-theme-muted",children:D.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),G2("div",{className:"flex flex-col gap-4",children:D.map((K)=>G2(b_A,{agent:K},K.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$==="all"&&Y.length>0&&G2("section",{children:[G2("div",{className:"flex items-center justify-between mb-4",children:[G2("div",{children:[G2("h2",{className:"text-lg font-semibold text-heading",children:"Discovered brains"},void 0,!1,void 0,this),G2("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),G2("span",{className:"text-sm text-theme-muted",children:Y.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),G2("div",{className:"flex flex-col gap-4",children:Y.map((K)=>G2(b_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&&G2("section",{children:[G2("div",{className:"flex items-center justify-between mb-4",children:[G2("h2",{className:"text-lg font-semibold text-heading",children:$==="approved"?"Approved brains":"Discovered brains"},void 0,!1,void 0,this),G2("span",{className:"text-sm text-theme-muted",children:A.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),G2("div",{className:"flex flex-col gap-4",children:A.map((K)=>G2(b_A,{agent:K},K.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.length===0&&G2("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"&&G2("div",{className:"mt-12",children:G2(uY,{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"&&G2("nav",{"aria-label":"Pagination",className:"flex items-center justify-center gap-3 mt-12",children:[B.hasPrevPage?G2("a",{href:U51(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):G2("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),G2("span",{className:"text-sm text-theme-muted",children:["Page ",B.currentPage," of ",B.totalPages]},void 0,!0,void 0,this),B.hasNextPage?G2("a",{href:U51(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):G2("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 $2,Fragment as s0Q}from"preact/jsx-dev-runtime";function d0Q(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"})}var ym=({children:A})=>$2("h2",{className:"text-sm font-semibold text-theme-muted uppercase tracking-wide mb-3",children:A},void 0,!1,void 0,this),n0Q=({skill:A})=>$2("div",{className:"flex items-start gap-3 px-4 py-3 bg-theme-subtle rounded-lg",children:[$2("div",{className:"flex-1",children:[$2("div",{className:"text-sm font-semibold text-heading",children:A.name},void 0,!1,void 0,this),$2("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&&$2("div",{className:"flex gap-1 flex-shrink-0",children:A.tags.map((Q)=>$2("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),o0Q=({label:A,value:Q,valueClassName:B})=>$2("div",{className:"flex justify-between text-[13px]",children:[$2("span",{className:"text-theme-muted",children:A},void 0,!1,void 0,this),$2("span",{className:B??"text-heading",children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this),G51=({agent:A,prevAgent:Q,nextAgent:B})=>{let{frontmatter:w,about:$,skills:I,notes:f}=A,D=c2A(w.url),Y=w.status==="approved";return $2(s0Q,{children:[$2(YQ,{title:w.name,description:$||`Agent profile for ${w.name}`},void 0,!1,void 0,this),$2("article",{className:"agent-detail",children:$2("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:[$2("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),$2("div",{className:"flex items-start gap-6 mb-8",children:[$2(p2A,{name:w.name,className:"w-[72px] h-[72px] text-3xl"},void 0,!1,void 0,this),$2("div",{children:[$2("div",{className:"flex items-center gap-3 mb-1",children:[$2("h1",{className:"text-3xl md:text-4xl font-bold text-heading",children:w.name},void 0,!1,void 0,this),$2(l2A,{kind:w.kind},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$2("div",{className:"text-base text-theme-muted mb-2",children:w.brainName},void 0,!1,void 0,this),$2("div",{className:"flex items-center gap-3 text-theme-muted",children:[w.organization&&$2("span",{className:"text-[15px]",children:w.organization},void 0,!1,void 0,this),w.organization&&$2("span",{className:"text-theme-muted opacity-40",children:"\xB7"},void 0,!1,void 0,this),$2("span",{className:"text-sm",children:["Discovered ",d0Q(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),$2("div",{className:"border-b border-theme mb-8"},void 0,!1,void 0,this),!Y&&$2("div",{className:"mb-8 rounded-xl border border-theme bg-theme-subtle px-5 py-4",children:[$2("div",{className:"text-sm font-semibold text-heading mb-1",children:"Saved for review"},void 0,!1,void 0,this),$2("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),$2("div",{className:"flex flex-col md:flex-row gap-12",children:[$2("div",{className:"flex-[2] min-w-0",children:[$&&$2("section",{className:"mb-8",children:[$2(ym,{children:"About"},void 0,!1,void 0,this),$2("p",{className:"text-[15px] text-theme leading-relaxed",children:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this),I.length>0&&$2("section",{className:"mb-8",children:[$2(ym,{children:"Skills"},void 0,!1,void 0,this),$2("div",{className:"flex flex-col gap-2.5",children:I.map((H)=>$2(n0Q,{skill:H},H.name,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),f&&$2("section",{className:"mb-8",children:[$2(ym,{children:"Notes"},void 0,!1,void 0,this),$2("p",{className:"text-[15px] text-theme leading-relaxed",children:f},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),$2("aside",{className:"flex-1 md:pl-8 md:border-l border-theme-muted/20",children:[$2("section",{className:"mb-8",children:[$2(ym,{children:"Brain"},void 0,!1,void 0,this),$2("div",{className:"p-4 bg-theme-subtle rounded-xl",children:[$2("div",{className:"text-[15px] font-semibold text-heading mb-1",children:w.brainName},void 0,!1,void 0,this),w.did&&$2("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),$2("section",{className:"mb-8",children:[$2(ym,{children:"Connection"},void 0,!1,void 0,this),$2("div",{className:"flex flex-col gap-3",children:[$2("div",{children:[$2("div",{className:"text-[13px] text-theme-muted mb-0.5",children:"Endpoint"},void 0,!1,void 0,this),$2("div",{className:"text-xs text-heading font-mono",children:w.url},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$2(o0Q,{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),$2("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)&&$2("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:[$2("div",{className:"min-h-[1px]",children:Q&&$2("a",{href:Q.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[$2("span",{children:"\u2190 Previous"},void 0,!1,void 0,this),$2("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),$2("div",{className:"min-h-[1px] md:text-right",children:B&&$2("a",{href:B.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[$2("span",{children:"Next \u2192"},void 0,!1,void 0,this),$2("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 a0Q=F.object({agents:F.array(I_),pageTitle:F.string().optional(),pagination:B$.nullable(),baseUrl:F.string().optional(),selectedStatus:F.union([F.literal("all"),f4])});function F51(){return{[E_A]:b1({name:E_A,description:"Agent directory list page template",schema:a0Q,dataSourceId:vm,requiredPermission:"public",layout:{component:J51}}),[L_A]:b1({name:L_A,description:"Individual agent profile template",schema:F.object({agent:I_,prevAgent:I_.nullable(),nextAgent:I_.nullable()}),dataSourceId:vm,requiredPermission:"public",layout:{component:G51}})}}var i2A={name:"@brains/agent-discovery",private:!0,version:"0.2.0-alpha.61",description:"Agent discovery \u2014 brain+anchor contacts and skills",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts,.tsx","lint:fix":"eslint . --ext .ts,.tsx --fix"},dependencies:{"@brains/dashboard":"workspace:*","@brains/plugins":"workspace:*","@brains/templates":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var e0Q=new D4;class R_A extends FQ{entityType=T9;schema=$_;adapter=e0Q;constructor(){super(T61,i2A)}interceptCreate(A,Q,B){return B51(A,Q,B,this.id)}createGenerationHandler(A){return new M_A(this.logger.child("AgentGenerationJobHandler"),A)}getTemplates(){return F51()}getDataSources(){return[new T2A(this.logger.child("AgentDataSource"))]}async onRegister(A){H51(A,this.id)}async getInstructions(){return X51()}}function __A(){return new R_A}I0();JA();I0();var f_=Af,K51=Af,gm=I2.extend({entityType:F.literal($6),metadata:K51});I0();class D_ extends W2{constructor(){super({entityType:$6,schema:gm,frontmatterSchema:f_})}fromMarkdown(A){let Q=this.parseFrontMatter(A,f_);return{content:A,entityType:$6,metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}I0();JA();var A1Q=F.object({skills:F.array(f_)}),Z51=b1({name:"skill:skill-derivation",description:"Derive skills from topic titles and brain capabilities",dataSourceId:"shell:ai-content",schema:A1Q,useKnowledgeContext:!0,basePrompt:`You are analyzing a brain's content to identify its high-level capabilities.
|
|
4865
4865
|
|
|
4866
4866
|
Given knowledge domains, CONSOLIDATE related topics into broader skills.
|
|
4867
4867
|
There should be FEWER skills than topics \u2014 combine related domains.
|
|
@@ -5011,9 +5011,9 @@ Context:
|
|
|
5011
5011
|
${JSON.stringify(w,null,2)}
|
|
5012
5012
|
|
|
5013
5013
|
Draft SWOT:
|
|
5014
|
-
${JSON.stringify(B,null,2)}`}function e2A(A){return A.map((Q)=>Q.detail===null?{title:Q.title}:{title:Q.title,detail:Q.detail})}function E1Q(A,Q){let B=["strengths","weaknesses","opportunities","threats"];for(let w of B){let $=new Set(A[w].map((I)=>I.theme.trim().toLowerCase()));for(let I of Q[w]){let f=I.sourceTheme.trim().toLowerCase();if(!$.has(f))throw Error(`SWOT refinement invented theme "${I.sourceTheme}" in ${w}`)}}}class AQA{logger;context;adapter=new QG;constructor(A,Q){this.logger=A;this.context=Q}validateAndParse(A){let Q=j_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 g_A(this.context),$;if(w.summary.brainSkillCount+w.summary.approvedAgentCount+w.summary.discoveredAgentCount===0)$={strengths:[],weaknesses:[],opportunities:[],threats:[]};else{await B.report({progress:0.6,message:"Synthesizing SWOT analysis"});let{object:H}=await this.context.ai.generateObject(await N1Q(this.context,w),x_A),W=x_A.parse(H);await B.report({progress:0.75,message:"Refining SWOT language"});let G=await this.context.ai.generateObject(await C1Q(this.context,w,W),s2A);$=s2A.parse(G.object),E1Q(W,$)}let f=new Date().toISOString(),D=this.adapter.createSwotContent({strengths:e2A($.strengths),weaknesses:e2A($.weaknesses),opportunities:e2A($.opportunities),threats:e2A($.threats),derivedAt:f});await B.report({progress:0.9,message:"Saving SWOT entity"});let Y=await this.context.entityService.getEntity({entityType:"swot",id:"swot"});if(Y)await this.context.entityService.updateEntity({entity:{...Y,content:D,metadata:{derivedAt:f}}});else await this.context.entityService.createEntity({entity:{id:"swot",entityType:"swot",content:D,metadata:{derivedAt:f}}});return this.logger.info("SWOT derivation complete",{derivedAt:f,brainSkillCount:w.summary.brainSkillCount,approvedAgentCount:w.summary.approvedAgentCount,discoveredAgentCount:w.summary.discoveredAgentCount}),{entityId:"swot"}}}JA();import{jsxDEV as O$}from"preact/jsx-dev-runtime";var QQA=F.object({title:F.string(),detail:F.string().optional()}),L1Q=F.discriminatedUnion("status",[F.object({status:F.literal("generating")}),F.object({status:F.literal("ready"),strengths:F.array(QQA).default([]),weaknesses:F.array(QQA).default([]),opportunities:F.array(QQA).default([]),threats:F.array(QQA).default([]),derivedAt:F.string()})]);function M1Q({items:A}){if(A.length===0)return O$("p",{class:"swot-empty",children:"\u2014"},void 0,!1,void 0,this);return O$("ul",{class:"swot-list",children:A.map((Q)=>O$("li",{class:"swot-item",children:[O$("b",{children:Q.title},void 0,!1,void 0,this),Q.detail?O$("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 BQA({title:A,tone:Q,items:B}){return O$("section",{class:`swot-cell is-${Q}`,children:[O$("div",{class:"swot-head",children:A},void 0,!1,void 0,this),O$(M1Q,{items:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function m_A({data:A}){let Q=L1Q.safeParse(A);if(!Q.success||Q.data.status==="generating")return O$("div",{"data-swot-widget":!0,children:O$("p",{class:"muted",children:"generating assessment\u2026"},void 0,!1,void 0,this)},void 0,!1,void 0,this);let B=Q.data;return O$("div",{"data-swot-widget":!0,children:O$("div",{class:"swot",role:"grid","aria-label":"SWOT analysis of agent network",children:[O$(BQA,{title:"Strengths",tone:"s",items:B.strengths},void 0,!1,void 0,this),O$(BQA,{title:"Weaknesses",tone:"w",items:B.weaknesses},void 0,!1,void 0,this),O$(BQA,{title:"Opportunities",tone:"o",items:B.opportunities},void 0,!1,void 0,this),O$(BQA,{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)}JA();var u_A={name:"@brains/assessment",private:!0,version:"0.2.0-alpha.
|
|
5014
|
+
${JSON.stringify(B,null,2)}`}function e2A(A){return A.map((Q)=>Q.detail===null?{title:Q.title}:{title:Q.title,detail:Q.detail})}function E1Q(A,Q){let B=["strengths","weaknesses","opportunities","threats"];for(let w of B){let $=new Set(A[w].map((I)=>I.theme.trim().toLowerCase()));for(let I of Q[w]){let f=I.sourceTheme.trim().toLowerCase();if(!$.has(f))throw Error(`SWOT refinement invented theme "${I.sourceTheme}" in ${w}`)}}}class AQA{logger;context;adapter=new QG;constructor(A,Q){this.logger=A;this.context=Q}validateAndParse(A){let Q=j_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 g_A(this.context),$;if(w.summary.brainSkillCount+w.summary.approvedAgentCount+w.summary.discoveredAgentCount===0)$={strengths:[],weaknesses:[],opportunities:[],threats:[]};else{await B.report({progress:0.6,message:"Synthesizing SWOT analysis"});let{object:H}=await this.context.ai.generateObject(await N1Q(this.context,w),x_A),W=x_A.parse(H);await B.report({progress:0.75,message:"Refining SWOT language"});let G=await this.context.ai.generateObject(await C1Q(this.context,w,W),s2A);$=s2A.parse(G.object),E1Q(W,$)}let f=new Date().toISOString(),D=this.adapter.createSwotContent({strengths:e2A($.strengths),weaknesses:e2A($.weaknesses),opportunities:e2A($.opportunities),threats:e2A($.threats),derivedAt:f});await B.report({progress:0.9,message:"Saving SWOT entity"});let Y=await this.context.entityService.getEntity({entityType:"swot",id:"swot"});if(Y)await this.context.entityService.updateEntity({entity:{...Y,content:D,metadata:{derivedAt:f}}});else await this.context.entityService.createEntity({entity:{id:"swot",entityType:"swot",content:D,metadata:{derivedAt:f}}});return this.logger.info("SWOT derivation complete",{derivedAt:f,brainSkillCount:w.summary.brainSkillCount,approvedAgentCount:w.summary.approvedAgentCount,discoveredAgentCount:w.summary.discoveredAgentCount}),{entityId:"swot"}}}JA();import{jsxDEV as O$}from"preact/jsx-dev-runtime";var QQA=F.object({title:F.string(),detail:F.string().optional()}),L1Q=F.discriminatedUnion("status",[F.object({status:F.literal("generating")}),F.object({status:F.literal("ready"),strengths:F.array(QQA).default([]),weaknesses:F.array(QQA).default([]),opportunities:F.array(QQA).default([]),threats:F.array(QQA).default([]),derivedAt:F.string()})]);function M1Q({items:A}){if(A.length===0)return O$("p",{class:"swot-empty",children:"\u2014"},void 0,!1,void 0,this);return O$("ul",{class:"swot-list",children:A.map((Q)=>O$("li",{class:"swot-item",children:[O$("b",{children:Q.title},void 0,!1,void 0,this),Q.detail?O$("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 BQA({title:A,tone:Q,items:B}){return O$("section",{class:`swot-cell is-${Q}`,children:[O$("div",{class:"swot-head",children:A},void 0,!1,void 0,this),O$(M1Q,{items:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function m_A({data:A}){let Q=L1Q.safeParse(A);if(!Q.success||Q.data.status==="generating")return O$("div",{"data-swot-widget":!0,children:O$("p",{class:"muted",children:"generating assessment\u2026"},void 0,!1,void 0,this)},void 0,!1,void 0,this);let B=Q.data;return O$("div",{"data-swot-widget":!0,children:O$("div",{class:"swot",role:"grid","aria-label":"SWOT analysis of agent network",children:[O$(BQA,{title:"Strengths",tone:"s",items:B.strengths},void 0,!1,void 0,this),O$(BQA,{title:"Weaknesses",tone:"w",items:B.weaknesses},void 0,!1,void 0,this),O$(BQA,{title:"Opportunities",tone:"o",items:B.opportunities},void 0,!1,void 0,this),O$(BQA,{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)}JA();var u_A={name:"@brains/assessment",private:!0,version:"0.2.0-alpha.61",description:"Assessment outputs and capability-profile analysis",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts,.tsx","lint:fix":"eslint . --ext .ts,.tsx --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/dashboard":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var c_A=new QG;class p_A extends FQ{entityType="swot";schema=Y_;adapter=c_A;initialSyncComplete=!1;constructor(){super("swot",u_A)}async onRegister(A){let Q=new AQA(this.logger.child("SwotDerivationHandler"),A);A.jobs.registerHandler("derive",Q),A.eval.registerHandler("deriveSwot",async()=>{let I=G6.from(async()=>{});if(!I)throw Error("Expected progress reporter to be created");await Q.process({reason:"eval"},"eval-swot-derive",I);let f=await A.entityService.getEntity({entityType:"swot",id:"swot"});if(!f)throw Error("Expected SWOT entity to be created during eval");return c_A.parseSwotContent(f.content).frontmatter});let B=async(I)=>{try{return await A.jobs.enqueue({type:"derive",data:{reason:I},options:{source:this.id,priority:10,deduplication:"coalesce",deduplicationKey:"swot",metadata:{operationType:"data_processing",operationTarget:`swot:${I}`}}})}catch(f){return this.logger.error("Failed to queue SWOT derivation",{error:f,reason:I}),null}},w=async(I)=>{if(!await A.entityService.getEntity({entityType:"swot",id:"swot"}))await B(I)};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:m_A,dataProvider:async()=>{let I=await A.entityService.getEntity({entityType:"swot",id:"swot"});if(!I)return{status:"generating"};let{frontmatter:f}=c_A.parseSwotContent(I.content);return{status:"ready",...f}}}}),{success:!0}});let $=async(I)=>{let{entityType:f}=I.payload;if(!this.initialSyncComplete)return{success:!0};if(f!=="agent"&&f!=="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 l_A(){return new p_A}I0();JA();var UFw=new QG,k51=F.object({name:F.string(),description:F.string(),tags:F.array(F.string())}),i_A=F.enum(["discovered","approved"]),O1Q=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:i_A,discoveredAt:F.string().datetime()}),b1Q=I2.extend({entityType:F.literal("agent"),metadata:F.object({name:F.string(),url:F.string().url(),status:i_A,slug:F.string()})}),R1Q=I2.extend({entityType:F.literal("skill"),metadata:Af}),_1Q=F.object({about:F.string(),skills:F.array(k51),notes:F.string()});function P1Q(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(`
|
|
5015
5015
|
`)}function k1Q(A){if(!A.trim())return[];return A.split(`
|
|
5016
|
-
`).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 j1Q=new NB(_1Q,{title:"Agent",mappings:[{key:"about",label:"About",type:"string"},{key:"skills",label:"Skills",type:"custom",formatter:P1Q,parser:k1Q},{key:"notes",label:"Notes",type:"string"}]});class j51 extends W2{constructor(){super({entityType:"agent",schema:b1Q,frontmatterSchema:O1Q})}fromMarkdown(A){return{content:A,entityType:"agent"}}createAgentContent(A){let Q=j1Q.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 x51 extends W2{constructor(){super({entityType:"skill",schema:R1Q,frontmatterSchema:Af})}fromMarkdown(A){let Q=this.parseFrontMatter(A,Af);return{content:A,entityType:"skill",metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}var JFw=new j51,GFw=new x51,FFw=F.object({skills:F.array(Af),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:i_A,discoveredAt:F.string().datetime().optional(),about:F.string(),skills:F.array(k51),notes:F.string().default("")}))});var x1Q=F.object({}).strict();function wQA(A={}){return x1Q.parse(A),[l_A()]}I0();JA();R8();s7();JA();I0();var $QA=vl.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.)")}),gZ=a4.extend($QA.shape);I0();zU();JA();var v1Q=new sH;class IQA{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,[$,I,f,D]=await Promise.all([SL(w),w.listEntities({entityType:"post",options:{limit:20}}),w.listEntities({entityType:"deck",options:{limit:20}}),zbA(w)]),Y=v1Q.parseProfileBody($,gZ),H=I.sort(Ek).slice(0,3).map(Am),W=f.sort(Ek).slice(0,3).map($m);if(!D.cta)throw Error("CTA not configured in site-info");let G={profile:Y,posts:H,decks:W,postsListUrl:this.postsListUrl,decksListUrl:this.decksListUrl,cta:D.cta,sections:D.sections??{}};return Q.parse(G)}}I0();zU();var h1Q=new sH;class fQA{id="professional:about";name="About Page DataSource";description="Fetches full profile data for the about page";async fetch(A,Q,B){let w=await SL(B.entityService),I={profile:h1Q.parseProfileBody(w,gZ)};return Q.parse(I)}}import{jsxDEV as Lw,Fragment as T1Q}from"preact/jsx-dev-runtime";var y1Q="grid md:grid-cols-[14rem_1px_1fr] gap-y-2 gap-x-0 md:gap-16 items-start",g1Q="border-t md:border-t-0 md:border-l border-rule-strong md:self-stretch",r_A=({number:A,title:Q,blurb:B,children:w})=>Lw("section",{className:"py-20 border-b border-rule px-6 md:px-12",children:Lw("div",{className:"max-w-6xl mx-auto",children:Lw("div",{className:y1Q,children:[Lw(JMA,{title:Q,number:A,blurb:B},void 0,!1,void 0,this),Lw("div",{className:g1Q,"aria-hidden":"true"},void 0,!1,void 0,this),Lw("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),d_A=({profile:A,posts:Q,decks:B,postsListUrl:w,decksListUrl:$,cta:I,sections:f})=>{let D=A.tagline||A.description,Y=Q.map((Z)=>({id:Z.id,url:Z.url,title:Z.metadata.title,date:Z.metadata.publishedAt||Z.created,description:Z.frontmatter.excerpt,series:Z.frontmatter.seriesName&&Z.frontmatter.seriesIndex?{name:Z.frontmatter.seriesName,index:Z.frontmatter.seriesIndex}:void 0})),H=B.map((Z)=>({id:Z.id,url:Z.url,title:Z.frontmatter.title||Z.id,date:Z.frontmatter.publishedAt??Z.created,description:Z.frontmatter.description})),W=A.name||"Home",G=A.intro||A.description||D||"Professional site",K=Boolean(A.description)||A.expertise!==void 0&&A.expertise.length>0;return Lw(T1Q,{children:[Lw(YQ,{title:W,description:G,ogType:"website"},void 0,!1,void 0,this),Lw("div",{className:"homepage-list bg-theme",children:[Lw("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:Lw("div",{className:"relative z-10 max-w-6xl mx-auto w-full",children:[A.name&&Lw("div",{className:"flex items-center gap-[0.6rem] mb-6 font-mono text-[0.7rem] font-medium uppercase tracking-[0.22em] text-accent",children:[Lw("span",{className:"w-[18px] h-px bg-accent","aria-hidden":"true"},void 0,!1,void 0,this),Lw("span",{children:A.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),D&&Lw("h1",{className:"font-heading text-[clamp(2.75rem,6.5vw,5.5rem)] font-normal text-heading leading-[1.02] tracking-[-0.025em] max-w-[18ch] [font-variation-settings:'opsz'_144,'SOFT'_30]",children:PAA(D,"italic font-normal text-accent [font-variation-settings:'opsz'_144,'SOFT'_80]")},void 0,!1,void 0,this),A.intro&&Lw("p",{className:"font-heading font-light text-[clamp(1.1rem,1.8vw,1.4rem)] leading-[1.5] text-theme-muted max-w-[42ch] mt-8 [font-variation-settings:'opsz'_24]",children:PAA(A.intro,"italic text-accent")},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Lw(r_A,{number:"01",title:"Essays",blurb:f.essays?.blurb,children:Lw(_AA,{items:Y,viewAllUrl:w,viewAllLabel:"View all essays"},void 0,!1,void 0,this)},void 0,!1,void 0,this),H.length>0&&Lw(r_A,{number:"02",title:"Presentations",blurb:f.presentations?.blurb,children:Lw(_AA,{items:H,viewAllUrl:$,viewAllLabel:"View all presentations"},void 0,!1,void 0,this)},void 0,!1,void 0,this),K&&Lw(r_A,{number:"03",title:"About",blurb:f.about?.blurb,children:Lw("div",{className:"flex flex-col gap-8",children:[A.description&&Lw("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&&Lw(GMA,{subjects:A.expertise},void 0,!1,void 0,this),Lw("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",Lw("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),Lw(QMA,{cta:I,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 dB,Fragment as S1Q}from"preact/jsx-dev-runtime";var n_A=({profile:A})=>{let Q=`About ${A.name||"Me"}`,B=A.description||A.intro||"About page",w=A.expertise&&A.expertise.length>0||A.currentFocus||A.availability||A.email||A.website||A.socialLinks&&A.socialLinks.length>0;return dB(S1Q,{children:[dB(YQ,{title:Q,description:B,ogType:"profile"},void 0,!1,void 0,this),dB("div",{className:"about-page bg-theme",children:[dB("header",{className:"hero-bg-pattern relative w-full py-16 md:py-24 px-6 md:px-12 bg-theme overflow-hidden",children:dB("div",{className:"relative z-10 max-w-4xl mx-auto",children:[dB("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&&dB("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),dB("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-12 md:py-16",children:[A.story&&dB("section",{className:"content-section-reveal mb-20 md:mb-28",children:dB(jf,{markdown:A.story},void 0,!1,void 0,this)},void 0,!1,void 0,this),w&&dB("div",{className:"content-section-reveal grid md:grid-cols-2 gap-x-16 gap-y-12",children:[A.expertise&&A.expertise.length>0&&dB("section",{children:[dB("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Expertise"},void 0,!1,void 0,this),dB("ul",{className:"flex flex-wrap gap-3",children:A.expertise.map(($,I)=>dB("li",{className:hT({variant:"accent",size:"lg"}),children:$},I,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.currentFocus&&dB("section",{children:[dB("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Current Focus"},void 0,!1,void 0,this),dB("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&&dB("section",{children:[dB("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Availability"},void 0,!1,void 0,this),dB("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)&&dB("section",{children:[dB("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Contact"},void 0,!1,void 0,this),dB("div",{className:"space-y-4",children:[A.email&&dB("p",{className:"text-lg",children:dB("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&&dB("p",{className:"text-lg",children:dB("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&&dB("div",{className:"flex flex-wrap gap-4 mt-4",children:A.socialLinks.map(($,I)=>dB(V5,{href:$.url,external:!0,variant:"secondary",size:"md",children:$.label||$.platform},I,!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 b$,Fragment as v51}from"preact/jsx-dev-runtime";var o_A=()=>{return b$(v51,{children:[b$(YQ,{title:"Thanks for subscribing!",description:"You've successfully subscribed to the newsletter."},void 0,!1,void 0,this),b$("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:b$("div",{className:"text-center max-w-md",children:[b$("div",{className:"text-6xl mb-6",children:"\uD83C\uDF89"},void 0,!1,void 0,this),b$("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Thanks for subscribing!"},void 0,!1,void 0,this),b$("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),b$(V5,{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)},s_A=()=>{return b$(v51,{children:[b$(YQ,{title:"Subscription failed",description:"There was a problem with your subscription."},void 0,!1,void 0,this),b$("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:b$("div",{className:"text-center max-w-md",children:[b$("div",{className:"text-6xl mb-6",children:"\uD83D\uDE22"},void 0,!1,void 0,this),b$("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Something went wrong"},void 0,!1,void 0,this),b$("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),b$(V5,{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)};JA();var h51=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')")}),y51=F.object({entityDisplay:F.object({post:h51,deck:h51}).describe("Display metadata for post and deck entity types (required for homepage)")});var g51={name:"@brains/site-professional",private:!0,version:"0.2.0-alpha.60",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 a_A extends Ww{dependencies=["blog","decks"];constructor(A){super("professional-site",g51,A,y51)}async onRegister(A){A.entities.extendFrontmatterSchema("anchor-profile",$QA);let Q=this.config.entityDisplay.post,B=this.config.entityDisplay.deck,w=`/${Q.pluralName??Q.label.toLowerCase()+"s"}`,$=`/${B.pluralName??B.label.toLowerCase()+"s"}`,I=new IQA(w,$);A.entities.registerDataSource(I);let f=new fQA;A.entities.registerDataSource(f);let D=F.object({profile:gZ,posts:F.array(nJ),decks:F.array(Bm),postsListUrl:F.string(),decksListUrl:F.string(),cta:KbA,sections:F.record(F.string(),Yn)}),Y=F.object({profile:gZ}),H=F.object({});A.templates.register({"homepage-list":b1({name:"homepage-list",description:"Professional homepage with essays and presentations",schema:D,dataSourceId:"professional:homepage-list",requiredPermission:"public",layout:{component:d_A}}),about:b1({name:"about",description:"About page with full profile information",schema:Y,dataSourceId:"professional:about",requiredPermission:"public",layout:{component:n_A}}),"subscribe-thanks":b1({name:"subscribe-thanks",description:"Newsletter subscription success page",schema:H,requiredPermission:"public",layout:{component:o_A}}),"subscribe-error":b1({name:"subscribe-error",description:"Newsletter subscription error page",schema:H,requiredPermission:"public",layout:{component:s_A}})}),this.logger.info("Professional site plugin registered successfully")}async getTools(){return[]}async getResources(){return[]}}function T51(A){return new a_A(A??{})}var S51=[{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 DQA}from"preact/jsx-dev-runtime";function m51({sections:A,siteInfo:Q,slots:B,wordmark:w}){return DQA("div",{className:"flex flex-col min-h-screen bg-theme overflow-x-clip",children:[DQA(IMA,{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),DQA("main",{className:"flex-grow flex flex-col bg-theme",children:A},void 0,!1,void 0,this),DQA(wMA,{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 u1Q={layouts:{default:m51},routes:S51,plugin:T51,entityDisplay:{post:{label:"Post"},deck:{label:"Deck"},project:{label:"Project"},series:{label:"Series",navigation:{slot:"secondary"}},topic:{label:"Topic",navigation:{slot:"secondary"}},link:{label:"Link",navigation:{slot:"secondary"}},base:{label:"Note",navigation:{show:!1}},"social-post":{label:"Social Post",pluralName:"social-posts",navigation:{slot:"secondary"}},newsletter:{label:"Newsletter",navigation:{slot:"secondary"}}}},Sm=u1Q;var u51=`/*
|
|
5016
|
+
`).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 j1Q=new NB(_1Q,{title:"Agent",mappings:[{key:"about",label:"About",type:"string"},{key:"skills",label:"Skills",type:"custom",formatter:P1Q,parser:k1Q},{key:"notes",label:"Notes",type:"string"}]});class j51 extends W2{constructor(){super({entityType:"agent",schema:b1Q,frontmatterSchema:O1Q})}fromMarkdown(A){return{content:A,entityType:"agent"}}createAgentContent(A){let Q=j1Q.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 x51 extends W2{constructor(){super({entityType:"skill",schema:R1Q,frontmatterSchema:Af})}fromMarkdown(A){let Q=this.parseFrontMatter(A,Af);return{content:A,entityType:"skill",metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}var JFw=new j51,GFw=new x51,FFw=F.object({skills:F.array(Af),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:i_A,discoveredAt:F.string().datetime().optional(),about:F.string(),skills:F.array(k51),notes:F.string().default("")}))});var x1Q=F.object({}).strict();function wQA(A={}){return x1Q.parse(A),[l_A()]}I0();JA();R8();s7();JA();I0();var $QA=vl.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.)")}),gZ=a4.extend($QA.shape);I0();zU();JA();var v1Q=new sH;class IQA{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,[$,I,f,D]=await Promise.all([SL(w),w.listEntities({entityType:"post",options:{limit:20}}),w.listEntities({entityType:"deck",options:{limit:20}}),zbA(w)]),Y=v1Q.parseProfileBody($,gZ),H=I.sort(Ek).slice(0,3).map(Am),W=f.sort(Ek).slice(0,3).map($m);if(!D.cta)throw Error("CTA not configured in site-info");let G={profile:Y,posts:H,decks:W,postsListUrl:this.postsListUrl,decksListUrl:this.decksListUrl,cta:D.cta,sections:D.sections??{}};return Q.parse(G)}}I0();zU();var h1Q=new sH;class fQA{id="professional:about";name="About Page DataSource";description="Fetches full profile data for the about page";async fetch(A,Q,B){let w=await SL(B.entityService),I={profile:h1Q.parseProfileBody(w,gZ)};return Q.parse(I)}}import{jsxDEV as Lw,Fragment as T1Q}from"preact/jsx-dev-runtime";var y1Q="grid md:grid-cols-[14rem_1px_1fr] gap-y-2 gap-x-0 md:gap-16 items-start",g1Q="border-t md:border-t-0 md:border-l border-rule-strong md:self-stretch",r_A=({number:A,title:Q,blurb:B,children:w})=>Lw("section",{className:"py-20 border-b border-rule px-6 md:px-12",children:Lw("div",{className:"max-w-6xl mx-auto",children:Lw("div",{className:y1Q,children:[Lw(JMA,{title:Q,number:A,blurb:B},void 0,!1,void 0,this),Lw("div",{className:g1Q,"aria-hidden":"true"},void 0,!1,void 0,this),Lw("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),d_A=({profile:A,posts:Q,decks:B,postsListUrl:w,decksListUrl:$,cta:I,sections:f})=>{let D=A.tagline||A.description,Y=Q.map((Z)=>({id:Z.id,url:Z.url,title:Z.metadata.title,date:Z.metadata.publishedAt||Z.created,description:Z.frontmatter.excerpt,series:Z.frontmatter.seriesName&&Z.frontmatter.seriesIndex?{name:Z.frontmatter.seriesName,index:Z.frontmatter.seriesIndex}:void 0})),H=B.map((Z)=>({id:Z.id,url:Z.url,title:Z.frontmatter.title||Z.id,date:Z.frontmatter.publishedAt??Z.created,description:Z.frontmatter.description})),W=A.name||"Home",G=A.intro||A.description||D||"Professional site",K=Boolean(A.description)||A.expertise!==void 0&&A.expertise.length>0;return Lw(T1Q,{children:[Lw(YQ,{title:W,description:G,ogType:"website"},void 0,!1,void 0,this),Lw("div",{className:"homepage-list bg-theme",children:[Lw("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:Lw("div",{className:"relative z-10 max-w-6xl mx-auto w-full",children:[A.name&&Lw("div",{className:"flex items-center gap-[0.6rem] mb-6 font-mono text-[0.7rem] font-medium uppercase tracking-[0.22em] text-accent",children:[Lw("span",{className:"w-[18px] h-px bg-accent","aria-hidden":"true"},void 0,!1,void 0,this),Lw("span",{children:A.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),D&&Lw("h1",{className:"font-heading text-[clamp(2.75rem,6.5vw,5.5rem)] font-normal text-heading leading-[1.02] tracking-[-0.025em] max-w-[18ch] [font-variation-settings:'opsz'_144,'SOFT'_30]",children:PAA(D,"italic font-normal text-accent [font-variation-settings:'opsz'_144,'SOFT'_80]")},void 0,!1,void 0,this),A.intro&&Lw("p",{className:"font-heading font-light text-[clamp(1.1rem,1.8vw,1.4rem)] leading-[1.5] text-theme-muted max-w-[42ch] mt-8 [font-variation-settings:'opsz'_24]",children:PAA(A.intro,"italic text-accent")},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Lw(r_A,{number:"01",title:"Essays",blurb:f.essays?.blurb,children:Lw(_AA,{items:Y,viewAllUrl:w,viewAllLabel:"View all essays"},void 0,!1,void 0,this)},void 0,!1,void 0,this),H.length>0&&Lw(r_A,{number:"02",title:"Presentations",blurb:f.presentations?.blurb,children:Lw(_AA,{items:H,viewAllUrl:$,viewAllLabel:"View all presentations"},void 0,!1,void 0,this)},void 0,!1,void 0,this),K&&Lw(r_A,{number:"03",title:"About",blurb:f.about?.blurb,children:Lw("div",{className:"flex flex-col gap-8",children:[A.description&&Lw("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&&Lw(GMA,{subjects:A.expertise},void 0,!1,void 0,this),Lw("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",Lw("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),Lw(QMA,{cta:I,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 dB,Fragment as S1Q}from"preact/jsx-dev-runtime";var n_A=({profile:A})=>{let Q=`About ${A.name||"Me"}`,B=A.description||A.intro||"About page",w=A.expertise&&A.expertise.length>0||A.currentFocus||A.availability||A.email||A.website||A.socialLinks&&A.socialLinks.length>0;return dB(S1Q,{children:[dB(YQ,{title:Q,description:B,ogType:"profile"},void 0,!1,void 0,this),dB("div",{className:"about-page bg-theme",children:[dB("header",{className:"hero-bg-pattern relative w-full py-16 md:py-24 px-6 md:px-12 bg-theme overflow-hidden",children:dB("div",{className:"relative z-10 max-w-4xl mx-auto",children:[dB("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&&dB("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),dB("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-12 md:py-16",children:[A.story&&dB("section",{className:"content-section-reveal mb-20 md:mb-28",children:dB(jf,{markdown:A.story},void 0,!1,void 0,this)},void 0,!1,void 0,this),w&&dB("div",{className:"content-section-reveal grid md:grid-cols-2 gap-x-16 gap-y-12",children:[A.expertise&&A.expertise.length>0&&dB("section",{children:[dB("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Expertise"},void 0,!1,void 0,this),dB("ul",{className:"flex flex-wrap gap-3",children:A.expertise.map(($,I)=>dB("li",{className:hT({variant:"accent",size:"lg"}),children:$},I,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.currentFocus&&dB("section",{children:[dB("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Current Focus"},void 0,!1,void 0,this),dB("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&&dB("section",{children:[dB("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Availability"},void 0,!1,void 0,this),dB("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)&&dB("section",{children:[dB("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Contact"},void 0,!1,void 0,this),dB("div",{className:"space-y-4",children:[A.email&&dB("p",{className:"text-lg",children:dB("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&&dB("p",{className:"text-lg",children:dB("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&&dB("div",{className:"flex flex-wrap gap-4 mt-4",children:A.socialLinks.map(($,I)=>dB(V5,{href:$.url,external:!0,variant:"secondary",size:"md",children:$.label||$.platform},I,!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 b$,Fragment as v51}from"preact/jsx-dev-runtime";var o_A=()=>{return b$(v51,{children:[b$(YQ,{title:"Thanks for subscribing!",description:"You've successfully subscribed to the newsletter."},void 0,!1,void 0,this),b$("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:b$("div",{className:"text-center max-w-md",children:[b$("div",{className:"text-6xl mb-6",children:"\uD83C\uDF89"},void 0,!1,void 0,this),b$("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Thanks for subscribing!"},void 0,!1,void 0,this),b$("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),b$(V5,{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)},s_A=()=>{return b$(v51,{children:[b$(YQ,{title:"Subscription failed",description:"There was a problem with your subscription."},void 0,!1,void 0,this),b$("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:b$("div",{className:"text-center max-w-md",children:[b$("div",{className:"text-6xl mb-6",children:"\uD83D\uDE22"},void 0,!1,void 0,this),b$("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Something went wrong"},void 0,!1,void 0,this),b$("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),b$(V5,{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)};JA();var h51=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')")}),y51=F.object({entityDisplay:F.object({post:h51,deck:h51}).describe("Display metadata for post and deck entity types (required for homepage)")});var g51={name:"@brains/site-professional",private:!0,version:"0.2.0-alpha.61",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 a_A extends Ww{dependencies=["blog","decks"];constructor(A){super("professional-site",g51,A,y51)}async onRegister(A){A.entities.extendFrontmatterSchema("anchor-profile",$QA);let Q=this.config.entityDisplay.post,B=this.config.entityDisplay.deck,w=`/${Q.pluralName??Q.label.toLowerCase()+"s"}`,$=`/${B.pluralName??B.label.toLowerCase()+"s"}`,I=new IQA(w,$);A.entities.registerDataSource(I);let f=new fQA;A.entities.registerDataSource(f);let D=F.object({profile:gZ,posts:F.array(nJ),decks:F.array(Bm),postsListUrl:F.string(),decksListUrl:F.string(),cta:KbA,sections:F.record(F.string(),Yn)}),Y=F.object({profile:gZ}),H=F.object({});A.templates.register({"homepage-list":b1({name:"homepage-list",description:"Professional homepage with essays and presentations",schema:D,dataSourceId:"professional:homepage-list",requiredPermission:"public",layout:{component:d_A}}),about:b1({name:"about",description:"About page with full profile information",schema:Y,dataSourceId:"professional:about",requiredPermission:"public",layout:{component:n_A}}),"subscribe-thanks":b1({name:"subscribe-thanks",description:"Newsletter subscription success page",schema:H,requiredPermission:"public",layout:{component:o_A}}),"subscribe-error":b1({name:"subscribe-error",description:"Newsletter subscription error page",schema:H,requiredPermission:"public",layout:{component:s_A}})}),this.logger.info("Professional site plugin registered successfully")}async getTools(){return[]}async getResources(){return[]}}function T51(A){return new a_A(A??{})}var S51=[{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 DQA}from"preact/jsx-dev-runtime";function m51({sections:A,siteInfo:Q,slots:B,wordmark:w}){return DQA("div",{className:"flex flex-col min-h-screen bg-theme overflow-x-clip",children:[DQA(IMA,{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),DQA("main",{className:"flex-grow flex flex-col bg-theme",children:A},void 0,!1,void 0,this),DQA(wMA,{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 u1Q={layouts:{default:m51},routes:S51,plugin:T51,entityDisplay:{post:{label:"Post"},deck:{label:"Deck"},project:{label:"Project"},series:{label:"Series",navigation:{slot:"secondary"}},topic:{label:"Topic",navigation:{slot:"secondary"}},link:{label:"Link",navigation:{slot:"secondary"}},base:{label:"Note",navigation:{show:!1}},"social-post":{label:"Social Post",pluralName:"social-posts",navigation:{slot:"secondary"}},newsletter:{label:"Newsletter",navigation:{slot:"secondary"}}}},Sm=u1Q;var u51=`/*
|
|
5017
5017
|
* Default theme \u2014 simplified editorial base inspired by the Rizom family.
|
|
5018
5018
|
*
|
|
5019
5019
|
* This theme is intentionally less branded than @brains/theme-rizom. It
|
|
@@ -5401,7 +5401,7 @@ ${JSON.stringify(B,null,2)}`}function e2A(A){return A.map((Q)=>Q.detail===null?{
|
|
|
5401
5401
|
|
|
5402
5402
|
.btn-primary:disabled { opacity: 0.5; }
|
|
5403
5403
|
}
|
|
5404
|
-
`;var X_=u51;import{join as l1Q}from"path";var c51={name:"@brains/rover",version:"0.2.0-alpha.60",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 p51=["prompt","note","link","wishlist","topics","directory-sync","agents","assessment","auth-service","cms","dashboard-root","mcp","webserver","discord","a2a"],l51=[...p51.filter((A)=>A!=="dashboard-root"),"image","dashboard","blog","series","decks","analytics","obsidian-vault","site-info","site-builder"],i1Q=[...l51,"portfolio","topics","content-pipeline","social-media","newsletter","stock-photo"],r1Q=["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."],i51=TF({name:"rover",version:c51.version,model:"gpt-5.4-mini",site:Sm,theme:X_,presets:{core:p51,default:l51,full:i1Q},evalDisable:["discord","webserver","mcp","analytics","dashboard","dashboard-root"],agentInstructions:r1Q,capabilities:[["prompt",_C,void 0],["image",Vv,void 0],["cms",bC,{}],["auth-service",Gy,void 0],["dashboard",hZ,void 0],["dashboard-root",hZ,{routePath:"/"}],["blog",VbA,{}],["series",PbA,void 0],["decks",Im,void 0],["note",EC,{}],["link",MC,{}],["portfolio",YRA,{}],["topics",J2A,{includeEntityTypes:["post","deck","project","link","anchor-profile"]}],["content-pipeline",TRA,{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",Nm,{autoGenerateOnBlogPublish:!0}],["newsletter",W61,{doubleOptIn:!0}],["obsidian-vault",$_A,{autoSync:!0}],["wishlist",P2A,{}],["stock-photo",U_A,{}],["agents",d2A,void 0],["assessment",wQA,void 0],["directory-sync",Sq,{seedContent:!0,seedContentPath:l1Q(import.meta.dir,"..","seed-content"),initialSync:!0}],["analytics",M2A,{}],["rizom-ecosystem",PC,void 0],["site-info",NC,void 0],["site-builder",zC,{cms:{}}]],interfaces:[["mcp",EK,()=>({})],["discord",wZ,()=>({})],["webserver",$Z,()=>({})],["a2a",ub,()=>({})]],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"}}});cF();I0();JA();JA();I0();var YQA=F.object({routeId:F.string(),sectionId:F.string()}),mm=I2.extend({entityType:F.literal("site-content"),template:F.string().optional(),content:F.string(),metadata:YQA});I0();class r51 extends W2{constructor(){super({entityType:"site-content",schema:mm,frontmatterSchema:YQA})}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 t_A=new r51;JA();var HQA=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")}),bZw=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 e_A{context;constructor(A){this.context=A}createJobOptions(A,Q){if(!A)return;return{source:A.operationType??Q,rootJobId:A.rootJobId??`${Q}-${Date.now()}`,metadata:{operationType:A.operationType??"content_operations",progressToken:A.progressToken,pluginId:A.pluginId??"site-content"}}}async fetchRoutes(){let A=await this.context.messaging.send({type:"site-builder:routes:list",payload:{}});if("noop"in A)throw Error("No handler for site-builder:routes:list \u2014 is site-builder plugin loaded?");if(!A.success||!A.data)throw Error("Failed to fetch routes from site-builder");return A.data}async generate(A,Q,B){let w=this.context.logger.child("SiteContentOperations"),$=await this.fetchRoutes(),I=$;if(A.routeId){if(I=$.filter((W)=>W.id===A.routeId),I.length===0)throw Error(`Route not found: ${A.routeId}`)}let f=[];for(let W of I)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}}f.push({route:W,section:G})}let D=f.length;if(A.dryRun)return{jobs:[],totalSections:D,queuedSections:D,batchId:`dry-run-${Date.now()}`};let Y=[],H=[];for(let{route:W,section:G}of f){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};H.push({type:"shell:content-generation",data:q})}if(H.length>0){let W=this.createJobOptions(B,"site:content-generation"),G=await this.context.jobs.enqueueBatch(H,W);for(let K=0;K<f.length;K++){let Z=f[K];if(Z)Y.push({jobId:`${G}-${K}`,routeId:Z.route.id,sectionId:Z.section.id})}return{jobs:Y,totalSections:D,queuedSections:Y.length,batchId:G}}return{jobs:[],totalSections:D,queuedSections:0,batchId:`empty-${Date.now()}`}}}class APA{siteConfig;operations;constructor(A,Q){this.siteConfig=Q;this.operations=new e_A(A)}async generateContent(A,Q){let B=HQA.parse(A);return this.operations.generate(B,this.siteConfig,Q)}}JA();function um(A,Q){return Q?A.optional():A}function BPA(A){switch(A.type){case"string":return um(F.string(),A.optional);case"number":return um(F.number(),A.optional);case"enum":{let Q=[...A.options];return um(F.enum(Q),A.optional)}case"object":{let Q={};for(let[B,w]of Object.entries(A.fields))Q[B]=BPA(w);return um(F.object(Q),A.optional)}case"array":{let Q=F.array(d1Q(A));if(A.minItems!==void 0)Q=Q.min(A.minItems);if(A.length!==void 0)Q=Q.length(A.length);return um(Q,A.optional)}}}function d1Q(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]=BPA($);return F.object(B)}}}function QPA(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])=>QPA(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,$])=>QPA(w,$)),B}}}}function n1Q(A,Q){let B={};for(let[I,f]of Object.entries(Q.fields))B[I]=BPA(f);let w=F.object(B),$=new NB(w,{title:Q.title,mappings:Object.entries(Q.fields).map(([I,f])=>QPA(I,f))});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 wPA(A){return Object.fromEntries(Object.entries(A.sections).map(([Q,B])=>[Q,n1Q(Q,B)]))}JA();var d51=F.object({namespace:F.string(),sections:F.record(F.any())}),n51=F.object({definitions:F.union([d51,F.array(d51)]).optional()});I0();function o51(A,Q){return[jQ(Q,"generate","Generate content for all routes, a specific route, or a specific section",HQA,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 I={rootJobId:`generate-${Date.now()}`,progressToken:w.progressToken,pluginId:Q,operationType:"content_operations",interfaceType:w.interfaceType,channelId:w.channelId},f=await $.generateContent(B,I);return{success:!0,message:`Generated ${f.queuedSections} of ${f.totalSections} sections. ${f.queuedSections>0?"Jobs are running in the background.":"No new content to generate."}`,data:{batchId:f.batchId,jobsQueued:f.queuedSections,totalSections:f.totalSections,jobs:f.jobs}}})]}var s51={name:"@brains/site-content",private:!0,version:"0.2.0-alpha.60",description:"Site content entity and generation orchestration",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/plugins":"workspace:*","@brains/site-info":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class $PA extends Ww{siteContentService;constructor(A={}){super("site-content",s51,A,n51)}async onRegister(A){A.entities.register("site-content",mm,t_A);for(let Q of uH(this.config.definitions))A.templates.register(wPA(Q),Q.namespace);this.siteContentService=new APA(A)}async getTools(){return o51(()=>this.siteContentService,this.id)}}function cm(A={}){return new $PA(A)}I0();JA();R8();JA();I0();var a51=F.enum(["available","early access","coming soon","planned"]),t51=F.object({title:F.string(),description:F.string()}),BG=F.object({name:F.string(),availability:a51,order:F.number()}),XQA=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(t51).min(1).max(6),story:F.string()}),s1Q=BG.pick({name:!0,availability:!0,order:!0}).extend({slug:F.string()}),W_=I2.extend({entityType:F.literal("product"),metadata:s1Q}),WQA=W_.extend({frontmatter:BG,body:XQA,labels:F.record(F.string(),F.string())}),UQA=WQA.extend({url:F.string().optional(),typeLabel:F.string().optional(),listUrl:F.string().optional(),listLabel:F.string().optional()});I0();JA();JA();class U_ extends NB{constructor(){super(XQA,{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 IPA extends W2{constructor(){super({entityType:"product",schema:W_,frontmatterSchema:BG,bodyFormatter:new U_})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,BG);return this.buildMarkdown(Q,B)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,BG),B=F2(Q.name);return{content:A,entityType:"product",metadata:{name:Q.name,slug:B,availability:Q.availability,order:Q.order}}}}var JQA=new IPA;JA();I0();var e51=F.object({title:F.string(),description:F.string()}),A91=F.object({title:F.string(),description:F.string()}),a1Q=F.object({title:F.string(),description:F.string()}),Q91=F.object({heading:F.string(),buttonText:F.string(),link:F.string()}),wG=F.object({headline:F.string(),tagline:F.string()}),t1Q=F.object({title:F.string(),description:F.string()}),GQA=F.object({vision:F.string(),pillars:F.array(e51).min(1).max(6),approach:F.array(t1Q).min(1).max(6),productsIntro:F.string(),technologies:F.array(a1Q).min(1).max(6),benefits:F.array(A91).min(1).max(6),cta:Q91}),B91=wG.pick({headline:!0}).extend({slug:F.string()}),J_=I2.extend({entityType:F.literal("products-overview"),metadata:B91}),pm=J_.extend({frontmatter:wG,body:GQA,labels:F.record(F.string(),F.string())});I0();JA();JA();class G_ extends NB{constructor(){super(GQA,{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 fPA extends W2{constructor(){super({entityType:"products-overview",schema:J_,frontmatterSchema:wG,bodyFormatter:new G_})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,wG);return this.buildMarkdown(Q,B)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,wG),B=F2(Q.headline);return{content:A,entityType:"products-overview",metadata:{headline:Q.headline,slug:B}}}}var DPA=new fPA;I0();JA();var e1Q=F.object({entityType:F.string(),query:F.object({id:F.string().optional()}).optional()});function w91(A,Q){let B=l2(A.content,BG),w=Q.parse(B.content),$=Q.getLabels();return WQA.parse({...A,frontmatter:B.metadata,body:w,labels:$})}function $91(A,Q){let B=l2(A.content,wG),w=Q.parse(B.content),$=Q.getLabels();return pm.parse({...A,frontmatter:B.metadata,body:w,labels:$})}class FQA{logger;id="products:entities";name="Products Entity DataSource";description="Fetches products and overview for the products page";overviewFormatter=new G_;productFormatter=new U_;constructor(A){this.logger=A;this.logger.debug("ProductsDataSource initialized")}async fetch(A,Q,B){let w=e1Q.parse(A),$=B.entityService;if(w.entityType==="products-overview"){let H=(await $.listEntities({entityType:"products-overview",options:{limit:1}}))[0];if(!H)throw Error("Products overview entity not found");let W=$91(H,this.overviewFormatter);return Q.parse(W)}if(w.query?.id){let H=(await $.listEntities({entityType:"product",options:{filter:{metadata:{slug:w.query.id}},limit:1}}))[0];if(!H)throw Error(`Product not found: ${w.query.id}`);return Q.parse({product:w91(H,this.productFormatter)})}let[I,f]=await Promise.all([$.listEntities({entityType:"products-overview",options:{limit:1}}),$.listEntities({entityType:"product",options:{sortFields:[{field:"order",direction:"asc"}]}})]),D=I[0];if(!D)throw Error("Products overview entity not found");return Q.parse({overview:$91(D,this.overviewFormatter),products:f.map((Y)=>w91(Y,this.productFormatter))})}}import{jsxDEV as B1,Fragment as B2Q}from"preact/jsx-dev-runtime";var I91=({overview:A,products:Q})=>{let{frontmatter:B,body:w,labels:$}=A;return B1(B2Q,{children:[B1(YQ,{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:`
|
|
5404
|
+
`;var X_=u51;import{join as l1Q}from"path";var c51={name:"@brains/rover",version:"0.2.0-alpha.61",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 p51=["prompt","note","link","wishlist","topics","directory-sync","agents","assessment","auth-service","cms","dashboard-root","mcp","webserver","discord","a2a"],l51=[...p51.filter((A)=>A!=="dashboard-root"),"image","dashboard","blog","series","decks","analytics","obsidian-vault","site-info","site-builder"],i1Q=[...l51,"portfolio","topics","content-pipeline","social-media","newsletter","stock-photo"],r1Q=["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."],i51=TF({name:"rover",version:c51.version,model:"gpt-5.4-mini",site:Sm,theme:X_,presets:{core:p51,default:l51,full:i1Q},evalDisable:["discord","webserver","mcp","analytics","dashboard","dashboard-root"],agentInstructions:r1Q,capabilities:[["prompt",_C,void 0],["image",Vv,void 0],["cms",bC,{}],["auth-service",Gy,void 0],["dashboard",hZ,void 0],["dashboard-root",hZ,{routePath:"/"}],["blog",VbA,{}],["series",PbA,void 0],["decks",Im,void 0],["note",EC,{}],["link",MC,{}],["portfolio",YRA,{}],["topics",J2A,{includeEntityTypes:["post","deck","project","link","anchor-profile"]}],["content-pipeline",TRA,{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",Nm,{autoGenerateOnBlogPublish:!0}],["newsletter",W61,{doubleOptIn:!0}],["obsidian-vault",$_A,{autoSync:!0}],["wishlist",P2A,{}],["stock-photo",U_A,{}],["agents",d2A,void 0],["assessment",wQA,void 0],["directory-sync",Sq,{seedContent:!0,seedContentPath:l1Q(import.meta.dir,"..","seed-content"),initialSync:!0}],["analytics",M2A,{}],["rizom-ecosystem",PC,void 0],["site-info",NC,void 0],["site-builder",zC,{cms:{}}]],interfaces:[["mcp",EK,()=>({})],["discord",wZ,()=>({})],["webserver",$Z,()=>({})],["a2a",ub,()=>({})]],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"}}});cF();I0();JA();JA();I0();var YQA=F.object({routeId:F.string(),sectionId:F.string()}),mm=I2.extend({entityType:F.literal("site-content"),template:F.string().optional(),content:F.string(),metadata:YQA});I0();class r51 extends W2{constructor(){super({entityType:"site-content",schema:mm,frontmatterSchema:YQA})}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 t_A=new r51;JA();var HQA=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")}),bZw=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 e_A{context;constructor(A){this.context=A}createJobOptions(A,Q){if(!A)return;return{source:A.operationType??Q,rootJobId:A.rootJobId??`${Q}-${Date.now()}`,metadata:{operationType:A.operationType??"content_operations",progressToken:A.progressToken,pluginId:A.pluginId??"site-content"}}}async fetchRoutes(){let A=await this.context.messaging.send({type:"site-builder:routes:list",payload:{}});if("noop"in A)throw Error("No handler for site-builder:routes:list \u2014 is site-builder plugin loaded?");if(!A.success||!A.data)throw Error("Failed to fetch routes from site-builder");return A.data}async generate(A,Q,B){let w=this.context.logger.child("SiteContentOperations"),$=await this.fetchRoutes(),I=$;if(A.routeId){if(I=$.filter((W)=>W.id===A.routeId),I.length===0)throw Error(`Route not found: ${A.routeId}`)}let f=[];for(let W of I)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}}f.push({route:W,section:G})}let D=f.length;if(A.dryRun)return{jobs:[],totalSections:D,queuedSections:D,batchId:`dry-run-${Date.now()}`};let Y=[],H=[];for(let{route:W,section:G}of f){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};H.push({type:"shell:content-generation",data:q})}if(H.length>0){let W=this.createJobOptions(B,"site:content-generation"),G=await this.context.jobs.enqueueBatch(H,W);for(let K=0;K<f.length;K++){let Z=f[K];if(Z)Y.push({jobId:`${G}-${K}`,routeId:Z.route.id,sectionId:Z.section.id})}return{jobs:Y,totalSections:D,queuedSections:Y.length,batchId:G}}return{jobs:[],totalSections:D,queuedSections:0,batchId:`empty-${Date.now()}`}}}class APA{siteConfig;operations;constructor(A,Q){this.siteConfig=Q;this.operations=new e_A(A)}async generateContent(A,Q){let B=HQA.parse(A);return this.operations.generate(B,this.siteConfig,Q)}}JA();function um(A,Q){return Q?A.optional():A}function BPA(A){switch(A.type){case"string":return um(F.string(),A.optional);case"number":return um(F.number(),A.optional);case"enum":{let Q=[...A.options];return um(F.enum(Q),A.optional)}case"object":{let Q={};for(let[B,w]of Object.entries(A.fields))Q[B]=BPA(w);return um(F.object(Q),A.optional)}case"array":{let Q=F.array(d1Q(A));if(A.minItems!==void 0)Q=Q.min(A.minItems);if(A.length!==void 0)Q=Q.length(A.length);return um(Q,A.optional)}}}function d1Q(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]=BPA($);return F.object(B)}}}function QPA(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])=>QPA(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,$])=>QPA(w,$)),B}}}}function n1Q(A,Q){let B={};for(let[I,f]of Object.entries(Q.fields))B[I]=BPA(f);let w=F.object(B),$=new NB(w,{title:Q.title,mappings:Object.entries(Q.fields).map(([I,f])=>QPA(I,f))});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 wPA(A){return Object.fromEntries(Object.entries(A.sections).map(([Q,B])=>[Q,n1Q(Q,B)]))}JA();var d51=F.object({namespace:F.string(),sections:F.record(F.any())}),n51=F.object({definitions:F.union([d51,F.array(d51)]).optional()});I0();function o51(A,Q){return[jQ(Q,"generate","Generate content for all routes, a specific route, or a specific section",HQA,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 I={rootJobId:`generate-${Date.now()}`,progressToken:w.progressToken,pluginId:Q,operationType:"content_operations",interfaceType:w.interfaceType,channelId:w.channelId},f=await $.generateContent(B,I);return{success:!0,message:`Generated ${f.queuedSections} of ${f.totalSections} sections. ${f.queuedSections>0?"Jobs are running in the background.":"No new content to generate."}`,data:{batchId:f.batchId,jobsQueued:f.queuedSections,totalSections:f.totalSections,jobs:f.jobs}}})]}var s51={name:"@brains/site-content",private:!0,version:"0.2.0-alpha.61",description:"Site content entity and generation orchestration",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/plugins":"workspace:*","@brains/site-info":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class $PA extends Ww{siteContentService;constructor(A={}){super("site-content",s51,A,n51)}async onRegister(A){A.entities.register("site-content",mm,t_A);for(let Q of uH(this.config.definitions))A.templates.register(wPA(Q),Q.namespace);this.siteContentService=new APA(A)}async getTools(){return o51(()=>this.siteContentService,this.id)}}function cm(A={}){return new $PA(A)}I0();JA();R8();JA();I0();var a51=F.enum(["available","early access","coming soon","planned"]),t51=F.object({title:F.string(),description:F.string()}),BG=F.object({name:F.string(),availability:a51,order:F.number()}),XQA=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(t51).min(1).max(6),story:F.string()}),s1Q=BG.pick({name:!0,availability:!0,order:!0}).extend({slug:F.string()}),W_=I2.extend({entityType:F.literal("product"),metadata:s1Q}),WQA=W_.extend({frontmatter:BG,body:XQA,labels:F.record(F.string(),F.string())}),UQA=WQA.extend({url:F.string().optional(),typeLabel:F.string().optional(),listUrl:F.string().optional(),listLabel:F.string().optional()});I0();JA();JA();class U_ extends NB{constructor(){super(XQA,{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 IPA extends W2{constructor(){super({entityType:"product",schema:W_,frontmatterSchema:BG,bodyFormatter:new U_})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,BG);return this.buildMarkdown(Q,B)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,BG),B=F2(Q.name);return{content:A,entityType:"product",metadata:{name:Q.name,slug:B,availability:Q.availability,order:Q.order}}}}var JQA=new IPA;JA();I0();var e51=F.object({title:F.string(),description:F.string()}),A91=F.object({title:F.string(),description:F.string()}),a1Q=F.object({title:F.string(),description:F.string()}),Q91=F.object({heading:F.string(),buttonText:F.string(),link:F.string()}),wG=F.object({headline:F.string(),tagline:F.string()}),t1Q=F.object({title:F.string(),description:F.string()}),GQA=F.object({vision:F.string(),pillars:F.array(e51).min(1).max(6),approach:F.array(t1Q).min(1).max(6),productsIntro:F.string(),technologies:F.array(a1Q).min(1).max(6),benefits:F.array(A91).min(1).max(6),cta:Q91}),B91=wG.pick({headline:!0}).extend({slug:F.string()}),J_=I2.extend({entityType:F.literal("products-overview"),metadata:B91}),pm=J_.extend({frontmatter:wG,body:GQA,labels:F.record(F.string(),F.string())});I0();JA();JA();class G_ extends NB{constructor(){super(GQA,{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 fPA extends W2{constructor(){super({entityType:"products-overview",schema:J_,frontmatterSchema:wG,bodyFormatter:new G_})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,wG);return this.buildMarkdown(Q,B)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,wG),B=F2(Q.headline);return{content:A,entityType:"products-overview",metadata:{headline:Q.headline,slug:B}}}}var DPA=new fPA;I0();JA();var e1Q=F.object({entityType:F.string(),query:F.object({id:F.string().optional()}).optional()});function w91(A,Q){let B=l2(A.content,BG),w=Q.parse(B.content),$=Q.getLabels();return WQA.parse({...A,frontmatter:B.metadata,body:w,labels:$})}function $91(A,Q){let B=l2(A.content,wG),w=Q.parse(B.content),$=Q.getLabels();return pm.parse({...A,frontmatter:B.metadata,body:w,labels:$})}class FQA{logger;id="products:entities";name="Products Entity DataSource";description="Fetches products and overview for the products page";overviewFormatter=new G_;productFormatter=new U_;constructor(A){this.logger=A;this.logger.debug("ProductsDataSource initialized")}async fetch(A,Q,B){let w=e1Q.parse(A),$=B.entityService;if(w.entityType==="products-overview"){let H=(await $.listEntities({entityType:"products-overview",options:{limit:1}}))[0];if(!H)throw Error("Products overview entity not found");let W=$91(H,this.overviewFormatter);return Q.parse(W)}if(w.query?.id){let H=(await $.listEntities({entityType:"product",options:{filter:{metadata:{slug:w.query.id}},limit:1}}))[0];if(!H)throw Error(`Product not found: ${w.query.id}`);return Q.parse({product:w91(H,this.productFormatter)})}let[I,f]=await Promise.all([$.listEntities({entityType:"products-overview",options:{limit:1}}),$.listEntities({entityType:"product",options:{sortFields:[{field:"order",direction:"asc"}]}})]),D=I[0];if(!D)throw Error("Products overview entity not found");return Q.parse({overview:$91(D,this.overviewFormatter),products:f.map((Y)=>w91(Y,this.productFormatter))})}}import{jsxDEV as B1,Fragment as B2Q}from"preact/jsx-dev-runtime";var I91=({overview:A,products:Q})=>{let{frontmatter:B,body:w,labels:$}=A;return B1(B2Q,{children:[B1(YQ,{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:`
|
|
5405
5405
|
@keyframes wave-drift {
|
|
5406
5406
|
from { transform: translateX(0); }
|
|
5407
5407
|
to { transform: translateX(-50%); }
|
|
@@ -5429,7 +5429,7 @@ ${JSON.stringify(B,null,2)}`}function e2A(A){return A.map((Q)=>Q.detail===null?{
|
|
|
5429
5429
|
@media (prefers-reduced-motion: reduce) {
|
|
5430
5430
|
.detail-wave { animation: none; }
|
|
5431
5431
|
}
|
|
5432
|
-
`},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:I},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(KI,{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(fR,{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,Y)=>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(Y+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:f.map((D,Y)=>n1("p",{className:Y===0?"text-2xl md:text-3xl leading-relaxed text-heading font-light":"text-lg leading-relaxed text-theme-muted",children:D},Y,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),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(V5,{href:$,variant:"outline-light",size:"lg",children:I},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};JA();var YPA=F.object({route:F.string().default("/products")});var D91={name:"@brains/products",private:!0,version:"0.2.0-alpha.60",description:"Product entity management and overview page for marketing showcase",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var I2Q=F.object({overview:pm,products:F.array(UQA)}),f2Q=F.object({product:UQA});class HPA extends FQ{entityType=JQA.entityType;schema=W_;adapter=JQA;constructor(A={}){super("products",D91,A,YPA)}getTemplates(){return{"product-list":b1({name:"product-list",description:"Products page \u2014 overview + brain model cards",schema:I2Q,dataSourceId:"products:entities",requiredPermission:"public",layout:{component:I91}}),"product-detail":b1({name:"product-detail",description:"Individual product detail page",schema:f2Q,dataSourceId:"products:entities",requiredPermission:"public",layout:{component:f91}})}}getDataSources(){return[new FQA(this.logger.child("ProductsDataSource"))]}async onRegister(A){A.entities.register("products-overview",J_,DPA)}}function XPA(A={}){return new HPA(A)}import{join as k2Q}from"path";import{jsxDEV as KQA,Fragment as D2Q}from"preact/jsx-dev-runtime";var F_=({children:A})=>KQA(D2Q,{children:[KQA("div",{id:"bgCanvasWrap",className:"rizom-frame-canvas-wrap fixed top-0 left-0 w-full h-full pointer-events-none",children:KQA("canvas",{id:"heroCanvas",className:"w-full h-full block"},void 0,!1,void 0,this)},void 0,!1,void 0,this),KQA("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 Uzw}from"preact/jsx-dev-runtime";import{jsxDEV as H2Q}from"preact/jsx-dev-runtime";var ZQA="px-6 md:px-10 xl:px-20",Y2Q=`${ZQA} relative z-[1]`,TZ=({id:A,className:Q,children:B})=>H2Q("section",{id:A,className:s1(Y2Q,Q),children:B},void 0,!1,void 0,this);import{jsxDEV as qzw}from"preact/jsx-dev-runtime";import{jsxDEV as Lzw}from"preact/jsx-dev-runtime";import{jsxDEV as G2Q}from"preact/jsx-dev-runtime";var X2Q="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)]",W2Q={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)]"},U2Q={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)]"},J2Q="w-full md:w-auto",jC=({href:A,variant:Q="primary",size:B="md",block:w=!1,className:$,children:I})=>G2Q("a",{href:A,className:s1("rizom-btn",`rizom-btn-${Q}`,`rizom-btn-${B}`,w&&"rizom-btn-block",X2Q,W2Q[Q],U2Q[B],w&&J2Q,$),children:I},void 0,!1,void 0,this);import{jsxDEV as Pzw}from"preact/jsx-dev-runtime";import{jsxDEV as vzw}from"preact/jsx-dev-runtime";import{Fragment as gzw}from"preact";import{jsxDEV as Szw}from"preact/jsx-dev-runtime";import{jsxDEV as Y91}from"preact/jsx-dev-runtime";var zQA=({sections:A})=>Y91(F_,{children:Y91("main",{children:A},void 0,!1,void 0,this)},void 0,!1,void 0,this);I0();JA();var H91=`/*
|
|
5432
|
+
`},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:I},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(KI,{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(fR,{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,Y)=>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(Y+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:f.map((D,Y)=>n1("p",{className:Y===0?"text-2xl md:text-3xl leading-relaxed text-heading font-light":"text-lg leading-relaxed text-theme-muted",children:D},Y,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),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(V5,{href:$,variant:"outline-light",size:"lg",children:I},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};JA();var YPA=F.object({route:F.string().default("/products")});var D91={name:"@brains/products",private:!0,version:"0.2.0-alpha.61",description:"Product entity management and overview page for marketing showcase",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var I2Q=F.object({overview:pm,products:F.array(UQA)}),f2Q=F.object({product:UQA});class HPA extends FQ{entityType=JQA.entityType;schema=W_;adapter=JQA;constructor(A={}){super("products",D91,A,YPA)}getTemplates(){return{"product-list":b1({name:"product-list",description:"Products page \u2014 overview + brain model cards",schema:I2Q,dataSourceId:"products:entities",requiredPermission:"public",layout:{component:I91}}),"product-detail":b1({name:"product-detail",description:"Individual product detail page",schema:f2Q,dataSourceId:"products:entities",requiredPermission:"public",layout:{component:f91}})}}getDataSources(){return[new FQA(this.logger.child("ProductsDataSource"))]}async onRegister(A){A.entities.register("products-overview",J_,DPA)}}function XPA(A={}){return new HPA(A)}import{join as k2Q}from"path";import{jsxDEV as KQA,Fragment as D2Q}from"preact/jsx-dev-runtime";var F_=({children:A})=>KQA(D2Q,{children:[KQA("div",{id:"bgCanvasWrap",className:"rizom-frame-canvas-wrap fixed top-0 left-0 w-full h-full pointer-events-none",children:KQA("canvas",{id:"heroCanvas",className:"w-full h-full block"},void 0,!1,void 0,this)},void 0,!1,void 0,this),KQA("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 Uzw}from"preact/jsx-dev-runtime";import{jsxDEV as H2Q}from"preact/jsx-dev-runtime";var ZQA="px-6 md:px-10 xl:px-20",Y2Q=`${ZQA} relative z-[1]`,TZ=({id:A,className:Q,children:B})=>H2Q("section",{id:A,className:s1(Y2Q,Q),children:B},void 0,!1,void 0,this);import{jsxDEV as qzw}from"preact/jsx-dev-runtime";import{jsxDEV as Lzw}from"preact/jsx-dev-runtime";import{jsxDEV as G2Q}from"preact/jsx-dev-runtime";var X2Q="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)]",W2Q={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)]"},U2Q={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)]"},J2Q="w-full md:w-auto",jC=({href:A,variant:Q="primary",size:B="md",block:w=!1,className:$,children:I})=>G2Q("a",{href:A,className:s1("rizom-btn",`rizom-btn-${Q}`,`rizom-btn-${B}`,w&&"rizom-btn-block",X2Q,W2Q[Q],U2Q[B],w&&J2Q,$),children:I},void 0,!1,void 0,this);import{jsxDEV as Pzw}from"preact/jsx-dev-runtime";import{jsxDEV as vzw}from"preact/jsx-dev-runtime";import{Fragment as gzw}from"preact";import{jsxDEV as Szw}from"preact/jsx-dev-runtime";import{jsxDEV as Y91}from"preact/jsx-dev-runtime";var zQA=({sections:A})=>Y91(F_,{children:Y91("main",{children:A},void 0,!1,void 0,this)},void 0,!1,void 0,this);I0();JA();var H91=`/*
|
|
5433
5433
|
* Shared globals + helpers used by tree / constellation / roots canvas
|
|
5434
5434
|
* scripts. Loaded as a shared static asset by the Rizom runtime package
|
|
5435
5435
|
* so the variant canvases
|
|
@@ -7882,7 +7882,7 @@ facts, owners, or tasks. Return only the required structured JSON.`});JA();var c
|
|
|
7882
7882
|
`),decisionsText:W.join(`
|
|
7883
7883
|
`),actionItemsText:G.join(`
|
|
7884
7884
|
`)}})}),Q.eval.registerHandler("decideProjection",async($)=>{let I=e2Q.parse($),f=qPA(I.messages,I.conversationId),D=I.existingSummary?_91({conversationId:I.conversationId,content:I.existingSummary,messageCount:I.existingMessageCount,projectionVersion:w.projectionVersion}):null;return new mZ(Q,B,w).decideProjection(f,D)}),Q.eval.registerHandler("retrieveMemory",async($)=>{let I=t2Q.parse($),f=I.memory?BQQ(Q,I.memory):Q;return new VQA(f).retrieve(I)}),Q.eval.registerHandler("projectMessages",async($)=>{let I=s2Q.parse($),f=qPA(I.messages,I.conversationId),D=AQQ({conversationId:I.conversationId,interfaceType:I.interfaceType,channelId:I.channelId,channelName:I.channelName,messages:f}),Y=I.existingSummary?_91({conversationId:I.conversationId,content:I.existingSummary,messageCount:I.existingMessageCount,projectionVersion:w.projectionVersion}):null,H=[],W=[],G=QQQ({context:Q,conversation:D,messages:f,existing:Y,upserted:H,deleted:W,projectionDecision:I.projectionDecision});return{result:await new mZ(G,B,w).projectConversation(I.conversationId),summaries:H.filter((q)=>q.entityType==="summary"),decisions:H.filter((q)=>q.entityType==="decision"),actionItems:H.filter((q)=>q.entityType==="action-item"),deleted:W}}),Q.eval.registerHandler("projectConversation",async($)=>{let I=o2Q.parse($);return new mZ(Q,B,w).projectConversation(I.conversationId)})}function _91(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 qPA(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:{}}})}function AQQ(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 QQQ(A){let Q=`${A.conversation.interfaceType}:${A.conversation.channelId}`;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 BQQ(A,Q){let B=Q.map(wQQ),w=B.map(($,I)=>({entity:$,score:Q[I]?.score??1,excerpt:Q[I]?.excerpt??DQQ($)}));return{...A,entityService:{...A.entityService,search:async()=>w,listEntities:async({entityType:$})=>B.filter((I)=>I.entityType===$)}}}function wQQ(A){if(A.entityType==="summary")return $QQ(A);if(A.entityType==="decision")return IQQ(A);return fQQ(A)}function EPA(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 $QQ(A){return{...EPA(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}}}function IQQ(A){return{...EPA(A),entityType:"decision",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,spaceId:`${A.interfaceType}:${A.channelId}`,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"}}}function fQQ(A){let Q=A.status==="done"||A.status==="dropped"?A.status:"open";return{...EPA(A),entityType:"action-item",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,spaceId:`${A.interfaceType}:${A.channelId}`,timeRange:{start:"2026-01-01T00:00:00.000Z",end:"2026-01-01T00:01:00.000Z"},sourceSummaryId:A.conversationId,sourceMessageCount:2,projectionVersion:1,status:Q}}}function DQQ(A){return A.content.replace(/^---[\s\S]*?---\s*/m,"").split(`
|
|
7885
|
-
`).map((Q)=>Q.trim()).find((Q)=>Q.length>0&&!Q.startsWith("#"))??""}var k91={name:"@brains/conversation-memory",private:!0,version:"0.2.0-alpha.
|
|
7885
|
+
`).map((Q)=>Q.trim()).find((Q)=>Q.length>0&&!Q.startsWith("#"))??""}var k91={name:"@brains/conversation-memory",private:!0,version:"0.2.0-alpha.61",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/conversation-service":"workspace:*","@brains/plugins":"workspace:*","@brains/templates":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/node":"^20.0.0",eslint:"^8.56.0",typescript:"^5.3.3"}};var HQQ=new SZ,XQQ=new q_,WQQ=new C_,LPA=F.object({conversationId:F.string()});class MPA extends FQ{entityType=_5;schema=im;adapter=HQQ;constructor(A={}){super(Z_,k91,A,GPA)}getConfig(){return this.config}getTemplates(){return{"summary-list":E91,"summary-detail":L91,"ai-response":M91}}getDataSources(){return[new NPA(this.logger.child("SummaryDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableProjection)return[];return[{id:"conversation-memory-projection",targetType:_5,job:{type:Z91,handler:new EQA(A,this.logger,this.config)},initialSync:{shouldEnqueue:async()=>A.spaces.length>0&&!await Wz(A,_5),jobData:{mode:"rebuild-all",reason:"initial-sync"},jobOptions:{source:JPA,deduplication:"coalesce",deduplicationKey:"conversation-memory:rebuild-all:initial-sync",metadata:{operationType:"data_processing",operationTarget:"conversation-memory:rebuild-all",pluginId:Z_}}},sourceChange:{sourceKind:jl,sourceTypes:[jl],shouldEnqueue:(Q)=>this.shouldEnqueueConversationProjection(A,Q),events:[Ij],jobData:(Q)=>{return{mode:"conversation",conversationId:LPA.parse(Q).conversationId,reason:"message-added"}},jobOptions:(Q)=>{let B=LPA.parse(Q);return{priority:5,delayMs:this.config.projectionDelayMs,source:JPA,deduplication:"skip",deduplicationKey:`conversation-memory:${B.conversationId}`,metadata:{operationType:"data_processing",operationTarget:`conversation-memory:${B.conversationId}`,pluginId:Z_}}}}}]}async shouldEnqueueConversationProjection(A,Q){let B=LPA.parse(Q),w=await A.conversations.get(B.conversationId);if(!w)return!1;let $=await A.conversations.getMessages(B.conversationId,{limit:this.config.maxSourceMessages});if(!hC({conversation:w,spaces:A.spaces,messages:$}).eligible)return!1;return $.length>0}async onRegister(A){A.entities.register(wH,dm,XQQ),A.entities.register($H,om,WQQ),b91({context:A,pluginId:this.id,config:this.config}),P91({context:A,logger:this.logger,config:this.config})}}function VPA(A){return new MPA(A)}I0();JA();I0();var $G=F.object({title:F.string(),section:F.string(),order:F.number().int(),sourcePath:F.string(),description:F.string().optional(),slug:F.string().optional()}),j91=$G.pick({title:!0,section:!0,order:!0,description:!0}).extend({slug:F.string()}),V_=I2.extend({entityType:F.literal("doc"),metadata:j91}),IG=V_.extend({frontmatter:$G,body:F.string()});I0();JA();class OPA extends W2{constructor(){super({entityType:"doc",schema:V_,frontmatterSchema:$G})}toMarkdown(A){let Q=this.extractBody(A.content),B=this.parseFrontMatter(A.content,$G);return this.buildMarkdown(Q,B)}fromMarkdown(A){let Q=this.parseFrontMatter(A,$G),B=Q.slug??F2(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 OQA=new OPA;I0();function x91(A){return[...A].sort((Q,B)=>{let w=Q.metadata.order-B.metadata.order;if(w!==0)return w;return Q.metadata.title.localeCompare(B.metadata.title)})}function v91(A){let Q=l2(A.content,$G);return IG.parse({...A,frontmatter:Q.metadata,body:Q.content})}class bQA extends d6{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 v91(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[$,I]=await Promise.all([this.fetchDetail(w.query.id,B.entityService),this.fetchList({limit:1000},B.entityService)]),f=x91(I.items),D=f.findIndex((W)=>W.id===$.item.id),Y=D>0?f[D-1]:null,H=D>=0&&D<f.length-1?f[D+1]:null;return Q.parse({doc:$.item,docs:f,prevDoc:Y,nextDoc:H})}buildDetailResult(A,Q){return{doc:A,docs:[A],prevDoc:Q?.prev??null,nextDoc:Q?.next??null}}buildListResult(A,Q,B){return{docs:x91(A),pagination:Q,baseUrl:B.baseUrl}}}I0();R8();JA();import{jsxDEV as Y5}from"preact/jsx-dev-runtime";var UQQ=["I","II","III","IV","V","VI","VII","VIII","IX","X"];function tm(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 tm(A)){let w=B.metadata.section;Q.set(w,[...Q.get(w)??[],B])}return[...Q.entries()].map(([B,w])=>({section:B,docs:w}))}function O_(A){return`/docs/${A.metadata.slug}`}function _QA(A){return`section-${A+1}`}function b_(A){return UQQ[A]??String(A+1)}var g91="text-[var(--docs-text)] font-bold",T91="text-[var(--docs-accent)] font-bold",S91="text-[var(--docs-text-muted)]",JQQ="docs-font-label text-xs uppercase tracking-[0.18em] text-[var(--docs-accent)]",GQQ="docs-font-display text-[var(--docs-heading)]",h91="inline-flex items-center justify-center rounded-lg border px-[18px] py-2.5 text-sm font-semibold transition-colors duration-150",y91="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",bPA="docs-font-label text-[13px] text-[var(--docs-text-light)] transition-colors duration-150 hover:text-[var(--docs-text)]",UW={wrap:"mx-auto max-w-6xl px-6 pt-20 md:px-12 md:pt-24",label:JQQ,display:GQQ,button:`${h91} border-[var(--docs-text)] text-[var(--docs-text)] hover:border-[var(--docs-accent)] hover:text-[var(--docs-accent)]`,primaryButton:`${h91} border-[var(--docs-accent)] bg-[var(--docs-accent)] text-white hover:bg-transparent hover:text-[var(--docs-accent)]`},m91=()=>Y5("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:[Y5("a",{href:"/docs",className:"docs-font-body text-xl font-bold","aria-label":"Brains docs",children:[Y5("span",{className:g91,children:"brains"},void 0,!1,void 0,this),Y5("span",{className:T91,children:"."},void 0,!1,void 0,this),Y5("span",{className:S91,children:"docs"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Y5("div",{className:"docs-header__nav flex items-center gap-4 md:gap-8",children:[Y5("a",{className:y91,href:"/docs/roadmap",children:"Roadmap"},void 0,!1,void 0,this),Y5("a",{className:y91,href:"https://github.com/rizom-ai/brains",children:"GitHub"},void 0,!1,void 0,this),Y5("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),u91=()=>Y5("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:[Y5("a",{href:"https://rizom.ai",className:"docs-font-body text-[15px] font-bold",children:[Y5("span",{className:g91,children:"rizom"},void 0,!1,void 0,this),Y5("span",{className:T91,children:"."},void 0,!1,void 0,this),Y5("span",{className:S91,children:"ai"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Y5("div",{className:"flex flex-wrap items-center justify-center gap-6 md:justify-end",children:[Y5("a",{className:bPA,href:"/docs/roadmap",children:"Roadmap"},void 0,!1,void 0,this),Y5("a",{className:bPA,href:"https://github.com/rizom-ai/brains",children:"GitHub"},void 0,!1,void 0,this),Y5("a",{className:bPA,href:"https://rizom.ai",children:"Rizom"},void 0,!1,void 0,this),Y5("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),FQQ=`
|
|
7886
7886
|
.docs-handbook {
|
|
7887
7887
|
--docs-bg: var(--color-bg, #0d0a1a);
|
|
7888
7888
|
--docs-bg-card: var(--color-bg-card, #1a0a3e);
|
|
@@ -8034,7 +8034,7 @@ facts, owners, or tasks. Return only the required structured JSON.`});JA();var c
|
|
|
8034
8034
|
background: transparent;
|
|
8035
8035
|
}
|
|
8036
8036
|
|
|
8037
|
-
`,c91=()=>Y5("style",{children:FQQ},void 0,!1,void 0,this);import{jsxDEV as H2,Fragment as KQQ}from"preact/jsx-dev-runtime";var PQA=({title:A,description:Q,children:B,detail:w=!1,footer:$=!1,contentClassName:I=""})=>H2(KQQ,{children:[H2(YQ,{title:A,description:Q},void 0,!1,void 0,this),H2(c91,{},void 0,!1,void 0,this),H2("div",{className:`docs-handbook${w?" docs-handbook--detail":""}`,children:[H2(m91,{},void 0,!1,void 0,this),H2("div",{className:`${UW.wrap} ${I}`.trim(),children:[B,$&&H2(u91,{},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),p91=({docsCount:A,sectionsCount:Q,startDoc:B})=>H2("section",{className:"border-b border-[var(--docs-text)] py-14 md:py-24 md:pb-[72px]",children:[H2("p",{className:`${UW.label} mb-8`,children:"Handbook \xB7 Brains docs"},void 0,!1,void 0,this),H2("h1",{className:`${UW.display} m-0 max-w-[16ch] text-5xl leading-[1.05] tracking-[-0.02em] md:text-7xl`,children:["Build, run, and publish"," ",H2("em",{className:"text-[var(--docs-accent)]",children:"brains."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),H2("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),H2("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:[H2("div",{children:[H2("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),H2("div",{children:[H2("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),H2("div",{children:[H2("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),H2("div",{className:"mt-9 flex flex-wrap gap-3.5",children:[B&&H2("a",{className:UW.primaryButton,href:O_(B),children:"Start reading"},void 0,!1,void 0,this),H2("a",{className:UW.button,href:"#sections",children:"Browse sections"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),l91=({groups:A})=>H2("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:[H2("p",{className:"m-0 mb-3.5 font-medium text-[var(--docs-text)]",children:"Sections"},void 0,!1,void 0,this),H2("ol",{className:"m-0 list-none p-0",children:A.map((Q,B)=>H2("li",{className:"grid grid-cols-[32px_1fr] gap-2 py-1.5",children:[H2("span",{className:"docs-font-display text-[var(--docs-text-light)] italic",children:[b_(B),"."]},void 0,!0,void 0,this),H2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:`#${_QA(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),i91=({group:A,index:Q})=>H2("article",{className:"mb-16 last:mb-0",id:_QA(Q),children:[H2("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:[H2("span",{className:"text-right docs-font-display text-3xl leading-[1.1] text-[var(--docs-accent)] italic md:text-4xl",children:[b_(Q),"."]},void 0,!0,void 0,this),H2("h2",{className:`${UW.display} m-0 text-3xl leading-[1.1] tracking-[-0.015em] md:text-4xl`,children:A.section},void 0,!1,void 0,this),H2("span",{className:"docs-chapter__leader"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),H2("ol",{className:"m-0 list-none p-0",children:A.docs.map((B)=>H2("li",{className:"border-b border-[var(--docs-border-light)] last:border-b-0",children:H2("a",{className:"group block py-[18px] pl-12 md:pl-[68px]",href:O_(B),children:[H2("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&&H2("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),r91=({title:A})=>H2("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:[H2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/",children:"Home"},void 0,!1,void 0,this),H2("span",{children:"/"},void 0,!1,void 0,this),H2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/docs",children:"Docs"},void 0,!1,void 0,this),H2("span",{children:"/"},void 0,!1,void 0,this),H2("span",{children:A},void 0,!1,void 0,this)]},void 0,!0,void 0,this),d91=({groups:A,activeGroupIndex:Q,activeSlug:B})=>H2("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:H2("nav",{className:"docs-font-label text-xs tracking-[0.06em] text-[var(--docs-text-light)]",children:[H2("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),H2("ol",{className:"m-0 list-none p-0",children:A.map((w,$)=>{let I=$===Q;return H2("li",{className:I?"mb-[22px]":"mb-3.5",children:[H2("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)] ${I?"text-[var(--docs-text)]":"text-[var(--docs-text-muted)]"}`,href:`/docs#${_QA($)}`,children:[H2("span",{className:"docs-font-display text-sm text-[var(--docs-accent)] italic",children:[b_($),"."]},void 0,!0,void 0,this)," ",w.section]},void 0,!0,void 0,this),I&&H2("ol",{className:"mt-0.5 list-none p-0",children:w.docs.map((f)=>{let D=f.metadata.slug===B;return H2("li",{children:H2("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:O_(f),"aria-current":D?"page":void 0,children:f.metadata.title},void 0,!1,void 0,this)},f.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),n91=({prevDoc:A,nextDoc:Q})=>{if(!A&&!Q)return null;return H2("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?H2("a",{className:"group border-t border-[var(--docs-border-light)] pt-[18px] transition-colors duration-150 hover:border-[var(--docs-accent)]",href:O_(A),children:[H2("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),H2("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):H2("span",{},void 0,!1,void 0,this),Q&&H2("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:O_(Q),children:[H2("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),H2("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 R_}from"preact/jsx-dev-runtime";var RPA=({docs:A})=>{let Q=tm(A),B=RQA(Q),$=Q.filter((I)=>I.metadata.slug!=="index")[0]??Q[0];return R_(PQA,{title:"Documentation",description:"Brains documentation",children:[R_(p91,{docsCount:A.length,sectionsCount:B.length,startDoc:$},void 0,!1,void 0,this),R_("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:[R_(l91,{groups:B},void 0,!1,void 0,this),R_("div",{children:B.map((I,f)=>R_(i91,{group:I,index:f},I.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 Sf}from"preact/jsx-dev-runtime";var _PA=({doc:A,docs:Q,prevDoc:B,nextDoc:w})=>{let $=RQA(Q.length>0?Q:[A]),I=tm(Q.length>0?Q:[A]),f=I.findIndex((Y)=>Y.metadata.slug===A.metadata.slug),D=Math.max($.findIndex((Y)=>Y.docs.some((H)=>H.metadata.slug===A.metadata.slug)),0);return Sf(PQA,{title:A.metadata.title,description:A.metadata.description??A.metadata.section,detail:!0,footer:!0,contentClassName:"pt-16",children:[Sf(r91,{title:A.metadata.title},void 0,!1,void 0,this),Sf("div",{className:"grid items-start gap-10 py-8 pb-24 md:grid-cols-[240px_minmax(0,1fr)] md:gap-20",children:[Sf(d91,{groups:$,activeGroupIndex:D,activeSlug:A.metadata.slug},void 0,!1,void 0,this),Sf("article",{className:"min-w-0",children:[Sf("header",{className:"mb-10 border-b border-[var(--docs-border)] pb-8",children:[Sf("p",{className:`${UW.label} m-0 mb-6 flex items-baseline gap-3`,children:[Sf("span",{className:"docs-font-display text-lg leading-none tracking-normal normal-case text-[var(--docs-accent)] italic",children:[b_(D),"."]},void 0,!0,void 0,this)," ",A.metadata.section,f>=0?` \xB7 ${f+1}/${I.length}`:""]},void 0,!0,void 0,this),Sf("h1",{className:`${UW.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&&Sf("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),Sf("div",{className:"docs-article__body",children:Sf(jf,{markdown:A.body},void 0,!1,void 0,this)},void 0,!1,void 0,this),Sf(n91,{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 ZQQ=F.object({docs:F.array(IG),pagination:B$.nullable(),baseUrl:F.string().optional()}),zQQ=F.object({doc:IG,docs:F.array(IG),prevDoc:IG.nullable(),nextDoc:IG.nullable()});function o91(){return{"doc-list":b1({name:"doc-list",description:"Documentation index template",schema:ZQQ,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:RPA}}),"doc-detail":b1({name:"doc-detail",description:"Documentation page template",schema:zQQ,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:_PA}})}}var s91={name:"@brains/doc",private:!0,version:"0.2.0-alpha.60",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 PPA extends FQ{entityType=OQA.entityType;schema=V_;adapter=OQA;constructor(){super("docs",s91,{},void 0)}getTemplates(){return o91()}getDataSources(){return[new bQA(this.logger.child("DocDataSource"))]}}function kPA(){return new PPA}I0();JA();JA();var a91=F.object({label:F.string(),href:F.string()}),t91=F.object({label:F.string(),title:F.string(),detail:F.string()}),qQQ=F.object({eyebrow:F.string(),name:F.string(),sub:F.string()}),CQQ=F.object({tone:F.enum(["capture","synthesis","share"]),title:F.string(),text:F.string()}),jPA=F.object({captures:F.number(),links:F.number(),topics:F.number(),summaries:F.number(),peers:F.number()}),__=F.object({eyebrow:F.string(),headline:F.string(),intro:F.string(),primaryCta:a91,secondaryCta:a91,inputs:F.array(t91).min(1),outputs:F.array(t91).min(1),core:qQQ,legend:F.array(CQQ).min(1)}),xPA=__.extend({counts:jPA}),e91={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."}]},A$1=new NB(__,{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 kQA(A){return A$1.parse(A)}function Q$1(A){return A$1.format(A)}JA();var EQQ=F.object({query:F.object({routeId:F.string().default("home"),sectionId:F.string().default("diagram")}).default({routeId:"home",sectionId:"diagram"})}).passthrough(),LQQ={captures:"base",links:"link",topics:"topic",summaries:"summary",peers:"agent"};class vPA{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=EQQ.parse(A??{}),$=await this.fetchContent(B,w.query.routeId,w.query.sectionId),I=await this.fetchCounts(B);return Q.parse({...$,counts:I})}async fetchContent(A,Q,B){let w=await A.entityService.getEntity({entityType:"site-content",id:`${Q}:${B}`});if(!w?.content)return e91;return __.parse(kQA(w.content))}async fetchCounts(A){let Q=await Promise.all(Object.entries(LQQ).map(async([B,w])=>[B,await this.countOrZero(A,w)]));return jPA.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 B$1=F.object({label:F.string(),href:F.string()}),MQQ=F.object({eyebrow:F.string(),headline:F.string(),intro:F.string(),primaryCta:B$1,secondaryCta:B$1,signals:F.array(F.object({label:F.string(),value:F.string(),note:F.string()}))}),VQQ=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()}))}),OQQ=F.object({title:F.string(),intro:F.string(),cards:F.array(F.object({label:F.string(),title:F.string(),text:F.string()}))}),bQQ=F.object({title:F.string(),intro:F.string(),points:F.array(F.string())}),RQQ={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."]},_QQ="font-body text-[15px] text-theme-muted transition-colors hover:text-theme";function w$1({href:A,label:Q}){return w1("a",{href:A,className:_QQ,children:Q},void 0,!1,void 0,this)}function PQQ({siteInfo:A,children:Q}){let B=[...A.navigation.primary,...A.navigation.secondary],w=A.cta??{buttonText:"Start here",buttonLink:"/about"};return w1(F_,{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(w$1,{...$},`${$.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(w$1,{...$},`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 kQQ=({sections:A,siteInfo:Q})=>w1(PQQ,{siteInfo:Q,children:A},void 0,!1,void 0,this);function jQQ({eyebrow:A,headline:Q,intro:B,primaryCta:w,secondaryCta:$,signals:I}){return w1(TZ,{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(jC,{href:w.href,size:"lg",variant:"primary-strong",children:w.label},void 0,!1,void 0,this),w1(jC,{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:I.map((f)=>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:f.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:f.value},void 0,!1,void 0,this),w1("p",{className:"mt-2 font-body text-body-xs text-theme-muted",children:f.note},void 0,!1,void 0,this)]},f.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 xQQ({eyebrow:A,title:Q,intro:B,steps:w}){return w1(TZ,{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 vQQ({title:A,intro:Q,cards:B}){return w1(TZ,{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 hQQ({title:A,intro:Q,points:B}){return w1(TZ,{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 yQQ=(A)=>{switch(A){case"capture":return"bg-accent";case"synthesis":return"bg-secondary";case"share":return"bg-accent-bright"}},gQQ=(A)=>new Intl.NumberFormat("en",{notation:A>999?"compact":"standard"}).format(A),em=(A,Q,B=`${Q}s`)=>`${gQQ(A)} ${A===1?Q:B}`;function TQQ({eyebrow:A,headline:Q,intro:B,primaryCta:w,secondaryCta:$,inputs:I,outputs:f,core:D,legend:Y,counts:H}){let W=[{key:"captures",className:"top-[-10px] left-1/2 -translate-x-1/2",label:em(H.captures,"capture")},{key:"topics",className:"top-1/2 right-[-28px] -translate-y-1/2",label:em(H.topics,"topic")},{key:"peers",className:"bottom-[-10px] left-1/2 -translate-x-1/2",label:em(H.peers,"peer brain")},{key:"summaries",className:"top-1/2 left-[-28px] -translate-y-1/2",label:em(H.summaries,"summary","summaries")}];return w1(TZ,{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(jC,{href:w.href,size:"lg",variant:"primary-strong",children:w.label},void 0,!1,void 0,this),w1(jC,{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:I.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:[em(H.links,"link")," indexed"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),w1("div",{className:"flex flex-col gap-3.5",children:f.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:Y.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 ${yQQ(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 SQQ=b1({name:"home-diagram",description:"Relay homepage system diagram with live entity counts",schema:xPA,formatter:{parse:(A)=>xPA.parse({...kQA(A),counts:{captures:0,links:0,topics:0,summaries:0,peers:0}}),format:(A)=>Q$1(__.parse(A))},dataSourceId:"relay-site:home-counts",requiredPermission:"public",layout:{component:TQQ}}),mQQ=(A)=>jQQ(MQQ.parse(A)),uQQ=(A)=>xQQ(VQQ.parse(A)),cQQ=(A)=>vQQ(OQQ.parse(A)),pQQ=(A)=>hQQ(bQQ.parse(A)),$$1={type:"object",label:"CTA",fields:{label:{type:"string",label:"Label"},href:{type:"string",label:"Href"}}},I$1={namespace:"relay-site",sections:{"home-hero":{title:"Home hero",description:"Relay homepage hero section",layout:mQQ,fields:{eyebrow:{type:"string",label:"Eyebrow"},headline:{type:"string",label:"Headline"},intro:{type:"string",label:"Intro"},primaryCta:{...$$1,label:"Primary CTA"},secondaryCta:{...$$1,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:uQQ,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:cQQ,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:pQQ,fields:{title:{type:"string",label:"Title"},intro:{type:"string",label:"Intro"},points:{type:"array",label:"Points",minItems:1,items:{type:"string",label:"Point"}}}}}},lQQ=[{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:RQQ}]}],f$1=UPA({packageName:"@brains/relay/site",contentNamespace:"relay-site",themeProfile:"studio",layout:kQQ,routes:lQQ,templates:{"home-diagram":SQQ},dataSources:[new vPA]});var D$1=["prompt","directory-sync","note","link","topics","conversation-memory","agents","assessment","auth-service","cms","dashboard","mcp","webserver","discord","a2a"],Y$1=[...D$1,"image","site-info","site-content","site-builder"],rQQ=[...Y$1,"docs","decks"],dQQ=["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.'],H$1=TF({name:"relay",version:"0.1.0",model:"gpt-5.4-mini",site:f$1,theme:K_,presets:{core:D$1,default:Y$1,full:rQQ},evalDisable:["webserver","mcp","discord"],agentInstructions:dQQ,capabilities:[["prompt",_C,void 0],["note",EC,{}],["link",MC,{}],["image",Vv,void 0],["topics",J2A,{includeEntityTypes:["base","link","summary","agent","skill","swot","deck","doc","anchor-profile","brain-character"],extractableStatuses:["published","draft"]}],["conversation-memory",VPA,{}],["docs",kPA,void 0],["decks",Im,void 0],["agents",d2A,void 0],["assessment",wQA,void 0],["auth-service",Gy,void 0],["cms",bC,{}],["dashboard",hZ,void 0],["directory-sync",Sq,{seedContent:!0,seedContentPath:iQQ(import.meta.dir,"..","seed-content"),initialSync:!0}],["site-content",cm,{definitions:I$1}],["rizom-ecosystem",PC,void 0],["site-info",NC,void 0],["site-builder",zC,{}]],interfaces:[["mcp",EK,()=>({})],["discord",wZ,()=>({captureUrls:!0})],["a2a",ub,()=>({})],["webserver",$Z,()=>({})]],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 K6Q}from"fs";import{join as Z6Q}from"path";import{execSync as z6Q}from"child_process";import{parseArgs as sQQ}from"util";var aQQ={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 JW(A,Q){let B=A[Q];return typeof B==="string"?B:void 0}function uZ(A,Q){let B=A[Q];return typeof B==="boolean"?B:void 0}function X$1(A){let{values:Q,positionals:B}=sQQ({args:A,options:aQQ,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:JW(Q,"model"),domain:JW(Q,"domain"),"content-repo":JW(Q,"content-repo"),backend:JW(Q,"backend"),"push-to":JW(Q,"push-to"),"ai-api-key":JW(Q,"ai-api-key"),"no-interactive":uZ(Q,"no-interactive"),preview:uZ(Q,"preview"),deploy:uZ(Q,"deploy"),regen:uZ(Q,"regen"),all:uZ(Q,"all"),only:JW(Q,"only"),"dry-run":uZ(Q,"dry-run"),"startup-check":uZ(Q,"startup-check"),"storage-dir":JW(Q,"storage-dir"),yes:uZ(Q,"yes"),remote:JW(Q,"remote"),token:JW(Q,"token")}}}Au();import{mkdirSync as f6Q}from"fs";import{join as D6Q}from"path";import{execSync as Y6Q}from"child_process";var xQA={name:"@rizom/brain",version:"0.2.0-alpha.60",description:"Brain runtime + CLI \u2014 scaffold, run, and manage AI brain instances",type:"module",bin:{brain:"./dist/brain.js"},exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.js"},"./cli":"./dist/brain.js","./plugins":{types:"./dist/plugins.d.ts",import:"./dist/plugins.js"},"./entities":{types:"./dist/entities.d.ts",import:"./dist/entities.js"},"./services":{types:"./dist/services.d.ts",import:"./dist/services.js"},"./interfaces":{types:"./dist/interfaces.d.ts",import:"./dist/interfaces.js"},"./templates":{types:"./dist/templates.d.ts",import:"./dist/templates.js"},"./site":{types:"./dist/site.d.ts",import:"./dist/site.js"},"./themes":{types:"./dist/themes.d.ts",import:"./dist/themes.js"},"./deploy":{types:"./dist/deploy.d.ts",import:"./dist/deploy.js"},"./tsconfig.instance.json":"./tsconfig.instance.json"},files:["dist","templates","tsconfig.instance.json"],scripts:{build:"bun scripts/build.ts",prepublishOnly:"bun scripts/build.ts","dev:start":"bun dist/brain.js start",typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts"},dependencies:{"@clack/prompts":"^0.11.0","@modelcontextprotocol/sdk":"^1.24.0","@tailwindcss/postcss":"^4.1.13","@tailwindcss/typography":"^0.5.19",postcss:"^8.5.6",preact:"^10.27.2","preact-render-to-string":"^6.3.1",tailwindcss:"^4.1.11"},optionalDependencies:{"@bitwarden/sdk-napi":"^1.0.0","@libsql/client":"^0.15.7","@tailwindcss/oxide":"^4.1.4","better-sqlite3":"^11.8.1",lightningcss:"^1.29.2","react-devtools-core":"^6.1.1",sharp:"^0.34.5"},devDependencies:{"@brains/app":"workspace:*","@brains/deploy-templates":"workspace:*","@brains/eslint-config":"workspace:*","@brains/mcp-service":"workspace:*","@brains/plugins":"workspace:*","@brains/ranger":"workspace:*","@brains/relay":"workspace:*","@brains/rover":"workspace:*","@brains/site-composition":"workspace:*","@brains/site-default":"workspace:*","@brains/site-personal":"workspace:*","@brains/site-professional":"workspace:*","@brains/theme-default":"workspace:*","@brains/theme-rizom":"workspace:*","@brains/typescript-config":"workspace:*","@brains/utils":"workspace:*","@types/bun":"latest",rollup:"^4.60.2","rollup-plugin-dts":"^6.4.1",typescript:"^5.3.3"},publishConfig:{access:"public"},repository:{type:"git",url:"https://github.com/rizom-ai/brains.git",directory:"packages/brain-cli"},license:"Apache-2.0",author:"Yeehaa <yeehaa@rizom.ai> (https://rizom.ai)",homepage:"https://github.com/rizom-ai/brains/tree/main/packages/brain-cli#readme",bugs:"https://github.com/rizom-ai/brains/issues",engines:{bun:">=1.3.3"},keywords:["brain","ai","cli","mcp","agent","personal-ai","knowledge-management"]};import{mkdirSync as V$1,writeFileSync as Bu,chmodSync as wu,existsSync as cPA,readFileSync as pPA}from"fs";import{basename as lPA,dirname as iPA,join as q8,resolve as CBQ}from"path";import{fileURLToPath as EBQ}from"url";var W$1=`ARG BUN_VERSION=1.3.10
|
|
8037
|
+
`,c91=()=>Y5("style",{children:FQQ},void 0,!1,void 0,this);import{jsxDEV as H2,Fragment as KQQ}from"preact/jsx-dev-runtime";var PQA=({title:A,description:Q,children:B,detail:w=!1,footer:$=!1,contentClassName:I=""})=>H2(KQQ,{children:[H2(YQ,{title:A,description:Q},void 0,!1,void 0,this),H2(c91,{},void 0,!1,void 0,this),H2("div",{className:`docs-handbook${w?" docs-handbook--detail":""}`,children:[H2(m91,{},void 0,!1,void 0,this),H2("div",{className:`${UW.wrap} ${I}`.trim(),children:[B,$&&H2(u91,{},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),p91=({docsCount:A,sectionsCount:Q,startDoc:B})=>H2("section",{className:"border-b border-[var(--docs-text)] py-14 md:py-24 md:pb-[72px]",children:[H2("p",{className:`${UW.label} mb-8`,children:"Handbook \xB7 Brains docs"},void 0,!1,void 0,this),H2("h1",{className:`${UW.display} m-0 max-w-[16ch] text-5xl leading-[1.05] tracking-[-0.02em] md:text-7xl`,children:["Build, run, and publish"," ",H2("em",{className:"text-[var(--docs-accent)]",children:"brains."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),H2("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),H2("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:[H2("div",{children:[H2("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),H2("div",{children:[H2("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),H2("div",{children:[H2("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),H2("div",{className:"mt-9 flex flex-wrap gap-3.5",children:[B&&H2("a",{className:UW.primaryButton,href:O_(B),children:"Start reading"},void 0,!1,void 0,this),H2("a",{className:UW.button,href:"#sections",children:"Browse sections"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),l91=({groups:A})=>H2("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:[H2("p",{className:"m-0 mb-3.5 font-medium text-[var(--docs-text)]",children:"Sections"},void 0,!1,void 0,this),H2("ol",{className:"m-0 list-none p-0",children:A.map((Q,B)=>H2("li",{className:"grid grid-cols-[32px_1fr] gap-2 py-1.5",children:[H2("span",{className:"docs-font-display text-[var(--docs-text-light)] italic",children:[b_(B),"."]},void 0,!0,void 0,this),H2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:`#${_QA(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),i91=({group:A,index:Q})=>H2("article",{className:"mb-16 last:mb-0",id:_QA(Q),children:[H2("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:[H2("span",{className:"text-right docs-font-display text-3xl leading-[1.1] text-[var(--docs-accent)] italic md:text-4xl",children:[b_(Q),"."]},void 0,!0,void 0,this),H2("h2",{className:`${UW.display} m-0 text-3xl leading-[1.1] tracking-[-0.015em] md:text-4xl`,children:A.section},void 0,!1,void 0,this),H2("span",{className:"docs-chapter__leader"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),H2("ol",{className:"m-0 list-none p-0",children:A.docs.map((B)=>H2("li",{className:"border-b border-[var(--docs-border-light)] last:border-b-0",children:H2("a",{className:"group block py-[18px] pl-12 md:pl-[68px]",href:O_(B),children:[H2("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&&H2("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),r91=({title:A})=>H2("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:[H2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/",children:"Home"},void 0,!1,void 0,this),H2("span",{children:"/"},void 0,!1,void 0,this),H2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/docs",children:"Docs"},void 0,!1,void 0,this),H2("span",{children:"/"},void 0,!1,void 0,this),H2("span",{children:A},void 0,!1,void 0,this)]},void 0,!0,void 0,this),d91=({groups:A,activeGroupIndex:Q,activeSlug:B})=>H2("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:H2("nav",{className:"docs-font-label text-xs tracking-[0.06em] text-[var(--docs-text-light)]",children:[H2("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),H2("ol",{className:"m-0 list-none p-0",children:A.map((w,$)=>{let I=$===Q;return H2("li",{className:I?"mb-[22px]":"mb-3.5",children:[H2("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)] ${I?"text-[var(--docs-text)]":"text-[var(--docs-text-muted)]"}`,href:`/docs#${_QA($)}`,children:[H2("span",{className:"docs-font-display text-sm text-[var(--docs-accent)] italic",children:[b_($),"."]},void 0,!0,void 0,this)," ",w.section]},void 0,!0,void 0,this),I&&H2("ol",{className:"mt-0.5 list-none p-0",children:w.docs.map((f)=>{let D=f.metadata.slug===B;return H2("li",{children:H2("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:O_(f),"aria-current":D?"page":void 0,children:f.metadata.title},void 0,!1,void 0,this)},f.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),n91=({prevDoc:A,nextDoc:Q})=>{if(!A&&!Q)return null;return H2("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?H2("a",{className:"group border-t border-[var(--docs-border-light)] pt-[18px] transition-colors duration-150 hover:border-[var(--docs-accent)]",href:O_(A),children:[H2("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),H2("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):H2("span",{},void 0,!1,void 0,this),Q&&H2("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:O_(Q),children:[H2("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),H2("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 R_}from"preact/jsx-dev-runtime";var RPA=({docs:A})=>{let Q=tm(A),B=RQA(Q),$=Q.filter((I)=>I.metadata.slug!=="index")[0]??Q[0];return R_(PQA,{title:"Documentation",description:"Brains documentation",children:[R_(p91,{docsCount:A.length,sectionsCount:B.length,startDoc:$},void 0,!1,void 0,this),R_("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:[R_(l91,{groups:B},void 0,!1,void 0,this),R_("div",{children:B.map((I,f)=>R_(i91,{group:I,index:f},I.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 Sf}from"preact/jsx-dev-runtime";var _PA=({doc:A,docs:Q,prevDoc:B,nextDoc:w})=>{let $=RQA(Q.length>0?Q:[A]),I=tm(Q.length>0?Q:[A]),f=I.findIndex((Y)=>Y.metadata.slug===A.metadata.slug),D=Math.max($.findIndex((Y)=>Y.docs.some((H)=>H.metadata.slug===A.metadata.slug)),0);return Sf(PQA,{title:A.metadata.title,description:A.metadata.description??A.metadata.section,detail:!0,footer:!0,contentClassName:"pt-16",children:[Sf(r91,{title:A.metadata.title},void 0,!1,void 0,this),Sf("div",{className:"grid items-start gap-10 py-8 pb-24 md:grid-cols-[240px_minmax(0,1fr)] md:gap-20",children:[Sf(d91,{groups:$,activeGroupIndex:D,activeSlug:A.metadata.slug},void 0,!1,void 0,this),Sf("article",{className:"min-w-0",children:[Sf("header",{className:"mb-10 border-b border-[var(--docs-border)] pb-8",children:[Sf("p",{className:`${UW.label} m-0 mb-6 flex items-baseline gap-3`,children:[Sf("span",{className:"docs-font-display text-lg leading-none tracking-normal normal-case text-[var(--docs-accent)] italic",children:[b_(D),"."]},void 0,!0,void 0,this)," ",A.metadata.section,f>=0?` \xB7 ${f+1}/${I.length}`:""]},void 0,!0,void 0,this),Sf("h1",{className:`${UW.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&&Sf("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),Sf("div",{className:"docs-article__body",children:Sf(jf,{markdown:A.body},void 0,!1,void 0,this)},void 0,!1,void 0,this),Sf(n91,{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 ZQQ=F.object({docs:F.array(IG),pagination:B$.nullable(),baseUrl:F.string().optional()}),zQQ=F.object({doc:IG,docs:F.array(IG),prevDoc:IG.nullable(),nextDoc:IG.nullable()});function o91(){return{"doc-list":b1({name:"doc-list",description:"Documentation index template",schema:ZQQ,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:RPA}}),"doc-detail":b1({name:"doc-detail",description:"Documentation page template",schema:zQQ,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:_PA}})}}var s91={name:"@brains/doc",private:!0,version:"0.2.0-alpha.61",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 PPA extends FQ{entityType=OQA.entityType;schema=V_;adapter=OQA;constructor(){super("docs",s91,{},void 0)}getTemplates(){return o91()}getDataSources(){return[new bQA(this.logger.child("DocDataSource"))]}}function kPA(){return new PPA}I0();JA();JA();var a91=F.object({label:F.string(),href:F.string()}),t91=F.object({label:F.string(),title:F.string(),detail:F.string()}),qQQ=F.object({eyebrow:F.string(),name:F.string(),sub:F.string()}),CQQ=F.object({tone:F.enum(["capture","synthesis","share"]),title:F.string(),text:F.string()}),jPA=F.object({captures:F.number(),links:F.number(),topics:F.number(),summaries:F.number(),peers:F.number()}),__=F.object({eyebrow:F.string(),headline:F.string(),intro:F.string(),primaryCta:a91,secondaryCta:a91,inputs:F.array(t91).min(1),outputs:F.array(t91).min(1),core:qQQ,legend:F.array(CQQ).min(1)}),xPA=__.extend({counts:jPA}),e91={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."}]},A$1=new NB(__,{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 kQA(A){return A$1.parse(A)}function Q$1(A){return A$1.format(A)}JA();var EQQ=F.object({query:F.object({routeId:F.string().default("home"),sectionId:F.string().default("diagram")}).default({routeId:"home",sectionId:"diagram"})}).passthrough(),LQQ={captures:"base",links:"link",topics:"topic",summaries:"summary",peers:"agent"};class vPA{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=EQQ.parse(A??{}),$=await this.fetchContent(B,w.query.routeId,w.query.sectionId),I=await this.fetchCounts(B);return Q.parse({...$,counts:I})}async fetchContent(A,Q,B){let w=await A.entityService.getEntity({entityType:"site-content",id:`${Q}:${B}`});if(!w?.content)return e91;return __.parse(kQA(w.content))}async fetchCounts(A){let Q=await Promise.all(Object.entries(LQQ).map(async([B,w])=>[B,await this.countOrZero(A,w)]));return jPA.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 B$1=F.object({label:F.string(),href:F.string()}),MQQ=F.object({eyebrow:F.string(),headline:F.string(),intro:F.string(),primaryCta:B$1,secondaryCta:B$1,signals:F.array(F.object({label:F.string(),value:F.string(),note:F.string()}))}),VQQ=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()}))}),OQQ=F.object({title:F.string(),intro:F.string(),cards:F.array(F.object({label:F.string(),title:F.string(),text:F.string()}))}),bQQ=F.object({title:F.string(),intro:F.string(),points:F.array(F.string())}),RQQ={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."]},_QQ="font-body text-[15px] text-theme-muted transition-colors hover:text-theme";function w$1({href:A,label:Q}){return w1("a",{href:A,className:_QQ,children:Q},void 0,!1,void 0,this)}function PQQ({siteInfo:A,children:Q}){let B=[...A.navigation.primary,...A.navigation.secondary],w=A.cta??{buttonText:"Start here",buttonLink:"/about"};return w1(F_,{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(w$1,{...$},`${$.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(w$1,{...$},`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 kQQ=({sections:A,siteInfo:Q})=>w1(PQQ,{siteInfo:Q,children:A},void 0,!1,void 0,this);function jQQ({eyebrow:A,headline:Q,intro:B,primaryCta:w,secondaryCta:$,signals:I}){return w1(TZ,{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(jC,{href:w.href,size:"lg",variant:"primary-strong",children:w.label},void 0,!1,void 0,this),w1(jC,{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:I.map((f)=>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:f.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:f.value},void 0,!1,void 0,this),w1("p",{className:"mt-2 font-body text-body-xs text-theme-muted",children:f.note},void 0,!1,void 0,this)]},f.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 xQQ({eyebrow:A,title:Q,intro:B,steps:w}){return w1(TZ,{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 vQQ({title:A,intro:Q,cards:B}){return w1(TZ,{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 hQQ({title:A,intro:Q,points:B}){return w1(TZ,{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 yQQ=(A)=>{switch(A){case"capture":return"bg-accent";case"synthesis":return"bg-secondary";case"share":return"bg-accent-bright"}},gQQ=(A)=>new Intl.NumberFormat("en",{notation:A>999?"compact":"standard"}).format(A),em=(A,Q,B=`${Q}s`)=>`${gQQ(A)} ${A===1?Q:B}`;function TQQ({eyebrow:A,headline:Q,intro:B,primaryCta:w,secondaryCta:$,inputs:I,outputs:f,core:D,legend:Y,counts:H}){let W=[{key:"captures",className:"top-[-10px] left-1/2 -translate-x-1/2",label:em(H.captures,"capture")},{key:"topics",className:"top-1/2 right-[-28px] -translate-y-1/2",label:em(H.topics,"topic")},{key:"peers",className:"bottom-[-10px] left-1/2 -translate-x-1/2",label:em(H.peers,"peer brain")},{key:"summaries",className:"top-1/2 left-[-28px] -translate-y-1/2",label:em(H.summaries,"summary","summaries")}];return w1(TZ,{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(jC,{href:w.href,size:"lg",variant:"primary-strong",children:w.label},void 0,!1,void 0,this),w1(jC,{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:I.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:[em(H.links,"link")," indexed"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),w1("div",{className:"flex flex-col gap-3.5",children:f.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:Y.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 ${yQQ(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 SQQ=b1({name:"home-diagram",description:"Relay homepage system diagram with live entity counts",schema:xPA,formatter:{parse:(A)=>xPA.parse({...kQA(A),counts:{captures:0,links:0,topics:0,summaries:0,peers:0}}),format:(A)=>Q$1(__.parse(A))},dataSourceId:"relay-site:home-counts",requiredPermission:"public",layout:{component:TQQ}}),mQQ=(A)=>jQQ(MQQ.parse(A)),uQQ=(A)=>xQQ(VQQ.parse(A)),cQQ=(A)=>vQQ(OQQ.parse(A)),pQQ=(A)=>hQQ(bQQ.parse(A)),$$1={type:"object",label:"CTA",fields:{label:{type:"string",label:"Label"},href:{type:"string",label:"Href"}}},I$1={namespace:"relay-site",sections:{"home-hero":{title:"Home hero",description:"Relay homepage hero section",layout:mQQ,fields:{eyebrow:{type:"string",label:"Eyebrow"},headline:{type:"string",label:"Headline"},intro:{type:"string",label:"Intro"},primaryCta:{...$$1,label:"Primary CTA"},secondaryCta:{...$$1,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:uQQ,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:cQQ,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:pQQ,fields:{title:{type:"string",label:"Title"},intro:{type:"string",label:"Intro"},points:{type:"array",label:"Points",minItems:1,items:{type:"string",label:"Point"}}}}}},lQQ=[{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:RQQ}]}],f$1=UPA({packageName:"@brains/relay/site",contentNamespace:"relay-site",themeProfile:"studio",layout:kQQ,routes:lQQ,templates:{"home-diagram":SQQ},dataSources:[new vPA]});var D$1=["prompt","directory-sync","note","link","topics","conversation-memory","agents","assessment","auth-service","cms","dashboard","mcp","webserver","discord","a2a"],Y$1=[...D$1,"image","site-info","site-content","site-builder"],rQQ=[...Y$1,"docs","decks"],dQQ=["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.'],H$1=TF({name:"relay",version:"0.1.0",model:"gpt-5.4-mini",site:f$1,theme:K_,presets:{core:D$1,default:Y$1,full:rQQ},evalDisable:["webserver","mcp","discord"],agentInstructions:dQQ,capabilities:[["prompt",_C,void 0],["note",EC,{}],["link",MC,{}],["image",Vv,void 0],["topics",J2A,{includeEntityTypes:["base","link","summary","agent","skill","swot","deck","doc","anchor-profile","brain-character"],extractableStatuses:["published","draft"]}],["conversation-memory",VPA,{}],["docs",kPA,void 0],["decks",Im,void 0],["agents",d2A,void 0],["assessment",wQA,void 0],["auth-service",Gy,void 0],["cms",bC,{}],["dashboard",hZ,void 0],["directory-sync",Sq,{seedContent:!0,seedContentPath:iQQ(import.meta.dir,"..","seed-content"),initialSync:!0}],["site-content",cm,{definitions:I$1}],["rizom-ecosystem",PC,void 0],["site-info",NC,void 0],["site-builder",zC,{}]],interfaces:[["mcp",EK,()=>({})],["discord",wZ,()=>({captureUrls:!0})],["a2a",ub,()=>({})],["webserver",$Z,()=>({})]],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 K6Q}from"fs";import{join as Z6Q}from"path";import{execSync as z6Q}from"child_process";import{parseArgs as sQQ}from"util";var aQQ={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 JW(A,Q){let B=A[Q];return typeof B==="string"?B:void 0}function uZ(A,Q){let B=A[Q];return typeof B==="boolean"?B:void 0}function X$1(A){let{values:Q,positionals:B}=sQQ({args:A,options:aQQ,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:JW(Q,"model"),domain:JW(Q,"domain"),"content-repo":JW(Q,"content-repo"),backend:JW(Q,"backend"),"push-to":JW(Q,"push-to"),"ai-api-key":JW(Q,"ai-api-key"),"no-interactive":uZ(Q,"no-interactive"),preview:uZ(Q,"preview"),deploy:uZ(Q,"deploy"),regen:uZ(Q,"regen"),all:uZ(Q,"all"),only:JW(Q,"only"),"dry-run":uZ(Q,"dry-run"),"startup-check":uZ(Q,"startup-check"),"storage-dir":JW(Q,"storage-dir"),yes:uZ(Q,"yes"),remote:JW(Q,"remote"),token:JW(Q,"token")}}}Au();import{mkdirSync as f6Q}from"fs";import{join as D6Q}from"path";import{execSync as Y6Q}from"child_process";var xQA={name:"@rizom/brain",version:"0.2.0-alpha.61",description:"Brain runtime + CLI \u2014 scaffold, run, and manage AI brain instances",type:"module",bin:{brain:"./dist/brain.js"},exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.js"},"./cli":"./dist/brain.js","./plugins":{types:"./dist/plugins.d.ts",import:"./dist/plugins.js"},"./entities":{types:"./dist/entities.d.ts",import:"./dist/entities.js"},"./services":{types:"./dist/services.d.ts",import:"./dist/services.js"},"./interfaces":{types:"./dist/interfaces.d.ts",import:"./dist/interfaces.js"},"./templates":{types:"./dist/templates.d.ts",import:"./dist/templates.js"},"./site":{types:"./dist/site.d.ts",import:"./dist/site.js"},"./themes":{types:"./dist/themes.d.ts",import:"./dist/themes.js"},"./deploy":{types:"./dist/deploy.d.ts",import:"./dist/deploy.js"},"./tsconfig.instance.json":"./tsconfig.instance.json"},files:["dist","templates","tsconfig.instance.json"],scripts:{build:"bun scripts/build.ts",prepublishOnly:"bun scripts/build.ts","dev:start":"bun dist/brain.js start",typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts"},dependencies:{"@clack/prompts":"^0.11.0","@modelcontextprotocol/sdk":"^1.24.0","@tailwindcss/postcss":"^4.1.13","@tailwindcss/typography":"^0.5.19",postcss:"^8.5.6",preact:"^10.27.2","preact-render-to-string":"^6.3.1",tailwindcss:"^4.1.11"},optionalDependencies:{"@bitwarden/sdk-napi":"^1.0.0","@libsql/client":"^0.15.7","@tailwindcss/oxide":"^4.1.4","better-sqlite3":"^11.8.1",lightningcss:"^1.29.2","react-devtools-core":"^6.1.1",sharp:"^0.34.5"},devDependencies:{"@brains/app":"workspace:*","@brains/deploy-templates":"workspace:*","@brains/eslint-config":"workspace:*","@brains/mcp-service":"workspace:*","@brains/plugins":"workspace:*","@brains/ranger":"workspace:*","@brains/relay":"workspace:*","@brains/rover":"workspace:*","@brains/site-composition":"workspace:*","@brains/site-default":"workspace:*","@brains/site-personal":"workspace:*","@brains/site-professional":"workspace:*","@brains/theme-default":"workspace:*","@brains/theme-rizom":"workspace:*","@brains/typescript-config":"workspace:*","@brains/utils":"workspace:*","@types/bun":"latest",rollup:"^4.60.2","rollup-plugin-dts":"^6.4.1",typescript:"^5.3.3"},publishConfig:{access:"public"},repository:{type:"git",url:"https://github.com/rizom-ai/brains.git",directory:"packages/brain-cli"},license:"Apache-2.0",author:"Yeehaa <yeehaa@rizom.ai> (https://rizom.ai)",homepage:"https://github.com/rizom-ai/brains/tree/main/packages/brain-cli#readme",bugs:"https://github.com/rizom-ai/brains/issues",engines:{bun:">=1.3.3"},keywords:["brain","ai","cli","mcp","agent","personal-ai","knowledge-management"]};import{mkdirSync as V$1,writeFileSync as Bu,chmodSync as wu,existsSync as cPA,readFileSync as pPA}from"fs";import{basename as lPA,dirname as iPA,join as q8,resolve as CBQ}from"path";import{fileURLToPath as EBQ}from"url";var W$1=`ARG BUN_VERSION=1.3.10
|
|
8038
8038
|
FROM oven/bun:\${BUN_VERSION}-slim AS runtime
|
|
8039
8039
|
|
|
8040
8040
|
WORKDIR /app
|
|
@@ -8234,7 +8234,7 @@ jobs:
|
|
|
8234
8234
|
github.event.workflow_run.conclusion == 'success'
|
|
8235
8235
|
runs-on: ubuntu-latest
|
|
8236
8236
|
steps:
|
|
8237
|
-
- uses: actions/checkout@
|
|
8237
|
+
- uses: actions/checkout@v5
|
|
8238
8238
|
with:
|
|
8239
8239
|
ref: \${{ github.event.workflow_run.head_sha || github.sha }}
|
|
8240
8240
|
|