@rizom/brain 0.2.0-alpha.119 → 0.2.0-alpha.120
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 +34 -34
- 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
|
@@ -518,7 +518,7 @@ Some entity actions are gated by policy beyond simple tool availability. Two cas
|
|
|
518
518
|
hash text NOT NULL,
|
|
519
519
|
created_at numeric
|
|
520
520
|
)
|
|
521
|
-
`;await A.session.run($);let I=(await A.values(hA`SELECT id, hash, created_at FROM ${hA.identifier(w)} ORDER BY created_at DESC LIMIT 1`))[0]??void 0,D=[];for(let U of B)if(!I||Number(I[2])<U.folderMillis){for(let Y of U.sql)D.push(A.run(hA.raw(Y)));D.push(A.run(hA`INSERT INTO ${hA.identifier(w)} ("hash", "created_at") VALUES(${U.hash}, ${U.folderMillis})`))}await A.session.migrate(D)}var bt=i(()=>{hX0();H$()});async function mX0(A,Q){let B=Q?.child("entity-migrate")??NQ.getInstance().child("entity-migrate"),{db:w,client:$,url:f}=oo(A);B.debug("Running entity database migrations...");try{await so($,f);let D=import.meta.url.includes("/dist/")?new URL("./migrations/entity-service",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await mb(w,{migrationsFolder:D}),await ao($),B.debug("Entity database migrations completed successfully")}catch(I){throw B.error("Entity database migration failed:",I),I}finally{$.close()}}var uX0=i(()=>{bt();SUA();WA()});async function cX0(A,Q){let B=Q?.child("job-queue-migrate")??NQ.getInstance().child("job-queue-migrate"),{db:w,client:$,url:f}=io(A);B.debug("Running job queue migrations...");try{await ro($,f);let D=import.meta.url.includes("/dist/")?new URL("./migrations/job-queue",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await mb(w,{migrationsFolder:D}),B.debug("Job queue migrations completed successfully")}catch(I){throw B.error("Job queue migration failed:",I),I}finally{$.close()}}var lX0=i(()=>{bt();RUA();WA()});async function pX0(A,Q){let B=Q?.child("conversation-migrate")??NQ.getInstance().child("conversation-migrate"),{db:w,client:$,url:f}=Ds(A);B.debug("Running conversation database migrations...");try{if(f.startsWith("file:"))await $.execute("PRAGMA journal_mode = WAL");let D=import.meta.url.includes("/dist/")?new URL("./migrations/conversation-service",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await mb(w,{migrationsFolder:D}),B.debug("Conversation database migrations completed successfully")}catch(I){throw B.error("Conversation database migration failed:",I),I}finally{$.close()}}var iX0=i(()=>{bt();ZYA();WA()});class Kg{logger;migrations;constructor(A,Q){this.logger=A,this.migrations=Q??{getStandardConfigWithDirectories:hx,migrateEntities:mX0,migrateJobQueue:cX0,migrateConversations:pX0}}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 wNA=i(()=>{Ot();uX0();lX0();iX0()});function J52(){return process.env[Y52]}function rX0(){return J52()!=="production"}var Y52="NODE_ENV";var Pt;var $NA=i(()=>{WA();Pt=H.object({theme:H.object({primaryColor:H.string().describe("Primary color for the CLI theme").default("#0066cc"),accentColor:H.string().describe("Accent color for the CLI theme").default("#ff6600")}).describe("Theme configuration for the CLI interface").default({primaryColor:"#0066cc",accentColor:"#ff6600"})})});var nX0;var dX0=i(()=>{nX0={name:"@brains/chat-repl",private:!0,version:"0.2.0-alpha.119",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.2.6"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14","@types/react":"^19.0.3",typescript:"^5.3.3"}}});var wB=h((W52,kt)=>{(function(){function A(IA,mA){Object.defineProperty(w.prototype,IA,{get:function(){console.warn("%s(...) is deprecated in plain JavaScript React classes. %s",mA[0],mA[1])}})}function Q(IA){if(IA===null||typeof IA!=="object")return null;return IA=TA&&IA[TA]||IA["@@iterator"],typeof IA==="function"?IA:null}function B(IA,mA){IA=(IA=IA.constructor)&&(IA.displayName||IA.name)||"ReactClass";var jA=IA+"."+mA;GA[jA]||(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.",mA,IA),GA[jA]=!0)}function w(IA,mA,jA){this.props=IA,this.context=mA,this.refs=cA,this.updater=jA||qA}function $(){}function f(IA,mA,jA){this.props=IA,this.context=mA,this.refs=cA,this.updater=jA||qA}function I(){}function D(IA){return""+IA}function U(IA){try{D(IA);var mA=!1}catch(K0){mA=!0}if(mA){mA=console;var jA=mA.error,iA=typeof Symbol==="function"&&Symbol.toStringTag&&IA[Symbol.toStringTag]||IA.constructor.name||"Object";return jA.call(mA,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",iA),D(IA)}}function Y(IA){if(IA==null)return null;if(typeof IA==="function")return IA.$$typeof===I0?null:IA.displayName||IA.name||null;if(typeof IA==="string")return IA;switch(IA){case e:return"Fragment";case XA:return"Profiler";case s:return"StrictMode";case w0:return"Suspense";case fA:return"SuspenseList";case KA:return"Activity"}if(typeof IA==="object")switch(typeof IA.tag==="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),IA.$$typeof){case l:return"Portal";case wA:return IA.displayName||"Context";case NA:return(IA._context.displayName||"Context")+".Consumer";case lA:var mA=IA.render;return IA=IA.displayName,IA||(IA=mA.displayName||mA.name||"",IA=IA!==""?"ForwardRef("+IA+")":"ForwardRef"),IA;case OA:return mA=IA.displayName||null,mA!==null?mA:Y(IA.type)||"Memo";case kA:mA=IA._payload,IA=IA._init;try{return Y(IA(mA))}catch(jA){}}return null}function J(IA){if(IA===e)return"<>";if(typeof IA==="object"&&IA!==null&&IA.$$typeof===kA)return"<...>";try{var mA=Y(IA);return mA?"<"+mA+">":"<...>"}catch(jA){return"<...>"}}function X(){var IA=Q0.A;return IA===null?null:IA.getOwner()}function G(){return Error("react-stack-top-frame")}function Z(IA){if(bA.call(IA,"key")){var mA=Object.getOwnPropertyDescriptor(IA,"key").get;if(mA&&mA.isReactWarning)return!1}return IA.key!==void 0}function N(IA,mA){function jA(){DA||(DA=!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)",mA))}jA.isReactWarning=!0,Object.defineProperty(IA,"key",{get:jA,configurable:!0})}function L(){var IA=Y(this.type);return e0[IA]||(e0[IA]=!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.")),IA=this.props.ref,IA!==void 0?IA:null}function V(IA,mA,jA,iA,K0,C0){var B0=jA.ref;return IA={$$typeof:c,type:IA,key:mA,props:jA,_owner:iA},(B0!==void 0?B0:null)!==null?Object.defineProperty(IA,"ref",{enumerable:!1,get:L}):Object.defineProperty(IA,"ref",{enumerable:!1,value:null}),IA._store={},Object.defineProperty(IA._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(IA,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(IA,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:K0}),Object.defineProperty(IA,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:C0}),Object.freeze&&(Object.freeze(IA.props),Object.freeze(IA)),IA}function M(IA,mA){return mA=V(IA.type,mA,IA.props,IA._owner,IA._debugStack,IA._debugTask),IA._store&&(mA._store.validated=IA._store.validated),mA}function O(IA){E(IA)?IA._store&&(IA._store.validated=1):typeof IA==="object"&&IA!==null&&IA.$$typeof===kA&&(IA._payload.status==="fulfilled"?E(IA._payload.value)&&IA._payload.value._store&&(IA._payload.value._store.validated=1):IA._store&&(IA._store.validated=1))}function E(IA){return typeof IA==="object"&&IA!==null&&IA.$$typeof===c}function S(IA){var mA={"=":"=0",":":"=2"};return"$"+IA.replace(/[=:]/g,function(jA){return mA[jA]})}function y(IA,mA){return typeof IA==="object"&&IA!==null&&IA.key!=null?(U(IA.key),S(""+IA.key)):mA.toString(36)}function T(IA){switch(IA.status){case"fulfilled":return IA.value;case"rejected":throw IA.reason;default:switch(typeof IA.status==="string"?IA.then(I,I):(IA.status="pending",IA.then(function(mA){IA.status==="pending"&&(IA.status="fulfilled",IA.value=mA)},function(mA){IA.status==="pending"&&(IA.status="rejected",IA.reason=mA)})),IA.status){case"fulfilled":return IA.value;case"rejected":throw IA.reason}}throw IA}function _(IA,mA,jA,iA,K0){var C0=typeof IA;if(C0==="undefined"||C0==="boolean")IA=null;var B0=!1;if(IA===null)B0=!0;else switch(C0){case"bigint":case"string":case"number":B0=!0;break;case"object":switch(IA.$$typeof){case c:case l:B0=!0;break;case kA:return B0=IA._init,_(B0(IA._payload),mA,jA,iA,K0)}}if(B0){B0=IA,K0=K0(B0);var a0=iA===""?"."+y(B0,0):iA;return Z0(K0)?(jA="",a0!=null&&(jA=a0.replace(yA,"$&/")+"/"),_(K0,mA,jA,"",function(m1){return m1})):K0!=null&&(E(K0)&&(K0.key!=null&&(B0&&B0.key===K0.key||U(K0.key)),jA=M(K0,jA+(K0.key==null||B0&&B0.key===K0.key?"":(""+K0.key).replace(yA,"$&/")+"/")+a0),iA!==""&&B0!=null&&E(B0)&&B0.key==null&&B0._store&&!B0._store.validated&&(jA._store.validated=2),K0=jA),mA.push(K0)),1}if(B0=0,a0=iA===""?".":iA+":",Z0(IA))for(var g0=0;g0<IA.length;g0++)iA=IA[g0],C0=a0+y(iA,g0),B0+=_(iA,mA,jA,C0,K0);else if(g0=Q(IA),typeof g0==="function")for(g0===IA.entries&&(dA||console.warn("Using Maps as children is not supported. Use an array of keyed ReactElements instead."),dA=!0),IA=g0.call(IA),g0=0;!(iA=IA.next()).done;)iA=iA.value,C0=a0+y(iA,g0++),B0+=_(iA,mA,jA,C0,K0);else if(C0==="object"){if(typeof IA.then==="function")return _(T(IA),mA,jA,iA,K0);throw mA=String(IA),Error("Objects are not valid as a React child (found: "+(mA==="[object Object]"?"object with keys {"+Object.keys(IA).join(", ")+"}":mA)+"). If you meant to render a collection of children, use an array instead.")}return B0}function x(IA,mA,jA){if(IA==null)return IA;var iA=[],K0=0;return _(IA,iA,"","",function(C0){return mA.call(jA,C0,K0++)}),iA}function g(IA){if(IA._status===-1){var mA=IA._ioInfo;mA!=null&&(mA.start=mA.end=performance.now()),mA=IA._result;var jA=mA();if(jA.then(function(K0){if(IA._status===0||IA._status===-1){IA._status=1,IA._result=K0;var C0=IA._ioInfo;C0!=null&&(C0.end=performance.now()),jA.status===void 0&&(jA.status="fulfilled",jA.value=K0)}},function(K0){if(IA._status===0||IA._status===-1){IA._status=2,IA._result=K0;var C0=IA._ioInfo;C0!=null&&(C0.end=performance.now()),jA.status===void 0&&(jA.status="rejected",jA.reason=K0)}}),mA=IA._ioInfo,mA!=null){mA.value=jA;var iA=jA.displayName;typeof iA==="string"&&(mA.name=iA)}IA._status===-1&&(IA._status=0,IA._result=jA)}if(IA._status===1)return mA=IA._result,mA===void 0&&console.error(`lazy: Expected the result of a dynamic import() call. Instead received: %s
|
|
521
|
+
`;await A.session.run($);let I=(await A.values(hA`SELECT id, hash, created_at FROM ${hA.identifier(w)} ORDER BY created_at DESC LIMIT 1`))[0]??void 0,D=[];for(let U of B)if(!I||Number(I[2])<U.folderMillis){for(let Y of U.sql)D.push(A.run(hA.raw(Y)));D.push(A.run(hA`INSERT INTO ${hA.identifier(w)} ("hash", "created_at") VALUES(${U.hash}, ${U.folderMillis})`))}await A.session.migrate(D)}var bt=i(()=>{hX0();H$()});async function mX0(A,Q){let B=Q?.child("entity-migrate")??NQ.getInstance().child("entity-migrate"),{db:w,client:$,url:f}=oo(A);B.debug("Running entity database migrations...");try{await so($,f);let D=import.meta.url.includes("/dist/")?new URL("./migrations/entity-service",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await mb(w,{migrationsFolder:D}),await ao($),B.debug("Entity database migrations completed successfully")}catch(I){throw B.error("Entity database migration failed:",I),I}finally{$.close()}}var uX0=i(()=>{bt();SUA();WA()});async function cX0(A,Q){let B=Q?.child("job-queue-migrate")??NQ.getInstance().child("job-queue-migrate"),{db:w,client:$,url:f}=io(A);B.debug("Running job queue migrations...");try{await ro($,f);let D=import.meta.url.includes("/dist/")?new URL("./migrations/job-queue",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await mb(w,{migrationsFolder:D}),B.debug("Job queue migrations completed successfully")}catch(I){throw B.error("Job queue migration failed:",I),I}finally{$.close()}}var lX0=i(()=>{bt();RUA();WA()});async function pX0(A,Q){let B=Q?.child("conversation-migrate")??NQ.getInstance().child("conversation-migrate"),{db:w,client:$,url:f}=Ds(A);B.debug("Running conversation database migrations...");try{if(f.startsWith("file:"))await $.execute("PRAGMA journal_mode = WAL");let D=import.meta.url.includes("/dist/")?new URL("./migrations/conversation-service",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await mb(w,{migrationsFolder:D}),B.debug("Conversation database migrations completed successfully")}catch(I){throw B.error("Conversation database migration failed:",I),I}finally{$.close()}}var iX0=i(()=>{bt();ZYA();WA()});class Kg{logger;migrations;constructor(A,Q){this.logger=A,this.migrations=Q??{getStandardConfigWithDirectories:hx,migrateEntities:mX0,migrateJobQueue:cX0,migrateConversations:pX0}}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 wNA=i(()=>{Ot();uX0();lX0();iX0()});function J52(){return process.env[Y52]}function rX0(){return J52()!=="production"}var Y52="NODE_ENV";var Pt;var $NA=i(()=>{WA();Pt=H.object({theme:H.object({primaryColor:H.string().describe("Primary color for the CLI theme").default("#0066cc"),accentColor:H.string().describe("Accent color for the CLI theme").default("#ff6600")}).describe("Theme configuration for the CLI interface").default({primaryColor:"#0066cc",accentColor:"#ff6600"})})});var nX0;var dX0=i(()=>{nX0={name:"@brains/chat-repl",private:!0,version:"0.2.0-alpha.120",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.2.6"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14","@types/react":"^19.0.3",typescript:"^5.3.3"}}});var wB=h((W52,kt)=>{(function(){function A(IA,mA){Object.defineProperty(w.prototype,IA,{get:function(){console.warn("%s(...) is deprecated in plain JavaScript React classes. %s",mA[0],mA[1])}})}function Q(IA){if(IA===null||typeof IA!=="object")return null;return IA=TA&&IA[TA]||IA["@@iterator"],typeof IA==="function"?IA:null}function B(IA,mA){IA=(IA=IA.constructor)&&(IA.displayName||IA.name)||"ReactClass";var jA=IA+"."+mA;GA[jA]||(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.",mA,IA),GA[jA]=!0)}function w(IA,mA,jA){this.props=IA,this.context=mA,this.refs=cA,this.updater=jA||qA}function $(){}function f(IA,mA,jA){this.props=IA,this.context=mA,this.refs=cA,this.updater=jA||qA}function I(){}function D(IA){return""+IA}function U(IA){try{D(IA);var mA=!1}catch(K0){mA=!0}if(mA){mA=console;var jA=mA.error,iA=typeof Symbol==="function"&&Symbol.toStringTag&&IA[Symbol.toStringTag]||IA.constructor.name||"Object";return jA.call(mA,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",iA),D(IA)}}function Y(IA){if(IA==null)return null;if(typeof IA==="function")return IA.$$typeof===I0?null:IA.displayName||IA.name||null;if(typeof IA==="string")return IA;switch(IA){case e:return"Fragment";case XA:return"Profiler";case s:return"StrictMode";case w0:return"Suspense";case fA:return"SuspenseList";case KA:return"Activity"}if(typeof IA==="object")switch(typeof IA.tag==="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),IA.$$typeof){case l:return"Portal";case wA:return IA.displayName||"Context";case NA:return(IA._context.displayName||"Context")+".Consumer";case lA:var mA=IA.render;return IA=IA.displayName,IA||(IA=mA.displayName||mA.name||"",IA=IA!==""?"ForwardRef("+IA+")":"ForwardRef"),IA;case OA:return mA=IA.displayName||null,mA!==null?mA:Y(IA.type)||"Memo";case kA:mA=IA._payload,IA=IA._init;try{return Y(IA(mA))}catch(jA){}}return null}function J(IA){if(IA===e)return"<>";if(typeof IA==="object"&&IA!==null&&IA.$$typeof===kA)return"<...>";try{var mA=Y(IA);return mA?"<"+mA+">":"<...>"}catch(jA){return"<...>"}}function X(){var IA=Q0.A;return IA===null?null:IA.getOwner()}function G(){return Error("react-stack-top-frame")}function Z(IA){if(bA.call(IA,"key")){var mA=Object.getOwnPropertyDescriptor(IA,"key").get;if(mA&&mA.isReactWarning)return!1}return IA.key!==void 0}function N(IA,mA){function jA(){DA||(DA=!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)",mA))}jA.isReactWarning=!0,Object.defineProperty(IA,"key",{get:jA,configurable:!0})}function L(){var IA=Y(this.type);return e0[IA]||(e0[IA]=!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.")),IA=this.props.ref,IA!==void 0?IA:null}function V(IA,mA,jA,iA,K0,C0){var B0=jA.ref;return IA={$$typeof:c,type:IA,key:mA,props:jA,_owner:iA},(B0!==void 0?B0:null)!==null?Object.defineProperty(IA,"ref",{enumerable:!1,get:L}):Object.defineProperty(IA,"ref",{enumerable:!1,value:null}),IA._store={},Object.defineProperty(IA._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(IA,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(IA,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:K0}),Object.defineProperty(IA,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:C0}),Object.freeze&&(Object.freeze(IA.props),Object.freeze(IA)),IA}function M(IA,mA){return mA=V(IA.type,mA,IA.props,IA._owner,IA._debugStack,IA._debugTask),IA._store&&(mA._store.validated=IA._store.validated),mA}function O(IA){E(IA)?IA._store&&(IA._store.validated=1):typeof IA==="object"&&IA!==null&&IA.$$typeof===kA&&(IA._payload.status==="fulfilled"?E(IA._payload.value)&&IA._payload.value._store&&(IA._payload.value._store.validated=1):IA._store&&(IA._store.validated=1))}function E(IA){return typeof IA==="object"&&IA!==null&&IA.$$typeof===c}function S(IA){var mA={"=":"=0",":":"=2"};return"$"+IA.replace(/[=:]/g,function(jA){return mA[jA]})}function y(IA,mA){return typeof IA==="object"&&IA!==null&&IA.key!=null?(U(IA.key),S(""+IA.key)):mA.toString(36)}function T(IA){switch(IA.status){case"fulfilled":return IA.value;case"rejected":throw IA.reason;default:switch(typeof IA.status==="string"?IA.then(I,I):(IA.status="pending",IA.then(function(mA){IA.status==="pending"&&(IA.status="fulfilled",IA.value=mA)},function(mA){IA.status==="pending"&&(IA.status="rejected",IA.reason=mA)})),IA.status){case"fulfilled":return IA.value;case"rejected":throw IA.reason}}throw IA}function _(IA,mA,jA,iA,K0){var C0=typeof IA;if(C0==="undefined"||C0==="boolean")IA=null;var B0=!1;if(IA===null)B0=!0;else switch(C0){case"bigint":case"string":case"number":B0=!0;break;case"object":switch(IA.$$typeof){case c:case l:B0=!0;break;case kA:return B0=IA._init,_(B0(IA._payload),mA,jA,iA,K0)}}if(B0){B0=IA,K0=K0(B0);var a0=iA===""?"."+y(B0,0):iA;return Z0(K0)?(jA="",a0!=null&&(jA=a0.replace(yA,"$&/")+"/"),_(K0,mA,jA,"",function(m1){return m1})):K0!=null&&(E(K0)&&(K0.key!=null&&(B0&&B0.key===K0.key||U(K0.key)),jA=M(K0,jA+(K0.key==null||B0&&B0.key===K0.key?"":(""+K0.key).replace(yA,"$&/")+"/")+a0),iA!==""&&B0!=null&&E(B0)&&B0.key==null&&B0._store&&!B0._store.validated&&(jA._store.validated=2),K0=jA),mA.push(K0)),1}if(B0=0,a0=iA===""?".":iA+":",Z0(IA))for(var g0=0;g0<IA.length;g0++)iA=IA[g0],C0=a0+y(iA,g0),B0+=_(iA,mA,jA,C0,K0);else if(g0=Q(IA),typeof g0==="function")for(g0===IA.entries&&(dA||console.warn("Using Maps as children is not supported. Use an array of keyed ReactElements instead."),dA=!0),IA=g0.call(IA),g0=0;!(iA=IA.next()).done;)iA=iA.value,C0=a0+y(iA,g0++),B0+=_(iA,mA,jA,C0,K0);else if(C0==="object"){if(typeof IA.then==="function")return _(T(IA),mA,jA,iA,K0);throw mA=String(IA),Error("Objects are not valid as a React child (found: "+(mA==="[object Object]"?"object with keys {"+Object.keys(IA).join(", ")+"}":mA)+"). If you meant to render a collection of children, use an array instead.")}return B0}function x(IA,mA,jA){if(IA==null)return IA;var iA=[],K0=0;return _(IA,iA,"","",function(C0){return mA.call(jA,C0,K0++)}),iA}function g(IA){if(IA._status===-1){var mA=IA._ioInfo;mA!=null&&(mA.start=mA.end=performance.now()),mA=IA._result;var jA=mA();if(jA.then(function(K0){if(IA._status===0||IA._status===-1){IA._status=1,IA._result=K0;var C0=IA._ioInfo;C0!=null&&(C0.end=performance.now()),jA.status===void 0&&(jA.status="fulfilled",jA.value=K0)}},function(K0){if(IA._status===0||IA._status===-1){IA._status=2,IA._result=K0;var C0=IA._ioInfo;C0!=null&&(C0.end=performance.now()),jA.status===void 0&&(jA.status="rejected",jA.reason=K0)}}),mA=IA._ioInfo,mA!=null){mA.value=jA;var iA=jA.displayName;typeof iA==="string"&&(mA.name=iA)}IA._status===-1&&(IA._status=0,IA._result=jA)}if(IA._status===1)return mA=IA._result,mA===void 0&&console.error(`lazy: Expected the result of a dynamic import() call. Instead received: %s
|
|
522
522
|
|
|
523
523
|
Your code should look like:
|
|
524
524
|
const MyComponent = lazy(() => import('./MyComponent'))
|
|
@@ -1814,7 +1814,7 @@ Example bad output: "A dreamlike crystal formation glowing with ethereal light i
|
|
|
1814
1814
|
Title: "${A.entityTitle??D}"
|
|
1815
1815
|
|
|
1816
1816
|
Content:
|
|
1817
|
-
${Y}`,lI2);U=`${w.trim()} ${O.imagePrompt}`}catch(O){this.logger.warn("AI prompt distillation failed, using fallback",{error:T0(O)})}}await this.reportProgress(B,{progress:zQ.PROCESS,message:"Generating image"});let J=this.context.identity.get(),X=this.context.identity.getProfile(),Z=NZ0(J,X)+U,N;try{N=await this.context.ai.generateImage(Z,{...$&&{aspectRatio:$}})}catch(O){return this.logger.error("Image generation failed",{jobId:Q,error:T0(O)}),$5.failure(O)}await this.reportProgress(B,{progress:zQ.GENERATE,message:"Creating image entity"});let L=X1(D),V=HU.createImageEntity({dataUrl:N.dataUrl,title:D});if(await this.context.entityService.getEntity({entityType:"image",id:L}))this.logger.debug("Deleting existing image for regeneration",{imageId:L}),await this.context.entityService.deleteEntity({entityType:"image",id:L});if(await this.context.entityService.createEntity({entity:{...V,id:L}}),this.logger.debug("Created image entity",{imageId:L}),f&&I){await this.reportProgress(B,{progress:zQ.SAVE,message:`Updating ${f} with cover image`});let O=await CL(this.context.entityService,f,I,this.logger);if(!O)return $5.failure(Error(`Target entity not found: ${f}/${I}`));let E=YV(O,L);await this.context.entities.update(E),this.logger.debug("Updated target entity with cover image",{targetEntityType:f,targetEntityId:I,imageId:L})}return await this.reportProgress(B,{progress:zQ.COMPLETE,message:"Image generation complete"}),this.logger.info("Image generation job complete",{jobId:Q,imageId:L,targetEntityType:f,targetEntityId:I}),{success:!0,imageId:L}}catch(U){return this.logger.error("Image generation job failed",{jobId:Q,error:T0(U)}),$5.failure(U)}}summarizeDataForLog(A){return{title:A.title,promptLength:A.prompt.length,aspectRatio:A.aspectRatio,targetEntityType:A.targetEntityType,targetEntityId:A.targetEntityId}}}aA();WA();H6();E7();var iI2=H.object({sourceEntityType:H.string().min(1),sourceEntityId:H.string().min(1),attachmentType:H.string().min(1),imageId:H.string().min(1),dedupKey:H.string().min(1).optional(),replace:H.boolean().optional(),targetEntityType:H.string().min(1).optional(),targetEntityId:H.string().min(1).optional(),targetImageField:H.enum(["coverImageId","ogImageId"]).optional()});class qzA extends ZB{context;constructor(A,Q){super(Q,{schema:iI2,jobTypeName:"image-render-source"});this.context=A}async process(A,Q,B){this.logger.debug("Starting source image render job",{jobId:Q,sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType,imageId:A.imageId});try{if(A.replace!==!0&&A.dedupKey){let U=await this.findImageByDedupKey(A.dedupKey);if(U)return await this.updateTarget(A,U.id),await this.reportProgress(B,{progress:zQ.COMPLETE,message:"Reusing existing generated image"}),{success:!0,imageId:U.id,reused:!0}}await this.reportProgress(B,{progress:zQ.PROCESS,message:"Rendering source image"});let w=await this.context.attachments.resolve({sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType});if(!w)return $5.failure(Error(`No attachment provider found for ${A.sourceEntityType}/${A.attachmentType}`));if(w.type!=="image")return $5.failure(Error(`Attachment provider returned ${w.type}; expected image`));await this.reportProgress(B,{progress:zQ.GENERATE,message:"Creating image entity"});let $=w.mimeType.split("/")[1]??"png",I={...HU.createImageEntity({dataUrl:sZA(w.data.toString("base64"),$),title:A.imageId,sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType,...A.dedupKey&&{dedupKey:A.dedupKey}}),id:A.imageId},D=await this.context.entityService.getEntity({entityType:"image",id:A.imageId});if(D)await this.context.entityService.updateEntity({entity:{...D,...I}});else await this.context.entityService.createEntity({entity:I});return await this.updateTarget(A,A.imageId),await this.reportProgress(B,{progress:zQ.COMPLETE,message:"Image render complete"}),{success:!0,imageId:A.imageId,reused:!1}}catch(w){return this.logger.error("Source image render job failed",{jobId:Q,error:T0(w)}),$5.failure(w)}}async findImageByDedupKey(A){return(await this.context.entityService.listEntities({entityType:"image",options:{filter:{metadata:{dedupKey:A}}}}))[0]}async updateTarget(A,Q){if(!A.targetEntityType||!A.targetEntityId)return;let B=await CL(this.context.entityService,A.targetEntityType,A.targetEntityId,this.logger);if(!B)throw Error(`Target entity not found: ${A.targetEntityType}/${A.targetEntityId}`);let $=(A.targetImageField??"coverImageId")==="ogImageId"?Gg(B,Q):YV(B,Q);await this.context.entities.update($)}}aA();WA();E7();WA();var zP={namespace:"upload",refKind:"upload",routePath:"/api/chat/uploads"};function ae(A){return["image/png","image/jpeg","image/webp","image/gif"].includes(A.toLowerCase())}function te(A){let Q=rI2(A.title,A.filename),B=X1(Q);if(!B)throw Error("Could not derive an image id from the uploaded filename. Provide a title.");return{id:B,title:Q}}function zZ0(A,Q){return`data:${A};base64,${Q.toString("base64")}`}function rI2(A,Q){let B=A?.trim();if(B)return B;return Q.replace(/\.[^.]+$/,"").trim()||Q}var dI2=H.object({uploadId:H.string().min(1),title:H.string().optional()});class LzA extends ZB{context;constructor(A,Q){super(A,{schema:dI2,jobTypeName:"upload-promote"});this.context=Q}async process(A,Q,B){await this.reportProgress(B,{progress:10,message:"Reading uploaded image"});let w=await this.context.uploads.scoped(zP).read(A.uploadId);if(!ae(w.record.mediaType))throw Error("Only image uploads can be promoted to image entities");let $=te({filename:w.record.filename,...A.title!==void 0?{title:A.title}:{}});await this.reportProgress(B,{progress:60,message:"Saving uploaded image"});let f=new Date().toISOString(),I=HU.createImageEntity({dataUrl:zZ0(w.record.mediaType,w.content),title:$.title}),D=await this.context.entityService.createEntity({entity:{id:$.id,...I,created:f,updated:f},options:{deduplicateId:!0}});return await this.reportProgress(B,{progress:100,message:"Uploaded image promoted"}),{entityId:D.entityId,status:"created"}}summarizeDataForLog(A){return{uploadId:A.uploadId,hasTitle:A.title!==void 0}}}var qZ0={name:"@brains/image-plugin",private:!0,version:"0.2.0-alpha.119",description:"Plugin for AI-powered image generation and management",type:"module",main:"./src/index.ts",exports:{".":"./src/index.ts"},scripts:{test:"bun test",typecheck:"tsc --noEmit",lint:"eslint src test --ext .ts","lint:fix":"eslint src test --ext .ts --fix"},dependencies:{"@brains/contracts":"workspace:*","@brains/entity-service":"workspace:*","@brains/image":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","@types/node":"^20.0.0",typescript:"^5.3.3"}};var oI2=H.object({defaultAspectRatio:H.enum(["1:1","16:9","9:16","4:3","3:4"]).default("16:9").describe("Default aspect ratio for generated images")});function XJ(A){let Q=A?.trim();if(!Q)return;return Q}function sI2(A){let Q=XJ(A.prompt);if(Q)return Q;let B=XJ(A.content);if(B&&!zzA(B))return B;return}function aI2(A){let Q=A.attachmentType==="og-image"?"og":A.attachmentType;return X1(`${Q}-${A.sourceEntityType}-${A.sourceEntityId}`)}function LZ0(A){let Q=XJ(A.title)??(A.targetEntityId?`cover-${A.targetEntityId}`:A.prompt.slice(0,60).trim());return X1(Q)}async function tI2(A,Q){let B=`${Q.attachmentType}:${Q.sourceEntityType}:${Q.sourceEntityId}:resolved-attachment`,w=await A.entityService.getEntity({entityType:Q.sourceEntityType,id:Q.sourceEntityId});return w?`${B}:${w.contentHash}`:B}function VzA(A,Q="generated"){let B=encodeURIComponent(A);return{mediaType:"image/png",url:`/api/chat/attachments/image?id=${B}`,downloadUrl:`/api/chat/attachments/image?id=${B}&download=1`,filename:`${A}.png`,source:{entityType:"image",entityId:A,attachmentType:Q}}}function eI2(A){let Q=encodeURIComponent(A.entityId);return{mediaType:A.mediaType,url:`/api/chat/attachments/image?id=${Q}`,downloadUrl:`/api/chat/attachments/image?id=${Q}&download=1`,filename:A.filename,source:{entityType:"image",entityId:A.entityId,attachmentType:"uploaded"}}}class EzA extends jQ{entityType=HU.entityType;schema=Wg;adapter=HU;constructor(A={}){super("image",qZ0,A,oI2)}getEntityTypeConfig(){return{embeddable:!1}}async interceptCreate(A,Q,B){if(A.from?.kind===zP.refKind)return this.promoteUpload(A,B);let w=sI2(A),$=XJ(A.targetEntityType),f=XJ(A.targetEntityId),I=$===this.entityType?f:void 0,D=A.from;if(D?.kind==="entity-attachment")return this.enqueueSourceImageRender({...A,from:D},B);if(!$||!f||I){if(!w)return{kind:"continue",input:A};let G=XJ(A.title)??I,Z=await B.jobs.enqueue({type:"image-generate",data:{prompt:w,...G&&{title:G}}}),N=LZ0({prompt:w,...G&&{title:G}});return{kind:"handled",result:{success:!0,data:{entityId:N,status:"generating",jobId:Z,attachment:VzA(N)}}}}let U=await $U(B.entityService,$,f,this.logger,"Target entity");if(!U.ok)return{kind:"handled",result:{success:!1,error:U.error}};if(!w)return{kind:"continue",input:{...A,targetEntityId:U.entity.id}};let Y=oe(U.entity.content),J=await B.jobs.enqueue({type:"image-generate",data:{prompt:w,...A.title&&{title:A.title},targetEntityType:$,targetEntityId:U.entity.id,entityTitle:typeof U.entity.metadata.title==="string"?U.entity.metadata.title:U.entity.id,...Y&&{entityContent:Y}}}),X=LZ0({prompt:w,...A.title&&{title:A.title},targetEntityId:U.entity.id});return{kind:"handled",result:{success:!0,data:{entityId:X,status:"generating",jobId:J,attachment:VzA(X)}}}}async promoteUpload(A,Q){let B=A.from;if(B?.kind!==zP.refKind)return{kind:"handled",result:{success:!1,error:"Unsupported upload ref kind"}};let w=B.id,$;try{$=await Q.uploads.scoped(zP).readRecord(w)}catch{return{kind:"handled",result:{success:!1,error:"Upload ref not found"}}}if(!ae($.mediaType))return{kind:"handled",result:{success:!1,error:"Only image uploads can be promoted to image entities"}};let f;try{f=te({filename:$.filename,...A.title!==void 0?{title:A.title}:{}})}catch(D){return{kind:"handled",result:{success:!1,error:D instanceof Error?D.message:String(D)}}}let I=await Q.jobs.enqueue({type:"upload-promote",data:{uploadId:w,...A.title!==void 0?{title:A.title}:{}}});return{kind:"handled",result:{success:!0,data:{entityId:f.id,status:"generating",jobId:I,attachment:eI2({mediaType:$.mediaType,entityId:f.id,filename:$.filename})}}}}async enqueueSourceImageRender(A,Q){let B=XJ(A.from.sourceEntityType),w=XJ(A.from.sourceEntityId),$=XJ(A.from.attachmentType);if(!B||!w||!$)return{kind:"handled",result:{success:!1,error:"Image source requires sourceEntityType, sourceEntityId, and attachmentType"}};let f=await $U(Q.entityService,B,w,this.logger,"Source entity");if(!f.ok)return{kind:"handled",result:{success:!1,error:f.error}};let I=XJ(A.targetEntityType),D=XJ(A.targetEntityId),U;if(I&&D){let Z=await $U(Q.entityService,I,D,this.logger,"Target entity");if(!Z.ok)return{kind:"handled",result:{success:!1,error:Z.error}};U=Z.entity.id}let Y={sourceEntityType:B,sourceEntityId:f.entity.id,attachmentType:$},J=await tI2(Q,Y),X=aI2(Y),G=await Q.jobs.enqueue({type:"image-render-source",data:{...Y,imageId:X,dedupKey:J,...A.replace===!0&&{replace:!0},...I&&{targetEntityType:I},...U&&{targetEntityId:U},...$==="og-image"&&{targetImageField:"ogImageId"}}});return{kind:"handled",result:{success:!0,data:{entityId:X,status:"generating",jobId:G,attachment:VzA(X,$)}}}}async getInstructions(){return'For durable raw image saves/promotions from uploaded images, call system_create with entityType: "image", the exact upload object shown in the current turn or conversation "Available upload refs" hint, and no transform. Do this only after the user explicitly asks to save/import/promote the uploaded image file itself. If that hint is absent, omit upload entirely; never invent upload IDs or placeholder upload refs. Describing or summarizing an uploaded image should use it as chat context, not create an image entity. Saving an image description, discussion, interpretation, or caption as a note should create a base entity with content from the conversation, not upload/transform. After a bare upload acknowledgement, a short label/title-only follow-up is ambiguous; ask what to do with the upload instead of turning that label into an AI image-generation prompt. For AI-generated images and cover images, call system_create with entityType: "image" and a prompt, and omit upload/sourceAttachment entirely unless the user explicitly asks to reuse the uploaded image file.'}createGenerationHandler(A){return new se(A,this.logger)}async onRegister(A){let Q=new se(A,this.logger);A.jobs.registerHandler("image-generate",Q),A.jobs.registerHandler("image-render-source",new qzA(A,this.logger)),A.jobs.registerHandler("upload-promote",new LzA(this.logger.child("UploadPromotionJobHandler"),A))}}function Xh(A){return new EzA(A)}aA();import{StdioServerTransport as AD2}from"@modelcontextprotocol/sdk/server/stdio.js";function VZ0(){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 MzA(){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 ee(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 MzA()}class WJ{static instance=null;mcpServer=null;transport=null;config;logger;static getInstance(A){return WJ.instance??=new WJ(A),WJ.instance}static resetInstance(){if(WJ.instance)WJ.instance.stop(),WJ.instance=null}static createFresh(A){return new WJ(A)}constructor(A={}){this.config=A,this.logger=this.config.logger?ee(this.config.logger):VZ0()}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 AD2,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 EZ0}from"crypto";import{WebStandardStreamableHTTPServerTransport as QD2}from"@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";import{isInitializeRequest as BD2}from"@modelcontextprotocol/sdk/types.js";var wD2={"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 $D2(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 ZK{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?ee(this.config.logger):MzA(),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 ZK.instance??=new ZK(A),ZK.instance}static resetInstance(){ZK.instance=null}static createFresh(A){return new ZK(A)}withCors(A){let Q=new Headers(A.headers);for(let[B,w]of Object.entries(wD2))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:`${$D2(A)}/.well-known/oauth-protected-resource`,...Q};return`Bearer ${Object.entries(w).map(([f,I])=>`${f}="${fD2(I)}"`).join(", ")}`}async authenticate(A){let Q=new URL(A.url).pathname;if(Q==="/health"||Q==="/status"||Q==="/mcp"&&A.method==="OPTIONS")return null;if(this.authConfig.disabled)return null;let B=A.headers.get("authorization");if(!B?.startsWith("Bearer "))return this.logger.warn("Authentication failed: Missing Bearer token"),this.getAuthErrorResponse("Unauthorized: Bearer token required",401,this.getBearerChallenge(A,{realm:"mcp"}));if(this.authConfig.token){if(B.substring(7)!==this.authConfig.token)return this.logger.warn("Authentication failed: Invalid token"),this.getAuthErrorResponse("Unauthorized: Invalid token",401,this.getBearerChallenge(A,{error:"invalid_token"}));return this.logger.debug("Authentication successful"),null}try{let w=await this.authConfig.verifyBearerToken?.(A);if(!w)return this.logger.warn("Authentication failed: Invalid token"),this.getAuthErrorResponse("Unauthorized: Invalid token",401,this.getBearerChallenge(A,{error:"invalid_token"}));let $=this.authConfig.requiredScopes??[],f=$.filter((I)=>!w.scope?.includes(I));if(f.length>0)return this.logger.warn(`Authentication failed: Missing required scope(s): ${f.join(", ")}`),this.getAuthErrorResponse("Forbidden: Missing required scope",403,this.getBearerChallenge(A,{error:"insufficient_scope",scope:$.join(" ")}));return this.logger.debug("Authentication successful"),null}catch(w){return this.logger.warn("Authentication failed: Invalid token",w),this.getAuthErrorResponse("Unauthorized: Invalid token",401,this.getBearerChallenge(A,{error:"invalid_token"}))}}async handleMcpRequest(A){let Q=A.headers.get("mcp-session-id")??void 0;if(A.method==="GET"){if(!Q||!this.transports[Q])return this.createTextResponse("Invalid or missing session ID",400);return this.logger.debug(`GET /mcp - SSE stream for session ${Q}`),this.withCors(await this.transports[Q].handleRequest(A))}if(A.method==="DELETE"){if(!Q||!this.transports[Q])return this.createTextResponse("Invalid or missing session ID",400);return this.logger.info(`DELETE /mcp - Terminating session ${Q}`),this.withCors(await this.transports[Q].handleRequest(A))}if(A.method==="OPTIONS")return this.withCors(new Response(null,{status:204}));if(A.method!=="POST")return this.createTextResponse("Method Not Allowed",405);if(!this.mcpServer)return this.createJsonResponse({jsonrpc:"2.0",error:{code:-32603,message:"Service Unavailable: MCP server not connected"},id:null},503);let B=await A.json();this.logger.debug(`POST /mcp - Session: ${Q??"new"}`);try{let w;if(Q&&this.transports[Q])w=this.transports[Q];else if(!Q&&BD2(B))w=new QD2({sessionIdGenerator:()=>EZ0(),onsessioninitialized:(f)=>{this.logger.info(`Session initialized: ${f}`),this.transports[f]=w},onsessionclosed:(f)=>{this.logger.info(`Session closed: ${f}`),delete this.transports[f]}}),await(this.mcpTransport?this.mcpTransport.createMcpServer():this.mcpServer).connect(w);else return this.createJsonResponse({jsonrpc:"2.0",error:{code:-32000,message:"Bad Request: Server not initialized"},id:null},400);return this.withCors(await w.handleRequest(A,{parsedBody:B}))}catch(w){return this.logger.error("MCP transport error:",w),this.createJsonResponse({jsonrpc:"2.0",error:{code:-32603,message:"Internal error"}},500)}}async handleAgentChatRequest(A){if(!this.agentService)return this.createJsonResponse({error:"Agent service not connected"},503);let{message:Q,conversationId:B}=await A.json();if(!Q||typeof Q!=="string")return this.createJsonResponse({error:"Missing or invalid 'message' field"},400);let w=B??EZ0();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 handleAgentConfirmRequest(A){if(!this.agentService)return this.createJsonResponse({error:"Agent service not connected"},503);let{conversationId:Q,confirmed:B,approvalId:w}=await A.json();if(!Q||typeof Q!=="string")return this.createJsonResponse({error:"Missing or invalid 'conversationId' field"},400);if(typeof B!=="boolean")return this.createJsonResponse({error:"Missing or invalid 'confirmed' field"},400);if(typeof w!=="string"||w.length===0)return this.createJsonResponse({error:"Missing or invalid 'approvalId' field"},400);this.logger.debug(`POST /api/chat/confirm - conversation: ${Q}`);try{let $=await this.agentService.confirmPendingAction(Q,B,w);return this.createJsonResponse($)}catch($){return this.logger.error("Agent confirm 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);if(Q.pathname==="/api/chat/confirm"&&A.method==="POST")return this.handleAgentConfirmRequest(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 fD2(A){return A.replace(/["\\]/g,(Q)=>`\\${Q}`)}import{randomUUID as DD2}from"crypto";import{mkdir as UD2,readFile as YD2,writeFile as JD2,chmod as XD2}from"fs/promises";import{dirname as WD2,join as HD2}from"path";function MZ0(A){let Q=A.toLowerCase();return Q==="localhost"||Q==="[::1]"||Q==="::1"||Q.startsWith("127.")}function CZ0(A){try{return new URL(A)}catch{return}}function CzA(A,Q){if(A===Q)return!0;let B=CZ0(A),w=CZ0(Q);if(!B||!w)return!1;if(!MZ0(B.hostname)||!MZ0(w.hostname))return!1;return B.protocol===w.protocol&&B.port===w.port&&ID2(B.pathname,w.pathname)&&B.search===w.search&&B.hash===w.hash}function ID2(A,Q){return A===Q||A===`${Q}/debug`||Q===`${A}/debug`}function OzA(A,Q){return A.some((B)=>CzA(B,Q))}var GD2="oauth-auth-codes.json",KD2=600;function OZ0(){return Math.floor(Date.now()/1000)}function FD2(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 ZD2(A){if(!A||typeof A!=="object")return{codes:[]};let Q=A.codes;if(!Array.isArray(Q))return{codes:[]};return{codes:Q.filter(FD2)}}async function ND2(A){let Q=await crypto.subtle.digest("SHA-256",new TextEncoder().encode(A));return Buffer.from(Q).toString("base64url")}class AAA{storeFile;writeQueue=Promise.resolve();constructor(A){this.storeFile=HD2(A.storageDir,A.storeFile??GD2)}async createCode(A){let Q=OZ0(),B={code:`ocd_${DD2()}`,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+KD2};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=OZ0(),B;if(await this.enqueueWrite(async()=>{let w=await this.readStore(),$=w.codes.findIndex((D)=>D.code===A.code),f=$>=0?w.codes[$]:void 0;if(!f)throw new HJ("Authorization code not found");if(f.consumed_at!==void 0)throw new HJ("Authorization code already consumed");if(f.expires_at<=Q)throw new HJ("Authorization code expired");if(f.client_id!==A.clientId)throw new HJ("Authorization code client mismatch");if(!CzA(f.redirect_uri,A.redirectUri))throw new HJ("Authorization code redirect URI mismatch");let I=await ND2(A.codeVerifier);if(f.code_challenge!==I)throw new HJ("PKCE verification failed");B={...f,consumed_at:Q},w.codes[$]=B,await this.writeStore(w)}),!B)throw new HJ("Authorization code not consumed");return B}async enqueueWrite(A){return this.writeQueue=this.writeQueue.then(A,A),this.writeQueue}async readStore(){try{return ZD2(JSON.parse(await YD2(this.storeFile,"utf8")))}catch(A){if(A.code==="ENOENT")return{codes:[]};throw A}}async writeStore(A){await UD2(WD2(this.storeFile),{recursive:!0,mode:448}),await JD2(this.storeFile,`${JSON.stringify(A,null,2)}
|
|
1817
|
+
${Y}`,lI2);U=`${w.trim()} ${O.imagePrompt}`}catch(O){this.logger.warn("AI prompt distillation failed, using fallback",{error:T0(O)})}}await this.reportProgress(B,{progress:zQ.PROCESS,message:"Generating image"});let J=this.context.identity.get(),X=this.context.identity.getProfile(),Z=NZ0(J,X)+U,N;try{N=await this.context.ai.generateImage(Z,{...$&&{aspectRatio:$}})}catch(O){return this.logger.error("Image generation failed",{jobId:Q,error:T0(O)}),$5.failure(O)}await this.reportProgress(B,{progress:zQ.GENERATE,message:"Creating image entity"});let L=X1(D),V=HU.createImageEntity({dataUrl:N.dataUrl,title:D});if(await this.context.entityService.getEntity({entityType:"image",id:L}))this.logger.debug("Deleting existing image for regeneration",{imageId:L}),await this.context.entityService.deleteEntity({entityType:"image",id:L});if(await this.context.entityService.createEntity({entity:{...V,id:L}}),this.logger.debug("Created image entity",{imageId:L}),f&&I){await this.reportProgress(B,{progress:zQ.SAVE,message:`Updating ${f} with cover image`});let O=await CL(this.context.entityService,f,I,this.logger);if(!O)return $5.failure(Error(`Target entity not found: ${f}/${I}`));let E=YV(O,L);await this.context.entities.update(E),this.logger.debug("Updated target entity with cover image",{targetEntityType:f,targetEntityId:I,imageId:L})}return await this.reportProgress(B,{progress:zQ.COMPLETE,message:"Image generation complete"}),this.logger.info("Image generation job complete",{jobId:Q,imageId:L,targetEntityType:f,targetEntityId:I}),{success:!0,imageId:L}}catch(U){return this.logger.error("Image generation job failed",{jobId:Q,error:T0(U)}),$5.failure(U)}}summarizeDataForLog(A){return{title:A.title,promptLength:A.prompt.length,aspectRatio:A.aspectRatio,targetEntityType:A.targetEntityType,targetEntityId:A.targetEntityId}}}aA();WA();H6();E7();var iI2=H.object({sourceEntityType:H.string().min(1),sourceEntityId:H.string().min(1),attachmentType:H.string().min(1),imageId:H.string().min(1),dedupKey:H.string().min(1).optional(),replace:H.boolean().optional(),targetEntityType:H.string().min(1).optional(),targetEntityId:H.string().min(1).optional(),targetImageField:H.enum(["coverImageId","ogImageId"]).optional()});class qzA extends ZB{context;constructor(A,Q){super(Q,{schema:iI2,jobTypeName:"image-render-source"});this.context=A}async process(A,Q,B){this.logger.debug("Starting source image render job",{jobId:Q,sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType,imageId:A.imageId});try{if(A.replace!==!0&&A.dedupKey){let U=await this.findImageByDedupKey(A.dedupKey);if(U)return await this.updateTarget(A,U.id),await this.reportProgress(B,{progress:zQ.COMPLETE,message:"Reusing existing generated image"}),{success:!0,imageId:U.id,reused:!0}}await this.reportProgress(B,{progress:zQ.PROCESS,message:"Rendering source image"});let w=await this.context.attachments.resolve({sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType});if(!w)return $5.failure(Error(`No attachment provider found for ${A.sourceEntityType}/${A.attachmentType}`));if(w.type!=="image")return $5.failure(Error(`Attachment provider returned ${w.type}; expected image`));await this.reportProgress(B,{progress:zQ.GENERATE,message:"Creating image entity"});let $=w.mimeType.split("/")[1]??"png",I={...HU.createImageEntity({dataUrl:sZA(w.data.toString("base64"),$),title:A.imageId,sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType,...A.dedupKey&&{dedupKey:A.dedupKey}}),id:A.imageId},D=await this.context.entityService.getEntity({entityType:"image",id:A.imageId});if(D)await this.context.entityService.updateEntity({entity:{...D,...I}});else await this.context.entityService.createEntity({entity:I});return await this.updateTarget(A,A.imageId),await this.reportProgress(B,{progress:zQ.COMPLETE,message:"Image render complete"}),{success:!0,imageId:A.imageId,reused:!1}}catch(w){return this.logger.error("Source image render job failed",{jobId:Q,error:T0(w)}),$5.failure(w)}}async findImageByDedupKey(A){return(await this.context.entityService.listEntities({entityType:"image",options:{filter:{metadata:{dedupKey:A}}}}))[0]}async updateTarget(A,Q){if(!A.targetEntityType||!A.targetEntityId)return;let B=await CL(this.context.entityService,A.targetEntityType,A.targetEntityId,this.logger);if(!B)throw Error(`Target entity not found: ${A.targetEntityType}/${A.targetEntityId}`);let $=(A.targetImageField??"coverImageId")==="ogImageId"?Gg(B,Q):YV(B,Q);await this.context.entities.update($)}}aA();WA();E7();WA();var zP={namespace:"upload",refKind:"upload",routePath:"/api/chat/uploads"};function ae(A){return["image/png","image/jpeg","image/webp","image/gif"].includes(A.toLowerCase())}function te(A){let Q=rI2(A.title,A.filename),B=X1(Q);if(!B)throw Error("Could not derive an image id from the uploaded filename. Provide a title.");return{id:B,title:Q}}function zZ0(A,Q){return`data:${A};base64,${Q.toString("base64")}`}function rI2(A,Q){let B=A?.trim();if(B)return B;return Q.replace(/\.[^.]+$/,"").trim()||Q}var dI2=H.object({uploadId:H.string().min(1),title:H.string().optional()});class LzA extends ZB{context;constructor(A,Q){super(A,{schema:dI2,jobTypeName:"upload-promote"});this.context=Q}async process(A,Q,B){await this.reportProgress(B,{progress:10,message:"Reading uploaded image"});let w=await this.context.uploads.scoped(zP).read(A.uploadId);if(!ae(w.record.mediaType))throw Error("Only image uploads can be promoted to image entities");let $=te({filename:w.record.filename,...A.title!==void 0?{title:A.title}:{}});await this.reportProgress(B,{progress:60,message:"Saving uploaded image"});let f=new Date().toISOString(),I=HU.createImageEntity({dataUrl:zZ0(w.record.mediaType,w.content),title:$.title}),D=await this.context.entityService.createEntity({entity:{id:$.id,...I,created:f,updated:f},options:{deduplicateId:!0}});return await this.reportProgress(B,{progress:100,message:"Uploaded image promoted"}),{entityId:D.entityId,status:"created"}}summarizeDataForLog(A){return{uploadId:A.uploadId,hasTitle:A.title!==void 0}}}var qZ0={name:"@brains/image-plugin",private:!0,version:"0.2.0-alpha.120",description:"Plugin for AI-powered image generation and management",type:"module",main:"./src/index.ts",exports:{".":"./src/index.ts"},scripts:{test:"bun test",typecheck:"tsc --noEmit",lint:"eslint src test --ext .ts","lint:fix":"eslint src test --ext .ts --fix"},dependencies:{"@brains/contracts":"workspace:*","@brains/entity-service":"workspace:*","@brains/image":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","@types/node":"^20.0.0",typescript:"^5.3.3"}};var oI2=H.object({defaultAspectRatio:H.enum(["1:1","16:9","9:16","4:3","3:4"]).default("16:9").describe("Default aspect ratio for generated images")});function XJ(A){let Q=A?.trim();if(!Q)return;return Q}function sI2(A){let Q=XJ(A.prompt);if(Q)return Q;let B=XJ(A.content);if(B&&!zzA(B))return B;return}function aI2(A){let Q=A.attachmentType==="og-image"?"og":A.attachmentType;return X1(`${Q}-${A.sourceEntityType}-${A.sourceEntityId}`)}function LZ0(A){let Q=XJ(A.title)??(A.targetEntityId?`cover-${A.targetEntityId}`:A.prompt.slice(0,60).trim());return X1(Q)}async function tI2(A,Q){let B=`${Q.attachmentType}:${Q.sourceEntityType}:${Q.sourceEntityId}:resolved-attachment`,w=await A.entityService.getEntity({entityType:Q.sourceEntityType,id:Q.sourceEntityId});return w?`${B}:${w.contentHash}`:B}function VzA(A,Q="generated"){let B=encodeURIComponent(A);return{mediaType:"image/png",url:`/api/chat/attachments/image?id=${B}`,downloadUrl:`/api/chat/attachments/image?id=${B}&download=1`,filename:`${A}.png`,source:{entityType:"image",entityId:A,attachmentType:Q}}}function eI2(A){let Q=encodeURIComponent(A.entityId);return{mediaType:A.mediaType,url:`/api/chat/attachments/image?id=${Q}`,downloadUrl:`/api/chat/attachments/image?id=${Q}&download=1`,filename:A.filename,source:{entityType:"image",entityId:A.entityId,attachmentType:"uploaded"}}}class EzA extends jQ{entityType=HU.entityType;schema=Wg;adapter=HU;constructor(A={}){super("image",qZ0,A,oI2)}getEntityTypeConfig(){return{embeddable:!1}}async interceptCreate(A,Q,B){if(A.from?.kind===zP.refKind)return this.promoteUpload(A,B);let w=sI2(A),$=XJ(A.targetEntityType),f=XJ(A.targetEntityId),I=$===this.entityType?f:void 0,D=A.from;if(D?.kind==="entity-attachment")return this.enqueueSourceImageRender({...A,from:D},B);if(!$||!f||I){if(!w)return{kind:"continue",input:A};let G=XJ(A.title)??I,Z=await B.jobs.enqueue({type:"image-generate",data:{prompt:w,...G&&{title:G}}}),N=LZ0({prompt:w,...G&&{title:G}});return{kind:"handled",result:{success:!0,data:{entityId:N,status:"generating",jobId:Z,attachment:VzA(N)}}}}let U=await $U(B.entityService,$,f,this.logger,"Target entity");if(!U.ok)return{kind:"handled",result:{success:!1,error:U.error}};if(!w)return{kind:"continue",input:{...A,targetEntityId:U.entity.id}};let Y=oe(U.entity.content),J=await B.jobs.enqueue({type:"image-generate",data:{prompt:w,...A.title&&{title:A.title},targetEntityType:$,targetEntityId:U.entity.id,entityTitle:typeof U.entity.metadata.title==="string"?U.entity.metadata.title:U.entity.id,...Y&&{entityContent:Y}}}),X=LZ0({prompt:w,...A.title&&{title:A.title},targetEntityId:U.entity.id});return{kind:"handled",result:{success:!0,data:{entityId:X,status:"generating",jobId:J,attachment:VzA(X)}}}}async promoteUpload(A,Q){let B=A.from;if(B?.kind!==zP.refKind)return{kind:"handled",result:{success:!1,error:"Unsupported upload ref kind"}};let w=B.id,$;try{$=await Q.uploads.scoped(zP).readRecord(w)}catch{return{kind:"handled",result:{success:!1,error:"Upload ref not found"}}}if(!ae($.mediaType))return{kind:"handled",result:{success:!1,error:"Only image uploads can be promoted to image entities"}};let f;try{f=te({filename:$.filename,...A.title!==void 0?{title:A.title}:{}})}catch(D){return{kind:"handled",result:{success:!1,error:D instanceof Error?D.message:String(D)}}}let I=await Q.jobs.enqueue({type:"upload-promote",data:{uploadId:w,...A.title!==void 0?{title:A.title}:{}}});return{kind:"handled",result:{success:!0,data:{entityId:f.id,status:"generating",jobId:I,attachment:eI2({mediaType:$.mediaType,entityId:f.id,filename:$.filename})}}}}async enqueueSourceImageRender(A,Q){let B=XJ(A.from.sourceEntityType),w=XJ(A.from.sourceEntityId),$=XJ(A.from.attachmentType);if(!B||!w||!$)return{kind:"handled",result:{success:!1,error:"Image source requires sourceEntityType, sourceEntityId, and attachmentType"}};let f=await $U(Q.entityService,B,w,this.logger,"Source entity");if(!f.ok)return{kind:"handled",result:{success:!1,error:f.error}};let I=XJ(A.targetEntityType),D=XJ(A.targetEntityId),U;if(I&&D){let Z=await $U(Q.entityService,I,D,this.logger,"Target entity");if(!Z.ok)return{kind:"handled",result:{success:!1,error:Z.error}};U=Z.entity.id}let Y={sourceEntityType:B,sourceEntityId:f.entity.id,attachmentType:$},J=await tI2(Q,Y),X=aI2(Y),G=await Q.jobs.enqueue({type:"image-render-source",data:{...Y,imageId:X,dedupKey:J,...A.replace===!0&&{replace:!0},...I&&{targetEntityType:I},...U&&{targetEntityId:U},...$==="og-image"&&{targetImageField:"ogImageId"}}});return{kind:"handled",result:{success:!0,data:{entityId:X,status:"generating",jobId:G,attachment:VzA(X,$)}}}}async getInstructions(){return'For durable raw image saves/promotions from uploaded images, call system_create with entityType: "image", the exact upload object shown in the current turn or conversation "Available upload refs" hint, and no transform. Do this only after the user explicitly asks to save/import/promote the uploaded image file itself. If that hint is absent, omit upload entirely; never invent upload IDs or placeholder upload refs. Describing or summarizing an uploaded image should use it as chat context, not create an image entity. Saving an image description, discussion, interpretation, or caption as a note should create a base entity with content from the conversation, not upload/transform. After a bare upload acknowledgement, a short label/title-only follow-up is ambiguous; ask what to do with the upload instead of turning that label into an AI image-generation prompt. For AI-generated images and cover images, call system_create with entityType: "image" and a prompt, and omit upload/sourceAttachment entirely unless the user explicitly asks to reuse the uploaded image file.'}createGenerationHandler(A){return new se(A,this.logger)}async onRegister(A){let Q=new se(A,this.logger);A.jobs.registerHandler("image-generate",Q),A.jobs.registerHandler("image-render-source",new qzA(A,this.logger)),A.jobs.registerHandler("upload-promote",new LzA(this.logger.child("UploadPromotionJobHandler"),A))}}function Xh(A){return new EzA(A)}aA();import{StdioServerTransport as AD2}from"@modelcontextprotocol/sdk/server/stdio.js";function VZ0(){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 MzA(){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 ee(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 MzA()}class WJ{static instance=null;mcpServer=null;transport=null;config;logger;static getInstance(A){return WJ.instance??=new WJ(A),WJ.instance}static resetInstance(){if(WJ.instance)WJ.instance.stop(),WJ.instance=null}static createFresh(A){return new WJ(A)}constructor(A={}){this.config=A,this.logger=this.config.logger?ee(this.config.logger):VZ0()}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 AD2,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 EZ0}from"crypto";import{WebStandardStreamableHTTPServerTransport as QD2}from"@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";import{isInitializeRequest as BD2}from"@modelcontextprotocol/sdk/types.js";var wD2={"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 $D2(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 ZK{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?ee(this.config.logger):MzA(),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 ZK.instance??=new ZK(A),ZK.instance}static resetInstance(){ZK.instance=null}static createFresh(A){return new ZK(A)}withCors(A){let Q=new Headers(A.headers);for(let[B,w]of Object.entries(wD2))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:`${$D2(A)}/.well-known/oauth-protected-resource`,...Q};return`Bearer ${Object.entries(w).map(([f,I])=>`${f}="${fD2(I)}"`).join(", ")}`}async authenticate(A){let Q=new URL(A.url).pathname;if(Q==="/health"||Q==="/status"||Q==="/mcp"&&A.method==="OPTIONS")return null;if(this.authConfig.disabled)return null;let B=A.headers.get("authorization");if(!B?.startsWith("Bearer "))return this.logger.warn("Authentication failed: Missing Bearer token"),this.getAuthErrorResponse("Unauthorized: Bearer token required",401,this.getBearerChallenge(A,{realm:"mcp"}));if(this.authConfig.token){if(B.substring(7)!==this.authConfig.token)return this.logger.warn("Authentication failed: Invalid token"),this.getAuthErrorResponse("Unauthorized: Invalid token",401,this.getBearerChallenge(A,{error:"invalid_token"}));return this.logger.debug("Authentication successful"),null}try{let w=await this.authConfig.verifyBearerToken?.(A);if(!w)return this.logger.warn("Authentication failed: Invalid token"),this.getAuthErrorResponse("Unauthorized: Invalid token",401,this.getBearerChallenge(A,{error:"invalid_token"}));let $=this.authConfig.requiredScopes??[],f=$.filter((I)=>!w.scope?.includes(I));if(f.length>0)return this.logger.warn(`Authentication failed: Missing required scope(s): ${f.join(", ")}`),this.getAuthErrorResponse("Forbidden: Missing required scope",403,this.getBearerChallenge(A,{error:"insufficient_scope",scope:$.join(" ")}));return this.logger.debug("Authentication successful"),null}catch(w){return this.logger.warn("Authentication failed: Invalid token",w),this.getAuthErrorResponse("Unauthorized: Invalid token",401,this.getBearerChallenge(A,{error:"invalid_token"}))}}async handleMcpRequest(A){let Q=A.headers.get("mcp-session-id")??void 0;if(A.method==="GET"){if(!Q||!this.transports[Q])return this.createTextResponse("Invalid or missing session ID",400);return this.logger.debug(`GET /mcp - SSE stream for session ${Q}`),this.withCors(await this.transports[Q].handleRequest(A))}if(A.method==="DELETE"){if(!Q||!this.transports[Q])return this.createTextResponse("Invalid or missing session ID",400);return this.logger.info(`DELETE /mcp - Terminating session ${Q}`),this.withCors(await this.transports[Q].handleRequest(A))}if(A.method==="OPTIONS")return this.withCors(new Response(null,{status:204}));if(A.method!=="POST")return this.createTextResponse("Method Not Allowed",405);if(!this.mcpServer)return this.createJsonResponse({jsonrpc:"2.0",error:{code:-32603,message:"Service Unavailable: MCP server not connected"},id:null},503);let B=await A.json();this.logger.debug(`POST /mcp - Session: ${Q??"new"}`);try{let w;if(Q&&this.transports[Q])w=this.transports[Q];else if(!Q&&BD2(B))w=new QD2({sessionIdGenerator:()=>EZ0(),onsessioninitialized:(f)=>{this.logger.info(`Session initialized: ${f}`),this.transports[f]=w},onsessionclosed:(f)=>{this.logger.info(`Session closed: ${f}`),delete this.transports[f]}}),await(this.mcpTransport?this.mcpTransport.createMcpServer():this.mcpServer).connect(w);else return this.createJsonResponse({jsonrpc:"2.0",error:{code:-32000,message:"Bad Request: Server not initialized"},id:null},400);return this.withCors(await w.handleRequest(A,{parsedBody:B}))}catch(w){return this.logger.error("MCP transport error:",w),this.createJsonResponse({jsonrpc:"2.0",error:{code:-32603,message:"Internal error"}},500)}}async handleAgentChatRequest(A){if(!this.agentService)return this.createJsonResponse({error:"Agent service not connected"},503);let{message:Q,conversationId:B}=await A.json();if(!Q||typeof Q!=="string")return this.createJsonResponse({error:"Missing or invalid 'message' field"},400);let w=B??EZ0();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 handleAgentConfirmRequest(A){if(!this.agentService)return this.createJsonResponse({error:"Agent service not connected"},503);let{conversationId:Q,confirmed:B,approvalId:w}=await A.json();if(!Q||typeof Q!=="string")return this.createJsonResponse({error:"Missing or invalid 'conversationId' field"},400);if(typeof B!=="boolean")return this.createJsonResponse({error:"Missing or invalid 'confirmed' field"},400);if(typeof w!=="string"||w.length===0)return this.createJsonResponse({error:"Missing or invalid 'approvalId' field"},400);this.logger.debug(`POST /api/chat/confirm - conversation: ${Q}`);try{let $=await this.agentService.confirmPendingAction(Q,B,w);return this.createJsonResponse($)}catch($){return this.logger.error("Agent confirm 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);if(Q.pathname==="/api/chat/confirm"&&A.method==="POST")return this.handleAgentConfirmRequest(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 fD2(A){return A.replace(/["\\]/g,(Q)=>`\\${Q}`)}import{randomUUID as DD2}from"crypto";import{mkdir as UD2,readFile as YD2,writeFile as JD2,chmod as XD2}from"fs/promises";import{dirname as WD2,join as HD2}from"path";function MZ0(A){let Q=A.toLowerCase();return Q==="localhost"||Q==="[::1]"||Q==="::1"||Q.startsWith("127.")}function CZ0(A){try{return new URL(A)}catch{return}}function CzA(A,Q){if(A===Q)return!0;let B=CZ0(A),w=CZ0(Q);if(!B||!w)return!1;if(!MZ0(B.hostname)||!MZ0(w.hostname))return!1;return B.protocol===w.protocol&&B.port===w.port&&ID2(B.pathname,w.pathname)&&B.search===w.search&&B.hash===w.hash}function ID2(A,Q){return A===Q||A===`${Q}/debug`||Q===`${A}/debug`}function OzA(A,Q){return A.some((B)=>CzA(B,Q))}var GD2="oauth-auth-codes.json",KD2=600;function OZ0(){return Math.floor(Date.now()/1000)}function FD2(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 ZD2(A){if(!A||typeof A!=="object")return{codes:[]};let Q=A.codes;if(!Array.isArray(Q))return{codes:[]};return{codes:Q.filter(FD2)}}async function ND2(A){let Q=await crypto.subtle.digest("SHA-256",new TextEncoder().encode(A));return Buffer.from(Q).toString("base64url")}class AAA{storeFile;writeQueue=Promise.resolve();constructor(A){this.storeFile=HD2(A.storageDir,A.storeFile??GD2)}async createCode(A){let Q=OZ0(),B={code:`ocd_${DD2()}`,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+KD2};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=OZ0(),B;if(await this.enqueueWrite(async()=>{let w=await this.readStore(),$=w.codes.findIndex((D)=>D.code===A.code),f=$>=0?w.codes[$]:void 0;if(!f)throw new HJ("Authorization code not found");if(f.consumed_at!==void 0)throw new HJ("Authorization code already consumed");if(f.expires_at<=Q)throw new HJ("Authorization code expired");if(f.client_id!==A.clientId)throw new HJ("Authorization code client mismatch");if(!CzA(f.redirect_uri,A.redirectUri))throw new HJ("Authorization code redirect URI mismatch");let I=await ND2(A.codeVerifier);if(f.code_challenge!==I)throw new HJ("PKCE verification failed");B={...f,consumed_at:Q},w.codes[$]=B,await this.writeStore(w)}),!B)throw new HJ("Authorization code not consumed");return B}async enqueueWrite(A){return this.writeQueue=this.writeQueue.then(A,A),this.writeQueue}async readStore(){try{return ZD2(JSON.parse(await YD2(this.storeFile,"utf8")))}catch(A){if(A.code==="ENOENT")return{codes:[]};throw A}}async writeStore(A){await UD2(WD2(this.storeFile),{recursive:!0,mode:448}),await JD2(this.storeFile,`${JSON.stringify(A,null,2)}
|
|
1818
1818
|
`,{mode:384}),await XD2(this.storeFile,384)}}class HJ extends Error{constructor(A){super(A);this.name="InvalidGrantError"}}WA();import{randomUUID as RZ0}from"crypto";import{mkdir as zD2,readFile as qD2,writeFile as LD2,chmod as VD2}from"fs/promises";import{dirname as ED2,join as MD2}from"path";var CD2="oauth-clients.json",OD2=H.enum(["none","client_secret_basic","client_secret_post"]),RD2=H.object({redirect_uris:H.array(H.string().url()).min(1),token_endpoint_auth_method:OD2.default("none"),grant_types:H.array(H.enum(["authorization_code","refresh_token"])).default(["authorization_code","refresh_token"]),response_types:H.array(H.literal("code")).default(["code"]),scope:H.string().optional(),client_name:H.string().optional(),client_uri:H.string().url().optional(),logo_uri:H.string().url().optional(),contacts:H.array(H.string()).optional()});function bD2(){return Math.floor(Date.now()/1000)}function PD2(){return`ocs_${RZ0().replaceAll("-","")}`}function kD2(A){if(!A||typeof A!=="object")return{clients:[]};let Q=A.clients;if(!Array.isArray(Q))return{clients:[]};return{clients:Q.filter(jD2)}}function jD2(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 QAA{storeFile;writeQueue=Promise.resolve();constructor(A){this.storeFile=MD2(A.storageDir,A.storeFile??CD2)}async registerClient(A){let Q=RD2.safeParse(A);if(!Q.success)throw new Wh(Q.error.message);let B=Q.data,w=bD2(),$=`oc_${RZ0()}`,f=B.token_endpoint_auth_method==="none",I={client_id:$,client_id_issued_at:w,redirect_uris:B.redirect_uris,token_endpoint_auth_method:B.token_endpoint_auth_method,grant_types:B.grant_types,response_types:B.response_types,...B.scope?{scope:B.scope}:{},...B.client_name?{client_name:B.client_name}:{},...B.client_uri?{client_uri:B.client_uri}:{},...B.logo_uri?{logo_uri:B.logo_uri}:{},...B.contacts?{contacts:B.contacts}:{},...!f?{client_secret:PD2(),client_secret_expires_at:0}:{}};return await this.enqueueWrite(async()=>{let D=await this.readStore();D.clients.push(I),await this.writeStore(D)}),I}async getClient(A){return(await this.readStore()).clients.find((B)=>B.client_id===A)}async enqueueWrite(A){return this.writeQueue=this.writeQueue.then(A,A),this.writeQueue}async readStore(){try{return kD2(JSON.parse(await qD2(this.storeFile,"utf8")))}catch(A){if(A.code==="ENOENT")return{clients:[]};throw A}}async writeStore(A){await zD2(ED2(this.storeFile),{recursive:!0,mode:448}),await LD2(this.storeFile,`${JSON.stringify(A,null,2)}
|
|
1819
1819
|
`,{mode:384}),await VD2(this.storeFile,384)}}class Wh extends Error{constructor(A){super(A);this.name="InvalidClientMetadataError"}}import{createHash as _D2}from"crypto";import{mkdir as vD2,readFile as TD2,writeFile as yD2,chmod as xD2}from"fs/promises";import{dirname as SD2,join as gD2}from"path";var hD2="oauth-signing-key.jwk";function bZ0(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 PZ0(A){let Q=JSON.stringify({crv:A.crv,kty:A.kty,x:A.x,y:A.y});return _D2("sha256").update(Q).digest("base64url")}function mD2(A){return{kty:"EC",crv:"P-256",x:A.x,y:A.y,kid:A.kid,use:"sig",alg:"ES256"}}async function uD2(){let A=await crypto.subtle.generateKey({name:"ECDSA",namedCurve:"P-256"},!0,["sign","verify"]),Q=await crypto.subtle.exportKey("jwk",A.privateKey);if(!bZ0(Q))throw Error("Generated OAuth signing key is not a P-256 private JWK");let B=PZ0(Q);return{...Q,kid:B,use:"sig",alg:"ES256"}}class BAA{keyFile;cachedKey;loadPromise;constructor(A){this.keyFile=gD2(A.storageDir,A.keyFile??hD2)}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 uD2();return await vD2(SD2(this.keyFile),{recursive:!0,mode:448}),await yD2(this.keyFile,`${JSON.stringify(Q,null,2)}
|
|
1820
1820
|
`,{mode:384}),await xD2(this.keyFile,384),Q}async getPublicJwk(){return mD2(await this.getPrivateJwk())}async readExistingKey(){try{let A=JSON.parse(await TD2(this.keyFile,"utf8"));if(!bZ0(A))throw Error(`OAuth signing key at ${this.keyFile} is not a private P-256 JWK`);let Q=typeof A.kid==="string"?A.kid:PZ0(A);return{...A,kid:Q,use:"sig",alg:"ES256"}}catch(A){if(A.code==="ENOENT")return;throw A}}}var s2={};SB(s2,{trimPadding:()=>jZ0,toUTF8String:()=>sD2,toBuffer:()=>rD2,toBase64:()=>nD2,isBase64URL:()=>tD2,isBase64:()=>aD2,fromUTF8String:()=>oD2,fromBuffer:()=>dD2});var kZ0=(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},cD2=kZ0("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"),lD2=kZ0("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"),pD2=/^[-A-Za-z0-9\-_]*$/,iD2=/^[-A-Za-z0-9+/]*={0,3}$/,LW={};LW.toArrayBuffer=(A,Q)=>{let B=A.length,w=A.length*0.75,$,f=0,I,D,U,Y;if(A[A.length-1]==="="){if(w--,A[A.length-2]==="=")w--}let J=new ArrayBuffer(w),X=new Uint8Array(J),G=Q?lD2:cD2;for($=0;$<B;$+=4)I=G[A.charCodeAt($)],D=G[A.charCodeAt($+1)],U=G[A.charCodeAt($+2)],Y=G[A.charCodeAt($+3)],X[f++]=I<<2|D>>4,X[f++]=(D&15)<<4|U>>2,X[f++]=(U&3)<<6|Y&63;return J};LW.fromArrayBuffer=(A,Q)=>{let B=new Uint8Array(A),w,$="",f=B.length,I=Q?"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_":"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";for(w=0;w<f;w+=3)$+=I[B[w]>>2],$+=I[(B[w]&3)<<4|B[w+1]>>4],$+=I[(B[w+1]&15)<<2|B[w+2]>>6],$+=I[B[w+2]&63];let D=f%3;if(D===2)$=$.substring(0,$.length-1)+(Q?"":"=");else if(D===1)$=$.substring(0,$.length-2)+(Q?"":"==");return $};LW.toString=(A,Q)=>{return new TextDecoder().decode(LW.toArrayBuffer(A,Q))};LW.fromString=(A,Q)=>{return LW.fromArrayBuffer(new TextEncoder().encode(A),Q)};LW.validate=(A,Q)=>{if(!(typeof A==="string"||A instanceof String))return!1;try{return Q?pD2.test(A):iD2.test(A)}catch(B){return!1}};LW.base64=LW;var NK=LW;function rD2(A,Q="base64url"){let B=NK.toArrayBuffer(A,Q==="base64url");return new Uint8Array(B)}function dD2(A,Q="base64url"){let B=new Uint8Array(A);return NK.fromArrayBuffer(B.buffer,Q==="base64url")}function nD2(A){let Q=NK.toArrayBuffer(A,!0);return NK.fromArrayBuffer(Q)}function oD2(A){return NK.fromString(A,!0)}function sD2(A){return NK.toString(A,!0)}function aD2(A){return NK.validate(A,!1)}function tD2(A){return A=jZ0(A),NK.validate(A,!0)}function jZ0(A){return A.replace(/=/g,"")}var q4={};SB(q4,{encode:()=>zU2,decodeFirst:()=>NU2});function qP(A,Q,B){if(Q<24)return[Q,1];let w=A.byteLength-B-1,$=new DataView(A.buffer,B+1),f,I=0;switch(Q){case 24:{if(w>0)f=$.getUint8(0),I=2;break}case 25:{if(w>1)f=$.getUint16(0,!1),I=3;break}case 26:{if(w>3)f=$.getUint32(0,!1),I=5;break}case 27:{if(w>7){let D=$.getBigUint64(0,!1);if(D>=24n&&D<=Number.MAX_SAFE_INTEGER)return[Number(D),9]}break}}if(f&&f>=24)return[f,I];throw Error("Length not supported or not well formed")}var wAA=0,Hh=1,RzA=2,bzA=3,PzA=4,kzA=5,jzA=6,_Z0=7;function VW(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==Hh){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 fAA{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 vZ0(A,Q,B){return qP(A,Q,B)}function eD2(A,Q,B){let[w,$]=vZ0(A,Q,B);return[-w-1,$]}function TZ0(A,Q,B){let[w,$]=qP(A,Q,B),f=B+$;return[new Uint8Array(A.buffer.slice(f,f+w)),$+w]}var AU2=new TextDecoder;function QU2(A,Q,B){let[w,$]=TZ0(A,Q,B);return[AU2.decode(w),$]}function BU2(A,Q,B){if(Q===0)return[[],1];let[w,$]=qP(A,Q,B),f=$,I=[];for(let D=0;D<w;D++){if(A.byteLength-B-f<=0)throw Error("array is not supported or well formed");let[Y,J]=RV(A,B+f);I.push(Y),f+=J}return[I,f]}var $AA="Map is not supported or well formed";function wU2(A,Q,B){if(Q===0)return[new Map,1];let[w,$]=qP(A,Q,B),f=$,I=new Map;for(let D=0;D<w;D++){let U=A.byteLength-B-f;if(U<=0)throw Error($AA);let[Y,J]=RV(A,B+f);if(f+=J,U-=J,U<=0)throw Error($AA);if(typeof Y!=="string"&&typeof Y!=="number")throw Error($AA);if(I.has(Y))throw Error($AA);let[X,G]=RV(A,B+f);f+=G,I.set(Y,X)}return[I,f]}function $U2(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 fU2(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 IU2(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 DU2(A,Q,B){let[w,$]=qP(A,Q,B),[f,I]=RV(A,B+$);return[new fAA(w,f),$+I]}function RV(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 wAA:return vZ0(A,$,Q);case Hh:return eD2(A,$,Q);case RzA:return TZ0(A,$,Q);case bzA:return QU2(A,$,Q);case PzA:return BU2(A,$,Q);case kzA:return wU2(A,$,Q);case jzA:return DU2(A,$,Q);case _Z0: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 $U2(A,Q);case 26:return fU2(A,Q);case 27:return IU2(A,Q)}}throw Error(`Unsupported or not well formed at ${Q}`)}function UU2(A){if(A===!0)return 245;else if(A===!1)return 244;else if(A===null)return 246;return 247}function YU2(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 JU2(A){if(typeof A=="number"){if(Number.isSafeInteger(A))if(A<0)return VW(Hh,Math.abs(A));else return VW(wAA,A);return[YU2(A)]}else if(A<0n)return VW(Hh,A*-1n);else return VW(wAA,A)}var XU2=new TextEncoder;function WU2(A,Q){Q.push(...VW(bzA,A.length)),Q.push(XU2.encode(A))}function HU2(A,Q){Q.push(...VW(RzA,A.length)),Q.push(A)}function GU2(A,Q){Q.push(...VW(PzA,A.length));for(let B of A)Gh(B,Q)}function KU2(A,Q){Q.push(new Uint8Array(VW(kzA,A.size)));for(let[B,w]of A.entries())Gh(B,Q),Gh(w,Q)}function FU2(A,Q){Q.push(...VW(jzA,A.tag)),Gh(A.value,Q)}function Gh(A,Q){if(typeof A=="boolean"||A===null||A==null){Q.push(UU2(A));return}if(typeof A=="number"||typeof A=="bigint"){Q.push(...JU2(A));return}if(typeof A=="string"){WU2(A,Q);return}if(A instanceof Uint8Array){HU2(A,Q);return}if(Array.isArray(A)){GU2(A,Q);return}if(A instanceof Map){KU2(A,Q);return}if(A instanceof fAA){FU2(A,Q);return}throw Error("Not implemented")}function _zA(A,Q){if(A.byteLength===0||A.byteLength<=Q||Q<0)throw Error("No data");if(A instanceof Uint8Array)return RV(new DataView(A.buffer),Q);else if(A instanceof ArrayBuffer)return RV(new DataView(A),Q);return RV(A,Q)}function vzA(A){let Q=[];Gh(A,Q);let B=0;for(let f of Q)if(typeof f=="number")B+=1;else B+=f.length;let w=new Uint8Array(B),$=0;for(let f of Q)if(typeof f=="number")w[$]=f,$+=1;else w.set(f,$),$+=f.length;return w}function NU2(A){let Q=new Uint8Array(A),B=_zA(Q,0),[w]=B;return w}function zU2(A){return vzA(A)}var MW={};SB(MW,{verify:()=>KL0,getRandomValues:()=>hZ0,digest:()=>gZ0});function yZ0(A){let Q=A.get(d2.kty);return TzA(Q)&&Q===gI.OKP}function lN(A){let Q=A.get(d2.kty);return TzA(Q)&&Q===gI.EC2}function LP(A){let Q=A.get(d2.kty);return TzA(Q)&&Q===gI.RSA}var d2;(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"})(d2||(d2={}));var gI;(function(A){A[A.OKP=1]="OKP",A[A.EC2=2]="EC2",A[A.RSA=3]="RSA"})(gI||(gI={}));function TzA(A){return Object.values(gI).indexOf(A)>=0}var C7;(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"})(C7||(C7={}));function xZ0(A){return Object.values(C7).indexOf(A)>=0}var EQ;(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"})(EQ||(EQ={}));function EW(A){return Object.values(EQ).indexOf(A)>=0}function pN(A){if([EQ.RS1].indexOf(A)>=0)return"SHA-1";else if([EQ.ES256,EQ.PS256,EQ.RS256].indexOf(A)>=0)return"SHA-256";else if([EQ.ES384,EQ.PS384,EQ.RS384].indexOf(A)>=0)return"SHA-384";else if([EQ.ES512,EQ.PS512,EQ.RS512,EQ.EdDSA].indexOf(A)>=0)return"SHA-512";throw Error(`Could not map COSE alg value of ${A} to a WebCrypto alg`)}var Kh=void 0;function Ff(){return new Promise((Q,B)=>{if(Kh)return Q(Kh);let w=LU2.stubThisGlobalThisCrypto();if(w)return Kh=w,Q(Kh);return B(new SZ0)})}class SZ0 extends Error{constructor(){super("An instance of the Crypto API could not be located");this.name="MissingWebCrypto"}}var LU2={stubThisGlobalThisCrypto:()=>globalThis.crypto,setCachedCrypto:(A)=>{Kh=A}};async function gZ0(A,Q){let B=await Ff(),w=pN(Q),$=await B.subtle.digest(w,A);return new Uint8Array($)}async function hZ0(A){return(await Ff()).getRandomValues(A),A}async function VP(A){let Q=await Ff(),{keyData:B,algorithm:w}=A;return Q.subtle.importKey("jwk",B,w,!1,["verify"])}async function IAA(A){let{cosePublicKey:Q,signature:B,data:w,shaHashOverride:$}=A,f=await Ff(),I=Q.get(d2.alg),D=Q.get(d2.crv),U=Q.get(d2.x),Y=Q.get(d2.y);if(!I)throw Error("Public key was missing alg (EC2)");if(!D)throw Error("Public key was missing crv (EC2)");if(!U)throw Error("Public key was missing x (EC2)");if(!Y)throw Error("Public key was missing y (EC2)");let J;if(D===C7.P256)J="P-256";else if(D===C7.P384)J="P-384";else if(D===C7.P521)J="P-521";else throw Error(`Unexpected COSE crv value of ${D} (EC2)`);let X={kty:"EC",crv:J,x:s2.fromBuffer(U),y:s2.fromBuffer(Y),ext:!1},Z=await VP({keyData:X,algorithm:{name:"ECDSA",namedCurve:J}}),N=pN(I);if($)N=pN($);let L={name:"ECDSA",hash:{name:N}};return f.subtle.verify(L,Z,B,w)}function yzA(A){if([EQ.EdDSA].indexOf(A)>=0)return"Ed25519";else if([EQ.ES256,EQ.ES384,EQ.ES512,EQ.ES256K].indexOf(A)>=0)return"ECDSA";else if([EQ.RS256,EQ.RS384,EQ.RS512,EQ.RS1].indexOf(A)>=0)return"RSASSA-PKCS1-v1_5";else if([EQ.PS256,EQ.PS384,EQ.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 DAA(A){let{cosePublicKey:Q,signature:B,data:w,shaHashOverride:$}=A,f=await Ff(),I=Q.get(d2.alg),D=Q.get(d2.n),U=Q.get(d2.e);if(!I)throw Error("Public key was missing alg (RSA)");if(!EW(I))throw Error(`Public key had invalid alg ${I} (RSA)`);if(!D)throw Error("Public key was missing n (RSA)");if(!U)throw Error("Public key was missing e (RSA)");let Y={kty:"RSA",alg:"",n:s2.fromBuffer(D),e:s2.fromBuffer(U),ext:!1},J={name:yzA(I),hash:{name:pN(I)}},X={name:yzA(I)};if($)J.hash.name=pN($);if(J.name==="RSASSA-PKCS1-v1_5"){if(J.hash.name==="SHA-256")Y.alg="RS256";else if(J.hash.name==="SHA-384")Y.alg="RS384";else if(J.hash.name==="SHA-512")Y.alg="RS512";else if(J.hash.name==="SHA-1")Y.alg="RS1"}else if(J.name==="RSA-PSS"){let Z=0;if(J.hash.name==="SHA-256")Y.alg="PS256",Z=32;else if(J.hash.name==="SHA-384")Y.alg="PS384",Z=48;else if(J.hash.name==="SHA-512")Y.alg="PS512",Z=64;X.saltLength=Z}else throw Error(`Unexpected RSA key algorithm ${I} (${J.name})`);let G=await VP({keyData:Y,algorithm:J});return f.subtle.verify(X,G,B,w)}function UAA(A){let Q=G2.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 p5(A){let Q;if(typeof A==="string")if(s2.isBase64URL(A))Q=s2.toBase64(A);else if(s2.isBase64(A))Q=A;else throw Error("Certificate is not a valid base64 or base64url string");else Q=s2.fromBuffer(A,"base64");let B="";for(let w=0;w<Math.ceil(Q.length/64);w+=1){let $=64*w;B+=`${Q.substr($,64)}
|
|
@@ -2393,8 +2393,8 @@ ${M}`)}if(w!==void 0&&f?.algorithms!==void 0){let V=f.algorithms.map((M)=>M.alg)
|
|
|
2393
2393
|
</form>
|
|
2394
2394
|
</main>
|
|
2395
2395
|
</body>
|
|
2396
|
-
</html>`}function Au(A){let Q=`${new URL(A.url).pathname}${new URL(A.url).search}`;return new Response(sVA(Q,"Operator login required"),{status:401,headers:{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store"}})}function hW(A){return A.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""")}import{randomUUID as eX2}from"crypto";function bV0(A){return Buffer.from(JSON.stringify(A)).toString("base64url")}function tX2(A){let Q=new Uint8Array(A);if(Q.length===64)return Q;if(Q[0]!==48)return Q;let B=2;if(Q[1]&&Q[1]>128)B+=Q[1]-128;if(Q[B]!==2)throw Error("Invalid DER ECDSA signature");let w=Q[B+1];if(w===void 0)throw Error("Invalid DER ECDSA signature");let $=B+2,f=Q.slice($,$+w);if(B=$+w,Q[B]!==2)throw Error("Invalid DER ECDSA signature");let I=Q[B+1];if(I===void 0)throw Error("Invalid DER ECDSA signature");let D=B+2,U=Q.slice(D,D+I);return new Uint8Array([...PV0(f),...PV0(U)])}function PV0(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 tVA(A,Q){let B={typ:"JWT",alg:"ES256",kid:A.kid},w=`${bV0(B)}.${bV0(Q)}`,$=await crypto.subtle.importKey("jwk",A,{name:"ECDSA",namedCurve:"P-256"},!1,["sign"]),f=await crypto.subtle.sign({name:"ECDSA",hash:"SHA-256"},$,new TextEncoder().encode(w));return`${w}.${Buffer.from(tX2(f)).toString("base64url")}`}var AW2=600;class eVA{clientStore;authCodeStore;refreshTokenStore;sessionStore;keyStore;authorizationApprovalTokens=new Map;constructor(A){this.clientStore=A.clientStore,this.authCodeStore=A.authCodeStore,this.refreshTokenStore=A.refreshTokenStore,this.sessionStore=A.sessionStore,this.keyStore=A.keyStore}async handleAuthorizePage(A){let Q=await this.sessionStore.getSessionFromRequest(A);if(!Q)return Au(A);let B=await this.validateAuthorizationRequest(new URL(A.url).searchParams);if(!B.success)return new Response(B.error,{status:400});let w=this.createAuthorizationApprovalToken(Q,B.params);return ck(RV0(B.params,w))}async handleAuthorizeApproval(A){let Q=await this.sessionStore.getSessionFromRequest(A);if(!Q)return Au(A);let B=await A.formData(),w=await this.validateAuthorizationRequest(new URLSearchParams(rVA(B)));if(!w.success)return new Response(w.error,{status:400});let $=B.get("approval_token"),f=typeof $==="string"?$:void 0;if(!f||!this.consumeAuthorizationApprovalToken(f,Q,w.params))return new Response("Invalid authorization approval token",{status:400});let I=await this.authCodeStore.createCode({clientId:w.params.clientId,redirectUri:w.params.redirectUri,codeChallenge:w.params.codeChallenge,...w.params.scope?{scope:w.params.scope}:{},subject:Q.subject}),D=new URL(w.params.redirectUri);if(D.searchParams.set("code",I.code),w.params.state)D.searchParams.set("state",w.params.state);return Response.redirect(D.toString(),302)}createAuthorizationApprovalToken(A,Q){this.pruneExpiredAuthorizationApprovalTokens();let B=`oat_${eX2()}`;return this.authorizationApprovalTokens.set(B,{token:B,sessionId:A.id,clientId:Q.clientId,redirectUri:Q.redirectUri,codeChallenge:Q.codeChallenge,...Q.scope?{scope:Q.scope}:{},...Q.state?{state:Q.state}:{},expiresAt:Math.floor(Date.now()/1000)+AW2}),B}consumeAuthorizationApprovalToken(A,Q,B){this.pruneExpiredAuthorizationApprovalTokens();let w=this.authorizationApprovalTokens.get(A);if(!w)return!1;return this.authorizationApprovalTokens.delete(A),w.sessionId===Q.id&&w.clientId===B.clientId&&w.redirectUri===B.redirectUri&&w.codeChallenge===B.codeChallenge&&w.scope===B.scope&&w.state===B.state}pruneExpiredAuthorizationApprovalTokens(){let A=Math.floor(Date.now()/1000);for(let[Q,B]of this.authorizationApprovalTokens.entries())if(B.expiresAt<=A)this.authorizationApprovalTokens.delete(Q)}async validateAuthorizationRequest(A){let Q=A.get("response_type"),B=A.get("client_id"),w=A.get("redirect_uri"),$=A.get("code_challenge"),f=A.get("code_challenge_method"),I=A.get("scope")??void 0,D=A.get("state")??void 0;if(Q!=="code")return{success:!1,error:"Unsupported response_type"};if(!B)return{success:!1,error:"Missing client_id"};if(!w)return{success:!1,error:"Missing redirect_uri"};if(!$)return{success:!1,error:"Missing code_challenge"};if(f!=="S256")return{success:!1,error:"Unsupported code_challenge_method"};let U=await this.clientStore.getClient(B);if(!U)return{success:!1,error:"Unknown client_id"};if(!OzA(U.redirect_uris,w))return{success:!1,error:"Unregistered redirect_uri"};let Y=I??U.scope;return{success:!0,params:{clientId:B,redirectUri:w,codeChallenge:$,...Y?{scope:Y}:{},...D?{state:D}:{},clientName:U.client_name??U.client_id}}}async handleClientRegistration(A){let Q;try{Q=await A.json()}catch{return N6("invalid_client_metadata","Request body must be JSON")}try{let B=await this.clientStore.registerClient(Q);return rI(B,201)}catch(B){if(B instanceof Wh)return N6("invalid_client_metadata",B.message);throw B}}async handleTokenRequest(A,Q){let B=await iVA(A),w=B.get("grant_type"),$=nVA(A,B),f=$.clientId??B.get("client_id");if($.error)return N6("invalid_client",$.error);if(!f)return N6("invalid_request","client_id is required");let I=await this.clientStore.getClient(f),D=dVA(I,$);if(D)return N6("invalid_client",D);if(w==="authorization_code")return this.handleAuthorizationCodeGrant(B,f,Q);if(w==="refresh_token")return this.handleRefreshTokenGrant(B,f,Q);return N6("unsupported_grant_type","Only authorization_code and refresh_token are supported")}async handleAuthorizationCodeGrant(A,Q,B){let w=A.get("code"),$=A.get("redirect_uri"),f=A.get("code_verifier");if(!w||!$||!f)return N6("invalid_request","code, redirect_uri, and code_verifier are required");let I=await this.clientStore.getClient(Q);if(!I||!OzA(I.redirect_uris,$))return N6("invalid_grant","Unregistered redirect_uri");try{let D=await this.authCodeStore.consumeCode({code:w,clientId:Q,redirectUri:$,codeVerifier:f});return await this.createTokenResponse({issuer:B,clientId:Q,subject:D.subject,...D.scope?{scope:D.scope}:{}})}catch(D){if(D instanceof HJ)return N6("invalid_grant",D.message);throw D}}async handleRefreshTokenGrant(A,Q,B){let w=A.get("refresh_token");if(!w)return N6("invalid_request","refresh_token is required");try{let $=await this.refreshTokenStore.rotateToken(w,Q);return await this.createTokenResponse({issuer:B,clientId:Q,subject:$.consumed.subject,...$.consumed.scope?{scope:$.consumed.scope}:{},refreshToken:$.replacement.token})}catch($){if($ instanceof uK)return N6("invalid_grant",$.message);throw $}}async createTokenResponse(A){let Q=Math.floor(Date.now()/1000),B=900,w=await tVA(await this.keyStore.getPrivateJwk(),{iss:A.issuer,sub:A.subject,aud:A.clientId,iat:Q,exp:Q+900,...A.scope?{scope:A.scope}:{}}),$=A.refreshToken??(await this.refreshTokenStore.issueToken({clientId:A.clientId,subject:A.subject,...A.scope?{scope:A.scope}:{}})).token;return rI({access_token:w,token_type:"Bearer",expires_in:900,...A.scope?{scope:A.scope}:{},refresh_token:$})}async handleRevokeRequest(A){let Q=await iVA(A),B=nVA(A,Q),w=B.clientId??Q.get("client_id")??void 0,$=Q.get("token");if(B.error)return N6("invalid_client",B.error);if(!$)return N6("invalid_request","token is required");if(w){let f=await this.clientStore.getClient(w),I=dVA(f,B);if(I)return N6("invalid_client",I)}return await this.refreshTokenStore.revokeToken($,w),new Response(null,{status:200})}}class AEA{passkeyService;sessionStore;setupFlow;constructor(A){this.passkeyService=A.passkeyService,this.sessionStore=A.sessionStore,this.setupFlow=A.setupFlow}async handleRegistrationOptions(A){if(await this.passkeyService.hasCredentials())return N6("access_denied","Passkey setup already completed");if(!this.setupFlow.hasValidSetupToken(A))return N6("access_denied","Invalid setup token");let Q=await this.passkeyService.generateRegistrationOptions(m0A(A));return rI(Q)}async handleRegistrationVerify(A){if(await this.passkeyService.hasCredentials())return N6("access_denied","Passkey setup already completed");if(!this.setupFlow.hasValidSetupToken(A))return N6("access_denied","Invalid setup token");let Q=await this.passkeyService.verifyRegistrationResponse(await A.json(),m0A(A));if(!Q.verified)return N6("access_denied","Passkey registration failed");await this.setupFlow.clearSetupState();let B=await this.sessionStore.createSession(Q.subject??"single-operator",{secure:sm(A)});return rI({verified:!0},200,{"Set-Cookie":B.cookie})}async handleAuthenticationOptions(A){if(!await this.passkeyService.hasCredentials())return N6("access_denied","No passkey registered");let Q=await this.passkeyService.generateAuthenticationOptions(m0A(A));return rI(Q)}async handleAuthenticationVerify(A){let Q=await this.passkeyService.verifyAuthenticationResponse(await A.json(),m0A(A));if(!Q.verified)return N6("access_denied","Passkey authentication failed");let B=await this.sessionStore.createSession(Q.subject??"single-operator",{secure:sm(A)});return rI({verified:!0},200,{"Set-Cookie":B.cookie})}}function m0A(A){let Q=yk(A),B=new URL(Q);return{origin:B.origin,rpID:B.hostname}}import{randomUUID as QW2}from"crypto";var BW2=1800;class QEA{setupStateStore;passkeyService;setupToken;constructor(A){this.setupStateStore=A.setupStateStore,this.passkeyService=A.passkeyService}async ensureSetupToken(){let A=this.getValidSetupToken();if(A)return A;let Q=await this.setupStateStore.getValidSetupToken(Math.floor(Date.now()/1000));if(Q)return this.setupToken=Q,Q;return this.createSetupToken()}async createSetupToken(){return this.setupToken={token:`setup_${QW2()}`,expiresAt:Math.floor(Date.now()/1000)+BW2},await this.setupStateStore.saveSetupToken(this.setupToken),this.setupToken}getValidSetupToken(){if(!this.setupToken)return;if(this.setupToken.expiresAt<=Math.floor(Date.now()/1000)){this.setupToken=void 0;return}return this.setupToken}hasValidSetupToken(A){let Q=this.getValidSetupToken();if(!Q)return!1;let B=new URL(A.url);return(B.searchParams.get("setup_token")??B.searchParams.get("token"))===Q.token}async clearSetupState(){this.setupToken=void 0,await this.setupStateStore.clearSetupState()}getSetupUrl(A){let Q=this.getValidSetupToken();if(!Q)return;return gW(A,`/setup?token=${encodeURIComponent(Q.token)}`)}async getOperatorSetupRequired(A){if(await this.passkeyService.hasCredentials())return;let Q=this.getValidSetupToken();if(!Q)return;return{setupUrl:gW(A,`/setup?token=${encodeURIComponent(Q.token)}`),expiresAt:Q.expiresAt,setupTokenId:MVA(Q.token)}}async handleSetupPage(A){if(await this.passkeyService.hasCredentials())return new Response("Setup already completed",{status:404});if(!this.hasValidSetupToken(A))return new Response("Not Found",{status:404});let Q=new URL(A.url).searchParams.get("token")??"";return ck(CV0(Q))}async hasSetupEmailDelivery(A,Q){return this.setupStateStore.hasDelivery(A,Q)}async recordSetupEmailDelivery(A,Q,B={}){await this.setupStateStore.recordDelivery(A,Q,B)}}class u0A{issuer;trustedIssuers;allowLocalhostIssuers;keyStore;clientStore;authCodeStore;sessionStore;passkeyService;setupFlow;oauthEndpoints;webauthnEndpoints;logger;constructor(A){this.issuer=MJ(A.issuer),this.trustedIssuers=new Set([this.issuer,...(A.trustedIssuers??[]).map((Q)=>MJ(Q))]),this.allowLocalhostIssuers=A.allowLocalhostIssuers??Tk(this.issuer),this.keyStore=new BAA({storageDir:A.storageDir}),this.clientStore=new QAA({storageDir:A.storageDir}),this.authCodeStore=new AAA({storageDir:A.storageDir}),this.sessionStore=new y0A({storageDir:A.storageDir}),this.passkeyService=new k0A({storageDir:A.storageDir,...A.logger?{logger:A.logger}:{}}),this.setupFlow=new QEA({setupStateStore:new CVA({storageDir:A.storageDir}),passkeyService:this.passkeyService}),this.oauthEndpoints=new eVA({clientStore:this.clientStore,authCodeStore:this.authCodeStore,refreshTokenStore:new _0A({storageDir:A.storageDir}),sessionStore:this.sessionStore,keyStore:this.keyStore}),this.webauthnEndpoints=new AEA({passkeyService:this.passkeyService,sessionStore:this.sessionStore,setupFlow:this.setupFlow}),this.logger=A.logger}getIssuer(){return this.issuer}async initialize(){if(await this.keyStore.getPrivateJwk(),this.logger?.debug("Auth service signing key loaded"),!await this.hasPasskeyCredentials()){await this.setupFlow.ensureSetupToken();let A=this.getSetupUrl();if(A)if(Tk(this.issuer))this.logger?.warn(`Passkey setup required: ${A}`);else this.logger?.warn("Passkey setup required. Ask through an anchor-visible interface for the setup URL.")}}async hasPasskeyCredentials(){return this.passkeyService.hasCredentials()}async getJwks(){return{keys:[await this.keyStore.getPublicJwk()]}}getAuthorizationServerMetadata(A=this.issuer){let Q=MJ(A);return{issuer:Q,authorization_endpoint:gW(Q,"/authorize"),token_endpoint:gW(Q,"/token"),registration_endpoint:gW(Q,"/register"),revocation_endpoint:gW(Q,"/revoke"),jwks_uri:gW(Q,"/.well-known/jwks.json"),response_types_supported:["code"],grant_types_supported:["authorization_code","refresh_token"],code_challenge_methods_supported:["S256"],token_endpoint_auth_methods_supported:["none","client_secret_basic","client_secret_post"],scopes_supported:["openid","profile","email","offline_access","mcp"],subject_types_supported:["public"],id_token_signing_alg_values_supported:["ES256"]}}getProtectedResourceMetadata(A,Q=this.issuer){return{resource:A,authorization_servers:[MJ(Q)],bearer_methods_supported:["header"],resource_signing_alg_values_supported:["ES256"],scopes_supported:["mcp"]}}async registerClient(A){return this.clientStore.registerClient(A)}async getRegisteredClient(A){return this.clientStore.getClient(A)}async createOperatorSession(A="single-operator",Q={}){return this.sessionStore.createSession(A,Q)}async getOperatorSession(A){return this.sessionStore.getSessionFromRequest(A)}createOperatorLoginResponse(A){return Au(A)}async verifyBearerToken(A,Q={}){let B=pVA(A);if(!B)return;let w=Q.issuer?MJ(Q.issuer):this.resolveRequestIssuer(A);return lVA(B,await this.getJwks(),{issuer:w,...Q.audience?{audience:Q.audience}:{}})}getSetupUrl(A=this.issuer){return this.setupFlow.getSetupUrl(A)}async getOperatorSetupRequired(A=this.issuer){return this.setupFlow.getOperatorSetupRequired(A)}async hasSetupEmailDelivery(A,Q){return this.setupFlow.hasSetupEmailDelivery(A,Q)}async recordSetupEmailDelivery(A,Q,B={}){await this.setupFlow.recordSetupEmailDelivery(A,Q,B)}async handleRequest(A){let Q;try{Q=this.resolveRequestIssuer(A)}catch(w){return this.logger?.warn("Rejected OAuth request from untrusted issuer",{error:w instanceof Error?w.message:String(w)}),new Response("Untrusted OAuth issuer",{status:400})}let B=new URL(A.url).pathname;if(A.method==="OPTIONS"&&VV0(B))return EV0();if(A.method==="GET"){if(B==="/.well-known/oauth-authorization-server")return z3(rI(this.getAuthorizationServerMetadata(Q)));if(B==="/.well-known/jwks.json")return z3(rI(await this.getJwks()));if(B==="/.well-known/oauth-protected-resource")return z3(rI(this.getProtectedResourceMetadata(Q,Q)))}if(A.method==="GET"&&B==="/setup")return this.setupFlow.handleSetupPage(A);if(A.method==="GET"&&B==="/login")return this.handleLoginPage(A);if((A.method==="GET"||A.method==="POST")&&B==="/logout")return this.handleLogout(A);if(A.method==="POST"&&B==="/webauthn/register/options")return this.webauthnEndpoints.handleRegistrationOptions(A);if(A.method==="POST"&&B==="/webauthn/register/verify")return this.webauthnEndpoints.handleRegistrationVerify(A);if(A.method==="POST"&&B==="/webauthn/auth/options")return this.webauthnEndpoints.handleAuthenticationOptions(A);if(A.method==="POST"&&B==="/webauthn/auth/verify")return this.webauthnEndpoints.handleAuthenticationVerify(A);if(A.method==="GET"&&B==="/authorize")return this.oauthEndpoints.handleAuthorizePage(A);if(A.method==="POST"&&B==="/authorize")return this.oauthEndpoints.handleAuthorizeApproval(A);if(A.method==="POST"&&B==="/register")return z3(await this.oauthEndpoints.handleClientRegistration(A));if(A.method==="POST"&&B==="/token")return z3(await this.oauthEndpoints.handleTokenRequest(A,Q));if(A.method==="POST"&&B==="/revoke")return z3(await this.oauthEndpoints.handleRevokeRequest(A));return new Response("Not Found",{status:404})}async handleWellKnownRequest(A){return this.handleRequest(A)}resolveRequestIssuer(A){let Q=yk(A,this.issuer);if(this.trustedIssuers.has(Q)||this.allowLocalhostIssuers&&Tk(Q))return Q;throw Error(`Request issuer ${Q} is not in trusted issuers`)}handleLoginPage(A){let Q=oVA(new URL(A.url).searchParams.get("return_to"));return ck(sVA(Q))}async handleLogout(A){await this.sessionStore.revokeSessionFromRequest(A);let Q=oVA(new URL(A.url).searchParams.get("return_to"));return new Response(null,{status:302,headers:{Location:Q,"Set-Cookie":bVA(sm(A)),"Cache-Control":"no-store"}})}}WA();var c0A="email:send",kV0=H.object({to:H.string().email(),subject:H.string().min(1),text:H.string().min(1),html:H.string().min(1).optional(),sensitivity:H.enum(["normal","secret"]).default("normal")}).strict();aA();WA();var jV0={name:"@brains/notifications",private:!0,version:"0.2.0-alpha.119",description:"Generic notification routing for transactional and administrative messages",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint src test --ext .ts","lint:fix":"eslint src test --ext .ts --fix"},dependencies:{"@brains/email-contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var BEA="notifications:send",$W2=H.object({}),fW2=H.discriminatedUnion("type",[H.object({type:H.literal("email"),address:H.string().email()}).strict()]),IW2=H.object({recipient:fW2,title:H.string().min(1),body:H.string().min(1),html:H.string().min(1).optional(),sensitivity:H.enum(["normal","secret"]).default("normal")}).strict(),_V0=H.discriminatedUnion("status",[H.object({status:H.literal("sent"),deliveryId:H.string().optional()}).strict(),H.object({status:H.literal("failed")}).strict()]);class vV0 extends YB{constructor(A={}){super("notifications",jV0,A,$W2)}async onRegister(A){A.messaging.subscribe(BEA,async(Q)=>{let B=IW2.parse(Q.payload),w={to:B.recipient.address,subject:B.title,text:B.body,...B.html?{html:B.html}:{},sensitivity:B.sensitivity},$=await A.messaging.send({type:c0A,payload:w});if(!("success"in $)||!$.success||!$.data)return{success:!1,error:"Notification delivery failed"};let f=$.data;if(f.status!=="sent")return{success:!1,error:"Notification delivery failed"};return{success:!0,data:f.id?{status:"sent",deliveryId:f.id}:{status:"sent"}}})}}function l0A(A={}){return new vV0(A)}aA();WA();var TV0={name:"@brains/auth-service",private:!0,version:"0.2.0-alpha.119",description:"Embedded OAuth/OIDC auth service for brain operator authentication",type:"module",main:"./src/index.ts",types:"./src/index.ts",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/notifications":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*","@simplewebauthn/server":"^13.3.0",jose:"^6.2.3"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","@types/node":"^20.0.0",typescript:"^5.3.3"},files:["src"]};var UW2=H.union([H.string().email(),H.object({to:H.string().email(),subject:H.string().min(1),body:H.string().min(1)}).strict()]),YW2=H.object({issuer:H.string().optional(),trustedIssuers:H.array(H.string()).default([]),allowLocalhostIssuers:H.boolean().optional(),storageDir:H.string().default("./data/auth"),setupEmail:UW2.optional()}),JW2=H.object({}),p0A;function RU(){return p0A}class wEA extends YB{service;constructor(A={}){super("auth-service",TV0,A,YW2)}async onRegister(A){await super.onRegister(A);let Q=this.config.issuer??(A.preferLocalUrls?A.localSiteUrl??A.siteUrl:A.siteUrl??A.localSiteUrl);this.service=new u0A({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(),p0A=this.service}async onReady(A){await this.requestSetupEmailIfNeeded(A)}async onShutdown(){if(p0A===this.service)p0A=void 0;this.service=void 0}async getTools(){return[oQ(this.id,"get_passkey_setup_url","Get the first-passkey setup URL when operator setup is required. Anchor-only.",JW2,async()=>{let A=this.getService();if(await A.hasPasskeyCredentials())return U8({status:"complete"});let Q=await A.getOperatorSetupRequired();if(Q)return U8({status:"setup_required",setupUrl:Q.setupUrl,expiresAt:Q.expiresAt});return U8({status:"unavailable",reason:"Passkey setup URL is not available."})},{visibility:"anchor"})]}getWebRoutes(){let A=(Q)=>this.getService().handleRequest(Q);return[{path:"/.well-known/oauth-authorization-server",method:"GET",public:!0,handler:A},{path:"/.well-known/oauth-authorization-server",method:"OPTIONS",public:!0,handler:A},{path:"/.well-known/jwks.json",method:"GET",public:!0,handler:A},{path:"/.well-known/jwks.json",method:"OPTIONS",public:!0,handler:A},{path:"/.well-known/oauth-protected-resource",method:"GET",public:!0,handler:A},{path:"/.well-known/oauth-protected-resource",method:"OPTIONS",public:!0,handler:A},{path:"/setup",method:"GET",public:!0,handler:A},{path:"/login",method:"GET",public:!0,handler:A},{path:"/logout",method:"GET",public:!0,handler:A},{path:"/logout",method:"POST",public:!0,handler:A},{path:"/authorize",method:"GET",public:!0,handler:A},{path:"/authorize",method:"POST",public:!0,handler:A},{path:"/register",method:"POST",public:!0,handler:A},{path:"/register",method:"OPTIONS",public:!0,handler:A},{path:"/token",method:"POST",public:!0,handler:A},{path:"/token",method:"OPTIONS",public:!0,handler:A},{path:"/revoke",method:"POST",public:!0,handler:A},{path:"/revoke",method:"OPTIONS",public:!0,handler:A},{path:"/webauthn/register/options",method:"POST",public:!0,handler:A},{path:"/webauthn/register/verify",method:"POST",public:!0,handler:A},{path:"/webauthn/auth/options",method:"POST",public:!0,handler:A},{path:"/webauthn/auth/verify",method:"POST",public:!0,handler:A}]}getService(){if(!this.service)throw Error("AuthServicePlugin has not been registered");return this.service}async requestSetupEmailIfNeeded(A){if(!this.config.setupEmail)return;let Q=this.getService();if(await Q.hasPasskeyCredentials())return;let B=await Q.getOperatorSetupRequired();if(!B)return;let w=XW2(this.config.setupEmail,B);if(await Q.hasSetupEmailDelivery(B.setupTokenId,w.to))return;let $=await A.messaging.send({type:BEA,payload:{recipient:{type:"email",address:w.to},title:w.subject,body:w.body,sensitivity:"secret"}});if(!("success"in $)||!$.success||!$.data){A.logger.warn("Passkey setup email delivery was not confirmed");return}let f=_V0.safeParse($.data);if(!f.success||f.data.status!=="sent"){A.logger.warn("Passkey setup email delivery was not confirmed");return}await Q.recordSetupEmailDelivery(B.setupTokenId,w.to,f.data.deliveryId?{deliveryId:f.data.deliveryId}:{})}}function XW2(A,Q){if(typeof A==="string"){let B=new Date(Q.expiresAt*1000).toISOString(),w=new URL(Q.setupUrl).origin;return{to:A,subject:"Set up your brain passkey",body:["Set up your brain passkey using this single-use link:","",Q.setupUrl,"",`This link expires at ${B}.`,`Dashboard: ${w}/`,`MCP endpoint: ${w}/mcp`,"The first successful passkey registration completes setup and closes this link."].join(`
|
|
2397
|
-
`)}}return{to:A.to,subject:yV0(A.subject,Q),body:yV0(A.body,Q)}}function yV0(A,Q){let B=new Date(Q.expiresAt*1000).toISOString(),w=new URL(Q.setupUrl).origin;return A.replaceAll("{{setupUrl}}",Q.setupUrl).replaceAll("{{expiresAt}}",B).replaceAll("{{origin}}",w)}function Qu(A){return new wEA(A)}WA();var $EA=H.object({transport:H.enum(["stdio","http"]).default("http"),httpPort:H.number().describe("Port for HTTP transport (only used when transport is 'http')").default(3333),authToken:H.string().describe("Bearer token for HTTP transport authentication").optional()});function xV0(A,Q){return[]}aA();function fEA(A,Q){A.messaging.subscribe("job-progress",async(B)=>{let w=FR.safeParse(B.payload);if(!w.success)return Q.warn("Received invalid job-progress message",{error:w.error.message}),{success:!1};let $=w.data,f=$.type,I=$.status,D=$.id;if(Q.debug(`${f} ${D} - ${I}:`,{id:$.id,message:$.message,progress:$.progress,metadata:$.metadata}),$.batchDetails)Q.debug(`Batch details for ${D}:`,{totalOperations:$.batchDetails.totalOperations,completedOperations:$.batchDetails.completedOperations,failedOperations:$.batchDetails.failedOperations,currentOperation:$.batchDetails.currentOperation,errors:$.batchDetails.errors});if($.jobDetails)Q.debug(`Job details for ${D}:`,{jobType:$.jobDetails.jobType,priority:$.jobDetails.priority,retryCount:$.jobDetails.retryCount});return{success:!0}}),Q.debug("Subscribed to job progress events")}var SV0={name:"@brains/mcp",private:!0,version:"0.2.0-alpha.119",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 q3 extends eX{mcpTransport;stdioServer;httpServer;domain;constructor(A={}){let Q={...A,authToken:A.authToken??process.env.MCP_AUTH_TOKEN};super("mcp",SV0,Q,$EA)}async getTools(){return xV0(this.id,()=>this.context)}async getResources(){return[]}async onRegister(A){if(this.domain=A.domain,this.config.transport==="http"&&!A.plugins.has("webserver"))throw Error("MCP HTTP transport requires the webserver interface. Standalone HTTP listeners have been removed.");if(this.logger.debug(`MCP interface initialized with ${this.config.transport} transport`),this.config.transport==="http")A.endpoints.register({label:"MCP",url:"/mcp",priority:30,visibility:"trusted"}),A.interactions.register({id:"mcp",label:"MCP",description:"Connect a trusted client through the Model Context Protocol.",href:"/mcp",kind:"protocol",priority:30,visibility:"trusted"});fEA(A,this.logger)}getOrCreateHttpServer(){if(this.httpServer)return this.httpServer;let A=RU();return this.httpServer=ZK.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||RU()))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=WJ.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(){WJ.resetInstance(),ZK.resetInstance()}}aA();WA();var eI=U1(Re0(),1);WA();aA();var mPA=H.object({botToken:H.string().min(1).describe("Discord bot token"),allowedChannels:H.array(H.string()).default([]),requireMention:H.boolean().default(!0),allowDMs:H.boolean().default(!0),showTypingIndicator:H.boolean().default(!0),statusMessage:H.string().default("Mention me to chat"),useThreads:H.boolean().default(!0),threadAutoArchive:H.union([H.literal(60),H.literal(1440),H.literal(4320),H.literal(10080)]).default(1440),...yx.shape,captureUrlEmoji:H.string().default("\uD83D\uDD16")});var be0={name:"@brains/discord",private:!0,version:"0.2.0-alpha.119",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 dQA=2000,Rd2=8000,bd2=100;function nQA(A){return!!A&&typeof A==="object"&&"send"in A&&"sendTyping"in A}class Qz extends iG{client=null;fetchText;pendingConfirmations=new Map;typingIntervals=new Map;constructor(A,Q={}){super("discord",be0,A,mPA);this.fetchText=Q.fetchText??Ao}async onRegister(A){await super.onRegister(A),this.client=new eI.Client({intents:[eI.GatewayIntentBits.Guilds,eI.GatewayIntentBits.GuildMessages,eI.GatewayIntentBits.MessageContent,eI.GatewayIntentBits.DirectMessages],partials:[eI.Partials.Channel]}),this.client.on(eI.Events.MessageCreate,(Q)=>{this.handleMessage(Q)}),this.client.on(eI.Events.InteractionCreate,(Q)=>{this.handleInteraction(Q)}),this.client.once(eI.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(!nQA(B))return;let w=uy(Q,dQA);for(let $ of w)B.send($).catch((f)=>this.logger.error("Failed to send message",{error:f}))}async sendMessageWithId({channelId:A,message:Q,approvalCard:B,approvalCards:w}){let $=w??(B?[B]:[]),f=$.length>0?this.buildApprovalMessagePayload(Q,$):Q;return this.sendPayloadWithId(A,f)}async sendPayloadWithId(A,Q){if(!A||!this.client)return;let B=this.client.channels.cache.get(A);if(!nQA(B))return;if(typeof Q!=="string")return(await B.send(Q)).id;let w=uy(Q,dQA),$;for(let f of w)$=(await B.send(f)).id;return $}async editMessage({channelId:A,messageId:Q,newMessage:B}){if(!A||!this.client)return!1;let w=this.client.channels.cache.get(A);if(!nQA(w))return!1;try{return await(await w.messages.fetch(Q)).edit(B.slice(0,dQA)),!0}catch{return!1}}supportsMessageEditing(){return!0}async handleMessage(A){if(A.author.id===this.client?.user?.id)return;if(!this.context)return;let Q=!A.guild,B=A.channel.isThread();if(Q&&!this.config.allowDMs)return;let w=!!this.client?.user&&A.mentions.has(this.client.user,{ignoreEveryone:!0});if(A.author.bot&&!w)return;let $=B&&"ownerId"in A.channel&&A.channel.ownerId===this.client?.user?.id,f=this.getSpaceChannelId(A),I=!Q&&this.isConfiguredSpace(f),D={channelId:f,isBot:A.author.bot};if(this.config.allowedChannels.length>0&&!Q&&!this.isAllowedChannel(A.channel.id,f))return;let U=Q||$||!this.config.requireMention||w;if(I&&(!U||this.willRouteUseNonSpaceConversation(A)))await this.capturePassiveSpaceMessage(A,f).catch((X)=>this.logger.error("Passive Discord space capture failed",{error:X,channelId:f}));if(!U){if(this.config.captureUrls){let X=this.extractCaptureableUrls(A.content,this.config.blockedUrlDomains);if(X.length>0){await A.react(this.config.captureUrlEmoji).catch((G)=>this.logger.debug("React failed",{error:G}));for(let G of X)await this.captureUrlViaAgent(G,A.channel.id,A.author.id,"discord",D).catch((Z)=>this.logger.error("URL capture failed",{error:Z,url:G}))}}return}let Y=this.stripMention(A.content);if(A.attachments.size>0){let X=this.context.permissions.getUserLevel("discord",A.author.id,D);if(X==="anchor"||X==="trusted")for(let Z of A.attachments.values()){let N=Z.name,L=Z.contentType??void 0,V=Z.size;if(!this.isUploadableTextFile(N,L))continue;if(!this.isFileSizeAllowed(V))continue;try{let M=await this.fetchText(Z.url);Y+=`
|
|
2396
|
+
</html>`}function Au(A){let Q=`${new URL(A.url).pathname}${new URL(A.url).search}`;return new Response(sVA(Q,"Operator login required"),{status:401,headers:{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store"}})}function hW(A){return A.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""")}import{randomUUID as eX2}from"crypto";function bV0(A){return Buffer.from(JSON.stringify(A)).toString("base64url")}function tX2(A){let Q=new Uint8Array(A);if(Q.length===64)return Q;if(Q[0]!==48)return Q;let B=2;if(Q[1]&&Q[1]>128)B+=Q[1]-128;if(Q[B]!==2)throw Error("Invalid DER ECDSA signature");let w=Q[B+1];if(w===void 0)throw Error("Invalid DER ECDSA signature");let $=B+2,f=Q.slice($,$+w);if(B=$+w,Q[B]!==2)throw Error("Invalid DER ECDSA signature");let I=Q[B+1];if(I===void 0)throw Error("Invalid DER ECDSA signature");let D=B+2,U=Q.slice(D,D+I);return new Uint8Array([...PV0(f),...PV0(U)])}function PV0(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 tVA(A,Q){let B={typ:"JWT",alg:"ES256",kid:A.kid},w=`${bV0(B)}.${bV0(Q)}`,$=await crypto.subtle.importKey("jwk",A,{name:"ECDSA",namedCurve:"P-256"},!1,["sign"]),f=await crypto.subtle.sign({name:"ECDSA",hash:"SHA-256"},$,new TextEncoder().encode(w));return`${w}.${Buffer.from(tX2(f)).toString("base64url")}`}var AW2=600;class eVA{clientStore;authCodeStore;refreshTokenStore;sessionStore;keyStore;authorizationApprovalTokens=new Map;constructor(A){this.clientStore=A.clientStore,this.authCodeStore=A.authCodeStore,this.refreshTokenStore=A.refreshTokenStore,this.sessionStore=A.sessionStore,this.keyStore=A.keyStore}async handleAuthorizePage(A){let Q=await this.sessionStore.getSessionFromRequest(A);if(!Q)return Au(A);let B=await this.validateAuthorizationRequest(new URL(A.url).searchParams);if(!B.success)return new Response(B.error,{status:400});let w=this.createAuthorizationApprovalToken(Q,B.params);return ck(RV0(B.params,w))}async handleAuthorizeApproval(A){let Q=await this.sessionStore.getSessionFromRequest(A);if(!Q)return Au(A);let B=await A.formData(),w=await this.validateAuthorizationRequest(new URLSearchParams(rVA(B)));if(!w.success)return new Response(w.error,{status:400});let $=B.get("approval_token"),f=typeof $==="string"?$:void 0;if(!f||!this.consumeAuthorizationApprovalToken(f,Q,w.params))return new Response("Invalid authorization approval token",{status:400});let I=await this.authCodeStore.createCode({clientId:w.params.clientId,redirectUri:w.params.redirectUri,codeChallenge:w.params.codeChallenge,...w.params.scope?{scope:w.params.scope}:{},subject:Q.subject}),D=new URL(w.params.redirectUri);if(D.searchParams.set("code",I.code),w.params.state)D.searchParams.set("state",w.params.state);return Response.redirect(D.toString(),302)}createAuthorizationApprovalToken(A,Q){this.pruneExpiredAuthorizationApprovalTokens();let B=`oat_${eX2()}`;return this.authorizationApprovalTokens.set(B,{token:B,sessionId:A.id,clientId:Q.clientId,redirectUri:Q.redirectUri,codeChallenge:Q.codeChallenge,...Q.scope?{scope:Q.scope}:{},...Q.state?{state:Q.state}:{},expiresAt:Math.floor(Date.now()/1000)+AW2}),B}consumeAuthorizationApprovalToken(A,Q,B){this.pruneExpiredAuthorizationApprovalTokens();let w=this.authorizationApprovalTokens.get(A);if(!w)return!1;return this.authorizationApprovalTokens.delete(A),w.sessionId===Q.id&&w.clientId===B.clientId&&w.redirectUri===B.redirectUri&&w.codeChallenge===B.codeChallenge&&w.scope===B.scope&&w.state===B.state}pruneExpiredAuthorizationApprovalTokens(){let A=Math.floor(Date.now()/1000);for(let[Q,B]of this.authorizationApprovalTokens.entries())if(B.expiresAt<=A)this.authorizationApprovalTokens.delete(Q)}async validateAuthorizationRequest(A){let Q=A.get("response_type"),B=A.get("client_id"),w=A.get("redirect_uri"),$=A.get("code_challenge"),f=A.get("code_challenge_method"),I=A.get("scope")??void 0,D=A.get("state")??void 0;if(Q!=="code")return{success:!1,error:"Unsupported response_type"};if(!B)return{success:!1,error:"Missing client_id"};if(!w)return{success:!1,error:"Missing redirect_uri"};if(!$)return{success:!1,error:"Missing code_challenge"};if(f!=="S256")return{success:!1,error:"Unsupported code_challenge_method"};let U=await this.clientStore.getClient(B);if(!U)return{success:!1,error:"Unknown client_id"};if(!OzA(U.redirect_uris,w))return{success:!1,error:"Unregistered redirect_uri"};let Y=I??U.scope;return{success:!0,params:{clientId:B,redirectUri:w,codeChallenge:$,...Y?{scope:Y}:{},...D?{state:D}:{},clientName:U.client_name??U.client_id}}}async handleClientRegistration(A){let Q;try{Q=await A.json()}catch{return N6("invalid_client_metadata","Request body must be JSON")}try{let B=await this.clientStore.registerClient(Q);return rI(B,201)}catch(B){if(B instanceof Wh)return N6("invalid_client_metadata",B.message);throw B}}async handleTokenRequest(A,Q){let B=await iVA(A),w=B.get("grant_type"),$=nVA(A,B),f=$.clientId??B.get("client_id");if($.error)return N6("invalid_client",$.error);if(!f)return N6("invalid_request","client_id is required");let I=await this.clientStore.getClient(f),D=dVA(I,$);if(D)return N6("invalid_client",D);if(w==="authorization_code")return this.handleAuthorizationCodeGrant(B,f,Q);if(w==="refresh_token")return this.handleRefreshTokenGrant(B,f,Q);return N6("unsupported_grant_type","Only authorization_code and refresh_token are supported")}async handleAuthorizationCodeGrant(A,Q,B){let w=A.get("code"),$=A.get("redirect_uri"),f=A.get("code_verifier");if(!w||!$||!f)return N6("invalid_request","code, redirect_uri, and code_verifier are required");let I=await this.clientStore.getClient(Q);if(!I||!OzA(I.redirect_uris,$))return N6("invalid_grant","Unregistered redirect_uri");try{let D=await this.authCodeStore.consumeCode({code:w,clientId:Q,redirectUri:$,codeVerifier:f});return await this.createTokenResponse({issuer:B,clientId:Q,subject:D.subject,...D.scope?{scope:D.scope}:{}})}catch(D){if(D instanceof HJ)return N6("invalid_grant",D.message);throw D}}async handleRefreshTokenGrant(A,Q,B){let w=A.get("refresh_token");if(!w)return N6("invalid_request","refresh_token is required");try{let $=await this.refreshTokenStore.rotateToken(w,Q);return await this.createTokenResponse({issuer:B,clientId:Q,subject:$.consumed.subject,...$.consumed.scope?{scope:$.consumed.scope}:{},refreshToken:$.replacement.token})}catch($){if($ instanceof uK)return N6("invalid_grant",$.message);throw $}}async createTokenResponse(A){let Q=Math.floor(Date.now()/1000),B=900,w=await tVA(await this.keyStore.getPrivateJwk(),{iss:A.issuer,sub:A.subject,aud:A.clientId,iat:Q,exp:Q+900,...A.scope?{scope:A.scope}:{}}),$=A.refreshToken??(await this.refreshTokenStore.issueToken({clientId:A.clientId,subject:A.subject,...A.scope?{scope:A.scope}:{}})).token;return rI({access_token:w,token_type:"Bearer",expires_in:900,...A.scope?{scope:A.scope}:{},refresh_token:$})}async handleRevokeRequest(A){let Q=await iVA(A),B=nVA(A,Q),w=B.clientId??Q.get("client_id")??void 0,$=Q.get("token");if(B.error)return N6("invalid_client",B.error);if(!$)return N6("invalid_request","token is required");if(w){let f=await this.clientStore.getClient(w),I=dVA(f,B);if(I)return N6("invalid_client",I)}return await this.refreshTokenStore.revokeToken($,w),new Response(null,{status:200})}}class AEA{passkeyService;sessionStore;setupFlow;constructor(A){this.passkeyService=A.passkeyService,this.sessionStore=A.sessionStore,this.setupFlow=A.setupFlow}async handleRegistrationOptions(A){if(await this.passkeyService.hasCredentials())return N6("access_denied","Passkey setup already completed");if(!this.setupFlow.hasValidSetupToken(A))return N6("access_denied","Invalid setup token");let Q=await this.passkeyService.generateRegistrationOptions(m0A(A));return rI(Q)}async handleRegistrationVerify(A){if(await this.passkeyService.hasCredentials())return N6("access_denied","Passkey setup already completed");if(!this.setupFlow.hasValidSetupToken(A))return N6("access_denied","Invalid setup token");let Q=await this.passkeyService.verifyRegistrationResponse(await A.json(),m0A(A));if(!Q.verified)return N6("access_denied","Passkey registration failed");await this.setupFlow.clearSetupState();let B=await this.sessionStore.createSession(Q.subject??"single-operator",{secure:sm(A)});return rI({verified:!0},200,{"Set-Cookie":B.cookie})}async handleAuthenticationOptions(A){if(!await this.passkeyService.hasCredentials())return N6("access_denied","No passkey registered");let Q=await this.passkeyService.generateAuthenticationOptions(m0A(A));return rI(Q)}async handleAuthenticationVerify(A){let Q=await this.passkeyService.verifyAuthenticationResponse(await A.json(),m0A(A));if(!Q.verified)return N6("access_denied","Passkey authentication failed");let B=await this.sessionStore.createSession(Q.subject??"single-operator",{secure:sm(A)});return rI({verified:!0},200,{"Set-Cookie":B.cookie})}}function m0A(A){let Q=yk(A),B=new URL(Q);return{origin:B.origin,rpID:B.hostname}}import{randomUUID as QW2}from"crypto";var BW2=1800;class QEA{setupStateStore;passkeyService;setupToken;constructor(A){this.setupStateStore=A.setupStateStore,this.passkeyService=A.passkeyService}async ensureSetupToken(){let A=this.getValidSetupToken();if(A)return A;let Q=await this.setupStateStore.getValidSetupToken(Math.floor(Date.now()/1000));if(Q)return this.setupToken=Q,Q;return this.createSetupToken()}async createSetupToken(){return this.setupToken={token:`setup_${QW2()}`,expiresAt:Math.floor(Date.now()/1000)+BW2},await this.setupStateStore.saveSetupToken(this.setupToken),this.setupToken}getValidSetupToken(){if(!this.setupToken)return;if(this.setupToken.expiresAt<=Math.floor(Date.now()/1000)){this.setupToken=void 0;return}return this.setupToken}hasValidSetupToken(A){let Q=this.getValidSetupToken();if(!Q)return!1;let B=new URL(A.url);return(B.searchParams.get("setup_token")??B.searchParams.get("token"))===Q.token}async clearSetupState(){this.setupToken=void 0,await this.setupStateStore.clearSetupState()}getSetupUrl(A){let Q=this.getValidSetupToken();if(!Q)return;return gW(A,`/setup?token=${encodeURIComponent(Q.token)}`)}async getOperatorSetupRequired(A){if(await this.passkeyService.hasCredentials())return;let Q=this.getValidSetupToken();if(!Q)return;return{setupUrl:gW(A,`/setup?token=${encodeURIComponent(Q.token)}`),expiresAt:Q.expiresAt,setupTokenId:MVA(Q.token)}}async handleSetupPage(A){if(await this.passkeyService.hasCredentials())return new Response("Setup already completed",{status:404});if(!this.hasValidSetupToken(A))return new Response("Not Found",{status:404});let Q=new URL(A.url).searchParams.get("token")??"";return ck(CV0(Q))}async hasSetupEmailDelivery(A,Q){return this.setupStateStore.hasDelivery(A,Q)}async recordSetupEmailDelivery(A,Q,B={}){await this.setupStateStore.recordDelivery(A,Q,B)}}class u0A{issuer;trustedIssuers;allowLocalhostIssuers;keyStore;clientStore;authCodeStore;sessionStore;passkeyService;setupFlow;oauthEndpoints;webauthnEndpoints;logger;constructor(A){this.issuer=MJ(A.issuer),this.trustedIssuers=new Set([this.issuer,...(A.trustedIssuers??[]).map((Q)=>MJ(Q))]),this.allowLocalhostIssuers=A.allowLocalhostIssuers??Tk(this.issuer),this.keyStore=new BAA({storageDir:A.storageDir}),this.clientStore=new QAA({storageDir:A.storageDir}),this.authCodeStore=new AAA({storageDir:A.storageDir}),this.sessionStore=new y0A({storageDir:A.storageDir}),this.passkeyService=new k0A({storageDir:A.storageDir,...A.logger?{logger:A.logger}:{}}),this.setupFlow=new QEA({setupStateStore:new CVA({storageDir:A.storageDir}),passkeyService:this.passkeyService}),this.oauthEndpoints=new eVA({clientStore:this.clientStore,authCodeStore:this.authCodeStore,refreshTokenStore:new _0A({storageDir:A.storageDir}),sessionStore:this.sessionStore,keyStore:this.keyStore}),this.webauthnEndpoints=new AEA({passkeyService:this.passkeyService,sessionStore:this.sessionStore,setupFlow:this.setupFlow}),this.logger=A.logger}getIssuer(){return this.issuer}async initialize(){if(await this.keyStore.getPrivateJwk(),this.logger?.debug("Auth service signing key loaded"),!await this.hasPasskeyCredentials()){await this.setupFlow.ensureSetupToken();let A=this.getSetupUrl();if(A)if(Tk(this.issuer))this.logger?.warn(`Passkey setup required: ${A}`);else this.logger?.warn("Passkey setup required. Ask through an anchor-visible interface for the setup URL.")}}async hasPasskeyCredentials(){return this.passkeyService.hasCredentials()}async getJwks(){return{keys:[await this.keyStore.getPublicJwk()]}}getAuthorizationServerMetadata(A=this.issuer){let Q=MJ(A);return{issuer:Q,authorization_endpoint:gW(Q,"/authorize"),token_endpoint:gW(Q,"/token"),registration_endpoint:gW(Q,"/register"),revocation_endpoint:gW(Q,"/revoke"),jwks_uri:gW(Q,"/.well-known/jwks.json"),response_types_supported:["code"],grant_types_supported:["authorization_code","refresh_token"],code_challenge_methods_supported:["S256"],token_endpoint_auth_methods_supported:["none","client_secret_basic","client_secret_post"],scopes_supported:["openid","profile","email","offline_access","mcp"],subject_types_supported:["public"],id_token_signing_alg_values_supported:["ES256"]}}getProtectedResourceMetadata(A,Q=this.issuer){return{resource:A,authorization_servers:[MJ(Q)],bearer_methods_supported:["header"],resource_signing_alg_values_supported:["ES256"],scopes_supported:["mcp"]}}async registerClient(A){return this.clientStore.registerClient(A)}async getRegisteredClient(A){return this.clientStore.getClient(A)}async createOperatorSession(A="single-operator",Q={}){return this.sessionStore.createSession(A,Q)}async getOperatorSession(A){return this.sessionStore.getSessionFromRequest(A)}createOperatorLoginResponse(A){return Au(A)}async verifyBearerToken(A,Q={}){let B=pVA(A);if(!B)return;let w=Q.issuer?MJ(Q.issuer):this.resolveRequestIssuer(A);return lVA(B,await this.getJwks(),{issuer:w,...Q.audience?{audience:Q.audience}:{}})}getSetupUrl(A=this.issuer){return this.setupFlow.getSetupUrl(A)}async getOperatorSetupRequired(A=this.issuer){return this.setupFlow.getOperatorSetupRequired(A)}async hasSetupEmailDelivery(A,Q){return this.setupFlow.hasSetupEmailDelivery(A,Q)}async recordSetupEmailDelivery(A,Q,B={}){await this.setupFlow.recordSetupEmailDelivery(A,Q,B)}async handleRequest(A){let Q;try{Q=this.resolveRequestIssuer(A)}catch(w){return this.logger?.warn("Rejected OAuth request from untrusted issuer",{error:w instanceof Error?w.message:String(w)}),new Response("Untrusted OAuth issuer",{status:400})}let B=new URL(A.url).pathname;if(A.method==="OPTIONS"&&VV0(B))return EV0();if(A.method==="GET"){if(B==="/.well-known/oauth-authorization-server")return z3(rI(this.getAuthorizationServerMetadata(Q)));if(B==="/.well-known/jwks.json")return z3(rI(await this.getJwks()));if(B==="/.well-known/oauth-protected-resource")return z3(rI(this.getProtectedResourceMetadata(Q,Q)))}if(A.method==="GET"&&B==="/setup")return this.setupFlow.handleSetupPage(A);if(A.method==="GET"&&B==="/login")return this.handleLoginPage(A);if((A.method==="GET"||A.method==="POST")&&B==="/logout")return this.handleLogout(A);if(A.method==="POST"&&B==="/webauthn/register/options")return this.webauthnEndpoints.handleRegistrationOptions(A);if(A.method==="POST"&&B==="/webauthn/register/verify")return this.webauthnEndpoints.handleRegistrationVerify(A);if(A.method==="POST"&&B==="/webauthn/auth/options")return this.webauthnEndpoints.handleAuthenticationOptions(A);if(A.method==="POST"&&B==="/webauthn/auth/verify")return this.webauthnEndpoints.handleAuthenticationVerify(A);if(A.method==="GET"&&B==="/authorize")return this.oauthEndpoints.handleAuthorizePage(A);if(A.method==="POST"&&B==="/authorize")return this.oauthEndpoints.handleAuthorizeApproval(A);if(A.method==="POST"&&B==="/register")return z3(await this.oauthEndpoints.handleClientRegistration(A));if(A.method==="POST"&&B==="/token")return z3(await this.oauthEndpoints.handleTokenRequest(A,Q));if(A.method==="POST"&&B==="/revoke")return z3(await this.oauthEndpoints.handleRevokeRequest(A));return new Response("Not Found",{status:404})}async handleWellKnownRequest(A){return this.handleRequest(A)}resolveRequestIssuer(A){let Q=yk(A,this.issuer);if(this.trustedIssuers.has(Q)||this.allowLocalhostIssuers&&Tk(Q))return Q;throw Error(`Request issuer ${Q} is not in trusted issuers`)}handleLoginPage(A){let Q=oVA(new URL(A.url).searchParams.get("return_to"));return ck(sVA(Q))}async handleLogout(A){await this.sessionStore.revokeSessionFromRequest(A);let Q=oVA(new URL(A.url).searchParams.get("return_to"));return new Response(null,{status:302,headers:{Location:Q,"Set-Cookie":bVA(sm(A)),"Cache-Control":"no-store"}})}}WA();var c0A="email:send",kV0=H.object({to:H.string().email(),subject:H.string().min(1),text:H.string().min(1),html:H.string().min(1).optional(),sensitivity:H.enum(["normal","secret"]).default("normal")}).strict();aA();WA();var jV0={name:"@brains/notifications",private:!0,version:"0.2.0-alpha.120",description:"Generic notification routing for transactional and administrative messages",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint src test --ext .ts","lint:fix":"eslint src test --ext .ts --fix"},dependencies:{"@brains/email-contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var BEA="notifications:send",$W2=H.object({}),fW2=H.discriminatedUnion("type",[H.object({type:H.literal("email"),address:H.string().email()}).strict()]),IW2=H.object({recipient:fW2,title:H.string().min(1),body:H.string().min(1),html:H.string().min(1).optional(),sensitivity:H.enum(["normal","secret"]).default("normal")}).strict(),_V0=H.discriminatedUnion("status",[H.object({status:H.literal("sent"),deliveryId:H.string().optional()}).strict(),H.object({status:H.literal("failed")}).strict()]);class vV0 extends YB{constructor(A={}){super("notifications",jV0,A,$W2)}async onRegister(A){A.messaging.subscribe(BEA,async(Q)=>{let B=IW2.parse(Q.payload),w={to:B.recipient.address,subject:B.title,text:B.body,...B.html?{html:B.html}:{},sensitivity:B.sensitivity},$=await A.messaging.send({type:c0A,payload:w});if(!("success"in $)||!$.success||!$.data)return{success:!1,error:"Notification delivery failed"};let f=$.data;if(f.status!=="sent")return{success:!1,error:"Notification delivery failed"};return{success:!0,data:f.id?{status:"sent",deliveryId:f.id}:{status:"sent"}}})}}function l0A(A={}){return new vV0(A)}aA();WA();var TV0={name:"@brains/auth-service",private:!0,version:"0.2.0-alpha.120",description:"Embedded OAuth/OIDC auth service for brain operator authentication",type:"module",main:"./src/index.ts",types:"./src/index.ts",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/notifications":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*","@simplewebauthn/server":"^13.3.0",jose:"^6.2.3"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","@types/node":"^20.0.0",typescript:"^5.3.3"},files:["src"]};var UW2=H.union([H.string().email(),H.object({to:H.string().email(),subject:H.string().min(1),body:H.string().min(1)}).strict()]),YW2=H.object({issuer:H.string().optional(),trustedIssuers:H.array(H.string()).default([]),allowLocalhostIssuers:H.boolean().optional(),storageDir:H.string().default("./data/auth"),setupEmail:UW2.optional()}),JW2=H.object({}),p0A;function RU(){return p0A}class wEA extends YB{service;constructor(A={}){super("auth-service",TV0,A,YW2)}async onRegister(A){await super.onRegister(A);let Q=this.config.issuer??(A.preferLocalUrls?A.localSiteUrl??A.siteUrl:A.siteUrl??A.localSiteUrl);this.service=new u0A({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(),p0A=this.service}async onReady(A){await this.requestSetupEmailIfNeeded(A)}async onShutdown(){if(p0A===this.service)p0A=void 0;this.service=void 0}async getTools(){return[oQ(this.id,"get_passkey_setup_url","Get the first-passkey setup URL when operator setup is required. Anchor-only.",JW2,async()=>{let A=this.getService();if(await A.hasPasskeyCredentials())return U8({status:"complete"});let Q=await A.getOperatorSetupRequired();if(Q)return U8({status:"setup_required",setupUrl:Q.setupUrl,expiresAt:Q.expiresAt});return U8({status:"unavailable",reason:"Passkey setup URL is not available."})},{visibility:"anchor"})]}getWebRoutes(){let A=(Q)=>this.getService().handleRequest(Q);return[{path:"/.well-known/oauth-authorization-server",method:"GET",public:!0,handler:A},{path:"/.well-known/oauth-authorization-server",method:"OPTIONS",public:!0,handler:A},{path:"/.well-known/jwks.json",method:"GET",public:!0,handler:A},{path:"/.well-known/jwks.json",method:"OPTIONS",public:!0,handler:A},{path:"/.well-known/oauth-protected-resource",method:"GET",public:!0,handler:A},{path:"/.well-known/oauth-protected-resource",method:"OPTIONS",public:!0,handler:A},{path:"/setup",method:"GET",public:!0,handler:A},{path:"/login",method:"GET",public:!0,handler:A},{path:"/logout",method:"GET",public:!0,handler:A},{path:"/logout",method:"POST",public:!0,handler:A},{path:"/authorize",method:"GET",public:!0,handler:A},{path:"/authorize",method:"POST",public:!0,handler:A},{path:"/register",method:"POST",public:!0,handler:A},{path:"/register",method:"OPTIONS",public:!0,handler:A},{path:"/token",method:"POST",public:!0,handler:A},{path:"/token",method:"OPTIONS",public:!0,handler:A},{path:"/revoke",method:"POST",public:!0,handler:A},{path:"/revoke",method:"OPTIONS",public:!0,handler:A},{path:"/webauthn/register/options",method:"POST",public:!0,handler:A},{path:"/webauthn/register/verify",method:"POST",public:!0,handler:A},{path:"/webauthn/auth/options",method:"POST",public:!0,handler:A},{path:"/webauthn/auth/verify",method:"POST",public:!0,handler:A}]}getService(){if(!this.service)throw Error("AuthServicePlugin has not been registered");return this.service}async requestSetupEmailIfNeeded(A){if(!this.config.setupEmail)return;let Q=this.getService();if(await Q.hasPasskeyCredentials())return;let B=await Q.getOperatorSetupRequired();if(!B)return;let w=XW2(this.config.setupEmail,B);if(await Q.hasSetupEmailDelivery(B.setupTokenId,w.to))return;let $=await A.messaging.send({type:BEA,payload:{recipient:{type:"email",address:w.to},title:w.subject,body:w.body,sensitivity:"secret"}});if(!("success"in $)||!$.success||!$.data){A.logger.warn("Passkey setup email delivery was not confirmed");return}let f=_V0.safeParse($.data);if(!f.success||f.data.status!=="sent"){A.logger.warn("Passkey setup email delivery was not confirmed");return}await Q.recordSetupEmailDelivery(B.setupTokenId,w.to,f.data.deliveryId?{deliveryId:f.data.deliveryId}:{})}}function XW2(A,Q){if(typeof A==="string"){let B=new Date(Q.expiresAt*1000).toISOString(),w=new URL(Q.setupUrl).origin;return{to:A,subject:"Set up your brain passkey",body:["Set up your brain passkey using this single-use link:","",Q.setupUrl,"",`This link expires at ${B}.`,`Dashboard: ${w}/`,`MCP endpoint: ${w}/mcp`,"The first successful passkey registration completes setup and closes this link."].join(`
|
|
2397
|
+
`)}}return{to:A.to,subject:yV0(A.subject,Q),body:yV0(A.body,Q)}}function yV0(A,Q){let B=new Date(Q.expiresAt*1000).toISOString(),w=new URL(Q.setupUrl).origin;return A.replaceAll("{{setupUrl}}",Q.setupUrl).replaceAll("{{expiresAt}}",B).replaceAll("{{origin}}",w)}function Qu(A){return new wEA(A)}WA();var $EA=H.object({transport:H.enum(["stdio","http"]).default("http"),httpPort:H.number().describe("Port for HTTP transport (only used when transport is 'http')").default(3333),authToken:H.string().describe("Bearer token for HTTP transport authentication").optional()});function xV0(A,Q){return[]}aA();function fEA(A,Q){A.messaging.subscribe("job-progress",async(B)=>{let w=FR.safeParse(B.payload);if(!w.success)return Q.warn("Received invalid job-progress message",{error:w.error.message}),{success:!1};let $=w.data,f=$.type,I=$.status,D=$.id;if(Q.debug(`${f} ${D} - ${I}:`,{id:$.id,message:$.message,progress:$.progress,metadata:$.metadata}),$.batchDetails)Q.debug(`Batch details for ${D}:`,{totalOperations:$.batchDetails.totalOperations,completedOperations:$.batchDetails.completedOperations,failedOperations:$.batchDetails.failedOperations,currentOperation:$.batchDetails.currentOperation,errors:$.batchDetails.errors});if($.jobDetails)Q.debug(`Job details for ${D}:`,{jobType:$.jobDetails.jobType,priority:$.jobDetails.priority,retryCount:$.jobDetails.retryCount});return{success:!0}}),Q.debug("Subscribed to job progress events")}var SV0={name:"@brains/mcp",private:!0,version:"0.2.0-alpha.120",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 q3 extends eX{mcpTransport;stdioServer;httpServer;domain;constructor(A={}){let Q={...A,authToken:A.authToken??process.env.MCP_AUTH_TOKEN};super("mcp",SV0,Q,$EA)}async getTools(){return xV0(this.id,()=>this.context)}async getResources(){return[]}async onRegister(A){if(this.domain=A.domain,this.config.transport==="http"&&!A.plugins.has("webserver"))throw Error("MCP HTTP transport requires the webserver interface. Standalone HTTP listeners have been removed.");if(this.logger.debug(`MCP interface initialized with ${this.config.transport} transport`),this.config.transport==="http")A.endpoints.register({label:"MCP",url:"/mcp",priority:30,visibility:"trusted"}),A.interactions.register({id:"mcp",label:"MCP",description:"Connect a trusted client through the Model Context Protocol.",href:"/mcp",kind:"protocol",priority:30,visibility:"trusted"});fEA(A,this.logger)}getOrCreateHttpServer(){if(this.httpServer)return this.httpServer;let A=RU();return this.httpServer=ZK.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||RU()))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=WJ.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(){WJ.resetInstance(),ZK.resetInstance()}}aA();WA();var eI=U1(Re0(),1);WA();aA();var mPA=H.object({botToken:H.string().min(1).describe("Discord bot token"),allowedChannels:H.array(H.string()).default([]),requireMention:H.boolean().default(!0),allowDMs:H.boolean().default(!0),showTypingIndicator:H.boolean().default(!0),statusMessage:H.string().default("Mention me to chat"),useThreads:H.boolean().default(!0),threadAutoArchive:H.union([H.literal(60),H.literal(1440),H.literal(4320),H.literal(10080)]).default(1440),...yx.shape,captureUrlEmoji:H.string().default("\uD83D\uDD16")});var be0={name:"@brains/discord",private:!0,version:"0.2.0-alpha.120",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 dQA=2000,Rd2=8000,bd2=100;function nQA(A){return!!A&&typeof A==="object"&&"send"in A&&"sendTyping"in A}class Qz extends iG{client=null;fetchText;pendingConfirmations=new Map;typingIntervals=new Map;constructor(A,Q={}){super("discord",be0,A,mPA);this.fetchText=Q.fetchText??Ao}async onRegister(A){await super.onRegister(A),this.client=new eI.Client({intents:[eI.GatewayIntentBits.Guilds,eI.GatewayIntentBits.GuildMessages,eI.GatewayIntentBits.MessageContent,eI.GatewayIntentBits.DirectMessages],partials:[eI.Partials.Channel]}),this.client.on(eI.Events.MessageCreate,(Q)=>{this.handleMessage(Q)}),this.client.on(eI.Events.InteractionCreate,(Q)=>{this.handleInteraction(Q)}),this.client.once(eI.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(!nQA(B))return;let w=uy(Q,dQA);for(let $ of w)B.send($).catch((f)=>this.logger.error("Failed to send message",{error:f}))}async sendMessageWithId({channelId:A,message:Q,approvalCard:B,approvalCards:w}){let $=w??(B?[B]:[]),f=$.length>0?this.buildApprovalMessagePayload(Q,$):Q;return this.sendPayloadWithId(A,f)}async sendPayloadWithId(A,Q){if(!A||!this.client)return;let B=this.client.channels.cache.get(A);if(!nQA(B))return;if(typeof Q!=="string")return(await B.send(Q)).id;let w=uy(Q,dQA),$;for(let f of w)$=(await B.send(f)).id;return $}async editMessage({channelId:A,messageId:Q,newMessage:B}){if(!A||!this.client)return!1;let w=this.client.channels.cache.get(A);if(!nQA(w))return!1;try{return await(await w.messages.fetch(Q)).edit(B.slice(0,dQA)),!0}catch{return!1}}supportsMessageEditing(){return!0}async handleMessage(A){if(A.author.id===this.client?.user?.id)return;if(!this.context)return;let Q=!A.guild,B=A.channel.isThread();if(Q&&!this.config.allowDMs)return;let w=!!this.client?.user&&A.mentions.has(this.client.user,{ignoreEveryone:!0});if(A.author.bot&&!w)return;let $=B&&"ownerId"in A.channel&&A.channel.ownerId===this.client?.user?.id,f=this.getSpaceChannelId(A),I=!Q&&this.isConfiguredSpace(f),D={channelId:f,isBot:A.author.bot};if(this.config.allowedChannels.length>0&&!Q&&!this.isAllowedChannel(A.channel.id,f))return;let U=Q||$||!this.config.requireMention||w;if(I&&(!U||this.willRouteUseNonSpaceConversation(A)))await this.capturePassiveSpaceMessage(A,f).catch((X)=>this.logger.error("Passive Discord space capture failed",{error:X,channelId:f}));if(!U){if(this.config.captureUrls){let X=this.extractCaptureableUrls(A.content,this.config.blockedUrlDomains);if(X.length>0){await A.react(this.config.captureUrlEmoji).catch((G)=>this.logger.debug("React failed",{error:G}));for(let G of X)await this.captureUrlViaAgent(G,A.channel.id,A.author.id,"discord",D).catch((Z)=>this.logger.error("URL capture failed",{error:Z,url:G}))}}return}let Y=this.stripMention(A.content);if(A.attachments.size>0){let X=this.context.permissions.getUserLevel("discord",A.author.id,D);if(X==="anchor"||X==="trusted")for(let Z of A.attachments.values()){let N=Z.name,L=Z.contentType??void 0,V=Z.size;if(!this.isUploadableTextFile(N,L))continue;if(!this.isFileSizeAllowed(V))continue;try{let M=await this.fetchText(Z.url);Y+=`
|
|
2398
2398
|
|
|
2399
2399
|
`+this.formatFileUploadMessage(N,M)}catch(M){this.logger.error("Failed to download attachment",{error:M,filename:N})}}}if(Y=Y.trim(),!Y)return;let J=A.channel.id;await this.routeToAgent(Y,J,A,D)}async handleInteraction(A){if(!this.context||!A.isButton())return;let Q=this.parseApprovalButtonCustomId(A.customId);if(!Q)return;let B=`discord-${A.channelId}`;if(!this.pendingConfirmations.get(B)?.has(Q.approvalId)){await A.reply({content:"This approval is no longer pending or has changed.",ephemeral:!0}).catch((f)=>this.logger.debug("Failed to reply to stale approval button",{error:f}));return}await A.deferUpdate().catch((f)=>this.logger.debug("Failed to defer approval button",{error:f})),this.removePendingApproval(B,Q.approvalId);let $=await this.context.agent.confirmPendingAction(B,Q.confirmed,Q.approvalId);await this.sendApprovalResultMessage({channelId:A.channelId,response:$})}async capturePassiveSpaceMessage(A,Q){if(!this.context)return;let B=this.stripMention(A.content).trim();if(!B)return;let w=`discord-${Q}`,$=this.getChannelName(A);await this.context.conversations.start({sessionId:w,interfaceType:"discord",channelId:Q,metadata:{channelName:$,interfaceType:"discord",channelId:Q}}),await this.context.conversations.addMessage({conversationId:w,role:"user",content:B,metadata:this.buildUserMessageMetadata(A,Q,$,{threadId:A.channel.isThread()?A.channel.id:void 0})})}async routeToAgent(A,Q,B,w){if(!this.context)return;let $=this.context.agent,f=Q;if(this.config.useThreads&&B.guild&&!B.channel.isThread())try{f=(await B.startThread({name:H7(A,bd2),autoArchiveDuration:this.config.threadAutoArchive})).id}catch(Y){this.logger.error("Failed to create thread",{error:Y})}let I=`discord-${f}`,D=this.context.permissions.getUserLevel("discord",B.author.id,w),U=this.getChannelName(B);this.startProcessingInput(f);try{let Y=this.client?.channels.cache.get(f);if(nQA(Y))this.startTypingIndicator(Y);if(this.pendingConfirmations.has(I)){await this.handleConfirmationResponse(A,I,f);return}let J=await $.chat(A,I,{userPermissionLevel:D,interfaceType:"discord",channelId:f,channelName:U,...this.buildUserMessageMetadata(B,Q,U,{threadId:f!==Q||B.channel.isThread()?f:void 0})}),X=this.getPendingApprovalCards(J.cards);if(X.length>0)this.pendingConfirmations.set(I,new Set(X.map((Z)=>Z.id)));else if(J.pendingConfirmations)this.pendingConfirmations.set(I,new Set(J.pendingConfirmations.map((Z)=>Z.id)));let G=await this.sendMessageWithId({channelId:f,message:this.formatAgentResponseText(J.text,X),approvalCards:X});if(G&&J.toolResults){for(let Z of J.toolResults)if(Z.jobId)this.trackAgentResponseForJob(Z.jobId,G,f)}}catch(Y){this.logger.error("Error handling message",{error:Y,channelId:f}),this.sendMessageToChannel({channelId:f,message:`**Error:** ${Y instanceof Error?Y.message:"Unknown error"}`})}finally{this.endProcessingInput(),this.stopTypingIndicator(f)}}buildApprovalMessagePayload(A,Q){let B=Q.length>1;return{content:H7(A.trim().length>0?`${A}
|
|
2400
2400
|
|
|
@@ -2465,7 +2465,7 @@ Use the buttons below${B?" for the matching action":", or reply **yes** / **no**
|
|
|
2465
2465
|
<p>Once built, this page will be replaced with your actual website.</p>
|
|
2466
2466
|
</div>
|
|
2467
2467
|
</body>
|
|
2468
|
-
</html>`;var DA1={name:"@brains/webserver",private:!0,version:"0.2.0-alpha.
|
|
2468
|
+
</html>`;var DA1={name:"@brains/webserver",private:!0,version:"0.2.0-alpha.120",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 Bz extends eX{serverManager;siteUrl;previewUrl;constructor(A={}){super("webserver",DA1,A,QkA)}async onRegister(A){if(this.siteUrl=A.siteUrl,this.previewUrl=A.previewUrl,this.siteUrl)A.endpoints.register({label:"Site",url:this.siteUrl,priority:10}),A.interactions.register({id:"site",label:"Public site",description:"Visit the published public site for this brain.",href:this.siteUrl,kind:"human",priority:10});if(this.config.enablePreview&&this.previewUrl)A.endpoints.register({label:"Preview",url:this.previewUrl,priority:20,visibility:"anchor"}),A.interactions.register({id:"preview",label:"Preview site",description:"Open the private preview build.",href:this.previewUrl,kind:"admin",priority:20,visibility:"anchor"});this.serverManager=new IBA({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&&!UA1(this.config.previewDistDir))await A(this.config.previewDistDir,{recursive:!0}),await Q(YA1(this.config.previewDistDir,"index.html"),BkA),this.logger.debug(`Created preview directory at ${this.config.previewDistDir}`);if(!UA1(this.config.productionDistDir))await A(this.config.productionDistDir,{recursive:!0}),await Q(YA1(this.config.productionDistDir,"index.html"),BkA),this.logger.debug(`Created production directory at ${this.config.productionDistDir}`)}}aA();var gA1="vercel.ai.error",Zn2=Symbol.for(gA1),JA1,XA1,bB=class A extends(XA1=Error,JA1=Zn2,XA1){constructor({name:Q,message:B,cause:w}){super(B);this[JA1]=!0,this.name=Q,this.cause=w}static isInstance(Q){return A.hasMarker(Q,gA1)}static hasMarker(Q,B){let w=Symbol.for(B);return Q!=null&&typeof Q==="object"&&w in Q&&typeof Q[w]==="boolean"&&Q[w]===!0}},hA1="AI_APICallError",mA1=`vercel.ai.error.${hA1}`,Nn2=Symbol.for(mA1),WA1,HA1,KZw=class extends(HA1=bB,WA1=Nn2,HA1){constructor({message:A,url:Q,requestBodyValues:B,statusCode:w,responseHeaders:$,responseBody:f,cause:I,isRetryable:D=w!=null&&(w===408||w===409||w===429||w>=500),data:U}){super({name:hA1,message:A,cause:I});this[WA1]=!0,this.url=Q,this.requestBodyValues=B,this.statusCode=w,this.responseHeaders=$,this.responseBody=f,this.isRetryable=D,this.data=U}static isInstance(A){return bB.hasMarker(A,mA1)}},uA1="AI_EmptyResponseBodyError",cA1=`vercel.ai.error.${uA1}`,zn2=Symbol.for(cA1),GA1,KA1,FZw=class extends(KA1=bB,GA1=zn2,KA1){constructor({message:A="Empty response body"}={}){super({name:uA1,message:A});this[GA1]=!0}static isInstance(A){return bB.hasMarker(A,cA1)}};function lA1(A){if(A==null)return"unknown error";if(typeof A==="string")return A;if(A instanceof Error)return A.message;return JSON.stringify(A)}var pA1="AI_InvalidArgumentError",iA1=`vercel.ai.error.${pA1}`,qn2=Symbol.for(iA1),FA1,ZA1,rA1=class extends(ZA1=bB,FA1=qn2,ZA1){constructor({message:A,cause:Q,argument:B}){super({name:pA1,message:A,cause:Q});this[FA1]=!0,this.argument=B}static isInstance(A){return bB.hasMarker(A,iA1)}},dA1="AI_InvalidPromptError",nA1=`vercel.ai.error.${dA1}`,Ln2=Symbol.for(nA1),NA1,zA1,ZZw=class extends(zA1=bB,NA1=Ln2,zA1){constructor({prompt:A,message:Q,cause:B}){super({name:dA1,message:`Invalid prompt: ${Q}`,cause:B});this[NA1]=!0,this.prompt=A}static isInstance(A){return bB.hasMarker(A,nA1)}},oA1="AI_InvalidResponseDataError",sA1=`vercel.ai.error.${oA1}`,Vn2=Symbol.for(sA1),qA1,LA1,NZw=class extends(LA1=bB,qA1=Vn2,LA1){constructor({data:A,message:Q=`Invalid response data: ${JSON.stringify(A)}.`}){super({name:oA1,message:Q});this[qA1]=!0,this.data=A}static isInstance(A){return bB.hasMarker(A,sA1)}},aA1="AI_JSONParseError",tA1=`vercel.ai.error.${aA1}`,En2=Symbol.for(tA1),VA1,EA1,wkA=class extends(EA1=bB,VA1=En2,EA1){constructor({text:A,cause:Q}){super({name:aA1,message:`JSON parsing failed: Text: ${A}.
|
|
2469
2469
|
Error message: ${lA1(Q)}`,cause:Q});this[VA1]=!0,this.text=A}static isInstance(A){return bB.hasMarker(A,tA1)}},eA1="AI_LoadAPIKeyError",A01=`vercel.ai.error.${eA1}`,Mn2=Symbol.for(A01),MA1,CA1,zZw=class extends(CA1=bB,MA1=Mn2,CA1){constructor({message:A}){super({name:eA1,message:A});this[MA1]=!0}static isInstance(A){return bB.hasMarker(A,A01)}},Q01="AI_LoadSettingError",B01=`vercel.ai.error.${Q01}`,Cn2=Symbol.for(B01),OA1,RA1,qZw=class extends(RA1=bB,OA1=Cn2,RA1){constructor({message:A}){super({name:Q01,message:A});this[OA1]=!0}static isInstance(A){return bB.hasMarker(A,B01)}},w01="AI_NoContentGeneratedError",$01=`vercel.ai.error.${w01}`,On2=Symbol.for($01),bA1,PA1,LZw=class extends(PA1=bB,bA1=On2,PA1){constructor({message:A="No content generated."}={}){super({name:w01,message:A});this[bA1]=!0}static isInstance(A){return bB.hasMarker(A,$01)}},f01="AI_NoSuchModelError",I01=`vercel.ai.error.${f01}`,Rn2=Symbol.for(I01),kA1,jA1,VZw=class extends(jA1=bB,kA1=Rn2,jA1){constructor({errorName:A=f01,modelId:Q,modelType:B,message:w=`No such ${B}: ${Q}`}){super({name:A,message:w});this[kA1]=!0,this.modelId=Q,this.modelType=B}static isInstance(A){return bB.hasMarker(A,I01)}},D01="AI_TooManyEmbeddingValuesForCallError",U01=`vercel.ai.error.${D01}`,bn2=Symbol.for(U01),_A1,vA1,EZw=class extends(vA1=bB,_A1=bn2,vA1){constructor(A){super({name:D01,message:`Too many values for a single embedding call. The ${A.provider} model "${A.modelId}" can only embed up to ${A.maxEmbeddingsPerCall} values per call, but ${A.values.length} values were provided.`});this[_A1]=!0,this.provider=A.provider,this.modelId=A.modelId,this.maxEmbeddingsPerCall=A.maxEmbeddingsPerCall,this.values=A.values}static isInstance(A){return bB.hasMarker(A,U01)}},Y01="AI_TypeValidationError",J01=`vercel.ai.error.${Y01}`,Pn2=Symbol.for(J01),TA1,yA1,AH=class A extends(yA1=bB,TA1=Pn2,yA1){constructor({value:Q,cause:B,context:w}){let $="Type validation failed";if(w==null?void 0:w.field)$+=` for ${w.field}`;if((w==null?void 0:w.entityName)||(w==null?void 0:w.entityId)){$+=" (";let f=[];if(w.entityName)f.push(w.entityName);if(w.entityId)f.push(`id: "${w.entityId}"`);$+=f.join(", "),$+=")"}super({name:Y01,message:`${$}: Value: ${JSON.stringify(Q)}.
|
|
2470
2470
|
Error message: ${lA1(B)}`,cause:B});this[TA1]=!0,this.value=Q,this.context=w}static isInstance(Q){return bB.hasMarker(Q,J01)}static wrap({value:Q,cause:B,context:w}){var $,f,I;if(A.isInstance(B)&&B.value===Q&&(($=B.context)==null?void 0:$.field)===(w==null?void 0:w.field)&&((f=B.context)==null?void 0:f.entityName)===(w==null?void 0:w.entityName)&&((I=B.context)==null?void 0:I.entityId)===(w==null?void 0:w.entityId))return B;return new A({value:Q,cause:B,context:w})}},X01="AI_UnsupportedFunctionalityError",W01=`vercel.ai.error.${X01}`,kn2=Symbol.for(W01),xA1,SA1,MZw=class extends(SA1=bB,xA1=kn2,SA1){constructor({functionality:A,message:Q=`'${A}' functionality not supported.`}){super({name:X01,message:Q});this[xA1]=!0,this.functionality=A}static isInstance(A){return bB.hasMarker(A,W01)}};G1();fW();fW();fW();var N01="AI_DownloadError",z01=`vercel.ai.error.${N01}`,jn2=Symbol.for(z01),H01,G01,SU=class extends(G01=bB,H01=jn2,G01){constructor({url:A,statusCode:Q,statusText:B,cause:w,message:$=w==null?`Failed to download ${A}: ${Q} ${B}`:`Failed to download ${A}: ${w}`}){super({name:N01,message:$,cause:w});this[H01]=!0,this.url=A,this.statusCode=Q,this.statusText=B}static isInstance(A){return bB.hasMarker(A,z01)}},YkA=2147483648;async function q01({response:A,url:Q,maxBytes:B=YkA}){let w=A.headers.get("content-length");if(w!=null){let J=parseInt(w,10);if(!isNaN(J)&&J>B)throw new SU({url:Q,message:`Download of ${Q} exceeded maximum size of ${B} bytes (Content-Length: ${J}).`})}let $=A.body;if($==null)return new Uint8Array(0);let f=$.getReader(),I=[],D=0;try{while(!0){let{done:J,value:X}=await f.read();if(J)break;if(D+=X.length,D>B)throw new SU({url:Q,message:`Download of ${Q} exceeded maximum size of ${B} bytes.`});I.push(X)}}finally{try{await f.cancel()}finally{f.releaseLock()}}let U=new Uint8Array(D),Y=0;for(let J of I)U.set(J,Y),Y+=J.length;return U}function JkA(A){let Q;try{Q=new URL(A)}catch(w){throw new SU({url:A,message:`Invalid URL: ${A}`})}if(Q.protocol==="data:")return;if(Q.protocol!=="http:"&&Q.protocol!=="https:")throw new SU({url:A,message:`URL scheme must be http, https, or data, got ${Q.protocol}`});let B=Q.hostname;if(!B)throw new SU({url:A,message:"URL must have a hostname"});if(B==="localhost"||B.endsWith(".local")||B.endsWith(".localhost"))throw new SU({url:A,message:`URL with hostname ${B} is not allowed`});if(B.startsWith("[")&&B.endsWith("]")){let w=B.slice(1,-1);if(_n2(w))throw new SU({url:A,message:`URL with IPv6 address ${B} is not allowed`});return}if(L01(B)){if(IkA(B))throw new SU({url:A,message:`URL with IP address ${B} is not allowed`});return}}function L01(A){let Q=A.split(".");if(Q.length!==4)return!1;return Q.every((B)=>{let w=Number(B);return Number.isInteger(w)&&w>=0&&w<=255&&String(w)===B})}function IkA(A){let Q=A.split(".").map(Number),[B,w]=Q;if(B===0)return!0;if(B===10)return!0;if(B===127)return!0;if(B===169&&w===254)return!0;if(B===172&&w>=16&&w<=31)return!0;if(B===192&&w===168)return!0;return!1}function _n2(A){let Q=A.toLowerCase();if(Q==="::1")return!0;if(Q==="::")return!0;if(Q.startsWith("::ffff:")){let B=Q.slice(7);if(L01(B))return IkA(B);let w=B.split(":");if(w.length===2){let $=parseInt(w[0],16),f=parseInt(w[1],16);if(!isNaN($)&&!isNaN(f)){let I=$>>8&255,D=$&255,U=f>>8&255,Y=f&255;return IkA(`${I}.${D}.${U}.${Y}`)}}}if(Q.startsWith("fc")||Q.startsWith("fd"))return!0;if(Q.startsWith("fe80"))return!0;return!1}var fF=({prefix:A,size:Q=16,alphabet:B="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",separator:w="-"}={})=>{let $=()=>{let f=B.length,I=Array(Q);for(let D=0;D<Q;D++)I[D]=B[Math.random()*f|0];return I.join("")};if(A==null)return $;if(B.includes(w))throw new rA1({argument:"separator",message:`The separator "${w}" must not be part of the alphabet "${B}".`});return()=>`${A}${w}${$()}`},V01=fF();function XkA(A){if(A==null)return"unknown error";if(typeof A==="string")return A;if(A instanceof Error)return A.message;return JSON.stringify(A)}function E01(A=globalThis){var Q,B,w;if(A.window)return"runtime/browser";if((Q=A.navigator)==null?void 0:Q.userAgent)return`runtime/${A.navigator.userAgent.toLowerCase()}`;if((w=(B=A.process)==null?void 0:B.versions)==null?void 0:w.node)return`runtime/node.js/${A.process.version.substring(0)}`;if(A.EdgeRuntime)return"runtime/vercel-edge";return"runtime/unknown"}function vn2(A){if(A==null)return{};let Q={};if(A instanceof Headers)A.forEach((B,w)=>{Q[w.toLowerCase()]=B});else{if(!Array.isArray(A))A=Object.entries(A);for(let[B,w]of A)if(w!=null)Q[B.toLowerCase()]=w}return Q}function DBA(A,...Q){let B=new Headers(vn2(A)),w=B.get("user-agent")||"";return B.set("user-agent",[w,...Q].filter(Boolean).join(" ")),Object.fromEntries(B.entries())}var Tn2=/"(?:_|\\u005[Ff])(?:_|\\u005[Ff])(?:p|\\u0070)(?:r|\\u0072)(?:o|\\u006[Ff])(?:t|\\u0074)(?:o|\\u006[Ff])(?:_|\\u005[Ff])(?:_|\\u005[Ff])"\s*:/,yn2=/"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/;function K01(A){let Q=JSON.parse(A);if(Q===null||typeof Q!=="object")return Q;if(Tn2.test(A)===!1&&yn2.test(A)===!1)return Q;return xn2(Q)}function xn2(A){let Q=[A];while(Q.length){let B=Q;Q=[];for(let w of B){if(Object.prototype.hasOwnProperty.call(w,"__proto__"))throw SyntaxError("Object contains forbidden prototype property");if(Object.prototype.hasOwnProperty.call(w,"constructor")&&w.constructor!==null&&typeof w.constructor==="object"&&Object.prototype.hasOwnProperty.call(w.constructor,"prototype"))throw SyntaxError("Object contains forbidden prototype property");for(let $ in w){let f=w[$];if(f&&typeof f==="object")Q.push(f)}}}return A}function Sn2(A){let{stackTraceLimit:Q}=Error;try{Error.stackTraceLimit=0}catch(B){return K01(A)}try{return K01(A)}finally{Error.stackTraceLimit=Q}}function WkA(A){if(A.type==="object"||Array.isArray(A.type)&&A.type.includes("object")){A.additionalProperties=!1;let{properties:B}=A;if(B!=null)for(let w of Object.keys(B))B[w]=BM(B[w])}if(A.items!=null)A.items=Array.isArray(A.items)?A.items.map(BM):BM(A.items);if(A.anyOf!=null)A.anyOf=A.anyOf.map(BM);if(A.allOf!=null)A.allOf=A.allOf.map(BM);if(A.oneOf!=null)A.oneOf=A.oneOf.map(BM);let{definitions:Q}=A;if(Q!=null)for(let B of Object.keys(Q))Q[B]=BM(Q[B]);return A}function BM(A){if(typeof A==="boolean")return A;return WkA(A)}var gn2=Symbol("Let zodToJsonSchema decide on which parser to use"),F01={name:void 0,$refStrategy:"root",basePath:["#"],effectStrategy:"input",pipeStrategy:"all",dateStrategy:"format:date-time",mapStrategy:"entries",removeAdditionalStrategy:"passthrough",allowedAdditionalProperties:!0,rejectedAdditionalProperties:!1,definitionPath:"definitions",strictUnions:!1,definitions:{},errorMessages:!1,patternStrategy:"escape",applyRegexFlags:!1,emailStrategy:"format:email",base64Strategy:"contentEncoding:base64",nameStrategy:"ref"},hn2=(A)=>typeof A==="string"?{...F01,name:A}:{...F01,...A};function AD(){return{}}function mn2(A,Q){var B,w,$;let f={type:"array"};if(((B=A.type)==null?void 0:B._def)&&(($=(w=A.type)==null?void 0:w._def)==null?void 0:$.typeName)!==W0.ZodAny)f.items=kw(A.type._def,{...Q,currentPath:[...Q.currentPath,"items"]});if(A.minLength)f.minItems=A.minLength.value;if(A.maxLength)f.maxItems=A.maxLength.value;if(A.exactLength)f.minItems=A.exactLength.value,f.maxItems=A.exactLength.value;return f}function un2(A){let Q={type:"integer",format:"int64"};if(!A.checks)return Q;for(let B of A.checks)switch(B.kind){case"min":if(B.inclusive)Q.minimum=B.value;else Q.exclusiveMinimum=B.value;break;case"max":if(B.inclusive)Q.maximum=B.value;else Q.exclusiveMaximum=B.value;break;case"multipleOf":Q.multipleOf=B.value;break}return Q}function cn2(){return{type:"boolean"}}function M01(A,Q){return kw(A.type._def,Q)}var ln2=(A,Q)=>{return kw(A.innerType._def,Q)};function C01(A,Q,B){let w=B!=null?B:Q.dateStrategy;if(Array.isArray(w))return{anyOf:w.map(($,f)=>C01(A,Q,$))};switch(w){case"string":case"format:date-time":return{type:"string",format:"date-time"};case"format:date":return{type:"string",format:"date"};case"integer":return pn2(A)}}var pn2=(A)=>{let Q={type:"integer",format:"unix-time"};for(let B of A.checks)switch(B.kind){case"min":Q.minimum=B.value;break;case"max":Q.maximum=B.value;break}return Q};function in2(A,Q){return{...kw(A.innerType._def,Q),default:A.defaultValue()}}function rn2(A,Q){return Q.effectStrategy==="input"?kw(A.schema._def,Q):AD()}function dn2(A){return{type:"string",enum:Array.from(A.values)}}var nn2=(A)=>{if("type"in A&&A.type==="string")return!1;return"allOf"in A};function on2(A,Q){let B=[kw(A.left._def,{...Q,currentPath:[...Q.currentPath,"allOf","0"]}),kw(A.right._def,{...Q,currentPath:[...Q.currentPath,"allOf","1"]})].filter(($)=>!!$),w=[];return B.forEach(($)=>{if(nn2($))w.push(...$.allOf);else{let f=$;if("additionalProperties"in $&&$.additionalProperties===!1){let{additionalProperties:I,...D}=$;f=D}w.push(f)}}),w.length?{allOf:w}:void 0}function sn2(A){let Q=typeof A.value;if(Q!=="bigint"&&Q!=="number"&&Q!=="boolean"&&Q!=="string")return{type:Array.isArray(A.value)?"array":"object"};return{type:Q==="bigint"?"integer":Q,const:A.value}}var $kA=void 0,SJ={cuid:/^[cC][^\s-]{8,}$/,cuid2:/^[0-9a-z]+$/,ulid:/^[0-9A-HJKMNP-TV-Z]{26}$/,email:/^(?!\.)(?!.*\.\.)([a-zA-Z0-9_'+\-\.]*)[a-zA-Z0-9_+-]@([a-zA-Z0-9][a-zA-Z0-9\-]*\.)+[a-zA-Z]{2,}$/,emoji:()=>{if($kA===void 0)$kA=RegExp("^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$","u");return $kA},uuid:/^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/,ipv4:/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/,ipv4Cidr:/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/(3[0-2]|[12]?[0-9])$/,ipv6:/^(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))$/,ipv6Cidr:/^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/,base64:/^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/,base64url:/^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z-_]{3}(=)?))?$/,nanoid:/^[a-zA-Z0-9_-]{21}$/,jwt:/^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]*$/};function O01(A,Q){let B={type:"string"};if(A.checks)for(let w of A.checks)switch(w.kind){case"min":B.minLength=typeof B.minLength==="number"?Math.max(B.minLength,w.value):w.value;break;case"max":B.maxLength=typeof B.maxLength==="number"?Math.min(B.maxLength,w.value):w.value;break;case"email":switch(Q.emailStrategy){case"format:email":gJ(B,"email",w.message,Q);break;case"format:idn-email":gJ(B,"idn-email",w.message,Q);break;case"pattern:zod":x4(B,SJ.email,w.message,Q);break}break;case"url":gJ(B,"uri",w.message,Q);break;case"uuid":gJ(B,"uuid",w.message,Q);break;case"regex":x4(B,w.regex,w.message,Q);break;case"cuid":x4(B,SJ.cuid,w.message,Q);break;case"cuid2":x4(B,SJ.cuid2,w.message,Q);break;case"startsWith":x4(B,RegExp(`^${fkA(w.value,Q)}`),w.message,Q);break;case"endsWith":x4(B,RegExp(`${fkA(w.value,Q)}$`),w.message,Q);break;case"datetime":gJ(B,"date-time",w.message,Q);break;case"date":gJ(B,"date",w.message,Q);break;case"time":gJ(B,"time",w.message,Q);break;case"duration":gJ(B,"duration",w.message,Q);break;case"length":B.minLength=typeof B.minLength==="number"?Math.max(B.minLength,w.value):w.value,B.maxLength=typeof B.maxLength==="number"?Math.min(B.maxLength,w.value):w.value;break;case"includes":{x4(B,RegExp(fkA(w.value,Q)),w.message,Q);break}case"ip":{if(w.version!=="v6")gJ(B,"ipv4",w.message,Q);if(w.version!=="v4")gJ(B,"ipv6",w.message,Q);break}case"base64url":x4(B,SJ.base64url,w.message,Q);break;case"jwt":x4(B,SJ.jwt,w.message,Q);break;case"cidr":{if(w.version!=="v6")x4(B,SJ.ipv4Cidr,w.message,Q);if(w.version!=="v4")x4(B,SJ.ipv6Cidr,w.message,Q);break}case"emoji":x4(B,SJ.emoji(),w.message,Q);break;case"ulid":{x4(B,SJ.ulid,w.message,Q);break}case"base64":{switch(Q.base64Strategy){case"format:binary":{gJ(B,"binary",w.message,Q);break}case"contentEncoding:base64":{B.contentEncoding="base64";break}case"pattern:zod":{x4(B,SJ.base64,w.message,Q);break}}break}case"nanoid":x4(B,SJ.nanoid,w.message,Q);case"toLowerCase":case"toUpperCase":case"trim":break;default:}return B}function fkA(A,Q){return Q.patternStrategy==="escape"?tn2(A):A}var an2=new Set("ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvxyz0123456789");function tn2(A){let Q="";for(let B=0;B<A.length;B++){if(!an2.has(A[B]))Q+="\\";Q+=A[B]}return Q}function gJ(A,Q,B,w){var $;if(A.format||(($=A.anyOf)==null?void 0:$.some((f)=>f.format))){if(!A.anyOf)A.anyOf=[];if(A.format)A.anyOf.push({format:A.format}),delete A.format;A.anyOf.push({format:Q,...B&&w.errorMessages&&{errorMessage:{format:B}}})}else A.format=Q}function x4(A,Q,B,w){var $;if(A.pattern||(($=A.allOf)==null?void 0:$.some((f)=>f.pattern))){if(!A.allOf)A.allOf=[];if(A.pattern)A.allOf.push({pattern:A.pattern}),delete A.pattern;A.allOf.push({pattern:Z01(Q,w),...B&&w.errorMessages&&{errorMessage:{pattern:B}}})}else A.pattern=Z01(Q,w)}function Z01(A,Q){var B;if(!Q.applyRegexFlags||!A.flags)return A.source;let w={i:A.flags.includes("i"),m:A.flags.includes("m"),s:A.flags.includes("s")},$=w.i?A.source.toLowerCase():A.source,f="",I=!1,D=!1,U=!1;for(let Y=0;Y<$.length;Y++){if(I){f+=$[Y],I=!1;continue}if(w.i){if(D){if($[Y].match(/[a-z]/)){if(U)f+=$[Y],f+=`${$[Y-2]}-${$[Y]}`.toUpperCase(),U=!1;else if($[Y+1]==="-"&&((B=$[Y+2])==null?void 0:B.match(/[a-z]/)))f+=$[Y],U=!0;else f+=`${$[Y]}${$[Y].toUpperCase()}`;continue}}else if($[Y].match(/[a-z]/)){f+=`[${$[Y]}${$[Y].toUpperCase()}]`;continue}}if(w.m){if($[Y]==="^"){f+=`(^|(?<=[\r
|
|
2471
2471
|
]))`;continue}else if($[Y]==="$"){f+=`($|(?=[\r
|
|
@@ -2475,7 +2475,7 @@ Error message: ${lA1(B)}`,cause:B});this[TA1]=!0,this.value=Q,this.context=w}sta
|
|
|
2475
2475
|
|
|
2476
2476
|
`)},flush(A){A.enqueue(`data: [DONE]
|
|
2477
2477
|
|
|
2478
|
-
`)}})}},Ka2={"content-type":"text/event-stream","cache-control":"no-cache",connection:"keep-alive","x-vercel-ai-ui-message-stream":"v1","x-accel-buffering":"no"};function u01({status:A,statusText:Q,headers:B,stream:w,consumeSseStream:$}){let f=w.pipeThrough(new Ga2);if($){let[I,D]=f.tee();f=I,$({stream:D})}return new Response(f.pipeThrough(new TextEncoderStream),{status:A,statusText:Q,headers:Ha2(B,Ka2)})}var ic=K.record(K.string(),wM.optional()),HNw=UBA(()=>pc(K.union([K.strictObject({type:K.literal("text-start"),id:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("text-delta"),id:K.string(),delta:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("text-end"),id:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("error"),errorText:K.string()}),K.strictObject({type:K.literal("tool-input-start"),toolCallId:K.string(),toolName:K.string(),providerExecuted:K.boolean().optional(),providerMetadata:N2.optional(),toolMetadata:ic.optional(),dynamic:K.boolean().optional(),title:K.string().optional()}),K.strictObject({type:K.literal("tool-input-delta"),toolCallId:K.string(),inputTextDelta:K.string()}),K.strictObject({type:K.literal("tool-input-available"),toolCallId:K.string(),toolName:K.string(),input:K.unknown(),providerExecuted:K.boolean().optional(),providerMetadata:N2.optional(),toolMetadata:ic.optional(),dynamic:K.boolean().optional(),title:K.string().optional()}),K.strictObject({type:K.literal("tool-input-error"),toolCallId:K.string(),toolName:K.string(),input:K.unknown(),providerExecuted:K.boolean().optional(),providerMetadata:N2.optional(),toolMetadata:ic.optional(),dynamic:K.boolean().optional(),errorText:K.string(),title:K.string().optional()}),K.strictObject({type:K.literal("tool-approval-request"),approvalId:K.string(),toolCallId:K.string()}),K.strictObject({type:K.literal("tool-output-available"),toolCallId:K.string(),output:K.unknown(),providerExecuted:K.boolean().optional(),providerMetadata:N2.optional(),toolMetadata:ic.optional(),dynamic:K.boolean().optional(),preliminary:K.boolean().optional()}),K.strictObject({type:K.literal("tool-output-error"),toolCallId:K.string(),errorText:K.string(),providerExecuted:K.boolean().optional(),providerMetadata:N2.optional(),toolMetadata:ic.optional(),dynamic:K.boolean().optional()}),K.strictObject({type:K.literal("tool-output-denied"),toolCallId:K.string()}),K.strictObject({type:K.literal("reasoning-start"),id:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("reasoning-delta"),id:K.string(),delta:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("reasoning-end"),id:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("source-url"),sourceId:K.string(),url:K.string(),title:K.string().optional(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("source-document"),sourceId:K.string(),mediaType:K.string(),title:K.string(),filename:K.string().optional(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("file"),url:K.string(),mediaType:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.custom((A)=>typeof A==="string"&&A.startsWith("data-"),{message:'Type must start with "data-"'}),id:K.string().optional(),data:K.unknown(),transient:K.boolean().optional()}),K.strictObject({type:K.literal("start-step")}),K.strictObject({type:K.literal("finish-step")}),K.strictObject({type:K.literal("start"),messageId:K.string().optional(),messageMetadata:K.unknown().optional()}),K.strictObject({type:K.literal("finish"),finishReason:K.enum(["stop","length","content-filter","tool-calls","error","other"]).optional(),messageMetadata:K.unknown().optional()}),K.strictObject({type:K.literal("abort"),reason:K.string().optional()}),K.strictObject({type:K.literal("message-metadata"),messageMetadata:K.unknown()})])));function Fa2(A){return A.type.startsWith("data-")}function GkA(A){return A.type.startsWith("tool-")}function Za2(A){return A.type==="dynamic-tool"}function b01(A){return GkA(A)||Za2(A)}function P01(A){return A.type.split("-").slice(1).join("-")}function Na2({lastMessage:A,messageId:Q}){return{message:(A==null?void 0:A.role)==="assistant"?A:{id:Q,metadata:void 0,role:"assistant",parts:[]},activeTextParts:{},activeReasoningParts:{},partialToolCalls:{}}}function za2({stream:A,messageMetadataSchema:Q,dataPartSchemas:B,runUpdateMessageJob:w,onError:$,onToolCall:f,onData:I}){return A.pipeThrough(new TransformStream({async transform(D,U){await w(async({state:Y,write:J})=>{var X,G,Z,N;function L(E){let y=Y.message.parts.filter(b01).find((T)=>T.toolCallId===E);if(y==null)throw new oj({chunkType:"tool-invocation",chunkId:E,message:`No tool invocation found for tool call ID "${E}".`});return y}function V(E){var S;let y=Y.message.parts.find((x)=>GkA(x)&&x.toolCallId===E.toolCallId),T=E,_=y;if(y!=null){if(y.state=E.state,_.input=T.input,_.output=T.output,_.errorText=T.errorText,_.rawInput=T.rawInput,_.preliminary=T.preliminary,E.title!==void 0)_.title=E.title;if(E.toolMetadata!==void 0)_.toolMetadata=E.toolMetadata;_.providerExecuted=(S=T.providerExecuted)!=null?S:y.providerExecuted;let x=T.providerMetadata;if(x!=null)if(E.state==="output-available"||E.state==="output-error"){let g=y;g.resultProviderMetadata=x}else y.callProviderMetadata=x}else Y.message.parts.push({type:`tool-${E.toolName}`,toolCallId:E.toolCallId,state:E.state,title:E.title,...E.toolMetadata!==void 0?{toolMetadata:E.toolMetadata}:{},input:T.input,output:T.output,rawInput:T.rawInput,errorText:T.errorText,providerExecuted:T.providerExecuted,preliminary:T.preliminary,...T.providerMetadata!=null&&(E.state==="output-available"||E.state==="output-error")?{resultProviderMetadata:T.providerMetadata}:{},...T.providerMetadata!=null&&!(E.state==="output-available"||E.state==="output-error")?{callProviderMetadata:T.providerMetadata}:{}})}function M(E){var S,y;let T=Y.message.parts.find((g)=>g.type==="dynamic-tool"&&g.toolCallId===E.toolCallId),_=E,x=T;if(T!=null){if(T.state=E.state,x.toolName=E.toolName,x.input=_.input,x.output=_.output,x.errorText=_.errorText,x.rawInput=(S=_.rawInput)!=null?S:x.rawInput,x.preliminary=_.preliminary,E.title!==void 0)x.title=E.title;if(E.toolMetadata!==void 0)x.toolMetadata=E.toolMetadata;x.providerExecuted=(y=_.providerExecuted)!=null?y:T.providerExecuted;let g=_.providerMetadata;if(g!=null)if(E.state==="output-available"||E.state==="output-error"){let n=T;n.resultProviderMetadata=g}else T.callProviderMetadata=g}else Y.message.parts.push({type:"dynamic-tool",toolName:E.toolName,toolCallId:E.toolCallId,state:E.state,input:_.input,output:_.output,errorText:_.errorText,preliminary:_.preliminary,providerExecuted:_.providerExecuted,title:E.title,...E.toolMetadata!==void 0?{toolMetadata:E.toolMetadata}:{},..._.providerMetadata!=null&&(E.state==="output-available"||E.state==="output-error")?{resultProviderMetadata:_.providerMetadata}:{},..._.providerMetadata!=null&&!(E.state==="output-available"||E.state==="output-error")?{callProviderMetadata:_.providerMetadata}:{}})}async function O(E){if(E!=null){let S=Y.message.metadata!=null?m01(Y.message.metadata,E):E;if(Q!=null)await XBA({value:S,schema:Q,context:{field:"message.metadata",entityId:Y.message.id}});Y.message.metadata=S}}switch(D.type){case"text-start":{let E={type:"text",text:"",providerMetadata:D.providerMetadata,state:"streaming"};Y.activeTextParts[D.id]=E,Y.message.parts.push(E),J();break}case"text-delta":{let E=Y.activeTextParts[D.id];if(E==null)throw new oj({chunkType:"text-delta",chunkId:D.id,message:`Received text-delta for missing text part with ID "${D.id}". Ensure a "text-start" chunk is sent before any "text-delta" chunks.`});E.text+=D.delta,E.providerMetadata=(X=D.providerMetadata)!=null?X:E.providerMetadata,J();break}case"text-end":{let E=Y.activeTextParts[D.id];if(E==null)throw new oj({chunkType:"text-end",chunkId:D.id,message:`Received text-end for missing text part with ID "${D.id}". Ensure a "text-start" chunk is sent before any "text-end" chunks.`});E.state="done",E.providerMetadata=(G=D.providerMetadata)!=null?G:E.providerMetadata,delete Y.activeTextParts[D.id],J();break}case"reasoning-start":{let E={type:"reasoning",text:"",providerMetadata:D.providerMetadata,state:"streaming"};Y.activeReasoningParts[D.id]=E,Y.message.parts.push(E),J();break}case"reasoning-delta":{let E=Y.activeReasoningParts[D.id];if(E==null)throw new oj({chunkType:"reasoning-delta",chunkId:D.id,message:`Received reasoning-delta for missing reasoning part with ID "${D.id}". Ensure a "reasoning-start" chunk is sent before any "reasoning-delta" chunks.`});E.text+=D.delta,E.providerMetadata=(Z=D.providerMetadata)!=null?Z:E.providerMetadata,J();break}case"reasoning-end":{let E=Y.activeReasoningParts[D.id];if(E==null)throw new oj({chunkType:"reasoning-end",chunkId:D.id,message:`Received reasoning-end for missing reasoning part with ID "${D.id}". Ensure a "reasoning-start" chunk is sent before any "reasoning-end" chunks.`});E.providerMetadata=(N=D.providerMetadata)!=null?N:E.providerMetadata,E.state="done",delete Y.activeReasoningParts[D.id],J();break}case"file":{Y.message.parts.push({type:"file",mediaType:D.mediaType,url:D.url,...D.providerMetadata!=null?{providerMetadata:D.providerMetadata}:{}}),J();break}case"source-url":{Y.message.parts.push({type:"source-url",sourceId:D.sourceId,url:D.url,title:D.title,providerMetadata:D.providerMetadata}),J();break}case"source-document":{Y.message.parts.push({type:"source-document",sourceId:D.sourceId,mediaType:D.mediaType,title:D.title,filename:D.filename,providerMetadata:D.providerMetadata}),J();break}case"tool-input-start":{let E=Y.message.parts.filter(GkA);if(Y.partialToolCalls[D.toolCallId]={text:"",toolName:D.toolName,index:E.length,dynamic:D.dynamic,title:D.title,toolMetadata:D.toolMetadata},D.dynamic)M({toolCallId:D.toolCallId,toolName:D.toolName,state:"input-streaming",input:void 0,providerExecuted:D.providerExecuted,title:D.title,toolMetadata:D.toolMetadata,providerMetadata:D.providerMetadata});else V({toolCallId:D.toolCallId,toolName:D.toolName,state:"input-streaming",input:void 0,providerExecuted:D.providerExecuted,title:D.title,toolMetadata:D.toolMetadata,providerMetadata:D.providerMetadata});J();break}case"tool-input-delta":{let E=Y.partialToolCalls[D.toolCallId];if(E==null)throw new oj({chunkType:"tool-input-delta",chunkId:D.toolCallId,message:`Received tool-input-delta for missing tool call with ID "${D.toolCallId}". Ensure a "tool-input-start" chunk is sent before any "tool-input-delta" chunks.`});E.text+=D.inputTextDelta;let{value:S}=await rc(E.text);if(E.dynamic)M({toolCallId:D.toolCallId,toolName:E.toolName,state:"input-streaming",input:S,title:E.title,toolMetadata:E.toolMetadata});else V({toolCallId:D.toolCallId,toolName:E.toolName,state:"input-streaming",input:S,title:E.title,toolMetadata:E.toolMetadata});J();break}case"tool-input-available":{if(D.dynamic)M({toolCallId:D.toolCallId,toolName:D.toolName,state:"input-available",input:D.input,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,title:D.title,toolMetadata:D.toolMetadata});else V({toolCallId:D.toolCallId,toolName:D.toolName,state:"input-available",input:D.input,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,title:D.title,toolMetadata:D.toolMetadata});if(J(),f&&!D.providerExecuted)await f({toolCall:D});break}case"tool-input-error":{let E=Y.message.parts.filter(b01).find((y)=>y.toolCallId===D.toolCallId);if(E!=null?E.type==="dynamic-tool":!!D.dynamic)M({toolCallId:D.toolCallId,toolName:D.toolName,state:"output-error",input:D.input,errorText:D.errorText,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,toolMetadata:D.toolMetadata});else V({toolCallId:D.toolCallId,toolName:D.toolName,state:"output-error",input:void 0,rawInput:D.input,errorText:D.errorText,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,toolMetadata:D.toolMetadata});J();break}case"tool-approval-request":{let E=L(D.toolCallId);E.state="approval-requested",E.approval={id:D.approvalId},J();break}case"tool-output-denied":{let E=L(D.toolCallId);E.state="output-denied",J();break}case"tool-output-available":{let E=L(D.toolCallId);if(E.type==="dynamic-tool")M({toolCallId:D.toolCallId,toolName:E.toolName,state:"output-available",input:E.input,output:D.output,preliminary:D.preliminary,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,title:E.title,toolMetadata:E.toolMetadata});else V({toolCallId:D.toolCallId,toolName:P01(E),state:"output-available",input:E.input,output:D.output,providerExecuted:D.providerExecuted,preliminary:D.preliminary,providerMetadata:D.providerMetadata,title:E.title,toolMetadata:E.toolMetadata});J();break}case"tool-output-error":{let E=L(D.toolCallId);if(E.type==="dynamic-tool")M({toolCallId:D.toolCallId,toolName:E.toolName,state:"output-error",input:E.input,errorText:D.errorText,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,title:E.title,toolMetadata:E.toolMetadata});else V({toolCallId:D.toolCallId,toolName:P01(E),state:"output-error",input:E.input,rawInput:E.rawInput,errorText:D.errorText,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,title:E.title,toolMetadata:E.toolMetadata});J();break}case"start-step":{Y.message.parts.push({type:"step-start"});break}case"finish-step":{Y.activeTextParts={},Y.activeReasoningParts={};break}case"start":{if(D.messageId!=null)Y.message.id=D.messageId;if(await O(D.messageMetadata),D.messageId!=null||D.messageMetadata!=null)J();break}case"finish":{if(D.finishReason!=null)Y.finishReason=D.finishReason;if(await O(D.messageMetadata),D.messageMetadata!=null)J();break}case"message-metadata":{if(await O(D.messageMetadata),D.messageMetadata!=null)J();break}case"error":{$==null||$(Error(D.errorText));break}default:if(Fa2(D)){if((B==null?void 0:B[D.type])!=null){let y=Y.message.parts.findIndex((_)=>("id"in _)&&("data"in _)&&_.id===D.id&&_.type===D.type),T=y>=0?y:Y.message.parts.length;await XBA({value:D.data,schema:B[D.type],context:{field:`message.parts[${T}].data`,entityName:D.type,entityId:D.id}})}let E=D;if(E.transient){I==null||I(E);break}let S=E.id!=null?Y.message.parts.find((y)=>E.type===y.type&&E.id===y.id):void 0;if(S!=null)S.data=E.data;else Y.message.parts.push(E);I==null||I(E),J()}}U.enqueue(D)})}}))}function qa2({messageId:A,originalMessages:Q=[],onStepFinish:B,onFinish:w,onError:$,stream:f}){let I=Q==null?void 0:Q[Q.length-1];if((I==null?void 0:I.role)!=="assistant")I=void 0;else A=I.id;let D=!1,U=f.pipeThrough(new TransformStream({transform(N,L){if(N.type==="start"){let V=N;if(V.messageId==null&&A!=null)V.messageId=A}if(N.type==="abort")D=!0;L.enqueue(N)}}));if(w==null&&B==null)return U;let Y=Na2({lastMessage:I?structuredClone(I):void 0,messageId:A!=null?A:""}),J=async(N)=>{await N({state:Y,write:()=>{}})},X=!1,G=async()=>{if(X||!w)return;X=!0;let N=Y.message.id===(I==null?void 0:I.id);await w({isAborted:D,isContinuation:N,responseMessage:Y.message,messages:[...N?Q.slice(0,-1):Q,Y.message],finishReason:Y.finishReason})},Z=async()=>{if(!B)return;let N=Y.message.id===(I==null?void 0:I.id);try{await B({isContinuation:N,responseMessage:structuredClone(Y.message),messages:[...N?Q.slice(0,-1):Q,structuredClone(Y.message)]})}catch(L){$(L)}};return za2({stream:U,runUpdateMessageJob:J,onError:$}).pipeThrough(new TransformStream({async transform(N,L){if(N.type==="finish-step")await Z();L.enqueue(N)},async cancel(){await G()},async flush(){await G()}}))}var GNw=fF({prefix:"aitxt",size:24});function c01({execute:A,onError:Q=XkA,originalMessages:B,onStepFinish:w,onFinish:$,generateId:f=V01}){let I,D=[],U=new ReadableStream({start(X){I=X}});function Y(X){try{I.enqueue(X)}catch(G){}}try{let X=A({writer:{write(G){Y(G)},merge(G){D.push((async()=>{let Z=G.getReader();while(!0){let{done:N,value:L}=await Z.read();if(N)break;Y(L)}})().catch((Z)=>{Y({type:"error",errorText:Q(Z)})}))},onError:Q}});if(X)D.push(X.catch((G)=>{Y({type:"error",errorText:Q(G)})}))}catch(X){Y({type:"error",errorText:Q(X)})}return new Promise(async(X)=>{while(D.length>0)await D.shift();X()}).finally(()=>{try{I.close()}catch(X){}}),qa2({stream:U,messageId:f(),originalMessages:B,onStepFinish:w,onFinish:$,onError:Q})}var _f=K.record(K.string(),wM.optional()),NNw=UBA(()=>pc(K.array(K.object({id:K.string(),role:K.enum(["system","user","assistant"]),metadata:K.unknown().optional(),parts:K.array(K.union([K.object({type:K.literal("text"),text:K.string(),state:K.enum(["streaming","done"]).optional(),providerMetadata:N2.optional()}),K.object({type:K.literal("reasoning"),text:K.string(),state:K.enum(["streaming","done"]).optional(),providerMetadata:N2.optional()}),K.object({type:K.literal("source-url"),sourceId:K.string(),url:K.string(),title:K.string().optional(),providerMetadata:N2.optional()}),K.object({type:K.literal("source-document"),sourceId:K.string(),mediaType:K.string(),title:K.string(),filename:K.string().optional(),providerMetadata:N2.optional()}),K.object({type:K.literal("file"),mediaType:K.string(),filename:K.string().optional(),url:K.string(),providerMetadata:N2.optional()}),K.object({type:K.literal("step-start")}),K.object({type:K.string().startsWith("data-"),id:K.string().optional(),data:K.unknown()}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("input-streaming"),input:K.unknown().optional(),providerExecuted:K.boolean().optional(),callProviderMetadata:N2.optional(),output:K.never().optional(),errorText:K.never().optional(),approval:K.never().optional()}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("input-available"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.never().optional()}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("approval-requested"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.never().optional(),reason:K.never().optional()})}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("approval-responded"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.boolean(),reason:K.string().optional()})}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("output-available"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.unknown(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),resultProviderMetadata:N2.optional(),preliminary:K.boolean().optional(),approval:K.object({id:K.string(),approved:K.literal(!0),reason:K.string().optional()}).optional()}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("output-error"),input:K.unknown().optional(),rawInput:K.unknown().optional(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.string(),callProviderMetadata:N2.optional(),resultProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.literal(!0),reason:K.string().optional()}).optional()}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("output-denied"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.literal(!1),reason:K.string().optional()})}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("input-streaming"),providerExecuted:K.boolean().optional(),callProviderMetadata:N2.optional(),input:K.unknown().optional(),output:K.never().optional(),errorText:K.never().optional(),approval:K.never().optional()}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("input-available"),providerExecuted:K.boolean().optional(),input:K.unknown(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.never().optional()}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("approval-requested"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.never().optional(),reason:K.never().optional()})}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("approval-responded"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.boolean(),reason:K.string().optional()})}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("output-available"),providerExecuted:K.boolean().optional(),input:K.unknown(),output:K.unknown(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),resultProviderMetadata:N2.optional(),preliminary:K.boolean().optional(),approval:K.object({id:K.string(),approved:K.literal(!0),reason:K.string().optional()}).optional()}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("output-error"),providerExecuted:K.boolean().optional(),input:K.unknown().optional(),rawInput:K.unknown().optional(),output:K.never().optional(),errorText:K.string(),callProviderMetadata:N2.optional(),resultProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.literal(!0),reason:K.string().optional()}).optional()}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("output-denied"),providerExecuted:K.boolean().optional(),input:K.unknown(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.literal(!1),reason:K.string().optional()})})])).nonempty("Message must contain at least one part")})).nonempty("Messages array must not be empty")));var qNw=fF({prefix:"aiobj",size:24});function l01(A){return({url:Q,abortSignal:B})=>os2({url:Q,maxBytes:A==null?void 0:A.maxBytes,abortSignal:B})}var VNw=fF({prefix:"aiobj",size:24});var ENw=l01();var La2="AI_NoSuchProviderError",Va2=`vercel.ai.error.${La2}`,Ea2=Symbol.for(Va2),Ma2;Ma2=Ea2;var MNw=l01();var p01={name:"@brains/web-chat",private:!0,version:"0.2.0-alpha.119",description:"Web chat interface for Brains",type:"module",exports:{".":"./src/index.ts"},files:["src","dist","package.json"],scripts:{build:"bun scripts/build-ui.ts","build:ui":"bun scripts/build-ui.ts",typecheck:"tsc --noEmit && tsc --noEmit -p ui-react/tsconfig.json",lint:"eslint . --ext .ts,.tsx","lint:fix":"eslint . --ext .ts,.tsx --fix",test:"bun test"},dependencies:{"@ai-sdk/react":"^3.0.116","@brains/auth-service":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*","@streamdown/cjk":"^1.0.3","@streamdown/code":"^1.1.1","@streamdown/math":"^1.0.2","@streamdown/mermaid":"^1.0.2",ai:"^6.0.86","class-variance-authority":"^0.7.0",cmdk:"^1.1.1","lucide-react":"^1.16.0",nanoid:"^5.0.4","radix-ui":"^1.4.3",react:"^19.2.6","react-dom":"^19.2.6",shiki:"^4.1.0",streamdown:"^2.5.0","use-stick-to-bottom":"^1.1.4"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","@types/react":"^19.0.3","@types/react-dom":"^19.0.3",typescript:"^5.3.3",vite:"^7.2.4"}};async function i01(A,Q){if(!await Q.resolveOperatorSession(A))return Q.createOperatorLoginRequiredResponse(A);let B=new URL(A.url),w=B.searchParams.get("id")?.trim();if(!w)return new Response("Missing document id",{status:400});let $=await Q.entityService.getEntity({entityType:"document",id:w});if(!$)return new Response("Document not found",{status:404});let f=Oa2($.content);if(!f)return new Response("Document content is not a PDF",{status:415});let I=ba2($.metadata,w);return d01({requestUrl:B,data:f.data,mediaType:f.mimeType,filename:I})}async function r01(A,Q){if(!await Q.resolveOperatorSession(A))return Q.createOperatorLoginRequiredResponse(A);let B=new URL(A.url),w=B.searchParams.get("id")?.trim();if(!w)return new Response("Missing image id",{status:400});let $=await Q.entityService.getEntity({entityType:"image",id:w});if(!$)return new Response("Image not found",{status:404});let f=Ra2($.content);if(!f)return new Response("Image content is not an image",{status:415});let I=Pa2($.metadata,w,f.mimeType);return d01({requestUrl:B,data:f.data,mediaType:f.mimeType,filename:I})}function d01(A){let Q=new Headers({"Content-Type":A.mediaType,"Content-Length":String(A.data.byteLength),"Content-Disposition":`${A.requestUrl.searchParams.has("download")?"attachment":"inline"}; filename="${ka2(A.filename)}"`});return new Response(A.data,{headers:Q})}function n01(A,Q){let B=A.match(/^data:([^;]+);base64,(.+)$/i);if(!B)return null;let[,w,$]=B;if(!w||!$||!Q.test(w))return null;let f=Buffer.from($,"base64"),I=f.buffer.slice(f.byteOffset,f.byteOffset+f.byteLength);return{mimeType:w,data:I}}function Oa2(A){let Q=n01(A,/^application\/pdf$/i);if(Q?.mimeType.toLowerCase()!=="application/pdf")return null;return{mimeType:"application/pdf",data:Q.data}}function Ra2(A){return n01(A,/^image\/[a-z0-9.+-]+$/i)}function ba2(A,Q){let B=A?.filename;return typeof B==="string"&&B.length>0?B:`${Q}.pdf`}function Pa2(A,Q,B){let w=A?.filename;if(typeof w==="string"&&w.length>0)return w;let $=A?.format;if(typeof $==="string"&&$.length>0)return`${Q}.${$==="jpeg"?"jpg":$}`;let f=B.split("/")[1];return`${Q}.${f&&f.length>0?f:"png"}`}function ka2(A){return A.replace(/["\\\r\n]/g,"_")}WA();aA();var dc="upload",o01=TR;var ja2={namespace:"upload",refKind:dc,routePath:"/api/chat/uploads"};function WBA(){return ja2}aA();var a01="upload.txt";var t01=5000000,_a2=[".md",".txt",".markdown"],va2=["text/plain","text/markdown","text/x-markdown"],KkA=new Map([[".png","image/png"],[".jpg","image/jpeg"],[".jpeg","image/jpeg"],[".webp","image/webp"],[".gif","image/gif"],[".pdf","application/pdf"]]),Ta2=new Set(KkA.values());function GBA(A){let Q=A.split(/[\\/]/).at(-1)?.trim()??"",B=Array.from(Q).filter((w)=>{let $=w.charCodeAt(0);return $>31&&$!==127}).join("").slice(0,160);return B.length>0?B:"upload.txt"}function e01(A,Q){let B=Q?.trim()??"";if(B.length>0)return B;let w=A.toLowerCase();if(w.endsWith(".md")||w.endsWith(".markdown"))return"text/markdown";if(w.endsWith(".txt"))return"text/plain";return"application/octet-stream"}function A11(A,Q){let B=Q?.trim()??"",w=B.split(";",1)[0]?.toLowerCase()??B;if(w.length>0&&w!=="application/octet-stream")return w;let $=e01(A,void 0);if($!=="application/octet-stream")return $;let f=A.toLowerCase();for(let[I,D]of KkA)if(f.endsWith(I))return D;return"application/octet-stream"}function Q11(A,Q){if(Q&&va2.some((B)=>Q.toLowerCase().startsWith(B)))return!0;return _a2.some((B)=>A.toLowerCase().endsWith(B))}function ya2(A){return A<=1e5}function xa2(A){return A<=5000000}function Sa2(A,Q){let B=A11(A,Q);if(Ta2.has(B))return!0;return KkA.has(ma2(A))}function ga2(A){if(A.includes(0))return!1;try{return new TextDecoder("utf-8",{fatal:!0}).decode(A),!0}catch{return!1}}function ha2(A){let Q=GBA(A.filename),B=e01(Q,A.mediaType);if(!Q11(Q,B))return{ok:!1,code:"unsupported_type",message:`Unsupported file upload type: ${Q}`};if(!ya2(A.content.byteLength))return{ok:!1,code:"file_too_large",message:`File upload too large: ${Q}`};if(!ga2(A.content))return{ok:!1,code:"binary_content",message:`Unsupported file upload type: ${Q}`};return{ok:!0,filename:Q,mediaType:B,sizeBytes:A.content.byteLength,text:new TextDecoder("utf-8").decode(A.content).replace(/^\uFEFF/,"")}}function KBA(A){let Q=GBA(A.filename),B=A11(Q,A.mediaType);if(Q11(Q,B)){let w=ha2({filename:Q,mediaType:B,content:A.content});return w.ok?{...w,kind:"text"}:w}if(!Sa2(Q,B))return{ok:!1,code:"unsupported_type",message:`Unsupported file upload type: ${Q}`};if(!xa2(A.content.byteLength))return{ok:!1,code:"file_too_large",message:`File upload too large: ${Q}`};if(!ua2(A.content,B))return{ok:!1,code:"unsupported_type",message:`Unsupported file upload type: ${Q}`};return{ok:!0,kind:"file",filename:Q,mediaType:B,sizeBytes:A.content.byteLength}}function ma2(A){let Q=A.lastIndexOf(".");return Q>=0?A.slice(Q).toLowerCase():""}function ua2(A,Q){switch(Q){case"image/png":return s01(A,[137,80,78,71]);case"image/jpeg":return s01(A,[255,216,255]);case"image/gif":return HBA(A,"GIF87a")||HBA(A,"GIF89a");case"image/webp":return HBA(A,"RIFF")&&B11(A,"WEBP",8);case"application/pdf":return HBA(A,"%PDF-");default:return!1}}function s01(A,Q){return Q.every((B,w)=>A[w]===B)}function HBA(A,Q){return B11(A,Q,0)}function B11(A,Q,B){return Array.from(Q).every((w,$)=>A[B+$]===w.charCodeAt(0))}var ca2="file",la2=16384;async function w11(A,Q){if(!await Q.resolveOperatorSession(A))return new Response("Forbidden",{status:403});let B=Number(A.headers.get("content-length"));if(Number.isFinite(B)&&B>t01+la2)return new Response("File upload too large",{status:400});let w;try{w=await A.formData()}catch{return new Response("Invalid multipart upload",{status:400})}let $=w.get(ca2);if(!($ instanceof File))return new Response("Missing upload file",{status:400});let f=Buffer.from(await $.arrayBuffer()),I=KBA({filename:$.name,mediaType:$.type,content:f});if(!I.ok)return new Response(I.message,{status:400});let D=Q.getUploadStore(),U=await D.save({filename:I.filename,mediaType:I.mediaType,content:f});return Response.json(D.toResponseBody(U),{status:201})}async function $11(A,Q){if(!await Q.resolveOperatorSession(A))return new Response("Forbidden",{status:403});let B=new URL(A.url).searchParams.get("id")?.trim();if(!B)return new Response("Missing upload id",{status:400});let w=await D11(B,Q.getUploadStore());if(w instanceof Response)return w;let{record:$,content:f}=w,I=U11($,f);if(I instanceof Response)return I;let D=new URL(A.url).searchParams.has("download")?"attachment":"inline",U=new Uint8Array(f).buffer;return new Response(U,{headers:{"Content-Type":$.mediaType,"Content-Length":String(f.byteLength),"Content-Disposition":`${D}; filename="${ra2($.filename)}"`}})}function f11(A){let Q=GBA(A.filename??a01),B=ia2(A.url);if(!B)return new Response(`Unsupported file upload URL: ${Q}`,{status:400});let w=KBA({filename:Q,mediaType:A.mediaType,content:B.buffer});if(!w.ok)return new Response(w.message,{status:400});return Y11(w,B.buffer)}async function I11(A,Q){let B=await D11(A,Q);if(B instanceof Response)return B;let{record:w,content:$}=B,f=U11(w,$);if(f instanceof Response)return f;return Y11(f,$,{kind:dc,id:A})}async function D11(A,Q){try{return await Q.read(A)}catch(B){if(B instanceof AW)return pa2(B);throw B}}function U11(A,Q){let B=KBA({filename:A.filename,mediaType:A.mediaType,content:Q});if(!B.ok)return new Response(B.message,{status:400});return B}function Y11(A,Q,B){if(A.kind==="text")return{kind:"text",filename:A.filename,mediaType:A.mediaType,content:A.text,sizeBytes:A.sizeBytes,...B!==void 0?{source:B}:{}};return{kind:"file",filename:A.filename,mediaType:A.mediaType,data:new Uint8Array(Q),sizeBytes:A.sizeBytes,...B!==void 0?{source:B}:{}}}function pa2(A){switch(A.code){case"invalid_ref":return new Response("Invalid upload ref",{status:400});case"invalid_metadata":return new Response("Invalid upload metadata",{status:500});case"not_found":return new Response("Upload not found",{status:404})}}function ia2(A){let Q=/^data:[^,]*,(.*)$/s.exec(A);if(!Q)return null;let w=A.slice(5,A.indexOf(",")).split(";").some(($)=>$.toLowerCase()==="base64");try{let $=w?Buffer.from(Q[1]??"","base64"):Buffer.from(decodeURIComponent(Q[1]??""),"utf8");return{buffer:$,byteLength:$.byteLength}}catch{return null}}function ra2(A){return A.replace(/["\\\r\n]/g,"_")}var da2=H.object({type:H.literal("text"),text:H.string()}),na2=H.object({type:H.literal("file"),mediaType:H.string().optional(),filename:H.string().optional(),url:H.string()}),oa2=H.object({state:H.literal("approval-responded"),approval:H.object({id:H.string(),approved:H.boolean()})}).passthrough(),sa2=H.object({role:H.string(),parts:H.array(H.unknown()).optional(),content:H.string().optional()}),J11=H.object({id:H.string().optional(),messages:H.array(sa2).min(1),trigger:H.string().optional()}),aa2=H.object({kind:H.literal(dc),id:H.string().regex(o01)}),ta2=H.object({type:H.literal("data-upload"),data:H.object({ref:aa2})});async function X11(A,Q){let B=ea2(A);if(!B)return{message:"",attachments:[]};let w=[],$=[];for(let I of B.parts??[]){let D=da2.safeParse(I);if(D.success){if(D.data.text.length>0)w.push(D.data.text);continue}let U=na2.safeParse(I);if(U.success){let J=f11(U.data);if(J instanceof Response)return J;$.push(J);continue}let Y=ta2.safeParse(I);if(Y.success){let J=await I11(Y.data.data.ref.id,Q.uploadStore);if(J instanceof Response)return J;$.push(J);continue}if(At2(I)==="data-upload")return new Response("Invalid upload ref",{status:400})}return{message:w.length>0?w.join(`
|
|
2478
|
+
`)}})}},Ka2={"content-type":"text/event-stream","cache-control":"no-cache",connection:"keep-alive","x-vercel-ai-ui-message-stream":"v1","x-accel-buffering":"no"};function u01({status:A,statusText:Q,headers:B,stream:w,consumeSseStream:$}){let f=w.pipeThrough(new Ga2);if($){let[I,D]=f.tee();f=I,$({stream:D})}return new Response(f.pipeThrough(new TextEncoderStream),{status:A,statusText:Q,headers:Ha2(B,Ka2)})}var ic=K.record(K.string(),wM.optional()),HNw=UBA(()=>pc(K.union([K.strictObject({type:K.literal("text-start"),id:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("text-delta"),id:K.string(),delta:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("text-end"),id:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("error"),errorText:K.string()}),K.strictObject({type:K.literal("tool-input-start"),toolCallId:K.string(),toolName:K.string(),providerExecuted:K.boolean().optional(),providerMetadata:N2.optional(),toolMetadata:ic.optional(),dynamic:K.boolean().optional(),title:K.string().optional()}),K.strictObject({type:K.literal("tool-input-delta"),toolCallId:K.string(),inputTextDelta:K.string()}),K.strictObject({type:K.literal("tool-input-available"),toolCallId:K.string(),toolName:K.string(),input:K.unknown(),providerExecuted:K.boolean().optional(),providerMetadata:N2.optional(),toolMetadata:ic.optional(),dynamic:K.boolean().optional(),title:K.string().optional()}),K.strictObject({type:K.literal("tool-input-error"),toolCallId:K.string(),toolName:K.string(),input:K.unknown(),providerExecuted:K.boolean().optional(),providerMetadata:N2.optional(),toolMetadata:ic.optional(),dynamic:K.boolean().optional(),errorText:K.string(),title:K.string().optional()}),K.strictObject({type:K.literal("tool-approval-request"),approvalId:K.string(),toolCallId:K.string()}),K.strictObject({type:K.literal("tool-output-available"),toolCallId:K.string(),output:K.unknown(),providerExecuted:K.boolean().optional(),providerMetadata:N2.optional(),toolMetadata:ic.optional(),dynamic:K.boolean().optional(),preliminary:K.boolean().optional()}),K.strictObject({type:K.literal("tool-output-error"),toolCallId:K.string(),errorText:K.string(),providerExecuted:K.boolean().optional(),providerMetadata:N2.optional(),toolMetadata:ic.optional(),dynamic:K.boolean().optional()}),K.strictObject({type:K.literal("tool-output-denied"),toolCallId:K.string()}),K.strictObject({type:K.literal("reasoning-start"),id:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("reasoning-delta"),id:K.string(),delta:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("reasoning-end"),id:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("source-url"),sourceId:K.string(),url:K.string(),title:K.string().optional(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("source-document"),sourceId:K.string(),mediaType:K.string(),title:K.string(),filename:K.string().optional(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("file"),url:K.string(),mediaType:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.custom((A)=>typeof A==="string"&&A.startsWith("data-"),{message:'Type must start with "data-"'}),id:K.string().optional(),data:K.unknown(),transient:K.boolean().optional()}),K.strictObject({type:K.literal("start-step")}),K.strictObject({type:K.literal("finish-step")}),K.strictObject({type:K.literal("start"),messageId:K.string().optional(),messageMetadata:K.unknown().optional()}),K.strictObject({type:K.literal("finish"),finishReason:K.enum(["stop","length","content-filter","tool-calls","error","other"]).optional(),messageMetadata:K.unknown().optional()}),K.strictObject({type:K.literal("abort"),reason:K.string().optional()}),K.strictObject({type:K.literal("message-metadata"),messageMetadata:K.unknown()})])));function Fa2(A){return A.type.startsWith("data-")}function GkA(A){return A.type.startsWith("tool-")}function Za2(A){return A.type==="dynamic-tool"}function b01(A){return GkA(A)||Za2(A)}function P01(A){return A.type.split("-").slice(1).join("-")}function Na2({lastMessage:A,messageId:Q}){return{message:(A==null?void 0:A.role)==="assistant"?A:{id:Q,metadata:void 0,role:"assistant",parts:[]},activeTextParts:{},activeReasoningParts:{},partialToolCalls:{}}}function za2({stream:A,messageMetadataSchema:Q,dataPartSchemas:B,runUpdateMessageJob:w,onError:$,onToolCall:f,onData:I}){return A.pipeThrough(new TransformStream({async transform(D,U){await w(async({state:Y,write:J})=>{var X,G,Z,N;function L(E){let y=Y.message.parts.filter(b01).find((T)=>T.toolCallId===E);if(y==null)throw new oj({chunkType:"tool-invocation",chunkId:E,message:`No tool invocation found for tool call ID "${E}".`});return y}function V(E){var S;let y=Y.message.parts.find((x)=>GkA(x)&&x.toolCallId===E.toolCallId),T=E,_=y;if(y!=null){if(y.state=E.state,_.input=T.input,_.output=T.output,_.errorText=T.errorText,_.rawInput=T.rawInput,_.preliminary=T.preliminary,E.title!==void 0)_.title=E.title;if(E.toolMetadata!==void 0)_.toolMetadata=E.toolMetadata;_.providerExecuted=(S=T.providerExecuted)!=null?S:y.providerExecuted;let x=T.providerMetadata;if(x!=null)if(E.state==="output-available"||E.state==="output-error"){let g=y;g.resultProviderMetadata=x}else y.callProviderMetadata=x}else Y.message.parts.push({type:`tool-${E.toolName}`,toolCallId:E.toolCallId,state:E.state,title:E.title,...E.toolMetadata!==void 0?{toolMetadata:E.toolMetadata}:{},input:T.input,output:T.output,rawInput:T.rawInput,errorText:T.errorText,providerExecuted:T.providerExecuted,preliminary:T.preliminary,...T.providerMetadata!=null&&(E.state==="output-available"||E.state==="output-error")?{resultProviderMetadata:T.providerMetadata}:{},...T.providerMetadata!=null&&!(E.state==="output-available"||E.state==="output-error")?{callProviderMetadata:T.providerMetadata}:{}})}function M(E){var S,y;let T=Y.message.parts.find((g)=>g.type==="dynamic-tool"&&g.toolCallId===E.toolCallId),_=E,x=T;if(T!=null){if(T.state=E.state,x.toolName=E.toolName,x.input=_.input,x.output=_.output,x.errorText=_.errorText,x.rawInput=(S=_.rawInput)!=null?S:x.rawInput,x.preliminary=_.preliminary,E.title!==void 0)x.title=E.title;if(E.toolMetadata!==void 0)x.toolMetadata=E.toolMetadata;x.providerExecuted=(y=_.providerExecuted)!=null?y:T.providerExecuted;let g=_.providerMetadata;if(g!=null)if(E.state==="output-available"||E.state==="output-error"){let n=T;n.resultProviderMetadata=g}else T.callProviderMetadata=g}else Y.message.parts.push({type:"dynamic-tool",toolName:E.toolName,toolCallId:E.toolCallId,state:E.state,input:_.input,output:_.output,errorText:_.errorText,preliminary:_.preliminary,providerExecuted:_.providerExecuted,title:E.title,...E.toolMetadata!==void 0?{toolMetadata:E.toolMetadata}:{},..._.providerMetadata!=null&&(E.state==="output-available"||E.state==="output-error")?{resultProviderMetadata:_.providerMetadata}:{},..._.providerMetadata!=null&&!(E.state==="output-available"||E.state==="output-error")?{callProviderMetadata:_.providerMetadata}:{}})}async function O(E){if(E!=null){let S=Y.message.metadata!=null?m01(Y.message.metadata,E):E;if(Q!=null)await XBA({value:S,schema:Q,context:{field:"message.metadata",entityId:Y.message.id}});Y.message.metadata=S}}switch(D.type){case"text-start":{let E={type:"text",text:"",providerMetadata:D.providerMetadata,state:"streaming"};Y.activeTextParts[D.id]=E,Y.message.parts.push(E),J();break}case"text-delta":{let E=Y.activeTextParts[D.id];if(E==null)throw new oj({chunkType:"text-delta",chunkId:D.id,message:`Received text-delta for missing text part with ID "${D.id}". Ensure a "text-start" chunk is sent before any "text-delta" chunks.`});E.text+=D.delta,E.providerMetadata=(X=D.providerMetadata)!=null?X:E.providerMetadata,J();break}case"text-end":{let E=Y.activeTextParts[D.id];if(E==null)throw new oj({chunkType:"text-end",chunkId:D.id,message:`Received text-end for missing text part with ID "${D.id}". Ensure a "text-start" chunk is sent before any "text-end" chunks.`});E.state="done",E.providerMetadata=(G=D.providerMetadata)!=null?G:E.providerMetadata,delete Y.activeTextParts[D.id],J();break}case"reasoning-start":{let E={type:"reasoning",text:"",providerMetadata:D.providerMetadata,state:"streaming"};Y.activeReasoningParts[D.id]=E,Y.message.parts.push(E),J();break}case"reasoning-delta":{let E=Y.activeReasoningParts[D.id];if(E==null)throw new oj({chunkType:"reasoning-delta",chunkId:D.id,message:`Received reasoning-delta for missing reasoning part with ID "${D.id}". Ensure a "reasoning-start" chunk is sent before any "reasoning-delta" chunks.`});E.text+=D.delta,E.providerMetadata=(Z=D.providerMetadata)!=null?Z:E.providerMetadata,J();break}case"reasoning-end":{let E=Y.activeReasoningParts[D.id];if(E==null)throw new oj({chunkType:"reasoning-end",chunkId:D.id,message:`Received reasoning-end for missing reasoning part with ID "${D.id}". Ensure a "reasoning-start" chunk is sent before any "reasoning-end" chunks.`});E.providerMetadata=(N=D.providerMetadata)!=null?N:E.providerMetadata,E.state="done",delete Y.activeReasoningParts[D.id],J();break}case"file":{Y.message.parts.push({type:"file",mediaType:D.mediaType,url:D.url,...D.providerMetadata!=null?{providerMetadata:D.providerMetadata}:{}}),J();break}case"source-url":{Y.message.parts.push({type:"source-url",sourceId:D.sourceId,url:D.url,title:D.title,providerMetadata:D.providerMetadata}),J();break}case"source-document":{Y.message.parts.push({type:"source-document",sourceId:D.sourceId,mediaType:D.mediaType,title:D.title,filename:D.filename,providerMetadata:D.providerMetadata}),J();break}case"tool-input-start":{let E=Y.message.parts.filter(GkA);if(Y.partialToolCalls[D.toolCallId]={text:"",toolName:D.toolName,index:E.length,dynamic:D.dynamic,title:D.title,toolMetadata:D.toolMetadata},D.dynamic)M({toolCallId:D.toolCallId,toolName:D.toolName,state:"input-streaming",input:void 0,providerExecuted:D.providerExecuted,title:D.title,toolMetadata:D.toolMetadata,providerMetadata:D.providerMetadata});else V({toolCallId:D.toolCallId,toolName:D.toolName,state:"input-streaming",input:void 0,providerExecuted:D.providerExecuted,title:D.title,toolMetadata:D.toolMetadata,providerMetadata:D.providerMetadata});J();break}case"tool-input-delta":{let E=Y.partialToolCalls[D.toolCallId];if(E==null)throw new oj({chunkType:"tool-input-delta",chunkId:D.toolCallId,message:`Received tool-input-delta for missing tool call with ID "${D.toolCallId}". Ensure a "tool-input-start" chunk is sent before any "tool-input-delta" chunks.`});E.text+=D.inputTextDelta;let{value:S}=await rc(E.text);if(E.dynamic)M({toolCallId:D.toolCallId,toolName:E.toolName,state:"input-streaming",input:S,title:E.title,toolMetadata:E.toolMetadata});else V({toolCallId:D.toolCallId,toolName:E.toolName,state:"input-streaming",input:S,title:E.title,toolMetadata:E.toolMetadata});J();break}case"tool-input-available":{if(D.dynamic)M({toolCallId:D.toolCallId,toolName:D.toolName,state:"input-available",input:D.input,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,title:D.title,toolMetadata:D.toolMetadata});else V({toolCallId:D.toolCallId,toolName:D.toolName,state:"input-available",input:D.input,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,title:D.title,toolMetadata:D.toolMetadata});if(J(),f&&!D.providerExecuted)await f({toolCall:D});break}case"tool-input-error":{let E=Y.message.parts.filter(b01).find((y)=>y.toolCallId===D.toolCallId);if(E!=null?E.type==="dynamic-tool":!!D.dynamic)M({toolCallId:D.toolCallId,toolName:D.toolName,state:"output-error",input:D.input,errorText:D.errorText,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,toolMetadata:D.toolMetadata});else V({toolCallId:D.toolCallId,toolName:D.toolName,state:"output-error",input:void 0,rawInput:D.input,errorText:D.errorText,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,toolMetadata:D.toolMetadata});J();break}case"tool-approval-request":{let E=L(D.toolCallId);E.state="approval-requested",E.approval={id:D.approvalId},J();break}case"tool-output-denied":{let E=L(D.toolCallId);E.state="output-denied",J();break}case"tool-output-available":{let E=L(D.toolCallId);if(E.type==="dynamic-tool")M({toolCallId:D.toolCallId,toolName:E.toolName,state:"output-available",input:E.input,output:D.output,preliminary:D.preliminary,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,title:E.title,toolMetadata:E.toolMetadata});else V({toolCallId:D.toolCallId,toolName:P01(E),state:"output-available",input:E.input,output:D.output,providerExecuted:D.providerExecuted,preliminary:D.preliminary,providerMetadata:D.providerMetadata,title:E.title,toolMetadata:E.toolMetadata});J();break}case"tool-output-error":{let E=L(D.toolCallId);if(E.type==="dynamic-tool")M({toolCallId:D.toolCallId,toolName:E.toolName,state:"output-error",input:E.input,errorText:D.errorText,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,title:E.title,toolMetadata:E.toolMetadata});else V({toolCallId:D.toolCallId,toolName:P01(E),state:"output-error",input:E.input,rawInput:E.rawInput,errorText:D.errorText,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,title:E.title,toolMetadata:E.toolMetadata});J();break}case"start-step":{Y.message.parts.push({type:"step-start"});break}case"finish-step":{Y.activeTextParts={},Y.activeReasoningParts={};break}case"start":{if(D.messageId!=null)Y.message.id=D.messageId;if(await O(D.messageMetadata),D.messageId!=null||D.messageMetadata!=null)J();break}case"finish":{if(D.finishReason!=null)Y.finishReason=D.finishReason;if(await O(D.messageMetadata),D.messageMetadata!=null)J();break}case"message-metadata":{if(await O(D.messageMetadata),D.messageMetadata!=null)J();break}case"error":{$==null||$(Error(D.errorText));break}default:if(Fa2(D)){if((B==null?void 0:B[D.type])!=null){let y=Y.message.parts.findIndex((_)=>("id"in _)&&("data"in _)&&_.id===D.id&&_.type===D.type),T=y>=0?y:Y.message.parts.length;await XBA({value:D.data,schema:B[D.type],context:{field:`message.parts[${T}].data`,entityName:D.type,entityId:D.id}})}let E=D;if(E.transient){I==null||I(E);break}let S=E.id!=null?Y.message.parts.find((y)=>E.type===y.type&&E.id===y.id):void 0;if(S!=null)S.data=E.data;else Y.message.parts.push(E);I==null||I(E),J()}}U.enqueue(D)})}}))}function qa2({messageId:A,originalMessages:Q=[],onStepFinish:B,onFinish:w,onError:$,stream:f}){let I=Q==null?void 0:Q[Q.length-1];if((I==null?void 0:I.role)!=="assistant")I=void 0;else A=I.id;let D=!1,U=f.pipeThrough(new TransformStream({transform(N,L){if(N.type==="start"){let V=N;if(V.messageId==null&&A!=null)V.messageId=A}if(N.type==="abort")D=!0;L.enqueue(N)}}));if(w==null&&B==null)return U;let Y=Na2({lastMessage:I?structuredClone(I):void 0,messageId:A!=null?A:""}),J=async(N)=>{await N({state:Y,write:()=>{}})},X=!1,G=async()=>{if(X||!w)return;X=!0;let N=Y.message.id===(I==null?void 0:I.id);await w({isAborted:D,isContinuation:N,responseMessage:Y.message,messages:[...N?Q.slice(0,-1):Q,Y.message],finishReason:Y.finishReason})},Z=async()=>{if(!B)return;let N=Y.message.id===(I==null?void 0:I.id);try{await B({isContinuation:N,responseMessage:structuredClone(Y.message),messages:[...N?Q.slice(0,-1):Q,structuredClone(Y.message)]})}catch(L){$(L)}};return za2({stream:U,runUpdateMessageJob:J,onError:$}).pipeThrough(new TransformStream({async transform(N,L){if(N.type==="finish-step")await Z();L.enqueue(N)},async cancel(){await G()},async flush(){await G()}}))}var GNw=fF({prefix:"aitxt",size:24});function c01({execute:A,onError:Q=XkA,originalMessages:B,onStepFinish:w,onFinish:$,generateId:f=V01}){let I,D=[],U=new ReadableStream({start(X){I=X}});function Y(X){try{I.enqueue(X)}catch(G){}}try{let X=A({writer:{write(G){Y(G)},merge(G){D.push((async()=>{let Z=G.getReader();while(!0){let{done:N,value:L}=await Z.read();if(N)break;Y(L)}})().catch((Z)=>{Y({type:"error",errorText:Q(Z)})}))},onError:Q}});if(X)D.push(X.catch((G)=>{Y({type:"error",errorText:Q(G)})}))}catch(X){Y({type:"error",errorText:Q(X)})}return new Promise(async(X)=>{while(D.length>0)await D.shift();X()}).finally(()=>{try{I.close()}catch(X){}}),qa2({stream:U,messageId:f(),originalMessages:B,onStepFinish:w,onFinish:$,onError:Q})}var _f=K.record(K.string(),wM.optional()),NNw=UBA(()=>pc(K.array(K.object({id:K.string(),role:K.enum(["system","user","assistant"]),metadata:K.unknown().optional(),parts:K.array(K.union([K.object({type:K.literal("text"),text:K.string(),state:K.enum(["streaming","done"]).optional(),providerMetadata:N2.optional()}),K.object({type:K.literal("reasoning"),text:K.string(),state:K.enum(["streaming","done"]).optional(),providerMetadata:N2.optional()}),K.object({type:K.literal("source-url"),sourceId:K.string(),url:K.string(),title:K.string().optional(),providerMetadata:N2.optional()}),K.object({type:K.literal("source-document"),sourceId:K.string(),mediaType:K.string(),title:K.string(),filename:K.string().optional(),providerMetadata:N2.optional()}),K.object({type:K.literal("file"),mediaType:K.string(),filename:K.string().optional(),url:K.string(),providerMetadata:N2.optional()}),K.object({type:K.literal("step-start")}),K.object({type:K.string().startsWith("data-"),id:K.string().optional(),data:K.unknown()}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("input-streaming"),input:K.unknown().optional(),providerExecuted:K.boolean().optional(),callProviderMetadata:N2.optional(),output:K.never().optional(),errorText:K.never().optional(),approval:K.never().optional()}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("input-available"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.never().optional()}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("approval-requested"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.never().optional(),reason:K.never().optional()})}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("approval-responded"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.boolean(),reason:K.string().optional()})}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("output-available"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.unknown(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),resultProviderMetadata:N2.optional(),preliminary:K.boolean().optional(),approval:K.object({id:K.string(),approved:K.literal(!0),reason:K.string().optional()}).optional()}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("output-error"),input:K.unknown().optional(),rawInput:K.unknown().optional(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.string(),callProviderMetadata:N2.optional(),resultProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.literal(!0),reason:K.string().optional()}).optional()}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("output-denied"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.literal(!1),reason:K.string().optional()})}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("input-streaming"),providerExecuted:K.boolean().optional(),callProviderMetadata:N2.optional(),input:K.unknown().optional(),output:K.never().optional(),errorText:K.never().optional(),approval:K.never().optional()}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("input-available"),providerExecuted:K.boolean().optional(),input:K.unknown(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.never().optional()}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("approval-requested"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.never().optional(),reason:K.never().optional()})}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("approval-responded"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.boolean(),reason:K.string().optional()})}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("output-available"),providerExecuted:K.boolean().optional(),input:K.unknown(),output:K.unknown(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),resultProviderMetadata:N2.optional(),preliminary:K.boolean().optional(),approval:K.object({id:K.string(),approved:K.literal(!0),reason:K.string().optional()}).optional()}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("output-error"),providerExecuted:K.boolean().optional(),input:K.unknown().optional(),rawInput:K.unknown().optional(),output:K.never().optional(),errorText:K.string(),callProviderMetadata:N2.optional(),resultProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.literal(!0),reason:K.string().optional()}).optional()}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("output-denied"),providerExecuted:K.boolean().optional(),input:K.unknown(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.literal(!1),reason:K.string().optional()})})])).nonempty("Message must contain at least one part")})).nonempty("Messages array must not be empty")));var qNw=fF({prefix:"aiobj",size:24});function l01(A){return({url:Q,abortSignal:B})=>os2({url:Q,maxBytes:A==null?void 0:A.maxBytes,abortSignal:B})}var VNw=fF({prefix:"aiobj",size:24});var ENw=l01();var La2="AI_NoSuchProviderError",Va2=`vercel.ai.error.${La2}`,Ea2=Symbol.for(Va2),Ma2;Ma2=Ea2;var MNw=l01();var p01={name:"@brains/web-chat",private:!0,version:"0.2.0-alpha.120",description:"Web chat interface for Brains",type:"module",exports:{".":"./src/index.ts"},files:["src","dist","package.json"],scripts:{build:"bun scripts/build-ui.ts","build:ui":"bun scripts/build-ui.ts",typecheck:"tsc --noEmit && tsc --noEmit -p ui-react/tsconfig.json",lint:"eslint . --ext .ts,.tsx","lint:fix":"eslint . --ext .ts,.tsx --fix",test:"bun test"},dependencies:{"@ai-sdk/react":"^3.0.116","@brains/auth-service":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*","@streamdown/cjk":"^1.0.3","@streamdown/code":"^1.1.1","@streamdown/math":"^1.0.2","@streamdown/mermaid":"^1.0.2",ai:"^6.0.86","class-variance-authority":"^0.7.0",cmdk:"^1.1.1","lucide-react":"^1.16.0",nanoid:"^5.0.4","radix-ui":"^1.4.3",react:"^19.2.6","react-dom":"^19.2.6",shiki:"^4.1.0",streamdown:"^2.5.0","use-stick-to-bottom":"^1.1.4"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","@types/react":"^19.0.3","@types/react-dom":"^19.0.3",typescript:"^5.3.3",vite:"^7.2.4"}};async function i01(A,Q){if(!await Q.resolveOperatorSession(A))return Q.createOperatorLoginRequiredResponse(A);let B=new URL(A.url),w=B.searchParams.get("id")?.trim();if(!w)return new Response("Missing document id",{status:400});let $=await Q.entityService.getEntity({entityType:"document",id:w});if(!$)return new Response("Document not found",{status:404});let f=Oa2($.content);if(!f)return new Response("Document content is not a PDF",{status:415});let I=ba2($.metadata,w);return d01({requestUrl:B,data:f.data,mediaType:f.mimeType,filename:I})}async function r01(A,Q){if(!await Q.resolveOperatorSession(A))return Q.createOperatorLoginRequiredResponse(A);let B=new URL(A.url),w=B.searchParams.get("id")?.trim();if(!w)return new Response("Missing image id",{status:400});let $=await Q.entityService.getEntity({entityType:"image",id:w});if(!$)return new Response("Image not found",{status:404});let f=Ra2($.content);if(!f)return new Response("Image content is not an image",{status:415});let I=Pa2($.metadata,w,f.mimeType);return d01({requestUrl:B,data:f.data,mediaType:f.mimeType,filename:I})}function d01(A){let Q=new Headers({"Content-Type":A.mediaType,"Content-Length":String(A.data.byteLength),"Content-Disposition":`${A.requestUrl.searchParams.has("download")?"attachment":"inline"}; filename="${ka2(A.filename)}"`});return new Response(A.data,{headers:Q})}function n01(A,Q){let B=A.match(/^data:([^;]+);base64,(.+)$/i);if(!B)return null;let[,w,$]=B;if(!w||!$||!Q.test(w))return null;let f=Buffer.from($,"base64"),I=f.buffer.slice(f.byteOffset,f.byteOffset+f.byteLength);return{mimeType:w,data:I}}function Oa2(A){let Q=n01(A,/^application\/pdf$/i);if(Q?.mimeType.toLowerCase()!=="application/pdf")return null;return{mimeType:"application/pdf",data:Q.data}}function Ra2(A){return n01(A,/^image\/[a-z0-9.+-]+$/i)}function ba2(A,Q){let B=A?.filename;return typeof B==="string"&&B.length>0?B:`${Q}.pdf`}function Pa2(A,Q,B){let w=A?.filename;if(typeof w==="string"&&w.length>0)return w;let $=A?.format;if(typeof $==="string"&&$.length>0)return`${Q}.${$==="jpeg"?"jpg":$}`;let f=B.split("/")[1];return`${Q}.${f&&f.length>0?f:"png"}`}function ka2(A){return A.replace(/["\\\r\n]/g,"_")}WA();aA();var dc="upload",o01=TR;var ja2={namespace:"upload",refKind:dc,routePath:"/api/chat/uploads"};function WBA(){return ja2}aA();var a01="upload.txt";var t01=5000000,_a2=[".md",".txt",".markdown"],va2=["text/plain","text/markdown","text/x-markdown"],KkA=new Map([[".png","image/png"],[".jpg","image/jpeg"],[".jpeg","image/jpeg"],[".webp","image/webp"],[".gif","image/gif"],[".pdf","application/pdf"]]),Ta2=new Set(KkA.values());function GBA(A){let Q=A.split(/[\\/]/).at(-1)?.trim()??"",B=Array.from(Q).filter((w)=>{let $=w.charCodeAt(0);return $>31&&$!==127}).join("").slice(0,160);return B.length>0?B:"upload.txt"}function e01(A,Q){let B=Q?.trim()??"";if(B.length>0)return B;let w=A.toLowerCase();if(w.endsWith(".md")||w.endsWith(".markdown"))return"text/markdown";if(w.endsWith(".txt"))return"text/plain";return"application/octet-stream"}function A11(A,Q){let B=Q?.trim()??"",w=B.split(";",1)[0]?.toLowerCase()??B;if(w.length>0&&w!=="application/octet-stream")return w;let $=e01(A,void 0);if($!=="application/octet-stream")return $;let f=A.toLowerCase();for(let[I,D]of KkA)if(f.endsWith(I))return D;return"application/octet-stream"}function Q11(A,Q){if(Q&&va2.some((B)=>Q.toLowerCase().startsWith(B)))return!0;return _a2.some((B)=>A.toLowerCase().endsWith(B))}function ya2(A){return A<=1e5}function xa2(A){return A<=5000000}function Sa2(A,Q){let B=A11(A,Q);if(Ta2.has(B))return!0;return KkA.has(ma2(A))}function ga2(A){if(A.includes(0))return!1;try{return new TextDecoder("utf-8",{fatal:!0}).decode(A),!0}catch{return!1}}function ha2(A){let Q=GBA(A.filename),B=e01(Q,A.mediaType);if(!Q11(Q,B))return{ok:!1,code:"unsupported_type",message:`Unsupported file upload type: ${Q}`};if(!ya2(A.content.byteLength))return{ok:!1,code:"file_too_large",message:`File upload too large: ${Q}`};if(!ga2(A.content))return{ok:!1,code:"binary_content",message:`Unsupported file upload type: ${Q}`};return{ok:!0,filename:Q,mediaType:B,sizeBytes:A.content.byteLength,text:new TextDecoder("utf-8").decode(A.content).replace(/^\uFEFF/,"")}}function KBA(A){let Q=GBA(A.filename),B=A11(Q,A.mediaType);if(Q11(Q,B)){let w=ha2({filename:Q,mediaType:B,content:A.content});return w.ok?{...w,kind:"text"}:w}if(!Sa2(Q,B))return{ok:!1,code:"unsupported_type",message:`Unsupported file upload type: ${Q}`};if(!xa2(A.content.byteLength))return{ok:!1,code:"file_too_large",message:`File upload too large: ${Q}`};if(!ua2(A.content,B))return{ok:!1,code:"unsupported_type",message:`Unsupported file upload type: ${Q}`};return{ok:!0,kind:"file",filename:Q,mediaType:B,sizeBytes:A.content.byteLength}}function ma2(A){let Q=A.lastIndexOf(".");return Q>=0?A.slice(Q).toLowerCase():""}function ua2(A,Q){switch(Q){case"image/png":return s01(A,[137,80,78,71]);case"image/jpeg":return s01(A,[255,216,255]);case"image/gif":return HBA(A,"GIF87a")||HBA(A,"GIF89a");case"image/webp":return HBA(A,"RIFF")&&B11(A,"WEBP",8);case"application/pdf":return HBA(A,"%PDF-");default:return!1}}function s01(A,Q){return Q.every((B,w)=>A[w]===B)}function HBA(A,Q){return B11(A,Q,0)}function B11(A,Q,B){return Array.from(Q).every((w,$)=>A[B+$]===w.charCodeAt(0))}var ca2="file",la2=16384;async function w11(A,Q){if(!await Q.resolveOperatorSession(A))return new Response("Forbidden",{status:403});let B=Number(A.headers.get("content-length"));if(Number.isFinite(B)&&B>t01+la2)return new Response("File upload too large",{status:400});let w;try{w=await A.formData()}catch{return new Response("Invalid multipart upload",{status:400})}let $=w.get(ca2);if(!($ instanceof File))return new Response("Missing upload file",{status:400});let f=Buffer.from(await $.arrayBuffer()),I=KBA({filename:$.name,mediaType:$.type,content:f});if(!I.ok)return new Response(I.message,{status:400});let D=Q.getUploadStore(),U=await D.save({filename:I.filename,mediaType:I.mediaType,content:f});return Response.json(D.toResponseBody(U),{status:201})}async function $11(A,Q){if(!await Q.resolveOperatorSession(A))return new Response("Forbidden",{status:403});let B=new URL(A.url).searchParams.get("id")?.trim();if(!B)return new Response("Missing upload id",{status:400});let w=await D11(B,Q.getUploadStore());if(w instanceof Response)return w;let{record:$,content:f}=w,I=U11($,f);if(I instanceof Response)return I;let D=new URL(A.url).searchParams.has("download")?"attachment":"inline",U=new Uint8Array(f).buffer;return new Response(U,{headers:{"Content-Type":$.mediaType,"Content-Length":String(f.byteLength),"Content-Disposition":`${D}; filename="${ra2($.filename)}"`}})}function f11(A){let Q=GBA(A.filename??a01),B=ia2(A.url);if(!B)return new Response(`Unsupported file upload URL: ${Q}`,{status:400});let w=KBA({filename:Q,mediaType:A.mediaType,content:B.buffer});if(!w.ok)return new Response(w.message,{status:400});return Y11(w,B.buffer)}async function I11(A,Q){let B=await D11(A,Q);if(B instanceof Response)return B;let{record:w,content:$}=B,f=U11(w,$);if(f instanceof Response)return f;return Y11(f,$,{kind:dc,id:A})}async function D11(A,Q){try{return await Q.read(A)}catch(B){if(B instanceof AW)return pa2(B);throw B}}function U11(A,Q){let B=KBA({filename:A.filename,mediaType:A.mediaType,content:Q});if(!B.ok)return new Response(B.message,{status:400});return B}function Y11(A,Q,B){if(A.kind==="text")return{kind:"text",filename:A.filename,mediaType:A.mediaType,content:A.text,sizeBytes:A.sizeBytes,...B!==void 0?{source:B}:{}};return{kind:"file",filename:A.filename,mediaType:A.mediaType,data:new Uint8Array(Q),sizeBytes:A.sizeBytes,...B!==void 0?{source:B}:{}}}function pa2(A){switch(A.code){case"invalid_ref":return new Response("Invalid upload ref",{status:400});case"invalid_metadata":return new Response("Invalid upload metadata",{status:500});case"not_found":return new Response("Upload not found",{status:404})}}function ia2(A){let Q=/^data:[^,]*,(.*)$/s.exec(A);if(!Q)return null;let w=A.slice(5,A.indexOf(",")).split(";").some(($)=>$.toLowerCase()==="base64");try{let $=w?Buffer.from(Q[1]??"","base64"):Buffer.from(decodeURIComponent(Q[1]??""),"utf8");return{buffer:$,byteLength:$.byteLength}}catch{return null}}function ra2(A){return A.replace(/["\\\r\n]/g,"_")}var da2=H.object({type:H.literal("text"),text:H.string()}),na2=H.object({type:H.literal("file"),mediaType:H.string().optional(),filename:H.string().optional(),url:H.string()}),oa2=H.object({state:H.literal("approval-responded"),approval:H.object({id:H.string(),approved:H.boolean()})}).passthrough(),sa2=H.object({role:H.string(),parts:H.array(H.unknown()).optional(),content:H.string().optional()}),J11=H.object({id:H.string().optional(),messages:H.array(sa2).min(1),trigger:H.string().optional()}),aa2=H.object({kind:H.literal(dc),id:H.string().regex(o01)}),ta2=H.object({type:H.literal("data-upload"),data:H.object({ref:aa2})});async function X11(A,Q){let B=ea2(A);if(!B)return{message:"",attachments:[]};let w=[],$=[];for(let I of B.parts??[]){let D=da2.safeParse(I);if(D.success){if(D.data.text.length>0)w.push(D.data.text);continue}let U=na2.safeParse(I);if(U.success){let J=f11(U.data);if(J instanceof Response)return J;$.push(J);continue}let Y=ta2.safeParse(I);if(Y.success){let J=await I11(Y.data.data.ref.id,Q.uploadStore);if(J instanceof Response)return J;$.push(J);continue}if(At2(I)==="data-upload")return new Response("Invalid upload ref",{status:400})}return{message:w.length>0?w.join(`
|
|
2479
2479
|
|
|
2480
2480
|
`):B.content??"",attachments:$}}function W11(A){let Q=A.messages.at(-1);if(!Q||Q.role==="user")return[];return(Q.parts??[]).map((B)=>oa2.safeParse(B)).filter((B)=>B.success).map((B)=>B.data.approval)}function ea2(A){for(let Q=A.messages.length-1;Q>=0;Q-=1){let B=A.messages[Q];if(B?.role==="user")return B}return}function At2(A){if(typeof A!=="object"||A===null||!("type"in A))return;let Q=A.type;return typeof Q==="string"?Q:void 0}function H11(A){return typeof A==="object"&&A!==null&&!Array.isArray(A)}function Qt2(A){return H11(A)&&A.kind==="upload"&&typeof A.id==="string"}function nc(A){if(Qt2(A))return"uploaded file";if(Array.isArray(A))return A.map((Q)=>nc(Q));if(!H11(A))return A;return G11(A)}function G11(A){return Object.fromEntries(Object.entries(A).map(([Q,B])=>[Q,nc(B)]))}function Bt2(A){if(A.kind!=="tool-approval")return A;return{...A,...A.input!==void 0?{input:G11(A.input)}:{},...A.output!==void 0?{output:nc(A.output)}:{}}}function K11(A,Q,B){A.write({type:"text-start",id:Q}),A.write({type:"text-delta",id:Q,delta:B}),A.write({type:"text-end",id:Q})}function FkA(A,Q){for(let B of Q){let w=Bt2(B);if(w.kind==="attachment"){A.write({type:"data-attachment",id:w.id,data:w});continue}if(w.kind==="sources"){A.write({type:"data-sources",id:w.id,data:w});continue}if(w.kind==="actions"){A.write({type:"data-actions",id:w.id,data:w});continue}let $=w.toolCallId??w.id,f=w.input??{};switch(A.write({type:"tool-input-available",toolCallId:$,toolName:w.toolName,input:f,dynamic:!0,title:w.preview?`${w.summary}
|
|
2481
2481
|
|
|
@@ -4629,7 +4629,7 @@ details.web-chat-data-part[open] > summary > .web-chat-data-part-chevron {
|
|
|
4629
4629
|
|
|
4630
4630
|
`);$=I.pop()??"";for(let D of I){let U=D.split(`
|
|
4631
4631
|
`).find((V)=>V.startsWith("data: "));if(!U)continue;let Y;try{Y=JSON.parse(U.slice(6))}catch{return B.cancel().catch(()=>{}),{success:!1,error:"Malformed SSE event from remote agent"}}let J=Y.result;if(!J)continue;if(J.final!==!0)continue;B.cancel().catch(()=>{});let G=J.status,Z=G?.state??"unknown",L=(G?.message?.parts??[]).filter((V)=>V.kind==="text"&&typeof V.text==="string").map((V)=>V.text).join(`
|
|
4632
|
-
`)||"No response text";return{success:!0,data:{state:Z,response:L}}}f=await u11(B,Q)}return{success:!1,error:"Stream ended without a terminal event"}}class oc extends Error{timeoutMs;constructor(A){super(`request timed out after ${A}ms`);this.timeoutMs=A;this.name="A2ARequestTimeoutError"}}class sc extends Error{timeoutMs;constructor(A){super(`A2A stream stalled waiting for final event after ${A}ms`);this.timeoutMs=A;this.name="A2AStreamIdleTimeoutError"}}async function yt2(A,Q,B,w){let $=new AbortController,f;try{return await Promise.race([A(Q,{...B,signal:$.signal}),new Promise((I,D)=>{f=setTimeout(()=>{$.abort(),D(new oc(w))},w)})])}catch(I){if(I instanceof oc)throw I;if($.signal.aborted)throw new oc(w);throw I}finally{if(f)clearTimeout(f)}}async function u11(A,Q){let B;try{return await Promise.race([A.read(),new Promise((w,$)=>{B=setTimeout(()=>$(new sc(Q)),Q)})])}catch(w){if(w instanceof sc)A.cancel().catch(()=>{});throw w}finally{if(B)clearTimeout(B)}}function xt2(A){if(A instanceof oc||A instanceof sc)return!0;return A instanceof Error}function St2(A,Q){let B=Q>1?` after ${Q} attempts`:"";if(A instanceof sc)return`${A.message}${B}`;let w=A instanceof Error?A.message:"Unknown network error";return`Failed to reach remote agent${B}: ${w}`}function l11(A={}){let Q=A.fetch??globalThis.fetch,B={requestTimeoutMs:A.requestTimeoutMs??bt2,streamIdleTimeoutMs:A.streamIdleTimeoutMs??Pt2,maxNetworkAttempts:A.maxNetworkAttempts??kt2};return{name:"a2a_call",description:"Call a saved remote A2A agent by its local directory id. Use this when the user asks what a saved agent has to say or asks a saved agent for its skills/capabilities. 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:m11,visibility:"anchor",handler:async(w)=>{let $=H.object(m11).safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};let{agent:f,message:I}=$.data,D=jt2(f);if(!D)return{success:!1,error:"Invalid agent id. Use a saved agent id from your directory, not a URL."};if(!A.entityService)return{success:!1,error:"Agent directory is unavailable. Add the agent first, then try again."};let U=await A.entityService.getEntity({entityType:"agent",id:D,visibilityScope:n$("a2a_call tool is anchor-only and resolves saved remote agents at any visibility")});if(!U)return{success:!1,error:`Agent ${D} is not in your directory. Add it first.`};if(U.metadata.status!=="approved")return{success:!1,error:`Agent ${D} is discovered but not approved yet. Approve it first.`};let Y=`https://${D}`,J=await _t2(Y,Q);if(!J)return{success:!1,error:`Could not fetch Agent Card from ${Y}`};let X=J.url,G;if(A.outboundTokens)try{let Z=new URL(X).hostname;G=A.outboundTokens[Z]}catch{}return vt2(X,I,Q,G,B)}}}var MkA={name:"@brains/a2a",private:!0,version:"0.2.0-alpha.119",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 ht2={"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization","X-Content-Type-Options":"nosniff"};class aj extends eX{agentCard;taskManager=new VkA;agentService;permissionContext;app;hasWebserver=!1;constructor(A={}){super("a2a",MkA,A,_11)}async onRegister(A){if(await super.onRegister(A),this.hasWebserver=A.plugins.has("webserver"),this.agentService=A.agent,this.permissionContext=A.permissions,this.hasWebserver)A.endpoints.register({label:"A2A",url:"/a2a",priority:25}),A.interactions.register({id:"a2a",label:"A2A",description:"Let other agents discover and talk to this brain.",href:"/a2a",kind:"agent",priority:25}),this.logger.info("A2A interface registered",{domain:A.domain});else this.logger.info("A2A interface registered in tool-only mode",{domain:A.domain})}async onReady(A){await this.rebuildAgentCard(A)}async rebuildAgentCard(A){let Q=A.identity.get(),B=A.identity.getProfile(),w=A.tools.listForPermissionLevel("public"),$=this.config.trustedTokens&&Object.keys(this.config.trustedTokens).length>0,f;if(A.entityService.hasEntityType("skill"))try{let I=await A.entityService.listEntities({entityType:"skill",options:{filter:{visibilityScope:"public"}}});if(I.length>0)f=I.map((D)=>RI.safeParse(D.metadata)).filter((D)=>D.success).map((D)=>D.data)}catch{}this.agentCard=v11({character:Q,profile:B,version:MkA.version,domain:A.domain,organization:this.config.organization,tools:w,skills:f,authEnabled:$}),this.logger.debug("Agent Card rebuilt",{skills:this.agentCard.skills.length})}getAgentCard(){return this.agentCard}resolveCallerPermission(A){if(!A?.startsWith("Bearer ")||!this.config.trustedTokens)return"public";let Q=A.slice(7),B=this.config.trustedTokens[Q];if(!B||!this.permissionContext)return"public";return this.permissionContext.getUserLevel("a2a",B)}withCors(A){let Q=new Headers(A.headers);for(let[B,w]of Object.entries(ht2))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 ij;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=x11.safeParse(B);if(!w.success)return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32600,message:"Invalid request"},id:null}));let $=this.resolveCallerPermission(Q.req.header("Authorization"));if(w.data.method==="message/stream"){let I=g11.safeParse(w.data.params??{});if(!I.success)return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32602,message:`Invalid params: ${I.error.message}`},id:w.data.id}));let{stream:D}=h11(w.data.id,I.data.message,{taskManager:this.taskManager,agentService:this.agentService,callerPermissionLevel:$});return this.withCors(new Response(D,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}}))}let f=await S11(w.data,{taskManager:this.taskManager,agentService:this.agentService,callerPermissionLevel:$});return this.withCors(Q.json(f))}),this.app=A,A}getWebRoutes(){if(!this.hasWebserver)return[];let A=(Q)=>Promise.resolve(this.getOrCreateApp().fetch(Q));return[{path:"/.well-known/agent-card.json",method:"GET",public:!0,handler:A},{path:"/a2a",method:"GET",public:!0,handler:A},{path:"/a2a",method:"POST",public:!0,handler:A},{path:"/a2a",method:"OPTIONS",public:!0,handler:A}]}async getTools(){return[l11({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 names an exact saved local agent id such as `yeehaa.io`, call `a2a_call` directly with that id. Do not preflight with `system_list` or `system_get`; the tool validates saved/approved status and reports errors.\n- If the user asks you to ask, message, contact, hear what a saved agent has to say, or ask a saved agent for its own skills/capabilities, 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, searching general content locally, or reading the saved agent entity metadata.\n- After `a2a_call` returns within a turn, answer that turn from its response. Do **not** supplement with `system_get` (or any other read tool) on the agent entity, unless the user explicitly asks for directory/profile details about the agent itself.\n- Each new turn that asks the same saved agent something \u2014 including short follow-ups like \"what skills does it have\", \"and what about X\", \"tell me more\" \u2014 is a **new** contact request and needs its **own** fresh `a2a_call`. Do not assume the previous turn's a2a response already covers a new question, and do not substitute `system_list`/`system_get` or a no-tool answer for the fresh call. If the previous turn targeted an exact saved local id such as `yeehaa.io`, use that same id again for the follow-up even if the previous response was a refusal or error; let `a2a_call` validate the current directory state again.\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")}}}}aA();class CkA{logger;handleImport;handleDelete;deleteOnFileRemoval;fileOperations;constructor(A,Q,B,w,$=!0){if(this.logger=A,this.fileOperations=w,this.deleteOnFileRemoval=$,B)this.handleImport=async(f)=>{let I=await B({type:"directory-import",data:{paths:[f]}});this.logger.debug("Queued import job for file change",{jobId:I,path:f})},this.handleDelete=async(f)=>{if(!this.deleteOnFileRemoval){this.logger.warn("File deleted but deleteOnFileRemoval is disabled",{path:f});return}try{let{entityType:I,id:D}=this.fileOperations.parseEntityFromPath(f),U=await B({type:"directory-delete",data:{entityId:D,entityType:I,filePath:f}});this.logger.info("Queued delete job for removed file",{jobId:U,path:f,entityId:D,entityType:I})}catch(I){this.logger.warn("Could not extract entity info from deleted file",{path:f,error:I})}};else this.handleImport=async(f)=>{await Q([f])},this.handleDelete=async(f)=>{this.logger.warn("File deleted but no job queue available",{path:f})}}async handleFileChange(A,Q){this.logger.debug("Processing file change",{event:A,path:Q});try{switch(A){case"add":case"change":await this.handleImport(Q);break;case"delete":case"unlink":await this.handleDelete(Q);break;default:this.logger.debug("Unhandled file event",{event:A,path:Q})}}catch(B){this.logger.error("Failed to handle file change",{event:A,path:Q,error:B})}}}var DB1=U1($B1(),1);import{extname as S2Q}from"path";var xBA=[".png",".jpg",".jpeg",".webp",".gif",".svg"];function DM(A){let Q=S2Q(A).toLowerCase();return xBA.includes(Q)}function fB1(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 MjA(A){switch(A.toLowerCase()){case"jpeg":return".jpg";case"svg+xml":return".svg";default:return`.${A.toLowerCase()}`}}import{isAbsolute as g2Q,relative as h2Q,sep as IB1,join as m2Q}from"path";function gU(A,Q){return g2Q(Q)?Q:m2Q(A,Q)}function $_(A,Q){let B=gU(A,Q),w=h2Q(A,B);return IB1==="/"?w:w.split(IB1).join("/")}function u2Q(A,Q){if(!$_(Q,A).startsWith("image/"))return!1;return DM(A)}function c2Q(A,Q){if($_(Q,A).split("/")[0]?.startsWith("_"))return!1;if(A.endsWith(".md"))return!0;return u2Q(A,Q)}class CjA{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=DB1.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(!c2Q(Q,this.syncPath))return;this.logger.debug("File change detected",{event:A,path:Q});let B=$_(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=gU(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 UB1(A,Q){if(A?.isWatching())return Q.logger.debug("Already watching directory"),A;return l2Q(Q)}function YB1(A){if(A)A.stop();return}function JB1(A,Q){if(A)A.setCallback(Q)}async function l2Q(A){let{logger:Q,syncPath:B,watchInterval:w,importEntities:$,jobQueueCallback:f,fileOperations:I,deleteOnFileRemoval:D}=A,U=new CkA(Q,$,f,I,D),Y=new CjA({syncPath:B,watchInterval:w,logger:Q,onFileChange:async(J,X)=>{await U.handleFileChange(J,X)}});return await Y.start(),Y}async function XB1(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:$}}aA();class OjA{logger;syncPath;deleteOnFileRemoval;constructor(A){this.logger=A.logger,this.syncPath=A.syncPath,this.deleteOnFileRemoval=A.deleteOnFileRemoval}prepareBatchOperations(A){let Q=[],B=this.createImportOperations(A);Q.push(...B);let w=B.length;if(this.deleteOnFileRemoval)Q.push({type:"directory-cleanup",data:{}});let $=A.length;return this.logger.debug("Prepared batch operations",{exportOperationsCount:0,importOperationsCount:w,totalFiles:$}),{operations:Q,exportOperationsCount:0,importOperationsCount:w,totalFiles:$}}async queueSyncBatch(A,Q,B,w){let $=this.prepareBatchOperations(B);if($.operations.length===0)return this.logger.debug("No sync operations needed",{source:Q}),null;return{batchId:await A.jobs.enqueueBatch($.operations,{source:Q,rootJobId:w?.rootJobId??J$(),metadata:{progressToken:w?.progressToken,operationType:"file_operations",operationTarget:this.syncPath,pluginId:w?.pluginId??"directory-sync",interfaceType:w?.interfaceType,channelId:w?.channelId}}),operationCount:$.operations.length,exportOperationsCount:$.exportOperationsCount,importOperationsCount:$.importOperationsCount,totalFiles:$.totalFiles}}createImportOperations(A){if(A.length===0)return[];let Q=50,B=[];for(let w=0;w<A.length;w+=Q){let $=A.slice(w,w+Q);B.push({type:"directory-import",data:{batchIndex:Math.floor(w/Q),paths:$,batchSize:$.length}})}return B}}class RjA{syncInProgress=!1;logger;fileOperations;batchOperationsManager;constructor(A){this.logger=A.logger,this.fileOperations=A.fileOperations,this.batchOperationsManager=new OjA({logger:A.logger,syncPath:A.syncPath,deleteOnFileRemoval:A.deleteOnFileRemoval})}async queueSyncBatch(A,Q,B){if(this.syncInProgress)return this.logger.debug("Sync already in progress, skipping",{source:Q}),null;this.syncInProgress=!0;try{let w=await this.fileOperations.getAllSyncFiles();return await this.batchOperationsManager.queueSyncBatch(A,Q,w,B)}finally{this.syncInProgress=!1}}}class bjA{options;constructor(A){this.options=A}createExportDeps(A,Q){return{entityService:this.options.entityService,logger:this.options.logger,fileOperations:this.options.fileOperations,deleteOnFileRemoval:A,entityTypes:Q}}createImportDeps(A){return{entityService:this.options.entityService,logger:this.options.logger,fileOperations:this.options.fileOperations,quarantine:this.options.quarantine,imageJobQueue:this.createImageJobQueueDeps(),entityTypes:A}}createCleanupDeps(A,Q){return{entityService:this.options.entityService,logger:this.options.logger,fileOperations:this.options.fileOperations,deleteOnFileRemoval:A,entityTypes:Q}}createImageJobQueueDeps(){return{logger:this.options.logger,syncPath:this.options.syncPath,jobQueueCallback:this.options.getJobQueueCallback(),coverImageConverter:this.options.coverImageConverter,inlineImageConverter:this.options.inlineImageConverter}}}import{basename as o2Q,dirname as s2Q,extname as a2Q}from"path";import{extname as p2Q}from"path";var SBA=[".pdf"],WB1=".meta.json";function UM(A){let Q=p2Q(A).toLowerCase();return SBA.includes(Q)}function HB1(A){return A.toLowerCase().endsWith(WB1)}function PjA(A){return`${A}${WB1}`}function GB1(A){switch(A.toLowerCase().replace(".","")){case"pdf":default:return"application/pdf"}}import{extname as i2Q,join as gBA}from"path";function hBA(A,Q){let w=$_(A,Q).split("/"),$,f;if(w.length===1)$="base",f=w;else if(w.length>1&&w[0])$=w[0],f=w.slice(1);else $="base",f=w;let I;if(f.length>1){let D=f[f.length-1];if(D)f[f.length-1]=KB1(D);I=f.join(":")}else I=KB1(f[0]??"");return{entityType:$,id:I}}function FB1(A,Q,B,w=".md"){let $=Q.split(":").filter((Y)=>Y.length>0),f=B==="base";if($.length===1)return f?gBA(A,`${$[0]}${w}`):gBA(A,B,`${$[0]}${w}`);let I=$;if($[0]===B)I=$.slice(1);let D=I[I.length-1],U=I.slice(0,-1);if(f)return gBA(A,...U,`${D}${w}`);return gBA(A,B,...U,`${D}${w}`)}function ZB1(A){if(A.entityType==="document")return".pdf";if(A.entityType!=="image")return".md";let Q=A.metadata.format;if(Q)return MjA(Q);let B=A.content.match(/^data:image\/([a-z+]+);base64,/i);return B?.[1]?MjA(B[1]):".md"}function KB1(A){let Q=i2Q(A).toLowerCase();return Q===".md"||xBA.includes(Q)||SBA.includes(Q)?A.slice(0,-Q.length):A}wU();import{mkdir as t2Q,readFile as f_,writeFile as jjA,stat as e2Q,utimes as AQQ}from"fs/promises";import{join as mBA}from"path";import{mkdir as NB1,readdir as d2Q,stat as n2Q}from"fs/promises";import{access as r2Q}from"fs/promises";async function X5(A){try{return await r2Q(A),!0}catch{return!1}}async function kjA(A,Q){return VB1(A,Q,{includeDocuments:!1,includeImages:!1})}async function zB1(A,Q){return VB1(A,Q,{includeDocuments:!0,includeImages:!0})}async function qB1(A,Q){if(!await X5(A))await NB1(A,{recursive:!0});for(let B of Q)if(B!=="base")await NB1(mBA(A,B),{recursive:!0})}async function LB1(A,Q){let B=[],w={totalFiles:0,byEntityType:{}};if(!await X5(A))return{files:B,stats:w};let $=await kjA(A,Q);for(let f of $)try{let I=mBA(A,f),D=await n2Q(I),{entityType:U}=hBA(A,f);B.push({path:f,entityType:U,modified:D.mtime}),w.totalFiles++,w.byEntityType[U]=(w.byEntityType[U]??0)+1}catch{continue}return{files:B,stats:w}}async function VB1(A,Q,B){let w=[];if(!await X5(A))return w;let $=async(f,I="",D=!1,U=!1)=>{let Y=await d2Q(f,{withFileTypes:!0});for(let J of Y){let X=I?mBA(I,J.name):J.name;if(J.isFile()&&!J.name.endsWith(".invalid")&&!HB1(J.name)){if(J.name.endsWith(".md"))w.push(X);else if(B.includeImages&&D&&DM(J.name))w.push(X);else if(B.includeDocuments&&U&&UM(J.name))w.push(X)}else if(J.isDirectory()&&!J.name.startsWith(".")){if(I===""&&!Q.hasEntityType(J.name))continue;let G=mBA(f,J.name),Z=J.name==="image"&&I==="",N=J.name==="document"&&I==="";await $(G,X,D||Z,U||N)}}};return await $(A),w}function QQQ(A){return typeof A==="object"&&A!==null}class _jA{syncPath;entityService;constructor(A,Q){this.syncPath=A,this.entityService=Q}parseEntityFromPath(A){return hBA(this.syncPath,A)}async readEntity(A){let Q=gU(this.syncPath,A),B=await e2Q(Q),{entityType:w,id:$}=this.parseEntityFromPath(A),f=B.birthtime.getTime()>0?B.birthtime:B.mtime,I=B.mtime,D,U;if(DM(A)||UM(A)){let X=(await f_(Q)).toString("base64"),G=a2Q(A);if(D=`data:${UM(A)?GB1(G):fB1(G)};base64,${X}`,UM(A))U=await this.readDocumentSidecar(Q,A)}else D=await f_(Q,"utf-8");let Y={entityType:w,id:$,content:D,created:f,updated:I};if(U)Y.metadata=U;return Y}async readDocumentSidecar(A,Q){let B={mimeType:"application/pdf",filename:o2Q(Q)},w=PjA(A);if(!await X5(w))return B;try{let $=await f_(w,"utf-8"),f=JSON.parse($),I=QQQ(f)?f:{};return{...B,...I}}catch{return B}}async writeEntity(A){let Q=this.getEntityFilePath(A),B=A.entityType==="image",w=A.entityType==="document";if(B||w){let f=B?/^data:image\/[a-z+]+;base64,(.+)$/i:/^data:application\/pdf;base64,(.+)$/i,I=A.content.match(f),D=I?.[1]?Buffer.from(I[1],"base64"):Buffer.from(A.content,"base64"),U=!1;if(await X5(Q)){let Y=await f_(Q),J=gB(Y.toString("base64")),X=gB(D.toString("base64"));if(J===X)U=!0}if(!U)await this.ensureEntityDirectory(A,Q),await jjA(Q,D);if(w)await this.writeDocumentSidecar(A,Q);if(U)return}else{let f=this.entityService.serializeEntity(A);if(await X5(Q)){let I=await f_(Q,"utf-8"),D=gB(I),U=gB(f);if(D===U)return}await this.ensureEntityDirectory(A,Q),await jjA(Q,f,"utf-8")}let $=new Date(A.updated);await AQQ(Q,$,$)}async ensureEntityDirectory(A,Q){if(A.entityType!=="base")await t2Q(s2Q(Q),{recursive:!0})}async writeDocumentSidecar(A,Q){let B=A.metadata,w={};for(let[I,D]of Object.entries(B)){if(I==="mimeType")continue;if(D===void 0)continue;w[I]=D}let $=PjA(Q),f=`${JSON.stringify(w,null,2)}
|
|
4632
|
+
`)||"No response text";return{success:!0,data:{state:Z,response:L}}}f=await u11(B,Q)}return{success:!1,error:"Stream ended without a terminal event"}}class oc extends Error{timeoutMs;constructor(A){super(`request timed out after ${A}ms`);this.timeoutMs=A;this.name="A2ARequestTimeoutError"}}class sc extends Error{timeoutMs;constructor(A){super(`A2A stream stalled waiting for final event after ${A}ms`);this.timeoutMs=A;this.name="A2AStreamIdleTimeoutError"}}async function yt2(A,Q,B,w){let $=new AbortController,f;try{return await Promise.race([A(Q,{...B,signal:$.signal}),new Promise((I,D)=>{f=setTimeout(()=>{$.abort(),D(new oc(w))},w)})])}catch(I){if(I instanceof oc)throw I;if($.signal.aborted)throw new oc(w);throw I}finally{if(f)clearTimeout(f)}}async function u11(A,Q){let B;try{return await Promise.race([A.read(),new Promise((w,$)=>{B=setTimeout(()=>$(new sc(Q)),Q)})])}catch(w){if(w instanceof sc)A.cancel().catch(()=>{});throw w}finally{if(B)clearTimeout(B)}}function xt2(A){if(A instanceof oc||A instanceof sc)return!0;return A instanceof Error}function St2(A,Q){let B=Q>1?` after ${Q} attempts`:"";if(A instanceof sc)return`${A.message}${B}`;let w=A instanceof Error?A.message:"Unknown network error";return`Failed to reach remote agent${B}: ${w}`}function l11(A={}){let Q=A.fetch??globalThis.fetch,B={requestTimeoutMs:A.requestTimeoutMs??bt2,streamIdleTimeoutMs:A.streamIdleTimeoutMs??Pt2,maxNetworkAttempts:A.maxNetworkAttempts??kt2};return{name:"a2a_call",description:"Call a saved remote A2A agent by its local directory id. Use this when the user asks what a saved agent has to say or asks a saved agent for its skills/capabilities. 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:m11,visibility:"anchor",handler:async(w)=>{let $=H.object(m11).safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};let{agent:f,message:I}=$.data,D=jt2(f);if(!D)return{success:!1,error:"Invalid agent id. Use a saved agent id from your directory, not a URL."};if(!A.entityService)return{success:!1,error:"Agent directory is unavailable. Add the agent first, then try again."};let U=await A.entityService.getEntity({entityType:"agent",id:D,visibilityScope:n$("a2a_call tool is anchor-only and resolves saved remote agents at any visibility")});if(!U)return{success:!1,error:`Agent ${D} is not in your directory. Add it first.`};if(U.metadata.status!=="approved")return{success:!1,error:`Agent ${D} is discovered but not approved yet. Approve it first.`};let Y=`https://${D}`,J=await _t2(Y,Q);if(!J)return{success:!1,error:`Could not fetch Agent Card from ${Y}`};let X=J.url,G;if(A.outboundTokens)try{let Z=new URL(X).hostname;G=A.outboundTokens[Z]}catch{}return vt2(X,I,Q,G,B)}}}var MkA={name:"@brains/a2a",private:!0,version:"0.2.0-alpha.120",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 ht2={"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization","X-Content-Type-Options":"nosniff"};class aj extends eX{agentCard;taskManager=new VkA;agentService;permissionContext;app;hasWebserver=!1;constructor(A={}){super("a2a",MkA,A,_11)}async onRegister(A){if(await super.onRegister(A),this.hasWebserver=A.plugins.has("webserver"),this.agentService=A.agent,this.permissionContext=A.permissions,this.hasWebserver)A.endpoints.register({label:"A2A",url:"/a2a",priority:25}),A.interactions.register({id:"a2a",label:"A2A",description:"Let other agents discover and talk to this brain.",href:"/a2a",kind:"agent",priority:25}),this.logger.info("A2A interface registered",{domain:A.domain});else this.logger.info("A2A interface registered in tool-only mode",{domain:A.domain})}async onReady(A){await this.rebuildAgentCard(A)}async rebuildAgentCard(A){let Q=A.identity.get(),B=A.identity.getProfile(),w=A.tools.listForPermissionLevel("public"),$=this.config.trustedTokens&&Object.keys(this.config.trustedTokens).length>0,f;if(A.entityService.hasEntityType("skill"))try{let I=await A.entityService.listEntities({entityType:"skill",options:{filter:{visibilityScope:"public"}}});if(I.length>0)f=I.map((D)=>RI.safeParse(D.metadata)).filter((D)=>D.success).map((D)=>D.data)}catch{}this.agentCard=v11({character:Q,profile:B,version:MkA.version,domain:A.domain,organization:this.config.organization,tools:w,skills:f,authEnabled:$}),this.logger.debug("Agent Card rebuilt",{skills:this.agentCard.skills.length})}getAgentCard(){return this.agentCard}resolveCallerPermission(A){if(!A?.startsWith("Bearer ")||!this.config.trustedTokens)return"public";let Q=A.slice(7),B=this.config.trustedTokens[Q];if(!B||!this.permissionContext)return"public";return this.permissionContext.getUserLevel("a2a",B)}withCors(A){let Q=new Headers(A.headers);for(let[B,w]of Object.entries(ht2))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 ij;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=x11.safeParse(B);if(!w.success)return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32600,message:"Invalid request"},id:null}));let $=this.resolveCallerPermission(Q.req.header("Authorization"));if(w.data.method==="message/stream"){let I=g11.safeParse(w.data.params??{});if(!I.success)return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32602,message:`Invalid params: ${I.error.message}`},id:w.data.id}));let{stream:D}=h11(w.data.id,I.data.message,{taskManager:this.taskManager,agentService:this.agentService,callerPermissionLevel:$});return this.withCors(new Response(D,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}}))}let f=await S11(w.data,{taskManager:this.taskManager,agentService:this.agentService,callerPermissionLevel:$});return this.withCors(Q.json(f))}),this.app=A,A}getWebRoutes(){if(!this.hasWebserver)return[];let A=(Q)=>Promise.resolve(this.getOrCreateApp().fetch(Q));return[{path:"/.well-known/agent-card.json",method:"GET",public:!0,handler:A},{path:"/a2a",method:"GET",public:!0,handler:A},{path:"/a2a",method:"POST",public:!0,handler:A},{path:"/a2a",method:"OPTIONS",public:!0,handler:A}]}async getTools(){return[l11({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 names an exact saved local agent id such as `yeehaa.io`, call `a2a_call` directly with that id. Do not preflight with `system_list` or `system_get`; the tool validates saved/approved status and reports errors.\n- If the user asks you to ask, message, contact, hear what a saved agent has to say, or ask a saved agent for its own skills/capabilities, 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, searching general content locally, or reading the saved agent entity metadata.\n- After `a2a_call` returns within a turn, answer that turn from its response. Do **not** supplement with `system_get` (or any other read tool) on the agent entity, unless the user explicitly asks for directory/profile details about the agent itself.\n- Each new turn that asks the same saved agent something \u2014 including short follow-ups like \"what skills does it have\", \"and what about X\", \"tell me more\" \u2014 is a **new** contact request and needs its **own** fresh `a2a_call`. Do not assume the previous turn's a2a response already covers a new question, and do not substitute `system_list`/`system_get` or a no-tool answer for the fresh call. If the previous turn targeted an exact saved local id such as `yeehaa.io`, use that same id again for the follow-up even if the previous response was a refusal or error; let `a2a_call` validate the current directory state again.\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")}}}}aA();class CkA{logger;handleImport;handleDelete;deleteOnFileRemoval;fileOperations;constructor(A,Q,B,w,$=!0){if(this.logger=A,this.fileOperations=w,this.deleteOnFileRemoval=$,B)this.handleImport=async(f)=>{let I=await B({type:"directory-import",data:{paths:[f]}});this.logger.debug("Queued import job for file change",{jobId:I,path:f})},this.handleDelete=async(f)=>{if(!this.deleteOnFileRemoval){this.logger.warn("File deleted but deleteOnFileRemoval is disabled",{path:f});return}try{let{entityType:I,id:D}=this.fileOperations.parseEntityFromPath(f),U=await B({type:"directory-delete",data:{entityId:D,entityType:I,filePath:f}});this.logger.info("Queued delete job for removed file",{jobId:U,path:f,entityId:D,entityType:I})}catch(I){this.logger.warn("Could not extract entity info from deleted file",{path:f,error:I})}};else this.handleImport=async(f)=>{await Q([f])},this.handleDelete=async(f)=>{this.logger.warn("File deleted but no job queue available",{path:f})}}async handleFileChange(A,Q){this.logger.debug("Processing file change",{event:A,path:Q});try{switch(A){case"add":case"change":await this.handleImport(Q);break;case"delete":case"unlink":await this.handleDelete(Q);break;default:this.logger.debug("Unhandled file event",{event:A,path:Q})}}catch(B){this.logger.error("Failed to handle file change",{event:A,path:Q,error:B})}}}var DB1=U1($B1(),1);import{extname as S2Q}from"path";var xBA=[".png",".jpg",".jpeg",".webp",".gif",".svg"];function DM(A){let Q=S2Q(A).toLowerCase();return xBA.includes(Q)}function fB1(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 MjA(A){switch(A.toLowerCase()){case"jpeg":return".jpg";case"svg+xml":return".svg";default:return`.${A.toLowerCase()}`}}import{isAbsolute as g2Q,relative as h2Q,sep as IB1,join as m2Q}from"path";function gU(A,Q){return g2Q(Q)?Q:m2Q(A,Q)}function $_(A,Q){let B=gU(A,Q),w=h2Q(A,B);return IB1==="/"?w:w.split(IB1).join("/")}function u2Q(A,Q){if(!$_(Q,A).startsWith("image/"))return!1;return DM(A)}function c2Q(A,Q){if($_(Q,A).split("/")[0]?.startsWith("_"))return!1;if(A.endsWith(".md"))return!0;return u2Q(A,Q)}class CjA{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=DB1.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(!c2Q(Q,this.syncPath))return;this.logger.debug("File change detected",{event:A,path:Q});let B=$_(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=gU(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 UB1(A,Q){if(A?.isWatching())return Q.logger.debug("Already watching directory"),A;return l2Q(Q)}function YB1(A){if(A)A.stop();return}function JB1(A,Q){if(A)A.setCallback(Q)}async function l2Q(A){let{logger:Q,syncPath:B,watchInterval:w,importEntities:$,jobQueueCallback:f,fileOperations:I,deleteOnFileRemoval:D}=A,U=new CkA(Q,$,f,I,D),Y=new CjA({syncPath:B,watchInterval:w,logger:Q,onFileChange:async(J,X)=>{await U.handleFileChange(J,X)}});return await Y.start(),Y}async function XB1(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:$}}aA();class OjA{logger;syncPath;deleteOnFileRemoval;constructor(A){this.logger=A.logger,this.syncPath=A.syncPath,this.deleteOnFileRemoval=A.deleteOnFileRemoval}prepareBatchOperations(A){let Q=[],B=this.createImportOperations(A);Q.push(...B);let w=B.length;if(this.deleteOnFileRemoval)Q.push({type:"directory-cleanup",data:{}});let $=A.length;return this.logger.debug("Prepared batch operations",{exportOperationsCount:0,importOperationsCount:w,totalFiles:$}),{operations:Q,exportOperationsCount:0,importOperationsCount:w,totalFiles:$}}async queueSyncBatch(A,Q,B,w){let $=this.prepareBatchOperations(B);if($.operations.length===0)return this.logger.debug("No sync operations needed",{source:Q}),null;return{batchId:await A.jobs.enqueueBatch($.operations,{source:Q,rootJobId:w?.rootJobId??J$(),metadata:{progressToken:w?.progressToken,operationType:"file_operations",operationTarget:this.syncPath,pluginId:w?.pluginId??"directory-sync",interfaceType:w?.interfaceType,channelId:w?.channelId}}),operationCount:$.operations.length,exportOperationsCount:$.exportOperationsCount,importOperationsCount:$.importOperationsCount,totalFiles:$.totalFiles}}createImportOperations(A){if(A.length===0)return[];let Q=50,B=[];for(let w=0;w<A.length;w+=Q){let $=A.slice(w,w+Q);B.push({type:"directory-import",data:{batchIndex:Math.floor(w/Q),paths:$,batchSize:$.length}})}return B}}class RjA{syncInProgress=!1;logger;fileOperations;batchOperationsManager;constructor(A){this.logger=A.logger,this.fileOperations=A.fileOperations,this.batchOperationsManager=new OjA({logger:A.logger,syncPath:A.syncPath,deleteOnFileRemoval:A.deleteOnFileRemoval})}async queueSyncBatch(A,Q,B){if(this.syncInProgress)return this.logger.debug("Sync already in progress, skipping",{source:Q}),null;this.syncInProgress=!0;try{let w=await this.fileOperations.getAllSyncFiles();return await this.batchOperationsManager.queueSyncBatch(A,Q,w,B)}finally{this.syncInProgress=!1}}}class bjA{options;constructor(A){this.options=A}createExportDeps(A,Q){return{entityService:this.options.entityService,logger:this.options.logger,fileOperations:this.options.fileOperations,deleteOnFileRemoval:A,entityTypes:Q}}createImportDeps(A){return{entityService:this.options.entityService,logger:this.options.logger,fileOperations:this.options.fileOperations,quarantine:this.options.quarantine,imageJobQueue:this.createImageJobQueueDeps(),entityTypes:A}}createCleanupDeps(A,Q){return{entityService:this.options.entityService,logger:this.options.logger,fileOperations:this.options.fileOperations,deleteOnFileRemoval:A,entityTypes:Q}}createImageJobQueueDeps(){return{logger:this.options.logger,syncPath:this.options.syncPath,jobQueueCallback:this.options.getJobQueueCallback(),coverImageConverter:this.options.coverImageConverter,inlineImageConverter:this.options.inlineImageConverter}}}import{basename as o2Q,dirname as s2Q,extname as a2Q}from"path";import{extname as p2Q}from"path";var SBA=[".pdf"],WB1=".meta.json";function UM(A){let Q=p2Q(A).toLowerCase();return SBA.includes(Q)}function HB1(A){return A.toLowerCase().endsWith(WB1)}function PjA(A){return`${A}${WB1}`}function GB1(A){switch(A.toLowerCase().replace(".","")){case"pdf":default:return"application/pdf"}}import{extname as i2Q,join as gBA}from"path";function hBA(A,Q){let w=$_(A,Q).split("/"),$,f;if(w.length===1)$="base",f=w;else if(w.length>1&&w[0])$=w[0],f=w.slice(1);else $="base",f=w;let I;if(f.length>1){let D=f[f.length-1];if(D)f[f.length-1]=KB1(D);I=f.join(":")}else I=KB1(f[0]??"");return{entityType:$,id:I}}function FB1(A,Q,B,w=".md"){let $=Q.split(":").filter((Y)=>Y.length>0),f=B==="base";if($.length===1)return f?gBA(A,`${$[0]}${w}`):gBA(A,B,`${$[0]}${w}`);let I=$;if($[0]===B)I=$.slice(1);let D=I[I.length-1],U=I.slice(0,-1);if(f)return gBA(A,...U,`${D}${w}`);return gBA(A,B,...U,`${D}${w}`)}function ZB1(A){if(A.entityType==="document")return".pdf";if(A.entityType!=="image")return".md";let Q=A.metadata.format;if(Q)return MjA(Q);let B=A.content.match(/^data:image\/([a-z+]+);base64,/i);return B?.[1]?MjA(B[1]):".md"}function KB1(A){let Q=i2Q(A).toLowerCase();return Q===".md"||xBA.includes(Q)||SBA.includes(Q)?A.slice(0,-Q.length):A}wU();import{mkdir as t2Q,readFile as f_,writeFile as jjA,stat as e2Q,utimes as AQQ}from"fs/promises";import{join as mBA}from"path";import{mkdir as NB1,readdir as d2Q,stat as n2Q}from"fs/promises";import{access as r2Q}from"fs/promises";async function X5(A){try{return await r2Q(A),!0}catch{return!1}}async function kjA(A,Q){return VB1(A,Q,{includeDocuments:!1,includeImages:!1})}async function zB1(A,Q){return VB1(A,Q,{includeDocuments:!0,includeImages:!0})}async function qB1(A,Q){if(!await X5(A))await NB1(A,{recursive:!0});for(let B of Q)if(B!=="base")await NB1(mBA(A,B),{recursive:!0})}async function LB1(A,Q){let B=[],w={totalFiles:0,byEntityType:{}};if(!await X5(A))return{files:B,stats:w};let $=await kjA(A,Q);for(let f of $)try{let I=mBA(A,f),D=await n2Q(I),{entityType:U}=hBA(A,f);B.push({path:f,entityType:U,modified:D.mtime}),w.totalFiles++,w.byEntityType[U]=(w.byEntityType[U]??0)+1}catch{continue}return{files:B,stats:w}}async function VB1(A,Q,B){let w=[];if(!await X5(A))return w;let $=async(f,I="",D=!1,U=!1)=>{let Y=await d2Q(f,{withFileTypes:!0});for(let J of Y){let X=I?mBA(I,J.name):J.name;if(J.isFile()&&!J.name.endsWith(".invalid")&&!HB1(J.name)){if(J.name.endsWith(".md"))w.push(X);else if(B.includeImages&&D&&DM(J.name))w.push(X);else if(B.includeDocuments&&U&&UM(J.name))w.push(X)}else if(J.isDirectory()&&!J.name.startsWith(".")){if(I===""&&!Q.hasEntityType(J.name))continue;let G=mBA(f,J.name),Z=J.name==="image"&&I==="",N=J.name==="document"&&I==="";await $(G,X,D||Z,U||N)}}};return await $(A),w}function QQQ(A){return typeof A==="object"&&A!==null}class _jA{syncPath;entityService;constructor(A,Q){this.syncPath=A,this.entityService=Q}parseEntityFromPath(A){return hBA(this.syncPath,A)}async readEntity(A){let Q=gU(this.syncPath,A),B=await e2Q(Q),{entityType:w,id:$}=this.parseEntityFromPath(A),f=B.birthtime.getTime()>0?B.birthtime:B.mtime,I=B.mtime,D,U;if(DM(A)||UM(A)){let X=(await f_(Q)).toString("base64"),G=a2Q(A);if(D=`data:${UM(A)?GB1(G):fB1(G)};base64,${X}`,UM(A))U=await this.readDocumentSidecar(Q,A)}else D=await f_(Q,"utf-8");let Y={entityType:w,id:$,content:D,created:f,updated:I};if(U)Y.metadata=U;return Y}async readDocumentSidecar(A,Q){let B={mimeType:"application/pdf",filename:o2Q(Q)},w=PjA(A);if(!await X5(w))return B;try{let $=await f_(w,"utf-8"),f=JSON.parse($),I=QQQ(f)?f:{};return{...B,...I}}catch{return B}}async writeEntity(A){let Q=this.getEntityFilePath(A),B=A.entityType==="image",w=A.entityType==="document";if(B||w){let f=B?/^data:image\/[a-z+]+;base64,(.+)$/i:/^data:application\/pdf;base64,(.+)$/i,I=A.content.match(f),D=I?.[1]?Buffer.from(I[1],"base64"):Buffer.from(A.content,"base64"),U=!1;if(await X5(Q)){let Y=await f_(Q),J=gB(Y.toString("base64")),X=gB(D.toString("base64"));if(J===X)U=!0}if(!U)await this.ensureEntityDirectory(A,Q),await jjA(Q,D);if(w)await this.writeDocumentSidecar(A,Q);if(U)return}else{let f=this.entityService.serializeEntity(A);if(await X5(Q)){let I=await f_(Q,"utf-8"),D=gB(I),U=gB(f);if(D===U)return}await this.ensureEntityDirectory(A,Q),await jjA(Q,f,"utf-8")}let $=new Date(A.updated);await AQQ(Q,$,$)}async ensureEntityDirectory(A,Q){if(A.entityType!=="base")await t2Q(s2Q(Q),{recursive:!0})}async writeDocumentSidecar(A,Q){let B=A.metadata,w={};for(let[I,D]of Object.entries(B)){if(I==="mimeType")continue;if(D===void 0)continue;w[I]=D}let $=PjA(Q),f=`${JSON.stringify(w,null,2)}
|
|
4633
4633
|
`;if(await X5($)){if(await f_($,"utf-8")===f)return}await this.ensureEntityDirectory(A,$),await jjA($,f,"utf-8")}getFilePath(A,Q,B=".md"){return FB1(this.syncPath,A,Q,B)}getEntityFilePath(A){return this.getFilePath(A.id,A.entityType,ZB1(A))}async getAllMarkdownFiles(){return kjA(this.syncPath,this.entityService)}async getAllSyncFiles(){return zB1(this.syncPath,this.entityService)}async ensureDirectoryStructure(A){await qB1(this.syncPath,A)}shouldUpdateEntity(A,Q){let B=gB(Q.content);return A.contentHash!==B}async gatherFileStatus(){return LB1(this.syncPath,this.entityService)}async syncDirectoryExists(){return X5(this.syncPath)}async fileExists(A){return X5(A)}}E7();WA();E7();async function uBA(A,Q,B,w){let{sourceUrl:$}=A,f=await Q.listEntities({entityType:"image",options:{filter:{metadata:{sourceUrl:$}},limit:1}});if(f[0])return w.debug("Reusing existing image entity",{sourceUrl:$,imageId:f[0].id}),f[0].id;let I=await B($),{base64:D}=RN(I),U=UV(D),Y=bN(D);if(!U||!Y)throw Error("Could not detect image format or dimensions");let J=await Q.createEntity({entity:{id:A.id,entityType:"image",content:I,metadata:{title:A.title,alt:A.alt,format:U,width:Y.width,height:Y.height,sourceUrl:$}}});return w.debug("Created image entity from URL",{sourceUrl:$,imageId:J.entityId}),J.entityId}var EB1=H.object({title:H.string(),slug:H.string().optional(),coverImageUrl:H.string().url(),coverImageId:H.string().optional(),coverImageAlt:H.string().optional()});class vjA{entityService;fetcher;logger;constructor(A,Q,B=WU){this.entityService=A;this.fetcher=B;this.logger=Q.child("FrontmatterImageConverter")}detectCoverImageUrl(A){let Q;try{Q=jB(A)}catch{return null}let{frontmatter:B}=Q,w=EB1.safeParse(B);if(!w.success)return null;if(w.data.coverImageId)return null;let{title:$,slug:f,coverImageUrl:I,coverImageAlt:D}=w.data;if(!jG(I))return null;return{sourceUrl:I,postTitle:$,postSlug:f??X1($),customAlt:D}}async convert(A){let Q;try{Q=jB(A)}catch(Y){return this.logger.debug("Parse failed",{error:Y}),{content:A,converted:!1}}let{frontmatter:B}=Q,w=EB1.safeParse(B);if(!w.success)return{content:A,converted:!1};if(w.data.coverImageId)return{content:A,converted:!1};let{title:$,slug:f,coverImageUrl:I,coverImageAlt:D}=w.data;if(!jG(I))return{content:A,converted:!1};let U={postTitle:$,postSlug:f??X1($),sourceUrl:I,customAlt:D};try{let Y=await this.createImageEntity(U),J={...B};return delete J.coverImageUrl,delete J.coverImageAlt,J.coverImageId=Y,{content:bG(J,Q.content),converted:!0,imageId:Y}}catch(Y){return this.logger.warn("Failed to convert coverImageUrl",{url:I,error:T0(Y)}),{content:A,converted:!1}}}async createImageEntity(A){let{postTitle:Q,postSlug:B,sourceUrl:w,customAlt:$}=A,f=`Cover image for ${Q}`;return uBA({id:`${B}-cover`,title:f,alt:$??f,sourceUrl:w},this.entityService,this.fetcher,this.logger)}}E7();WA();class Jl{entityService;fetcher;logger;constructor(A,Q,B=WU){this.entityService=A;this.fetcher=B;this.logger=Q.child("MarkdownImageConverter")}detectInlineImages(A,Q){let B=[],w=ANA(A);for(let $ of w){if(!jG($.url))continue;if($.url.startsWith("entity://"))continue;let f=this.reconstructMarkdown($);B.push({sourceUrl:$.url,alt:$.alt,originalMarkdown:f,postSlug:Q})}return B}reconstructMarkdown(A){if(A.title)return``;return``}async convert(A,Q){let B=this.detectInlineImages(A,Q);if(B.length===0)return{content:A,converted:!1,convertedCount:0};let w=A,$=0,f=0;for(let I of B)try{let D=await this.createImageEntity(I,f++),U=``;w=w.replace(I.originalMarkdown,U),$++,this.logger.debug("Converted inline image",{sourceUrl:I.sourceUrl,imageId:D})}catch(D){this.logger.warn("Failed to convert inline image",{sourceUrl:I.sourceUrl,error:T0(D)})}return{content:w,converted:$>0,convertedCount:$}}async createImageEntity(A,Q){let{sourceUrl:B,alt:w,postSlug:$}=A;return uBA({id:`${$}-inline-${Q}`,title:w||`Inline image ${Q+1} for ${$}`,alt:w||"",sourceUrl:B},this.entityService,this.fetcher,this.logger)}}class TjA{logger;entityService;fileOperations;constructor(A,Q,B){this.logger=A,this.entityService=Q,this.fileOperations=B}async importEntitiesWithProgress(A,Q,B,w){this.logger.debug("Importing entities with progress reporting");let $={imported:0,skipped:0,failed:0,quarantined:0,quarantinedFiles:[],errors:[],jobIds:[]},f=A??await this.fileOperations.getAllSyncFiles(),I=f.length;await Q.report({progress:0,message:`Starting import of ${I} files`});for(let D=0;D<I;D+=B){let U=f.slice(D,D+B),Y=await w(U);$.imported+=Y.imported,$.skipped+=Y.skipped,$.failed+=Y.failed,$.quarantined+=Y.quarantined,$.errors.push(...Y.errors),$.quarantinedFiles.push(...Y.quarantinedFiles),$.jobIds.push(...Y.jobIds);let J=Math.min(D+B,I),X=Math.round(J/I*40);await Q.report({progress:X,message:`Imported ${J}/${I} files`})}return $}async exportEntitiesWithProgress(A,Q,B,w){this.logger.debug("Exporting entities with progress reporting");let $=A??this.entityService.getEntityTypes();await Q.report({progress:50,message:`Starting export of ${$.length} entity types`});let f=await w(A);return await Q.report({progress:100,message:`Exported ${f.exported} entities`}),this.logger.debug("Export completed",f),f}}WA();import{rename as BQQ,appendFile as wQQ,readFile as $QQ,writeFile as fQQ,access as IQQ}from"fs/promises";import{join as MB1}from"path";class yjA{logger;syncPath;constructor(A,Q){this.logger=A;this.syncPath=Q}isValidationError(A){if(A instanceof H.ZodError)return!0;let Q=T0(A);return Q.includes("invalid_type")||Q.includes("invalid_enum_value")||Q.includes("Required")||Q.includes("Invalid frontmatter")||Q.includes("Unknown entity type")}async quarantineInvalidFile(A,Q,B,w){let $=w(A),f=`${$}.invalid`;try{await BQQ($,f),B.quarantined++,B.quarantinedFiles.push(A);let I=MB1(this.syncPath,".import-errors.log"),D=new Date().toISOString(),U=T0(Q),Y=`${D} - ${A}: ${U}
|
|
4634
4634
|
\u2192 ${A}.invalid
|
|
4635
4635
|
|
|
@@ -4657,7 +4657,7 @@ details.web-chat-data-part[open] > summary > .web-chat-data-part-chevron {
|
|
|
4657
4657
|
*...and ${A.files.length-10} more files*`)}if(A.exists&&A.stats.totalFiles===0)Q.push(`
|
|
4658
4658
|
## Getting Started
|
|
4659
4659
|
`),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(`
|
|
4660
|
-
`)}}aA();class GwA extends ZB{directorySync;constructor(A,Q,B){super(A,{schema:y_A,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}}}aA();class KwA extends ZB{directorySync;constructor(A,Q,B){super(A,{schema:T_A,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}}}aA();class FwA extends ZB{directorySync;context;constructor(A,Q,B){super(A,{schema:__A,jobTypeName:"directory-sync"});this.context=Q,this.directorySync=B}async process(A,Q,B){let w=Date.now(),$=A.syncDirection??"both";this.logger.info("Starting directory sync job",{jobId:Q,operation:A.operation,syncDirection:$});let f={imported:0,skipped:0,failed:0,quarantined:0,quarantinedFiles:[],errors:[],jobIds:[]},I={exported:0,failed:0,errors:[]};if($!=="export")if(await B.report({progress:10,message:"Scanning directory for changes"}),f=await this.importWithProgress(A.paths,B),$==="import")await this.waitForImportJobs(f.jobIds,B),await B.report({progress:100,message:`Import complete: ${f.imported} imported`});else await B.report({progress:50,message:`Imported ${f.imported} entities`}),await this.waitForImportJobs(f.jobIds,B),await B.report({progress:56,message:"Processing complete, starting export"});if($!=="import"){let U=$==="export"?10:60;await B.report({progress:U,message:"Exporting entities to directory"}),I=await this.exportWithProgress(A.entityTypes,B),await B.report({progress:100,message:$==="export"?`Export complete: ${I.exported} exported`:`Sync complete: ${f.imported} imported, ${I.exported} exported`})}let D=Date.now()-w;return this.logger.info("Directory sync job completed",{jobId:Q,duration:D,imported:f.imported,exported:I.exported}),{import:f,export:I,duration:D}}async importWithProgress(A,Q){try{return await this.directorySync.importEntitiesWithProgress(A,Q,10)}catch(B){throw this.logger.error("Import phase failed",{error:B}),B}}async exportWithProgress(A,Q){try{return await this.directorySync.exportEntitiesWithProgress(A,Q,10)}catch(B){throw this.logger.error("Export phase failed",{error:B}),B}}async waitForImportJobs(A,Q){if(A.length===0)return;this.logger.debug(`Waiting for ${A.length} import jobs to complete`);let{entityService:B}=this.context,w=300000,$=500,f=Date.now(),I=async()=>{let U=(await Promise.all(A.map((J)=>B.getAsyncJobStatus(J)))).filter((J)=>J&&(J.status==="completed"||J.status==="failed")).length;if(U===A.length){this.logger.debug("All import jobs completed");return}if(Date.now()-f>w){this.logger.warn(`Timeout waiting for import jobs (${U}/${A.length} completed)`);return}let Y=Math.round(U/A.length*100);return await Q.report({progress:50+Math.round(Y*0.05),message:`Processing ${U}/${A.length} entities`}),await new Promise((J)=>setTimeout(J,$)),I()};return I()}summarizeDataForLog(A){return{operation:A.operation,syncDirection:A.syncDirection}}}aA();class ZwA extends ZB{context;directorySync;gitSync;constructor(A,Q,B,w){super(A,{schema:v_A,jobTypeName:"sync-request"});this.context=Q;this.directorySync=B;this.gitSync=w}async process(A,Q,B){await B.report({progress:5,message:"Pulling latest content from git"});let w=await this.gitSync.withLock(async()=>{return await this.gitSync.pull(),await B.report({progress:35,message:"Scanning pulled content for sync changes"}),this.directorySync.queueSyncBatch(this.context,A.source,{rootJobId:Q,interfaceType:A.interfaceType,channelId:A.channelId})});if(!w)return await B.report({progress:100,message:"Sync complete: no files to import"}),{gitPulled:!0,batchQueued:!1};return await B.report({progress:100,message:`Sync queued: ${w.importOperationsCount} import jobs for ${w.totalFiles} files`}),Q6Q(w)}summarizeDataForLog(A){return{source:A.source,interfaceType:A.interfaceType,channelId:A.channelId}}}function Q6Q(A){return{gitPulled:!0,batchQueued:!0,batchId:A.batchId,importOperations:A.importOperationsCount,totalFiles:A.totalFiles}}aA();class NwA extends ZB{context;constructor(A,Q,B){super(A,{schema:WwA,jobTypeName:"directory-delete"});this.context=Q}async process(A,Q,B){let w=WwA.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}}}aA();WA();var B6Q=H.object({});class zwA extends ZB{directorySync;constructor(A,Q){super(A,{schema:B6Q,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}}aA();E7();WA();H6();E7();import{readFile as w6Q,writeFile as $6Q}from"fs/promises";var f6Q=x_A;class qwA extends ZB{context;fetcher;constructor(A,Q,B=WU){super(Q,{schema:f6Q,jobTypeName:"cover-image-convert"});this.context=A,this.fetcher=B}async process(A,Q,B){let{filePath:w,sourceUrl:$,postTitle:f,postSlug:I,customAlt:D}=A;this.logger.debug("Starting image conversion job",{jobId:Q,filePath:w,sourceUrl:$,postSlug:I});try{await this.reportProgress(B,{progress:zQ.INIT,message:`Reading file: ${w}`});let U;try{U=await w6Q(w,"utf-8")}catch(L){return this.logger.error("Failed to read file",{filePath:w,error:T0(L)}),$5.failure(L)}let Y;try{Y=jB(U)}catch(L){return this.logger.warn("Failed to parse markdown",{filePath:w,error:T0(L)}),$5.failure(L)}let J=Y.frontmatter;if(J.coverImageId)return this.logger.debug("File already has coverImageId, skipping",{filePath:w}),await this.reportProgress(B,{progress:zQ.COMPLETE,message:"Already converted"}),{success:!0,skipped:!0};await this.reportProgress(B,{progress:zQ.FETCH,message:"Checking for existing image"});let X=await this.context.entityService.listEntities({entityType:"image",options:{filter:{metadata:{sourceUrl:$}},limit:1}}),G;if(X[0])G=X[0].id,this.logger.debug("Reusing existing image entity",{sourceUrl:$,imageId:G}),await this.reportProgress(B,{progress:zQ.EXTRACT,message:`Reusing existing image: ${G}`});else{await this.reportProgress(B,{progress:zQ.PROCESS,message:`Fetching image from ${$}`});let L;try{L=await this.fetcher($)}catch(y){return this.logger.error("Failed to fetch image",{sourceUrl:$,error:T0(y)}),$5.failure(y)}await this.reportProgress(B,{progress:zQ.GENERATE,message:"Creating image entity"});let{base64:V}=RN(L),M=UV(V),O=bN(V);if(!M||!O)return this.logger.error("Could not detect image format or dimensions",{sourceUrl:$}),$5.failure(Error("Could not detect image format or dimensions"));G=`${I}-cover`;let E=`Cover image for ${f}`,S=D??E;await this.context.entityService.createEntity({entity:{id:G,entityType:"image",content:L,metadata:{title:E,alt:S,format:M,width:O.width,height:O.height,sourceUrl:$}}}),this.logger.debug("Created image entity",{imageId:G,sourceUrl:$}),await this.reportProgress(B,{progress:zQ.EXTRACT,message:`Created image: ${G}`})}await this.reportProgress(B,{progress:zQ.SAVE,message:"Updating file"});let Z={...J};delete Z.coverImageUrl,delete Z.coverImageAlt,Z.coverImageId=G;let N=bG(Z,Y.content);try{await $6Q(w,N,"utf-8")}catch(L){return this.logger.error("Failed to write file",{filePath:w,error:T0(L)}),$5.failure(L)}return await this.reportProgress(B,{progress:zQ.COMPLETE,message:"Conversion complete"}),this.logger.info("Image conversion complete",{filePath:w,imageId:G,sourceUrl:$}),{success:!0,imageId:G}}catch(U){return this.logger.error("Image conversion job failed",{jobId:Q,filePath:w,error:T0(U)}),$5.failure(U)}}summarizeDataForLog(A){return{filePath:A.filePath,sourceUrl:A.sourceUrl,postSlug:A.postSlug}}}aA();E7();WA();H6();import{readFile as I6Q,writeFile as D6Q}from"fs/promises";class LwA extends ZB{converter;constructor(A,Q,B=WU){super(Q,{schema:S_A,jobTypeName:"inline-image-convert"});this.converter=new Jl(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:zQ.INIT,message:`Reading file: ${w}`});let f;try{f=await I6Q(w,"utf-8")}catch(U){let Y=T0(U);return this.logger.error("Failed to read file",{filePath:w,error:Y}),{success:!1,error:Y}}await this.reportProgress(B,{progress:zQ.FETCH,message:"Detecting inline images"});let I=this.converter.detectInlineImages(f,$);if(I.length===0)return this.logger.debug("No inline images to convert",{filePath:w}),await this.reportProgress(B,{progress:zQ.COMPLETE,message:"No images to convert"}),{success:!0,skipped:!0,convertedCount:0};this.logger.debug("Found inline images to convert",{filePath:w,count:I.length}),await this.reportProgress(B,{progress:zQ.PROCESS,message:`Converting ${I.length} images`});let D=await this.converter.convert(f,$);if(!D.converted)return this.logger.debug("No images were converted",{filePath:w}),await this.reportProgress(B,{progress:zQ.COMPLETE,message:"No images converted"}),{success:!0,skipped:!0,convertedCount:0};await this.reportProgress(B,{progress:zQ.SAVE,message:"Writing updated file"});try{await D6Q(w,D.content,"utf-8")}catch(U){let Y=T0(U);return this.logger.error("Failed to write file",{filePath:w,error:Y}),{success:!1,error:Y}}return await this.reportProgress(B,{progress:zQ.COMPLETE,message:"Conversion complete"}),this.logger.info("Inline image conversion complete",{filePath:w,convertedCount:D.convertedCount}),{success:!0,convertedCount:D.convertedCount}}catch(f){let I=T0(f);return this.logger.error("Inline image conversion job failed",{jobId:Q,filePath:w,error:I}),{success:!1,error:I}}}summarizeDataForLog(A){return{filePath:A.filePath,postSlug:A.postSlug}}}function B51(A,Q,B){let w=($)=>B.child($);A.jobs.registerHandler("directory-sync",new FwA(w("DirectorySyncJobHandler"),A,Q)),A.jobs.registerHandler("directory-export",new GwA(w("DirectoryExportJobHandler"),A,Q)),A.jobs.registerHandler("directory-import",new KwA(w("DirectoryImportJobHandler"),A,Q)),A.jobs.registerHandler("directory-delete",new NwA(w("DirectoryDeleteJobHandler"),A,Q)),A.jobs.registerHandler("directory-cleanup",new zwA(w("DirectoryCleanupJobHandler"),Q)),A.jobs.registerHandler("cover-image-convert",new qwA(A,w("CoverImageConversionJobHandler"))),A.jobs.registerHandler("inline-image-convert",new LwA(A,w("InlineImageConversionJobHandler"))),B.debug("Registered async job handlers")}aA();import{unlink as U6Q,access as Y6Q}from"fs/promises";function w51(A,Q,B,w){let{subscribe:$}=A.messaging,{entityService:f}=A;$("entity:created",async(I)=>{let{entity:D}=I.payload;try{await Q.fileOps.writeEntity(D),B.debug("Auto-exported created entity",{id:D.id,entityType:D.entityType})}catch(U){B.error("Auto-export FAILED for created entity",{id:D.id,entityType:D.entityType,error:U instanceof Error?U.message:String(U),stack:U instanceof Error?U.stack:void 0})}return{success:!0}}),$("entity:updated",async(I)=>{let{entityType:D,entityId:U}=I.payload;try{let Y=await f.getEntity({entityType:D,id:U});if(!Y)return B.debug("Entity not found in DB, skipping export",{entityType:D,entityId:U}),{success:!1};await Q.fileOps.writeEntity(Y),B.debug("Auto-exported updated entity",{id:Y.id,entityType:Y.entityType})}catch(Y){B.error("Auto-export FAILED for updated entity",{entityType:D,entityId:U,error:Y instanceof Error?Y.message:String(Y),stack:Y instanceof Error?Y.stack:void 0})}return{success:!0}}),$("entity:deleted",async(I)=>{let{entityId:D,entityType:U}=I.payload,Y=Q.fileOps.getFilePath(D,U);if(await Y6Q(Y).then(()=>!0,()=>!1))await U6Q(Y),B.debug("Auto-deleted entity file",{id:D,entityType:U,path:Y});return{success:!0}}),B.debug("Setup auto-sync for entity events",{entityTypes:w})}function $51(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:J$(),metadata:{operationType:"file_operations",operationTarget:B,pluginId:"directory-sync"}})})}WA();aA();import{readdir as D51,mkdir as X6Q,copyFile as W6Q}from"fs/promises";import{join as I51,resolve as g_A}from"path";import{join as J6Q}from"path";async function f51(A){if(!await X5(J6Q(A,".git")))return!1;try{return await mJ(A).revparse(["--verify","HEAD"]),!0}catch{return!1}}async function H6Q(A,Q){if(!await X5(A))return!0;if((await D51(A)).filter(($)=>!$.startsWith(".")&&!$.startsWith("_")).length>0)return!1;if(await f51(A))return Q.debug("Git repository with history detected - skipping seed content",{path:A}),!1;return!0}async function U51(A,Q){let B=await D51(A,{withFileTypes:!0});for(let w of B){let $=I51(A,w.name),f=I51(Q,w.name);if(w.isDirectory()){if(!await X5(f))await X6Q(f,{recursive:!0});await U51($,f)}else await W6Q($,f)}}async function Y51(A,Q,B){let w=g_A(process.cwd(),A);B=B?g_A(B):g_A(process.cwd(),"seed-content");let $=await H6Q(w,Q);if($&&await X5(B))Q.debug("Copying seed content to brain-data directory"),await U51(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 J51(A,Q,B,w,$){let f=!1,I=async()=>{if(f)return;f=!0;let D=Q();if(B.seedContent){let U=B.syncPath??A.dataDir;await Y51(U,w,B.seedContentPath)}try{if($){w.debug("Git enabled \u2014 pulling before import");let Y=await $.pull();if(Y.files.length>0)w.info("Pulled changes from remote",{filesChanged:Y.files.length})}w.debug("Starting initial sync");let U=await D.sync();w.debug("Initial sync completed",{imported:U.import.imported,failed:U.import.failed,duration:U.duration}),await A.messaging.send({type:jL.initialSyncCompleted,payload:{success:!0},...{broadcast:!0}})}catch(U){w.error("Initial sync failed",U),await A.messaging.send({type:jL.initialSyncCompleted,payload:{success:!1,error:T0(U)},...{broadcast:!0}})}};A.messaging.subscribe(jL.pluginsRegistered,async()=>{return w.debug("Plugins registered, starting initial sync"),await I(),{success:!0}})}WA();function X51(A,Q,B,w){let $=new GL(()=>{Q.withLock(async()=>{try{await Q.commit(),await Q.push()}catch(D){w.error("Git auto-commit failed",{error:D})}})},B),f=["entity:created","entity:updated","entity:deleted"],I=[];for(let D of f){let U=A.subscribe(D,async()=>{return $.trigger(),{success:!0}});I.push(U)}return()=>{$.dispose();for(let D of I)D()}}function W51(A,Q,B,w,$){if(w<=0)return()=>{};let f=w*60*1000,I=!1,D=async()=>{if(I)return;I=!0;try{let{files:Y,result:J}=await A.withLock(async()=>{let X=await A.pull();if(X.files.length===0)return{files:[],result:null};let G=await Q.queueSyncBatch(B,"periodic-sync");return{files:X.files,result:G}});if(Y.length>0)$.info("Periodic sync: pulled changes",{filesChanged:Y.length});if(J)$.debug("Periodic sync: queued imports",{importOperations:J.importOperationsCount,totalFiles:J.totalFiles})}catch(Y){$.error("Periodic git sync failed",{error:Y})}finally{I=!1}},U=setInterval(()=>{D()},f);return $.info("Started periodic git sync",{intervalMinutes:w}),()=>{clearInterval(U)}}import{spawnSync as G51}from"child_process";import{cpSync as G6Q,existsSync as H51,mkdirSync as K6Q,mkdtempSync as F6Q,rmSync as Z6Q}from"fs";import{tmpdir as N6Q}from"os";import{fileURLToPath as z6Q}from"url";import{join as q6Q,resolve as L6Q}from"path";function Uz(A,Q){let B=G51("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 V6Q(A){return A.startsWith("file://")}function E6Q(A){return z6Q(A)}function M6Q(A,Q){return G51("git",["--git-dir",A,"show-ref","--verify","--quiet",`refs/heads/${Q}`]).status===0}async function K51(A){if(!A.bootstrapFromSeed)return;if(!A.gitUrl||!V6Q(A.gitUrl))return;if(!A.seedContentPath)throw Error("directory-sync git.bootstrapFromSeed requires seedContentPath for local file:// remotes");let Q=A.branch??"main",B=E6Q(A.gitUrl),w=L6Q(A.seedContentPath);if(!H51(w))throw Error(`Seed content path not found: ${w}`);if(!H51(B))A.logger.debug("Creating local bare content remote",{remotePath:B,branch:Q}),K6Q(B,{recursive:!0}),Uz(process.cwd(),["init","--bare",`--initial-branch=${Q}`,B]);if(M6Q(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 $=F6Q(q6Q(N6Q(),"directory-sync-seed-"));try{Uz($,["init",`--initial-branch=${Q}`]),Uz($,["config","user.name",A.authorName??"Brain"]),Uz($,["config","user.email",A.authorEmail??"brain@localhost"]),G6Q(w,$,{recursive:!0}),Uz($,["add","."]),Uz($,["commit","-m","seed content remote"]),Uz($,["remote","add","origin",A.gitUrl]),Uz($,["push","-u","origin",Q])}finally{Z6Q($,{recursive:!0,force:!0})}}function F51(A,Q,B,w,$){let{subscribe:f}=A.messaging;f("entity:export:request",async(I)=>{try{return{success:!0,data:await Q().exportEntities(I.payload.entityTypes)}}catch(D){return{success:!1,error:D instanceof Error?D.message:"Export failed"}}}),f("entity:import:request",async(I)=>{try{let D=Q(),U=I.payload.paths,Y=await D.importEntities(U);if(U&&U.length>0)await D.removeOrphanedEntities();return{success:!0,data:Y}}catch(D){return{success:!1,error:D instanceof Error?D.message:"Import failed"}}}),f("sync:status:request",async()=>{try{let D=await Q().getStatus();return{success:!0,data:{syncPath:D.syncPath,isInitialized:D.exists,watchEnabled:D.watching}}}catch(I){return{success:!1,error:I instanceof Error?I.message:"Status check failed"}}}),f("sync:configure:request",async(I)=>{try{return await B({syncPath:I.payload.syncPath}),{success:!0,data:{syncPath:I.payload.syncPath,configured:!0}}}catch(D){return{success:!1,error:D instanceof Error?D.message:"Configuration failed"}}}),f("git-sync:get-repo-info",async()=>{if(!$?.repo)return{success:!1,error:"Git not configured"};return{success:!0,data:{repo:$.repo,branch:$.branch??"main"}}}),w.debug("Registered message handlers")}aA();WA();aA();WA();function Z51(A,Q){return oQ(A,"history","Get version history for an entity from git. Without sha: returns commit list. With sha: returns entity content at that version.",H.object({entityType:H.string().describe("Entity type (e.g. post, note, link)"),id:H.string().describe("Entity ID"),sha:H.string().optional().describe("Commit SHA to retrieve content at. Omit to list commit history."),limit:H.number().int().positive().optional().default(10).describe("Max commits to return (list mode only)")}),async(B)=>{let w=`${B.entityType}/${B.id}.md`;try{if(B.sha){let f=await Q.show(B.sha,w);return U8({sha:B.sha,entityType:B.entityType,id:B.id,content:f},`Content at ${B.sha.slice(0,7)}`)}let $=await Q.log(w,B.limit);if($.length===0)return U8({commits:[]},`No history found for ${B.entityType}/${B.id}`);return U8({commits:$,entityType:B.entityType,id:B.id},`${$.length} version${$.length===1?"":"s"} found`)}catch($){return X$($ instanceof Error?$.message:"History lookup failed")}})}function N51(A,Q,B,w){let $=[oQ(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.",H.object({}),async(f,I)=>{try{let D=I.channelId?`${I.interfaceType}:${I.channelId}`:`plugin:${B}`,U={interfaceType:I.interfaceType,channelId:I.channelId};if(w){let J=await Q.jobs.enqueue({type:"sync-request",data:{source:D,interfaceType:U.interfaceType,channelId:U.channelId},toolContext:I});return U8({jobId:J,status:"queued",gitPulled:!0},"Sync queued: pulling from git and scanning files")}let Y=await A.queueSyncBatch(Q,D,U);if(!Y)return U8({gitPulled:!1},"No files to sync");return U8({batchId:Y.batchId,importOperations:Y.importOperationsCount,totalFiles:Y.totalFiles,gitPulled:!1},`Sync started: ${Y.importOperationsCount} import jobs queued for ${Y.totalFiles} files`)}catch(D){return X$(D instanceof Error?D.message:"Sync failed")}},{cli:{name:"sync"}}),oQ(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.",H.object({}),async()=>{try{let f=await A.getStatus(),I={syncPath:f.syncPath,lastSync:f.lastSync?.toISOString(),watching:f.watching};if(w){let D=await w.getStatus();I.git={isRepo:D.isRepo,branch:D.branch,hasChanges:D.hasChanges,ahead:D.ahead,behind:D.behind,remote:D.remote}}return U8(I)}catch(f){return X$(f instanceof Error?f.message:"Status check failed")}},{visibility:"public"})];if(w)$.push(Z51(B,w));return $}var z51={name:"@brains/directory-sync",private:!0,version:"0.2.0-alpha.119",description:"Directory-based entity synchronization plugin for Brains",type:"module",main:"./src/index.ts",types:"./src/index.ts",exports:{".":{types:"./src/index.ts",import:"./src/index.ts"}},scripts:{test:"bun test",typecheck:"tsc --noEmit",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",clean:"rm -rf .turbo"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/image":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*",chokidar:"^3.5.3","simple-git":"^3.21.0"},devDependencies:{"@brains/typescript-config":"workspace:*","@types/bun":"latest","@types/node":"^20.0.0",typescript:"^5.3.3"},peerDependencies:{}};class h_A extends YB{directorySync;gitSync;gitCleanups=[];constructor(A={}){super("directory-sync",z51,A,El)}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:Ml,basePrompt:"",formatter:new HwA,requiredPermission:"anchor"}});let w=this.config.syncPath??A.dataDir;this.directorySync=new Xl({syncPath:w,autoSync:this.config.autoSync,watchInterval:this.config.watchInterval,includeMetadata:this.config.includeMetadata,entityTypes:this.config.entityTypes,deleteOnFileRemoval:this.config.deleteOnFileRemoval,entityService:B,logger:Q});try{await this.directorySync.initializeDirectory(),this.logger.debug("Directory structure initialized",{path:w})}catch(I){throw this.logger.error("Failed to initialize directory",I),I}await this.registerJobHandlers(A);let $=this.requireDirectorySync();if(w51(A,$,this.logger,this.config.entityTypes),this.config.autoSync)$51(A,$,this.config.syncPath??A.dataDir);let f=this.config.git!==void 0&&(this.config.git.repo!==void 0||this.config.git.gitUrl!==void 0);if(this.config.git&&!f)this.logger.debug("Git block present but no repo/gitUrl configured \u2014 git sync disabled");if(f&&this.config.git){await K51({gitUrl:this.config.git.gitUrl,branch:this.config.git.branch,seedContentPath:this.config.seedContentPath,bootstrapFromSeed:this.config.git.bootstrapFromSeed,authorName:this.config.git.authorName,authorEmail:this.config.git.authorEmail,logger:this.logger.child("ContentRemoteBootstrap")});let I=this.config.syncPath??A.dataDir;if(this.gitSync=new j_A({logger:this.logger.child("GitSync"),dataDir:I,repo:this.config.git.repo,gitUrl:this.config.git.gitUrl,branch:this.config.git.branch,authToken:this.config.git.authToken,authorName:this.config.git.authorName,authorEmail:this.config.git.authorEmail}),await this.gitSync.initialize(),this.logger.info("Git integration enabled",{repo:this.config.git.repo}),A.jobs.registerHandler("sync-request",new ZwA(this.logger.child("DirectorySyncRequestJobHandler"),A,this.requireDirectorySync(),this.gitSync)),this.gitCleanups.push(X51(A.messaging,this.gitSync,this.config.commitDebounce,this.logger.child("GitAutoCommit"))),this.config.autoSync)this.gitCleanups.push(W51(this.gitSync,this.requireDirectorySync(),A,this.config.syncInterval,this.logger.child("GitPeriodicSync")))}if(this.config.initialSync)J51(A,()=>this.requireDirectorySync(),this.config,this.logger,this.gitSync);F51(A,()=>this.requireDirectorySync(),(I)=>this.configure(I),this.logger,this.config.git)}async getTools(){let A=this.requireDirectorySync();return N51(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 Xl({...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){B51(A,this.requireDirectorySync(),this.logger)}}function WM(A={}){return new h_A(A)}aA();WA();var q51={name:"@brains/email-resend",private:!0,version:"0.2.0-alpha.119",description:"Generic email delivery adapter for Resend",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint src test --ext .ts","lint:fix":"eslint src test --ext .ts --fix"},dependencies:{"@brains/email-contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var R6Q=H.object({apiKey:H.string().min(1).optional(),from:H.string().min(1).optional()});class L51 extends YB{fetchImpl;constructor(A={},Q={}){super("email-resend",q51,A,R6Q);this.fetchImpl=Q.fetchImpl??fetch}async onRegister(A){if(!this.config.apiKey||!this.config.from){this.logger.warn("Email Resend adapter is disabled because apiKey or from is missing");return}let Q=this.logger;A.messaging.subscribe(c0A,async(B)=>{let w=kV0.parse(B.payload);try{return{success:!0,data:await this.sendWithResend(w)}}catch($){if(w.sensitivity==="secret")Q.warn("Email delivery failed for a secret message");else Q.warn("Email delivery failed",{to:w.to,subject:w.subject,error:$ instanceof Error?$.message:String($)});return{success:!1,error:"Email delivery failed"}}})}async sendWithResend(A){let Q=this.config.apiKey,B=this.config.from;if(!Q||!B)return{status:"failed"};let w=await this.fetchImpl("https://api.resend.com/emails",{method:"POST",headers:{Authorization:`Bearer ${Q}`,"Content-Type":"application/json"},body:JSON.stringify({from:B,to:A.to,subject:A.subject,text:A.text,...A.html?{html:A.html}:{}})});if(!w.ok)throw Error("Resend email request failed");let $=await w.json();return $.id?{status:"sent",id:$.id}:{status:"sent"}}}function VwA(A={}){return new L51(A)}aA();import{render as TG1}from"preact-render-to-string";import{h as oM}from"preact";function V51(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=V51(A[Q]))&&(w&&(w+=" "),w+=B)}else for(B in A)A[B]&&(w&&(w+=" "),w+=B);return w}function W_(){for(var A,Q,B=0,w="",$=arguments.length;B<$;B++)(A=arguments[B])&&(Q=V51(A))&&(w&&(w+=" "),w+=Q);return w}var b6Q=(A)=>{let Q=k6Q(A),{conflictingClassGroups:B,conflictingClassGroupModifiers:w}=A;return{getClassGroupId:(I)=>{let D=I.split("-");if(D[0]===""&&D.length!==1)D.shift();return R51(D,Q)||P6Q(I)},getConflictingClassGroupIds:(I,D)=>{let U=B[I]||[];if(D&&w[I])return[...U,...w[I]];return U}}},R51=(A,Q)=>{if(A.length===0)return Q.classGroupId;let B=A[0],w=Q.nextPart.get(B),$=w?R51(A.slice(1),w):void 0;if($)return $;if(Q.validators.length===0)return;let f=A.join("-");return Q.validators.find(({validator:I})=>I(f))?.classGroupId},E51=/^\[(.+)\]$/,P6Q=(A)=>{if(E51.test(A)){let Q=E51.exec(A)[1],B=Q?.substring(0,Q.indexOf(":"));if(B)return"arbitrary.."+B}},k6Q=(A)=>{let{theme:Q,prefix:B}=A,w={nextPart:new Map,validators:[]};return _6Q(Object.entries(A.classGroups),B).forEach(([f,I])=>{u_A(I,w,f,Q)}),w},u_A=(A,Q,B,w)=>{A.forEach(($)=>{if(typeof $==="string"){let f=$===""?Q:M51(Q,$);f.classGroupId=B;return}if(typeof $==="function"){if(j6Q($)){u_A($(w),Q,B,w);return}Q.validators.push({validator:$,classGroupId:B});return}Object.entries($).forEach(([f,I])=>{u_A(I,M51(Q,f),B,w)})})},M51=(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},j6Q=(A)=>A.isThemeGetter,_6Q=(A,Q)=>{if(!Q)return A;return A.map(([B,w])=>{let $=w.map((f)=>{if(typeof f==="string")return Q+f;if(typeof f==="object")return Object.fromEntries(Object.entries(f).map(([I,D])=>[Q+I,D]));return f});return[B,$]})},v6Q=(A)=>{if(A<1)return{get:()=>{return},set:()=>{}};let Q=0,B=new Map,w=new Map,$=(f,I)=>{if(B.set(f,I),Q++,Q>A)Q=0,w=B,B=new Map};return{get(f){let I=B.get(f);if(I!==void 0)return I;if((I=w.get(f))!==void 0)return $(f,I),I},set(f,I){if(B.has(f))B.set(f,I);else $(f,I)}}};var T6Q=(A)=>{let{separator:Q,experimentalParseClassName:B}=A,w=Q.length===1,$=Q[0],f=Q.length,I=(D)=>{let U=[],Y=0,J=0,X;for(let V=0;V<D.length;V++){let M=D[V];if(Y===0){if(M===$&&(w||D.slice(V,V+f)===Q)){U.push(D.slice(J,V)),J=V+f;continue}if(M==="/"){X=V;continue}}if(M==="[")Y++;else if(M==="]")Y--}let G=U.length===0?D:D.substring(J),Z=G.startsWith("!"),N=Z?G.substring(1):G,L=X&&X>J?X-J:void 0;return{modifiers:U,hasImportantModifier:Z,baseClassName:N,maybePostfixModifierPosition:L}};if(B)return(D)=>B({className:D,parseClassName:I});return I},y6Q=(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},x6Q=(A)=>({cache:v6Q(A.cacheSize),parseClassName:T6Q(A),...b6Q(A)}),S6Q=/\s+/,g6Q=(A,Q)=>{let{parseClassName:B,getClassGroupId:w,getConflictingClassGroupIds:$}=Q,f=[],I=A.trim().split(S6Q),D="";for(let U=I.length-1;U>=0;U-=1){let Y=I[U],{modifiers:J,hasImportantModifier:X,baseClassName:G,maybePostfixModifierPosition:Z}=B(Y),N=Boolean(Z),L=w(N?G.substring(0,Z):G);if(!L){if(!N){D=Y+(D.length>0?" "+D:D);continue}if(L=w(G),!L){D=Y+(D.length>0?" "+D:D);continue}N=!1}let V=y6Q(J).join(":"),M=X?V+"!":V,O=M+L;if(f.includes(O))continue;f.push(O);let E=$(L,N);for(let S=0;S<E.length;++S){let y=E[S];f.push(M+y)}D=Y+(D.length>0?" "+D:D)}return D};function h6Q(){let A=0,Q,B,w="";while(A<arguments.length)if(Q=arguments[A++]){if(B=b51(Q))w&&(w+=" "),w+=B}return w}var b51=(A)=>{if(typeof A==="string")return A;let Q,B="";for(let w=0;w<A.length;w++)if(A[w]){if(Q=b51(A[w]))B&&(B+=" "),B+=Q}return B};function C51(A,...Q){let B,w,$,f=I;function I(U){let Y=Q.reduce((J,X)=>X(J),A());return B=x6Q(Y),w=B.cache.get,$=B.cache.set,f=D,D(U)}function D(U){let Y=w(U);if(Y)return Y;let J=g6Q(U,B);return $(U,J),J}return function(){return f(h6Q.apply(null,arguments))}}var y8=(A)=>{let Q=(B)=>B[A]||[];return Q.isThemeGetter=!0,Q},P51=/^\[(?:([a-z-]+):)?(.+)\]$/i,m6Q=/^\d+\/\d+$/,u6Q=new Set(["px","full","screen"]),c6Q=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,l6Q=/\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$/,p6Q=/^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/,i6Q=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,r6Q=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,YF=(A)=>H_(A)||u6Q.has(A)||m6Q.test(A),Yz=(A)=>G_(A,"length",A5Q),H_=(A)=>Boolean(A)&&!Number.isNaN(Number(A)),m_A=(A)=>G_(A,"number",H_),Cl=(A)=>Boolean(A)&&Number.isInteger(Number(A)),d6Q=(A)=>A.endsWith("%")&&H_(A.slice(0,-1)),rQ=(A)=>P51.test(A),Jz=(A)=>c6Q.test(A),n6Q=new Set(["length","size","percentage"]),o6Q=(A)=>G_(A,n6Q,k51),s6Q=(A)=>G_(A,"position",k51),a6Q=new Set(["image","url"]),t6Q=(A)=>G_(A,a6Q,B5Q),e6Q=(A)=>G_(A,"",Q5Q),Ol=()=>!0,G_=(A,Q,B)=>{let w=P51.exec(A);if(w){if(w[1])return typeof Q==="string"?w[1]===Q:Q.has(w[1]);return B(w[2])}return!1},A5Q=(A)=>l6Q.test(A)&&!p6Q.test(A),k51=()=>!1,Q5Q=(A)=>i6Q.test(A),B5Q=(A)=>r6Q.test(A);var O51=()=>{let A=y8("colors"),Q=y8("spacing"),B=y8("blur"),w=y8("brightness"),$=y8("borderColor"),f=y8("borderRadius"),I=y8("borderSpacing"),D=y8("borderWidth"),U=y8("contrast"),Y=y8("grayscale"),J=y8("hueRotate"),X=y8("invert"),G=y8("gap"),Z=y8("gradientColorStops"),N=y8("gradientColorStopPositions"),L=y8("inset"),V=y8("margin"),M=y8("opacity"),O=y8("padding"),E=y8("saturate"),S=y8("scale"),y=y8("sepia"),T=y8("skew"),_=y8("space"),x=y8("translate"),g=()=>["auto","contain","none"],n=()=>["auto","hidden","clip","visible","scroll"],m=()=>["auto",rQ,Q],BA=()=>[rQ,Q],a=()=>["",YF,Yz],j=()=>["auto",H_,rQ],R=()=>["bottom","center","left","left-bottom","left-top","right","right-bottom","right-top","top"],P=()=>["solid","dashed","dotted","double","none"],c=()=>["normal","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity"],l=()=>["start","end","center","between","around","evenly","stretch"],e=()=>["","0",rQ],s=()=>["auto","avoid","all","avoid-page","page","left","right","column"],XA=()=>[H_,rQ];return{cacheSize:500,separator:":",theme:{colors:[Ol],spacing:[YF,Yz],blur:["none","",Jz,rQ],brightness:XA(),borderColor:[A],borderRadius:["none","","full",Jz,rQ],borderSpacing:BA(),borderWidth:a(),contrast:XA(),grayscale:e(),hueRotate:XA(),invert:e(),gap:BA(),gradientColorStops:[A],gradientColorStopPositions:[d6Q,Yz],inset:m(),margin:m(),opacity:XA(),padding:BA(),saturate:XA(),scale:XA(),sepia:e(),skew:XA(),space:BA(),translate:BA()},classGroups:{aspect:[{aspect:["auto","square","video",rQ]}],container:["container"],columns:[{columns:[Jz]}],"break-after":[{"break-after":s()}],"break-before":[{"break-before":s()}],"break-inside":[{"break-inside":["auto","avoid","avoid-page","avoid-column"]}],"box-decoration":[{"box-decoration":["slice","clone"]}],box:[{box:["border","content"]}],display:["block","inline-block","inline","flex","inline-flex","table","inline-table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row-group","table-row","flow-root","grid","inline-grid","contents","list-item","hidden"],float:[{float:["right","left","none","start","end"]}],clear:[{clear:["left","right","both","none","start","end"]}],isolation:["isolate","isolation-auto"],"object-fit":[{object:["contain","cover","fill","none","scale-down"]}],"object-position":[{object:[...R(),rQ]}],overflow:[{overflow:n()}],"overflow-x":[{"overflow-x":n()}],"overflow-y":[{"overflow-y":n()}],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",Cl,rQ]}],basis:[{basis:m()}],"flex-direction":[{flex:["row","row-reverse","col","col-reverse"]}],"flex-wrap":[{flex:["wrap","wrap-reverse","nowrap"]}],flex:[{flex:["1","auto","initial","none",rQ]}],grow:[{grow:e()}],shrink:[{shrink:e()}],order:[{order:["first","last","none",Cl,rQ]}],"grid-cols":[{"grid-cols":[Ol]}],"col-start-end":[{col:["auto",{span:["full",Cl,rQ]},rQ]}],"col-start":[{"col-start":j()}],"col-end":[{"col-end":j()}],"grid-rows":[{"grid-rows":[Ol]}],"row-start-end":[{row:["auto",{span:[Cl,rQ]},rQ]}],"row-start":[{"row-start":j()}],"row-end":[{"row-end":j()}],"grid-flow":[{"grid-flow":["row","col","dense","row-dense","col-dense"]}],"auto-cols":[{"auto-cols":["auto","min","max","fr",rQ]}],"auto-rows":[{"auto-rows":["auto","min","max","fr",rQ]}],gap:[{gap:[G]}],"gap-x":[{"gap-x":[G]}],"gap-y":[{"gap-y":[G]}],"justify-content":[{justify:["normal",...l()]}],"justify-items":[{"justify-items":["start","end","center","stretch"]}],"justify-self":[{"justify-self":["auto","start","end","center","stretch"]}],"align-content":[{content:["normal",...l(),"baseline"]}],"align-items":[{items:["start","end","center","baseline","stretch"]}],"align-self":[{self:["auto","start","end","center","stretch","baseline"]}],"place-content":[{"place-content":[...l(),"baseline"]}],"place-items":[{"place-items":["start","end","center","baseline","stretch"]}],"place-self":[{"place-self":["auto","start","end","center","stretch"]}],p:[{p:[O]}],px:[{px:[O]}],py:[{py:[O]}],ps:[{ps:[O]}],pe:[{pe:[O]}],pt:[{pt:[O]}],pr:[{pr:[O]}],pb:[{pb:[O]}],pl:[{pl:[O]}],m:[{m:[V]}],mx:[{mx:[V]}],my:[{my:[V]}],ms:[{ms:[V]}],me:[{me:[V]}],mt:[{mt:[V]}],mr:[{mr:[V]}],mb:[{mb:[V]}],ml:[{ml:[V]}],"space-x":[{"space-x":[_]}],"space-x-reverse":["space-x-reverse"],"space-y":[{"space-y":[_]}],"space-y-reverse":["space-y-reverse"],w:[{w:["auto","min","max","fit","svw","lvw","dvw",rQ,Q]}],"min-w":[{"min-w":[rQ,Q,"min","max","fit"]}],"max-w":[{"max-w":[rQ,Q,"none","full","min","max","fit","prose",{screen:[Jz]},Jz]}],h:[{h:[rQ,Q,"auto","min","max","fit","svh","lvh","dvh"]}],"min-h":[{"min-h":[rQ,Q,"min","max","fit","svh","lvh","dvh"]}],"max-h":[{"max-h":[rQ,Q,"min","max","fit","svh","lvh","dvh"]}],size:[{size:[rQ,Q,"auto","min","max","fit"]}],"font-size":[{text:["base",Jz,Yz]}],"font-smoothing":["antialiased","subpixel-antialiased"],"font-style":["italic","not-italic"],"font-weight":[{font:["thin","extralight","light","normal","medium","semibold","bold","extrabold","black",m_A]}],"font-family":[{font:[Ol]}],"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",rQ]}],"line-clamp":[{"line-clamp":["none",H_,m_A]}],leading:[{leading:["none","tight","snug","normal","relaxed","loose",YF,rQ]}],"list-image":[{"list-image":["none",rQ]}],"list-style-type":[{list:["none","disc","decimal",rQ]}],"list-style-position":[{list:["inside","outside"]}],"placeholder-color":[{placeholder:[A]}],"placeholder-opacity":[{"placeholder-opacity":[M]}],"text-alignment":[{text:["left","center","right","justify","start","end"]}],"text-color":[{text:[A]}],"text-opacity":[{"text-opacity":[M]}],"text-decoration":["underline","overline","line-through","no-underline"],"text-decoration-style":[{decoration:[...P(),"wavy"]}],"text-decoration-thickness":[{decoration:["auto","from-font",YF,Yz]}],"underline-offset":[{"underline-offset":["auto",YF,rQ]}],"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:BA()}],"vertical-align":[{align:["baseline","top","middle","bottom","text-top","text-bottom","sub","super",rQ]}],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",rQ]}],"bg-attachment":[{bg:["fixed","local","scroll"]}],"bg-clip":[{"bg-clip":["border","padding","content","text"]}],"bg-opacity":[{"bg-opacity":[M]}],"bg-origin":[{"bg-origin":["border","padding","content"]}],"bg-position":[{bg:[...R(),s6Q]}],"bg-repeat":[{bg:["no-repeat",{repeat:["","x","y","round","space"]}]}],"bg-size":[{bg:["auto","cover","contain",o6Q]}],"bg-image":[{bg:["none",{"gradient-to":["t","tr","r","br","b","bl","l","tl"]},t6Q]}],"bg-color":[{bg:[A]}],"gradient-from-pos":[{from:[N]}],"gradient-via-pos":[{via:[N]}],"gradient-to-pos":[{to:[N]}],"gradient-from":[{from:[Z]}],"gradient-via":[{via:[Z]}],"gradient-to":[{to:[Z]}],rounded:[{rounded:[f]}],"rounded-s":[{"rounded-s":[f]}],"rounded-e":[{"rounded-e":[f]}],"rounded-t":[{"rounded-t":[f]}],"rounded-r":[{"rounded-r":[f]}],"rounded-b":[{"rounded-b":[f]}],"rounded-l":[{"rounded-l":[f]}],"rounded-ss":[{"rounded-ss":[f]}],"rounded-se":[{"rounded-se":[f]}],"rounded-ee":[{"rounded-ee":[f]}],"rounded-es":[{"rounded-es":[f]}],"rounded-tl":[{"rounded-tl":[f]}],"rounded-tr":[{"rounded-tr":[f]}],"rounded-br":[{"rounded-br":[f]}],"rounded-bl":[{"rounded-bl":[f]}],"border-w":[{border:[D]}],"border-w-x":[{"border-x":[D]}],"border-w-y":[{"border-y":[D]}],"border-w-s":[{"border-s":[D]}],"border-w-e":[{"border-e":[D]}],"border-w-t":[{"border-t":[D]}],"border-w-r":[{"border-r":[D]}],"border-w-b":[{"border-b":[D]}],"border-w-l":[{"border-l":[D]}],"border-opacity":[{"border-opacity":[M]}],"border-style":[{border:[...P(),"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":[M]}],"divide-style":[{divide:P()}],"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:["",...P()]}],"outline-offset":[{"outline-offset":[YF,rQ]}],"outline-w":[{outline:[YF,Yz]}],"outline-color":[{outline:[A]}],"ring-w":[{ring:a()}],"ring-w-inset":["ring-inset"],"ring-color":[{ring:[A]}],"ring-opacity":[{"ring-opacity":[M]}],"ring-offset-w":[{"ring-offset":[YF,Yz]}],"ring-offset-color":[{"ring-offset":[A]}],shadow:[{shadow:["","inner","none",Jz,e6Q]}],"shadow-color":[{shadow:[Ol]}],opacity:[{opacity:[M]}],"mix-blend":[{"mix-blend":[...c(),"plus-lighter","plus-darker"]}],"bg-blend":[{"bg-blend":c()}],filter:[{filter:["","none"]}],blur:[{blur:[B]}],brightness:[{brightness:[w]}],contrast:[{contrast:[U]}],"drop-shadow":[{"drop-shadow":["","none",Jz,rQ]}],grayscale:[{grayscale:[Y]}],"hue-rotate":[{"hue-rotate":[J]}],invert:[{invert:[X]}],saturate:[{saturate:[E]}],sepia:[{sepia:[y]}],"backdrop-filter":[{"backdrop-filter":["","none"]}],"backdrop-blur":[{"backdrop-blur":[B]}],"backdrop-brightness":[{"backdrop-brightness":[w]}],"backdrop-contrast":[{"backdrop-contrast":[U]}],"backdrop-grayscale":[{"backdrop-grayscale":[Y]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[J]}],"backdrop-invert":[{"backdrop-invert":[X]}],"backdrop-opacity":[{"backdrop-opacity":[M]}],"backdrop-saturate":[{"backdrop-saturate":[E]}],"backdrop-sepia":[{"backdrop-sepia":[y]}],"border-collapse":[{border:["collapse","separate"]}],"border-spacing":[{"border-spacing":[I]}],"border-spacing-x":[{"border-spacing-x":[I]}],"border-spacing-y":[{"border-spacing-y":[I]}],"table-layout":[{table:["auto","fixed"]}],caption:[{caption:["top","bottom"]}],transition:[{transition:["none","all","","colors","opacity","shadow","transform",rQ]}],duration:[{duration:XA()}],ease:[{ease:["linear","in","out","in-out",rQ]}],delay:[{delay:XA()}],animate:[{animate:["none","spin","ping","pulse","bounce",rQ]}],transform:[{transform:["","gpu","none"]}],scale:[{scale:[S]}],"scale-x":[{"scale-x":[S]}],"scale-y":[{"scale-y":[S]}],rotate:[{rotate:[Cl,rQ]}],"translate-x":[{"translate-x":[x]}],"translate-y":[{"translate-y":[x]}],"skew-x":[{"skew-x":[T]}],"skew-y":[{"skew-y":[T]}],"transform-origin":[{origin:["center","top","top-right","right","bottom-right","bottom","bottom-left","left","top-left",rQ]}],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",rQ]}],"caret-color":[{caret:[A]}],"pointer-events":[{"pointer-events":["none","auto"]}],resize:[{resize:["none","y","x",""]}],"scroll-behavior":[{scroll:["auto","smooth"]}],"scroll-m":[{"scroll-m":BA()}],"scroll-mx":[{"scroll-mx":BA()}],"scroll-my":[{"scroll-my":BA()}],"scroll-ms":[{"scroll-ms":BA()}],"scroll-me":[{"scroll-me":BA()}],"scroll-mt":[{"scroll-mt":BA()}],"scroll-mr":[{"scroll-mr":BA()}],"scroll-mb":[{"scroll-mb":BA()}],"scroll-ml":[{"scroll-ml":BA()}],"scroll-p":[{"scroll-p":BA()}],"scroll-px":[{"scroll-px":BA()}],"scroll-py":[{"scroll-py":BA()}],"scroll-ps":[{"scroll-ps":BA()}],"scroll-pe":[{"scroll-pe":BA()}],"scroll-pt":[{"scroll-pt":BA()}],"scroll-pr":[{"scroll-pr":BA()}],"scroll-pb":[{"scroll-pb":BA()}],"scroll-pl":[{"scroll-pl":BA()}],"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",rQ]}],fill:[{fill:[A,"none"]}],"stroke-w":[{stroke:[YF,Yz,m_A]}],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"]}}},w5Q=(A,{cacheSize:Q,prefix:B,separator:w,experimentalParseClassName:$,extend:f={},override:I={}})=>{Rl(A,"cacheSize",Q),Rl(A,"prefix",B),Rl(A,"separator",w),Rl(A,"experimentalParseClassName",$);for(let D in I)$5Q(A[D],I[D]);for(let D in f)f5Q(A[D],f[D]);return A},Rl=(A,Q,B)=>{if(B!==void 0)A[Q]=B},$5Q=(A,Q)=>{if(Q)for(let B in Q)Rl(A,B,Q[B])},f5Q=(A,Q)=>{if(Q)for(let B in Q){let w=Q[B];if(w!==void 0)A[B]=(A[B]||[]).concat(w)}},EwA=(A,...Q)=>typeof A==="function"?C51(O51,A,...Q):C51(()=>w5Q(O51(),A),...Q);var I5Q=EwA({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 B2(...A){return I5Q(W_(A))}var j51=(A)=>typeof A==="boolean"?`${A}`:A===0?"0":A,_51=W_,rw=(A,Q)=>(B)=>{var w;if((Q===null||Q===void 0?void 0:Q.variants)==null)return _51(A,B===null||B===void 0?void 0:B.class,B===null||B===void 0?void 0:B.className);let{variants:$,defaultVariants:f}=Q,I=Object.keys($).map((Y)=>{let J=B===null||B===void 0?void 0:B[Y],X=f===null||f===void 0?void 0:f[Y];if(J===null)return null;let G=j51(J)||j51(X);return $[Y][G]}),D=B&&Object.entries(B).reduce((Y,J)=>{let[X,G]=J;if(G===void 0)return Y;return Y[X]=G,Y},{}),U=Q===null||Q===void 0?void 0:(w=Q.compoundVariants)===null||w===void 0?void 0:w.reduce((Y,J)=>{let{class:X,className:G,...Z}=J;return Object.entries(Z).every((N)=>{let[L,V]=N;return Array.isArray(V)?V.includes({...f,...D}[L]):{...f,...D}[L]===V})?[...Y,X,G]:Y},[]);return _51(A,I,U,B===null||B===void 0?void 0:B.class,B===null||B===void 0?void 0:B.className)};import{jsxDEV as c_A}from"preact/jsx-dev-runtime";var v51=rw("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 l_A({variant:A,title:Q,children:B,className:w}){return c_A("div",{className:B2(v51({variant:A}),w),role:"alert",children:[Q&&c_A("p",{className:"font-medium text-current opacity-90",children:Q},void 0,!1,void 0,this),c_A("div",{className:B2(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 D5Q}from"preact/jsx-dev-runtime";var T51=rw("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 HM({variant:A,size:Q,className:B,children:w,ssrOnClick:$,type:f="button",...I}){return D5Q("button",{type:f,className:B2(T51({variant:A,size:Q}),B),...I,...$&&{onclick:$},children:w},void 0,!1,void 0,this)}import{jsxDEV as U5Q}from"preact/jsx-dev-runtime";var y51=rw("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 L$({href:A,children:Q,variant:B,size:w,external:$=!1,className:f,"aria-label":I}){let D=$?{target:"_blank",rel:"noopener noreferrer"}:{};return U5Q("a",{href:A,className:B2(y51({variant:B,size:w}),f),"aria-label":I,...D,children:Q},void 0,!1,void 0,this)}import{jsxDEV as MwA}from"preact/jsx-dev-runtime";var x51=rw("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"}}),Y5Q={sm:"w-4 h-4",md:"w-5 h-5",lg:"w-6 h-6"};function K_({variant:A,size:Q,className:B}){let w=Y5Q[Q??"md"];return MwA("button",{onclick:"toggleTheme()",type:"button",className:B2(x51({variant:A,size:Q}),B),"aria-label":"Toggle dark mode",children:MwA("svg",{className:B2(w,"transition-colors"),fill:"none",stroke:"currentColor",strokeWidth:1.6,viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:[MwA("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),MwA("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 p_A}from"preact/jsx-dev-runtime";var S51=rw("flex flex-wrap",{variants:{orientation:{horizontal:"justify-center gap-6 items-center",vertical:"flex-col gap-2.5"}},defaultVariants:{orientation:"horizontal"}});function CwA({items:A,className:Q,linkClassName:B="hover:text-accent transition-colors",orientation:w,children:$}){if(A.length===0&&!$)return null;let f=[...A].sort((I,D)=>I.priority-D.priority);return p_A("ul",{className:B2(S51({orientation:w}),Q),children:[f.map((I)=>p_A("li",{children:p_A("a",{href:I.href,className:B,children:I.label},void 0,!1,void 0,this)},I.href,!1,void 0,this)),$]},void 0,!0,void 0,this)}import{jsxDEV as wOw}from"preact/jsx-dev-runtime";import{jsxDEV as IOw}from"preact/jsx-dev-runtime";import{createContext as J5Q,h as X5Q}from"preact";import{useContext as W5Q}from"preact/hooks";var i_A=J5Q(null);function F_({headCollector:A,children:Q}){return X5Q(i_A.Provider,{value:A},Q)}function g51(){return W5Q(i_A)}function KQ(A){let Q=g51();if(Q)Q.setHeadProps(A);return null}import{createContext as uIQ,h as cIQ}from"preact";import{useContext as lIQ}from"preact/hooks";e3A();var n41=U1(d41(),1),hIQ=new fh({gfm:!0,breaks:!0}),mIQ={allowedTags:["h1","h2","h3","h4","h5","h6","p","br","hr","ul","ol","li","blockquote","cite","code","pre","em","strong","del","ins","sub","sup","a","img","span","table","thead","tbody","tr","th","td","div"],allowedAttributes:{a:["href","title","name"],img:["src","srcset","sizes","alt","title","width","height","class","loading","decoding"],code:["class"],pre:["class"],span:["class"],cite:["class"],div:["class"],th:["align","colspan","rowspan","scope"],td:["align","colspan","rowspan"]},allowedSchemes:["http","https","mailto","tel"],allowedSchemesByTag:{img:["http","https","entity"]},allowProtocolRelative:!1,disallowedTagsMode:"discard"};function GTA(A,Q){let{imageRenderer:B}=Q??{},$=(B?new fh({gfm:!0,breaks:!0}).use({renderer:{image(f,I,D){return B(f,I,D)??!1}}}):hIQ).parse(A);return $=$.replace(/<\/blockquote>\s*<p>(\u2014|--|\u2013)([\s\S]*?)<\/p>/g,`</blockquote>
|
|
4660
|
+
`)}}aA();class GwA extends ZB{directorySync;constructor(A,Q,B){super(A,{schema:y_A,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}}}aA();class KwA extends ZB{directorySync;constructor(A,Q,B){super(A,{schema:T_A,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}}}aA();class FwA extends ZB{directorySync;context;constructor(A,Q,B){super(A,{schema:__A,jobTypeName:"directory-sync"});this.context=Q,this.directorySync=B}async process(A,Q,B){let w=Date.now(),$=A.syncDirection??"both";this.logger.info("Starting directory sync job",{jobId:Q,operation:A.operation,syncDirection:$});let f={imported:0,skipped:0,failed:0,quarantined:0,quarantinedFiles:[],errors:[],jobIds:[]},I={exported:0,failed:0,errors:[]};if($!=="export")if(await B.report({progress:10,message:"Scanning directory for changes"}),f=await this.importWithProgress(A.paths,B),$==="import")await this.waitForImportJobs(f.jobIds,B),await B.report({progress:100,message:`Import complete: ${f.imported} imported`});else await B.report({progress:50,message:`Imported ${f.imported} entities`}),await this.waitForImportJobs(f.jobIds,B),await B.report({progress:56,message:"Processing complete, starting export"});if($!=="import"){let U=$==="export"?10:60;await B.report({progress:U,message:"Exporting entities to directory"}),I=await this.exportWithProgress(A.entityTypes,B),await B.report({progress:100,message:$==="export"?`Export complete: ${I.exported} exported`:`Sync complete: ${f.imported} imported, ${I.exported} exported`})}let D=Date.now()-w;return this.logger.info("Directory sync job completed",{jobId:Q,duration:D,imported:f.imported,exported:I.exported}),{import:f,export:I,duration:D}}async importWithProgress(A,Q){try{return await this.directorySync.importEntitiesWithProgress(A,Q,10)}catch(B){throw this.logger.error("Import phase failed",{error:B}),B}}async exportWithProgress(A,Q){try{return await this.directorySync.exportEntitiesWithProgress(A,Q,10)}catch(B){throw this.logger.error("Export phase failed",{error:B}),B}}async waitForImportJobs(A,Q){if(A.length===0)return;this.logger.debug(`Waiting for ${A.length} import jobs to complete`);let{entityService:B}=this.context,w=300000,$=500,f=Date.now(),I=async()=>{let U=(await Promise.all(A.map((J)=>B.getAsyncJobStatus(J)))).filter((J)=>J&&(J.status==="completed"||J.status==="failed")).length;if(U===A.length){this.logger.debug("All import jobs completed");return}if(Date.now()-f>w){this.logger.warn(`Timeout waiting for import jobs (${U}/${A.length} completed)`);return}let Y=Math.round(U/A.length*100);return await Q.report({progress:50+Math.round(Y*0.05),message:`Processing ${U}/${A.length} entities`}),await new Promise((J)=>setTimeout(J,$)),I()};return I()}summarizeDataForLog(A){return{operation:A.operation,syncDirection:A.syncDirection}}}aA();class ZwA extends ZB{context;directorySync;gitSync;constructor(A,Q,B,w){super(A,{schema:v_A,jobTypeName:"sync-request"});this.context=Q;this.directorySync=B;this.gitSync=w}async process(A,Q,B){await B.report({progress:5,message:"Pulling latest content from git"});let w=await this.gitSync.withLock(async()=>{return await this.gitSync.pull(),await B.report({progress:35,message:"Scanning pulled content for sync changes"}),this.directorySync.queueSyncBatch(this.context,A.source,{rootJobId:Q,interfaceType:A.interfaceType,channelId:A.channelId})});if(!w)return await B.report({progress:100,message:"Sync complete: no files to import"}),{gitPulled:!0,batchQueued:!1};return await B.report({progress:100,message:`Sync queued: ${w.importOperationsCount} import jobs for ${w.totalFiles} files`}),Q6Q(w)}summarizeDataForLog(A){return{source:A.source,interfaceType:A.interfaceType,channelId:A.channelId}}}function Q6Q(A){return{gitPulled:!0,batchQueued:!0,batchId:A.batchId,importOperations:A.importOperationsCount,totalFiles:A.totalFiles}}aA();class NwA extends ZB{context;constructor(A,Q,B){super(A,{schema:WwA,jobTypeName:"directory-delete"});this.context=Q}async process(A,Q,B){let w=WwA.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}}}aA();WA();var B6Q=H.object({});class zwA extends ZB{directorySync;constructor(A,Q){super(A,{schema:B6Q,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}}aA();E7();WA();H6();E7();import{readFile as w6Q,writeFile as $6Q}from"fs/promises";var f6Q=x_A;class qwA extends ZB{context;fetcher;constructor(A,Q,B=WU){super(Q,{schema:f6Q,jobTypeName:"cover-image-convert"});this.context=A,this.fetcher=B}async process(A,Q,B){let{filePath:w,sourceUrl:$,postTitle:f,postSlug:I,customAlt:D}=A;this.logger.debug("Starting image conversion job",{jobId:Q,filePath:w,sourceUrl:$,postSlug:I});try{await this.reportProgress(B,{progress:zQ.INIT,message:`Reading file: ${w}`});let U;try{U=await w6Q(w,"utf-8")}catch(L){return this.logger.error("Failed to read file",{filePath:w,error:T0(L)}),$5.failure(L)}let Y;try{Y=jB(U)}catch(L){return this.logger.warn("Failed to parse markdown",{filePath:w,error:T0(L)}),$5.failure(L)}let J=Y.frontmatter;if(J.coverImageId)return this.logger.debug("File already has coverImageId, skipping",{filePath:w}),await this.reportProgress(B,{progress:zQ.COMPLETE,message:"Already converted"}),{success:!0,skipped:!0};await this.reportProgress(B,{progress:zQ.FETCH,message:"Checking for existing image"});let X=await this.context.entityService.listEntities({entityType:"image",options:{filter:{metadata:{sourceUrl:$}},limit:1}}),G;if(X[0])G=X[0].id,this.logger.debug("Reusing existing image entity",{sourceUrl:$,imageId:G}),await this.reportProgress(B,{progress:zQ.EXTRACT,message:`Reusing existing image: ${G}`});else{await this.reportProgress(B,{progress:zQ.PROCESS,message:`Fetching image from ${$}`});let L;try{L=await this.fetcher($)}catch(y){return this.logger.error("Failed to fetch image",{sourceUrl:$,error:T0(y)}),$5.failure(y)}await this.reportProgress(B,{progress:zQ.GENERATE,message:"Creating image entity"});let{base64:V}=RN(L),M=UV(V),O=bN(V);if(!M||!O)return this.logger.error("Could not detect image format or dimensions",{sourceUrl:$}),$5.failure(Error("Could not detect image format or dimensions"));G=`${I}-cover`;let E=`Cover image for ${f}`,S=D??E;await this.context.entityService.createEntity({entity:{id:G,entityType:"image",content:L,metadata:{title:E,alt:S,format:M,width:O.width,height:O.height,sourceUrl:$}}}),this.logger.debug("Created image entity",{imageId:G,sourceUrl:$}),await this.reportProgress(B,{progress:zQ.EXTRACT,message:`Created image: ${G}`})}await this.reportProgress(B,{progress:zQ.SAVE,message:"Updating file"});let Z={...J};delete Z.coverImageUrl,delete Z.coverImageAlt,Z.coverImageId=G;let N=bG(Z,Y.content);try{await $6Q(w,N,"utf-8")}catch(L){return this.logger.error("Failed to write file",{filePath:w,error:T0(L)}),$5.failure(L)}return await this.reportProgress(B,{progress:zQ.COMPLETE,message:"Conversion complete"}),this.logger.info("Image conversion complete",{filePath:w,imageId:G,sourceUrl:$}),{success:!0,imageId:G}}catch(U){return this.logger.error("Image conversion job failed",{jobId:Q,filePath:w,error:T0(U)}),$5.failure(U)}}summarizeDataForLog(A){return{filePath:A.filePath,sourceUrl:A.sourceUrl,postSlug:A.postSlug}}}aA();E7();WA();H6();import{readFile as I6Q,writeFile as D6Q}from"fs/promises";class LwA extends ZB{converter;constructor(A,Q,B=WU){super(Q,{schema:S_A,jobTypeName:"inline-image-convert"});this.converter=new Jl(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:zQ.INIT,message:`Reading file: ${w}`});let f;try{f=await I6Q(w,"utf-8")}catch(U){let Y=T0(U);return this.logger.error("Failed to read file",{filePath:w,error:Y}),{success:!1,error:Y}}await this.reportProgress(B,{progress:zQ.FETCH,message:"Detecting inline images"});let I=this.converter.detectInlineImages(f,$);if(I.length===0)return this.logger.debug("No inline images to convert",{filePath:w}),await this.reportProgress(B,{progress:zQ.COMPLETE,message:"No images to convert"}),{success:!0,skipped:!0,convertedCount:0};this.logger.debug("Found inline images to convert",{filePath:w,count:I.length}),await this.reportProgress(B,{progress:zQ.PROCESS,message:`Converting ${I.length} images`});let D=await this.converter.convert(f,$);if(!D.converted)return this.logger.debug("No images were converted",{filePath:w}),await this.reportProgress(B,{progress:zQ.COMPLETE,message:"No images converted"}),{success:!0,skipped:!0,convertedCount:0};await this.reportProgress(B,{progress:zQ.SAVE,message:"Writing updated file"});try{await D6Q(w,D.content,"utf-8")}catch(U){let Y=T0(U);return this.logger.error("Failed to write file",{filePath:w,error:Y}),{success:!1,error:Y}}return await this.reportProgress(B,{progress:zQ.COMPLETE,message:"Conversion complete"}),this.logger.info("Inline image conversion complete",{filePath:w,convertedCount:D.convertedCount}),{success:!0,convertedCount:D.convertedCount}}catch(f){let I=T0(f);return this.logger.error("Inline image conversion job failed",{jobId:Q,filePath:w,error:I}),{success:!1,error:I}}}summarizeDataForLog(A){return{filePath:A.filePath,postSlug:A.postSlug}}}function B51(A,Q,B){let w=($)=>B.child($);A.jobs.registerHandler("directory-sync",new FwA(w("DirectorySyncJobHandler"),A,Q)),A.jobs.registerHandler("directory-export",new GwA(w("DirectoryExportJobHandler"),A,Q)),A.jobs.registerHandler("directory-import",new KwA(w("DirectoryImportJobHandler"),A,Q)),A.jobs.registerHandler("directory-delete",new NwA(w("DirectoryDeleteJobHandler"),A,Q)),A.jobs.registerHandler("directory-cleanup",new zwA(w("DirectoryCleanupJobHandler"),Q)),A.jobs.registerHandler("cover-image-convert",new qwA(A,w("CoverImageConversionJobHandler"))),A.jobs.registerHandler("inline-image-convert",new LwA(A,w("InlineImageConversionJobHandler"))),B.debug("Registered async job handlers")}aA();import{unlink as U6Q,access as Y6Q}from"fs/promises";function w51(A,Q,B,w){let{subscribe:$}=A.messaging,{entityService:f}=A;$("entity:created",async(I)=>{let{entity:D}=I.payload;try{await Q.fileOps.writeEntity(D),B.debug("Auto-exported created entity",{id:D.id,entityType:D.entityType})}catch(U){B.error("Auto-export FAILED for created entity",{id:D.id,entityType:D.entityType,error:U instanceof Error?U.message:String(U),stack:U instanceof Error?U.stack:void 0})}return{success:!0}}),$("entity:updated",async(I)=>{let{entityType:D,entityId:U}=I.payload;try{let Y=await f.getEntity({entityType:D,id:U});if(!Y)return B.debug("Entity not found in DB, skipping export",{entityType:D,entityId:U}),{success:!1};await Q.fileOps.writeEntity(Y),B.debug("Auto-exported updated entity",{id:Y.id,entityType:Y.entityType})}catch(Y){B.error("Auto-export FAILED for updated entity",{entityType:D,entityId:U,error:Y instanceof Error?Y.message:String(Y),stack:Y instanceof Error?Y.stack:void 0})}return{success:!0}}),$("entity:deleted",async(I)=>{let{entityId:D,entityType:U}=I.payload,Y=Q.fileOps.getFilePath(D,U);if(await Y6Q(Y).then(()=>!0,()=>!1))await U6Q(Y),B.debug("Auto-deleted entity file",{id:D,entityType:U,path:Y});return{success:!0}}),B.debug("Setup auto-sync for entity events",{entityTypes:w})}function $51(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:J$(),metadata:{operationType:"file_operations",operationTarget:B,pluginId:"directory-sync"}})})}WA();aA();import{readdir as D51,mkdir as X6Q,copyFile as W6Q}from"fs/promises";import{join as I51,resolve as g_A}from"path";import{join as J6Q}from"path";async function f51(A){if(!await X5(J6Q(A,".git")))return!1;try{return await mJ(A).revparse(["--verify","HEAD"]),!0}catch{return!1}}async function H6Q(A,Q){if(!await X5(A))return!0;if((await D51(A)).filter(($)=>!$.startsWith(".")&&!$.startsWith("_")).length>0)return!1;if(await f51(A))return Q.debug("Git repository with history detected - skipping seed content",{path:A}),!1;return!0}async function U51(A,Q){let B=await D51(A,{withFileTypes:!0});for(let w of B){let $=I51(A,w.name),f=I51(Q,w.name);if(w.isDirectory()){if(!await X5(f))await X6Q(f,{recursive:!0});await U51($,f)}else await W6Q($,f)}}async function Y51(A,Q,B){let w=g_A(process.cwd(),A);B=B?g_A(B):g_A(process.cwd(),"seed-content");let $=await H6Q(w,Q);if($&&await X5(B))Q.debug("Copying seed content to brain-data directory"),await U51(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 J51(A,Q,B,w,$){let f=!1,I=async()=>{if(f)return;f=!0;let D=Q();if(B.seedContent){let U=B.syncPath??A.dataDir;await Y51(U,w,B.seedContentPath)}try{if($){w.debug("Git enabled \u2014 pulling before import");let Y=await $.pull();if(Y.files.length>0)w.info("Pulled changes from remote",{filesChanged:Y.files.length})}w.debug("Starting initial sync");let U=await D.sync();w.debug("Initial sync completed",{imported:U.import.imported,failed:U.import.failed,duration:U.duration}),await A.messaging.send({type:jL.initialSyncCompleted,payload:{success:!0},...{broadcast:!0}})}catch(U){w.error("Initial sync failed",U),await A.messaging.send({type:jL.initialSyncCompleted,payload:{success:!1,error:T0(U)},...{broadcast:!0}})}};A.messaging.subscribe(jL.pluginsRegistered,async()=>{return w.debug("Plugins registered, starting initial sync"),await I(),{success:!0}})}WA();function X51(A,Q,B,w){let $=new GL(()=>{Q.withLock(async()=>{try{await Q.commit(),await Q.push()}catch(D){w.error("Git auto-commit failed",{error:D})}})},B),f=["entity:created","entity:updated","entity:deleted"],I=[];for(let D of f){let U=A.subscribe(D,async()=>{return $.trigger(),{success:!0}});I.push(U)}return()=>{$.dispose();for(let D of I)D()}}function W51(A,Q,B,w,$){if(w<=0)return()=>{};let f=w*60*1000,I=!1,D=async()=>{if(I)return;I=!0;try{let{files:Y,result:J}=await A.withLock(async()=>{let X=await A.pull();if(X.files.length===0)return{files:[],result:null};let G=await Q.queueSyncBatch(B,"periodic-sync");return{files:X.files,result:G}});if(Y.length>0)$.info("Periodic sync: pulled changes",{filesChanged:Y.length});if(J)$.debug("Periodic sync: queued imports",{importOperations:J.importOperationsCount,totalFiles:J.totalFiles})}catch(Y){$.error("Periodic git sync failed",{error:Y})}finally{I=!1}},U=setInterval(()=>{D()},f);return $.info("Started periodic git sync",{intervalMinutes:w}),()=>{clearInterval(U)}}import{spawnSync as G51}from"child_process";import{cpSync as G6Q,existsSync as H51,mkdirSync as K6Q,mkdtempSync as F6Q,rmSync as Z6Q}from"fs";import{tmpdir as N6Q}from"os";import{fileURLToPath as z6Q}from"url";import{join as q6Q,resolve as L6Q}from"path";function Uz(A,Q){let B=G51("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 V6Q(A){return A.startsWith("file://")}function E6Q(A){return z6Q(A)}function M6Q(A,Q){return G51("git",["--git-dir",A,"show-ref","--verify","--quiet",`refs/heads/${Q}`]).status===0}async function K51(A){if(!A.bootstrapFromSeed)return;if(!A.gitUrl||!V6Q(A.gitUrl))return;if(!A.seedContentPath)throw Error("directory-sync git.bootstrapFromSeed requires seedContentPath for local file:// remotes");let Q=A.branch??"main",B=E6Q(A.gitUrl),w=L6Q(A.seedContentPath);if(!H51(w))throw Error(`Seed content path not found: ${w}`);if(!H51(B))A.logger.debug("Creating local bare content remote",{remotePath:B,branch:Q}),K6Q(B,{recursive:!0}),Uz(process.cwd(),["init","--bare",`--initial-branch=${Q}`,B]);if(M6Q(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 $=F6Q(q6Q(N6Q(),"directory-sync-seed-"));try{Uz($,["init",`--initial-branch=${Q}`]),Uz($,["config","user.name",A.authorName??"Brain"]),Uz($,["config","user.email",A.authorEmail??"brain@localhost"]),G6Q(w,$,{recursive:!0}),Uz($,["add","."]),Uz($,["commit","-m","seed content remote"]),Uz($,["remote","add","origin",A.gitUrl]),Uz($,["push","-u","origin",Q])}finally{Z6Q($,{recursive:!0,force:!0})}}function F51(A,Q,B,w,$){let{subscribe:f}=A.messaging;f("entity:export:request",async(I)=>{try{return{success:!0,data:await Q().exportEntities(I.payload.entityTypes)}}catch(D){return{success:!1,error:D instanceof Error?D.message:"Export failed"}}}),f("entity:import:request",async(I)=>{try{let D=Q(),U=I.payload.paths,Y=await D.importEntities(U);if(U&&U.length>0)await D.removeOrphanedEntities();return{success:!0,data:Y}}catch(D){return{success:!1,error:D instanceof Error?D.message:"Import failed"}}}),f("sync:status:request",async()=>{try{let D=await Q().getStatus();return{success:!0,data:{syncPath:D.syncPath,isInitialized:D.exists,watchEnabled:D.watching}}}catch(I){return{success:!1,error:I instanceof Error?I.message:"Status check failed"}}}),f("sync:configure:request",async(I)=>{try{return await B({syncPath:I.payload.syncPath}),{success:!0,data:{syncPath:I.payload.syncPath,configured:!0}}}catch(D){return{success:!1,error:D instanceof Error?D.message:"Configuration failed"}}}),f("git-sync:get-repo-info",async()=>{if(!$?.repo)return{success:!1,error:"Git not configured"};return{success:!0,data:{repo:$.repo,branch:$.branch??"main"}}}),w.debug("Registered message handlers")}aA();WA();aA();WA();function Z51(A,Q){return oQ(A,"history","Get version history for an entity from git. Without sha: returns commit list. With sha: returns entity content at that version.",H.object({entityType:H.string().describe("Entity type (e.g. post, note, link)"),id:H.string().describe("Entity ID"),sha:H.string().optional().describe("Commit SHA to retrieve content at. Omit to list commit history."),limit:H.number().int().positive().optional().default(10).describe("Max commits to return (list mode only)")}),async(B)=>{let w=`${B.entityType}/${B.id}.md`;try{if(B.sha){let f=await Q.show(B.sha,w);return U8({sha:B.sha,entityType:B.entityType,id:B.id,content:f},`Content at ${B.sha.slice(0,7)}`)}let $=await Q.log(w,B.limit);if($.length===0)return U8({commits:[]},`No history found for ${B.entityType}/${B.id}`);return U8({commits:$,entityType:B.entityType,id:B.id},`${$.length} version${$.length===1?"":"s"} found`)}catch($){return X$($ instanceof Error?$.message:"History lookup failed")}})}function N51(A,Q,B,w){let $=[oQ(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.",H.object({}),async(f,I)=>{try{let D=I.channelId?`${I.interfaceType}:${I.channelId}`:`plugin:${B}`,U={interfaceType:I.interfaceType,channelId:I.channelId};if(w){let J=await Q.jobs.enqueue({type:"sync-request",data:{source:D,interfaceType:U.interfaceType,channelId:U.channelId},toolContext:I});return U8({jobId:J,status:"queued",gitPulled:!0},"Sync queued: pulling from git and scanning files")}let Y=await A.queueSyncBatch(Q,D,U);if(!Y)return U8({gitPulled:!1},"No files to sync");return U8({batchId:Y.batchId,importOperations:Y.importOperationsCount,totalFiles:Y.totalFiles,gitPulled:!1},`Sync started: ${Y.importOperationsCount} import jobs queued for ${Y.totalFiles} files`)}catch(D){return X$(D instanceof Error?D.message:"Sync failed")}},{cli:{name:"sync"}}),oQ(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.",H.object({}),async()=>{try{let f=await A.getStatus(),I={syncPath:f.syncPath,lastSync:f.lastSync?.toISOString(),watching:f.watching};if(w){let D=await w.getStatus();I.git={isRepo:D.isRepo,branch:D.branch,hasChanges:D.hasChanges,ahead:D.ahead,behind:D.behind,remote:D.remote}}return U8(I)}catch(f){return X$(f instanceof Error?f.message:"Status check failed")}},{visibility:"public"})];if(w)$.push(Z51(B,w));return $}var z51={name:"@brains/directory-sync",private:!0,version:"0.2.0-alpha.120",description:"Directory-based entity synchronization plugin for Brains",type:"module",main:"./src/index.ts",types:"./src/index.ts",exports:{".":{types:"./src/index.ts",import:"./src/index.ts"}},scripts:{test:"bun test",typecheck:"tsc --noEmit",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",clean:"rm -rf .turbo"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/image":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*",chokidar:"^3.5.3","simple-git":"^3.21.0"},devDependencies:{"@brains/typescript-config":"workspace:*","@types/bun":"latest","@types/node":"^20.0.0",typescript:"^5.3.3"},peerDependencies:{}};class h_A extends YB{directorySync;gitSync;gitCleanups=[];constructor(A={}){super("directory-sync",z51,A,El)}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:Ml,basePrompt:"",formatter:new HwA,requiredPermission:"anchor"}});let w=this.config.syncPath??A.dataDir;this.directorySync=new Xl({syncPath:w,autoSync:this.config.autoSync,watchInterval:this.config.watchInterval,includeMetadata:this.config.includeMetadata,entityTypes:this.config.entityTypes,deleteOnFileRemoval:this.config.deleteOnFileRemoval,entityService:B,logger:Q});try{await this.directorySync.initializeDirectory(),this.logger.debug("Directory structure initialized",{path:w})}catch(I){throw this.logger.error("Failed to initialize directory",I),I}await this.registerJobHandlers(A);let $=this.requireDirectorySync();if(w51(A,$,this.logger,this.config.entityTypes),this.config.autoSync)$51(A,$,this.config.syncPath??A.dataDir);let f=this.config.git!==void 0&&(this.config.git.repo!==void 0||this.config.git.gitUrl!==void 0);if(this.config.git&&!f)this.logger.debug("Git block present but no repo/gitUrl configured \u2014 git sync disabled");if(f&&this.config.git){await K51({gitUrl:this.config.git.gitUrl,branch:this.config.git.branch,seedContentPath:this.config.seedContentPath,bootstrapFromSeed:this.config.git.bootstrapFromSeed,authorName:this.config.git.authorName,authorEmail:this.config.git.authorEmail,logger:this.logger.child("ContentRemoteBootstrap")});let I=this.config.syncPath??A.dataDir;if(this.gitSync=new j_A({logger:this.logger.child("GitSync"),dataDir:I,repo:this.config.git.repo,gitUrl:this.config.git.gitUrl,branch:this.config.git.branch,authToken:this.config.git.authToken,authorName:this.config.git.authorName,authorEmail:this.config.git.authorEmail}),await this.gitSync.initialize(),this.logger.info("Git integration enabled",{repo:this.config.git.repo}),A.jobs.registerHandler("sync-request",new ZwA(this.logger.child("DirectorySyncRequestJobHandler"),A,this.requireDirectorySync(),this.gitSync)),this.gitCleanups.push(X51(A.messaging,this.gitSync,this.config.commitDebounce,this.logger.child("GitAutoCommit"))),this.config.autoSync)this.gitCleanups.push(W51(this.gitSync,this.requireDirectorySync(),A,this.config.syncInterval,this.logger.child("GitPeriodicSync")))}if(this.config.initialSync)J51(A,()=>this.requireDirectorySync(),this.config,this.logger,this.gitSync);F51(A,()=>this.requireDirectorySync(),(I)=>this.configure(I),this.logger,this.config.git)}async getTools(){let A=this.requireDirectorySync();return N51(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 Xl({...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){B51(A,this.requireDirectorySync(),this.logger)}}function WM(A={}){return new h_A(A)}aA();WA();var q51={name:"@brains/email-resend",private:!0,version:"0.2.0-alpha.120",description:"Generic email delivery adapter for Resend",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint src test --ext .ts","lint:fix":"eslint src test --ext .ts --fix"},dependencies:{"@brains/email-contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var R6Q=H.object({apiKey:H.string().min(1).optional(),from:H.string().min(1).optional()});class L51 extends YB{fetchImpl;constructor(A={},Q={}){super("email-resend",q51,A,R6Q);this.fetchImpl=Q.fetchImpl??fetch}async onRegister(A){if(!this.config.apiKey||!this.config.from){this.logger.warn("Email Resend adapter is disabled because apiKey or from is missing");return}let Q=this.logger;A.messaging.subscribe(c0A,async(B)=>{let w=kV0.parse(B.payload);try{return{success:!0,data:await this.sendWithResend(w)}}catch($){if(w.sensitivity==="secret")Q.warn("Email delivery failed for a secret message");else Q.warn("Email delivery failed",{to:w.to,subject:w.subject,error:$ instanceof Error?$.message:String($)});return{success:!1,error:"Email delivery failed"}}})}async sendWithResend(A){let Q=this.config.apiKey,B=this.config.from;if(!Q||!B)return{status:"failed"};let w=await this.fetchImpl("https://api.resend.com/emails",{method:"POST",headers:{Authorization:`Bearer ${Q}`,"Content-Type":"application/json"},body:JSON.stringify({from:B,to:A.to,subject:A.subject,text:A.text,...A.html?{html:A.html}:{}})});if(!w.ok)throw Error("Resend email request failed");let $=await w.json();return $.id?{status:"sent",id:$.id}:{status:"sent"}}}function VwA(A={}){return new L51(A)}aA();import{render as TG1}from"preact-render-to-string";import{h as oM}from"preact";function V51(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=V51(A[Q]))&&(w&&(w+=" "),w+=B)}else for(B in A)A[B]&&(w&&(w+=" "),w+=B);return w}function W_(){for(var A,Q,B=0,w="",$=arguments.length;B<$;B++)(A=arguments[B])&&(Q=V51(A))&&(w&&(w+=" "),w+=Q);return w}var b6Q=(A)=>{let Q=k6Q(A),{conflictingClassGroups:B,conflictingClassGroupModifiers:w}=A;return{getClassGroupId:(I)=>{let D=I.split("-");if(D[0]===""&&D.length!==1)D.shift();return R51(D,Q)||P6Q(I)},getConflictingClassGroupIds:(I,D)=>{let U=B[I]||[];if(D&&w[I])return[...U,...w[I]];return U}}},R51=(A,Q)=>{if(A.length===0)return Q.classGroupId;let B=A[0],w=Q.nextPart.get(B),$=w?R51(A.slice(1),w):void 0;if($)return $;if(Q.validators.length===0)return;let f=A.join("-");return Q.validators.find(({validator:I})=>I(f))?.classGroupId},E51=/^\[(.+)\]$/,P6Q=(A)=>{if(E51.test(A)){let Q=E51.exec(A)[1],B=Q?.substring(0,Q.indexOf(":"));if(B)return"arbitrary.."+B}},k6Q=(A)=>{let{theme:Q,prefix:B}=A,w={nextPart:new Map,validators:[]};return _6Q(Object.entries(A.classGroups),B).forEach(([f,I])=>{u_A(I,w,f,Q)}),w},u_A=(A,Q,B,w)=>{A.forEach(($)=>{if(typeof $==="string"){let f=$===""?Q:M51(Q,$);f.classGroupId=B;return}if(typeof $==="function"){if(j6Q($)){u_A($(w),Q,B,w);return}Q.validators.push({validator:$,classGroupId:B});return}Object.entries($).forEach(([f,I])=>{u_A(I,M51(Q,f),B,w)})})},M51=(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},j6Q=(A)=>A.isThemeGetter,_6Q=(A,Q)=>{if(!Q)return A;return A.map(([B,w])=>{let $=w.map((f)=>{if(typeof f==="string")return Q+f;if(typeof f==="object")return Object.fromEntries(Object.entries(f).map(([I,D])=>[Q+I,D]));return f});return[B,$]})},v6Q=(A)=>{if(A<1)return{get:()=>{return},set:()=>{}};let Q=0,B=new Map,w=new Map,$=(f,I)=>{if(B.set(f,I),Q++,Q>A)Q=0,w=B,B=new Map};return{get(f){let I=B.get(f);if(I!==void 0)return I;if((I=w.get(f))!==void 0)return $(f,I),I},set(f,I){if(B.has(f))B.set(f,I);else $(f,I)}}};var T6Q=(A)=>{let{separator:Q,experimentalParseClassName:B}=A,w=Q.length===1,$=Q[0],f=Q.length,I=(D)=>{let U=[],Y=0,J=0,X;for(let V=0;V<D.length;V++){let M=D[V];if(Y===0){if(M===$&&(w||D.slice(V,V+f)===Q)){U.push(D.slice(J,V)),J=V+f;continue}if(M==="/"){X=V;continue}}if(M==="[")Y++;else if(M==="]")Y--}let G=U.length===0?D:D.substring(J),Z=G.startsWith("!"),N=Z?G.substring(1):G,L=X&&X>J?X-J:void 0;return{modifiers:U,hasImportantModifier:Z,baseClassName:N,maybePostfixModifierPosition:L}};if(B)return(D)=>B({className:D,parseClassName:I});return I},y6Q=(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},x6Q=(A)=>({cache:v6Q(A.cacheSize),parseClassName:T6Q(A),...b6Q(A)}),S6Q=/\s+/,g6Q=(A,Q)=>{let{parseClassName:B,getClassGroupId:w,getConflictingClassGroupIds:$}=Q,f=[],I=A.trim().split(S6Q),D="";for(let U=I.length-1;U>=0;U-=1){let Y=I[U],{modifiers:J,hasImportantModifier:X,baseClassName:G,maybePostfixModifierPosition:Z}=B(Y),N=Boolean(Z),L=w(N?G.substring(0,Z):G);if(!L){if(!N){D=Y+(D.length>0?" "+D:D);continue}if(L=w(G),!L){D=Y+(D.length>0?" "+D:D);continue}N=!1}let V=y6Q(J).join(":"),M=X?V+"!":V,O=M+L;if(f.includes(O))continue;f.push(O);let E=$(L,N);for(let S=0;S<E.length;++S){let y=E[S];f.push(M+y)}D=Y+(D.length>0?" "+D:D)}return D};function h6Q(){let A=0,Q,B,w="";while(A<arguments.length)if(Q=arguments[A++]){if(B=b51(Q))w&&(w+=" "),w+=B}return w}var b51=(A)=>{if(typeof A==="string")return A;let Q,B="";for(let w=0;w<A.length;w++)if(A[w]){if(Q=b51(A[w]))B&&(B+=" "),B+=Q}return B};function C51(A,...Q){let B,w,$,f=I;function I(U){let Y=Q.reduce((J,X)=>X(J),A());return B=x6Q(Y),w=B.cache.get,$=B.cache.set,f=D,D(U)}function D(U){let Y=w(U);if(Y)return Y;let J=g6Q(U,B);return $(U,J),J}return function(){return f(h6Q.apply(null,arguments))}}var y8=(A)=>{let Q=(B)=>B[A]||[];return Q.isThemeGetter=!0,Q},P51=/^\[(?:([a-z-]+):)?(.+)\]$/i,m6Q=/^\d+\/\d+$/,u6Q=new Set(["px","full","screen"]),c6Q=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,l6Q=/\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$/,p6Q=/^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/,i6Q=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,r6Q=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,YF=(A)=>H_(A)||u6Q.has(A)||m6Q.test(A),Yz=(A)=>G_(A,"length",A5Q),H_=(A)=>Boolean(A)&&!Number.isNaN(Number(A)),m_A=(A)=>G_(A,"number",H_),Cl=(A)=>Boolean(A)&&Number.isInteger(Number(A)),d6Q=(A)=>A.endsWith("%")&&H_(A.slice(0,-1)),rQ=(A)=>P51.test(A),Jz=(A)=>c6Q.test(A),n6Q=new Set(["length","size","percentage"]),o6Q=(A)=>G_(A,n6Q,k51),s6Q=(A)=>G_(A,"position",k51),a6Q=new Set(["image","url"]),t6Q=(A)=>G_(A,a6Q,B5Q),e6Q=(A)=>G_(A,"",Q5Q),Ol=()=>!0,G_=(A,Q,B)=>{let w=P51.exec(A);if(w){if(w[1])return typeof Q==="string"?w[1]===Q:Q.has(w[1]);return B(w[2])}return!1},A5Q=(A)=>l6Q.test(A)&&!p6Q.test(A),k51=()=>!1,Q5Q=(A)=>i6Q.test(A),B5Q=(A)=>r6Q.test(A);var O51=()=>{let A=y8("colors"),Q=y8("spacing"),B=y8("blur"),w=y8("brightness"),$=y8("borderColor"),f=y8("borderRadius"),I=y8("borderSpacing"),D=y8("borderWidth"),U=y8("contrast"),Y=y8("grayscale"),J=y8("hueRotate"),X=y8("invert"),G=y8("gap"),Z=y8("gradientColorStops"),N=y8("gradientColorStopPositions"),L=y8("inset"),V=y8("margin"),M=y8("opacity"),O=y8("padding"),E=y8("saturate"),S=y8("scale"),y=y8("sepia"),T=y8("skew"),_=y8("space"),x=y8("translate"),g=()=>["auto","contain","none"],n=()=>["auto","hidden","clip","visible","scroll"],m=()=>["auto",rQ,Q],BA=()=>[rQ,Q],a=()=>["",YF,Yz],j=()=>["auto",H_,rQ],R=()=>["bottom","center","left","left-bottom","left-top","right","right-bottom","right-top","top"],P=()=>["solid","dashed","dotted","double","none"],c=()=>["normal","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity"],l=()=>["start","end","center","between","around","evenly","stretch"],e=()=>["","0",rQ],s=()=>["auto","avoid","all","avoid-page","page","left","right","column"],XA=()=>[H_,rQ];return{cacheSize:500,separator:":",theme:{colors:[Ol],spacing:[YF,Yz],blur:["none","",Jz,rQ],brightness:XA(),borderColor:[A],borderRadius:["none","","full",Jz,rQ],borderSpacing:BA(),borderWidth:a(),contrast:XA(),grayscale:e(),hueRotate:XA(),invert:e(),gap:BA(),gradientColorStops:[A],gradientColorStopPositions:[d6Q,Yz],inset:m(),margin:m(),opacity:XA(),padding:BA(),saturate:XA(),scale:XA(),sepia:e(),skew:XA(),space:BA(),translate:BA()},classGroups:{aspect:[{aspect:["auto","square","video",rQ]}],container:["container"],columns:[{columns:[Jz]}],"break-after":[{"break-after":s()}],"break-before":[{"break-before":s()}],"break-inside":[{"break-inside":["auto","avoid","avoid-page","avoid-column"]}],"box-decoration":[{"box-decoration":["slice","clone"]}],box:[{box:["border","content"]}],display:["block","inline-block","inline","flex","inline-flex","table","inline-table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row-group","table-row","flow-root","grid","inline-grid","contents","list-item","hidden"],float:[{float:["right","left","none","start","end"]}],clear:[{clear:["left","right","both","none","start","end"]}],isolation:["isolate","isolation-auto"],"object-fit":[{object:["contain","cover","fill","none","scale-down"]}],"object-position":[{object:[...R(),rQ]}],overflow:[{overflow:n()}],"overflow-x":[{"overflow-x":n()}],"overflow-y":[{"overflow-y":n()}],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",Cl,rQ]}],basis:[{basis:m()}],"flex-direction":[{flex:["row","row-reverse","col","col-reverse"]}],"flex-wrap":[{flex:["wrap","wrap-reverse","nowrap"]}],flex:[{flex:["1","auto","initial","none",rQ]}],grow:[{grow:e()}],shrink:[{shrink:e()}],order:[{order:["first","last","none",Cl,rQ]}],"grid-cols":[{"grid-cols":[Ol]}],"col-start-end":[{col:["auto",{span:["full",Cl,rQ]},rQ]}],"col-start":[{"col-start":j()}],"col-end":[{"col-end":j()}],"grid-rows":[{"grid-rows":[Ol]}],"row-start-end":[{row:["auto",{span:[Cl,rQ]},rQ]}],"row-start":[{"row-start":j()}],"row-end":[{"row-end":j()}],"grid-flow":[{"grid-flow":["row","col","dense","row-dense","col-dense"]}],"auto-cols":[{"auto-cols":["auto","min","max","fr",rQ]}],"auto-rows":[{"auto-rows":["auto","min","max","fr",rQ]}],gap:[{gap:[G]}],"gap-x":[{"gap-x":[G]}],"gap-y":[{"gap-y":[G]}],"justify-content":[{justify:["normal",...l()]}],"justify-items":[{"justify-items":["start","end","center","stretch"]}],"justify-self":[{"justify-self":["auto","start","end","center","stretch"]}],"align-content":[{content:["normal",...l(),"baseline"]}],"align-items":[{items:["start","end","center","baseline","stretch"]}],"align-self":[{self:["auto","start","end","center","stretch","baseline"]}],"place-content":[{"place-content":[...l(),"baseline"]}],"place-items":[{"place-items":["start","end","center","baseline","stretch"]}],"place-self":[{"place-self":["auto","start","end","center","stretch"]}],p:[{p:[O]}],px:[{px:[O]}],py:[{py:[O]}],ps:[{ps:[O]}],pe:[{pe:[O]}],pt:[{pt:[O]}],pr:[{pr:[O]}],pb:[{pb:[O]}],pl:[{pl:[O]}],m:[{m:[V]}],mx:[{mx:[V]}],my:[{my:[V]}],ms:[{ms:[V]}],me:[{me:[V]}],mt:[{mt:[V]}],mr:[{mr:[V]}],mb:[{mb:[V]}],ml:[{ml:[V]}],"space-x":[{"space-x":[_]}],"space-x-reverse":["space-x-reverse"],"space-y":[{"space-y":[_]}],"space-y-reverse":["space-y-reverse"],w:[{w:["auto","min","max","fit","svw","lvw","dvw",rQ,Q]}],"min-w":[{"min-w":[rQ,Q,"min","max","fit"]}],"max-w":[{"max-w":[rQ,Q,"none","full","min","max","fit","prose",{screen:[Jz]},Jz]}],h:[{h:[rQ,Q,"auto","min","max","fit","svh","lvh","dvh"]}],"min-h":[{"min-h":[rQ,Q,"min","max","fit","svh","lvh","dvh"]}],"max-h":[{"max-h":[rQ,Q,"min","max","fit","svh","lvh","dvh"]}],size:[{size:[rQ,Q,"auto","min","max","fit"]}],"font-size":[{text:["base",Jz,Yz]}],"font-smoothing":["antialiased","subpixel-antialiased"],"font-style":["italic","not-italic"],"font-weight":[{font:["thin","extralight","light","normal","medium","semibold","bold","extrabold","black",m_A]}],"font-family":[{font:[Ol]}],"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",rQ]}],"line-clamp":[{"line-clamp":["none",H_,m_A]}],leading:[{leading:["none","tight","snug","normal","relaxed","loose",YF,rQ]}],"list-image":[{"list-image":["none",rQ]}],"list-style-type":[{list:["none","disc","decimal",rQ]}],"list-style-position":[{list:["inside","outside"]}],"placeholder-color":[{placeholder:[A]}],"placeholder-opacity":[{"placeholder-opacity":[M]}],"text-alignment":[{text:["left","center","right","justify","start","end"]}],"text-color":[{text:[A]}],"text-opacity":[{"text-opacity":[M]}],"text-decoration":["underline","overline","line-through","no-underline"],"text-decoration-style":[{decoration:[...P(),"wavy"]}],"text-decoration-thickness":[{decoration:["auto","from-font",YF,Yz]}],"underline-offset":[{"underline-offset":["auto",YF,rQ]}],"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:BA()}],"vertical-align":[{align:["baseline","top","middle","bottom","text-top","text-bottom","sub","super",rQ]}],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",rQ]}],"bg-attachment":[{bg:["fixed","local","scroll"]}],"bg-clip":[{"bg-clip":["border","padding","content","text"]}],"bg-opacity":[{"bg-opacity":[M]}],"bg-origin":[{"bg-origin":["border","padding","content"]}],"bg-position":[{bg:[...R(),s6Q]}],"bg-repeat":[{bg:["no-repeat",{repeat:["","x","y","round","space"]}]}],"bg-size":[{bg:["auto","cover","contain",o6Q]}],"bg-image":[{bg:["none",{"gradient-to":["t","tr","r","br","b","bl","l","tl"]},t6Q]}],"bg-color":[{bg:[A]}],"gradient-from-pos":[{from:[N]}],"gradient-via-pos":[{via:[N]}],"gradient-to-pos":[{to:[N]}],"gradient-from":[{from:[Z]}],"gradient-via":[{via:[Z]}],"gradient-to":[{to:[Z]}],rounded:[{rounded:[f]}],"rounded-s":[{"rounded-s":[f]}],"rounded-e":[{"rounded-e":[f]}],"rounded-t":[{"rounded-t":[f]}],"rounded-r":[{"rounded-r":[f]}],"rounded-b":[{"rounded-b":[f]}],"rounded-l":[{"rounded-l":[f]}],"rounded-ss":[{"rounded-ss":[f]}],"rounded-se":[{"rounded-se":[f]}],"rounded-ee":[{"rounded-ee":[f]}],"rounded-es":[{"rounded-es":[f]}],"rounded-tl":[{"rounded-tl":[f]}],"rounded-tr":[{"rounded-tr":[f]}],"rounded-br":[{"rounded-br":[f]}],"rounded-bl":[{"rounded-bl":[f]}],"border-w":[{border:[D]}],"border-w-x":[{"border-x":[D]}],"border-w-y":[{"border-y":[D]}],"border-w-s":[{"border-s":[D]}],"border-w-e":[{"border-e":[D]}],"border-w-t":[{"border-t":[D]}],"border-w-r":[{"border-r":[D]}],"border-w-b":[{"border-b":[D]}],"border-w-l":[{"border-l":[D]}],"border-opacity":[{"border-opacity":[M]}],"border-style":[{border:[...P(),"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":[M]}],"divide-style":[{divide:P()}],"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:["",...P()]}],"outline-offset":[{"outline-offset":[YF,rQ]}],"outline-w":[{outline:[YF,Yz]}],"outline-color":[{outline:[A]}],"ring-w":[{ring:a()}],"ring-w-inset":["ring-inset"],"ring-color":[{ring:[A]}],"ring-opacity":[{"ring-opacity":[M]}],"ring-offset-w":[{"ring-offset":[YF,Yz]}],"ring-offset-color":[{"ring-offset":[A]}],shadow:[{shadow:["","inner","none",Jz,e6Q]}],"shadow-color":[{shadow:[Ol]}],opacity:[{opacity:[M]}],"mix-blend":[{"mix-blend":[...c(),"plus-lighter","plus-darker"]}],"bg-blend":[{"bg-blend":c()}],filter:[{filter:["","none"]}],blur:[{blur:[B]}],brightness:[{brightness:[w]}],contrast:[{contrast:[U]}],"drop-shadow":[{"drop-shadow":["","none",Jz,rQ]}],grayscale:[{grayscale:[Y]}],"hue-rotate":[{"hue-rotate":[J]}],invert:[{invert:[X]}],saturate:[{saturate:[E]}],sepia:[{sepia:[y]}],"backdrop-filter":[{"backdrop-filter":["","none"]}],"backdrop-blur":[{"backdrop-blur":[B]}],"backdrop-brightness":[{"backdrop-brightness":[w]}],"backdrop-contrast":[{"backdrop-contrast":[U]}],"backdrop-grayscale":[{"backdrop-grayscale":[Y]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[J]}],"backdrop-invert":[{"backdrop-invert":[X]}],"backdrop-opacity":[{"backdrop-opacity":[M]}],"backdrop-saturate":[{"backdrop-saturate":[E]}],"backdrop-sepia":[{"backdrop-sepia":[y]}],"border-collapse":[{border:["collapse","separate"]}],"border-spacing":[{"border-spacing":[I]}],"border-spacing-x":[{"border-spacing-x":[I]}],"border-spacing-y":[{"border-spacing-y":[I]}],"table-layout":[{table:["auto","fixed"]}],caption:[{caption:["top","bottom"]}],transition:[{transition:["none","all","","colors","opacity","shadow","transform",rQ]}],duration:[{duration:XA()}],ease:[{ease:["linear","in","out","in-out",rQ]}],delay:[{delay:XA()}],animate:[{animate:["none","spin","ping","pulse","bounce",rQ]}],transform:[{transform:["","gpu","none"]}],scale:[{scale:[S]}],"scale-x":[{"scale-x":[S]}],"scale-y":[{"scale-y":[S]}],rotate:[{rotate:[Cl,rQ]}],"translate-x":[{"translate-x":[x]}],"translate-y":[{"translate-y":[x]}],"skew-x":[{"skew-x":[T]}],"skew-y":[{"skew-y":[T]}],"transform-origin":[{origin:["center","top","top-right","right","bottom-right","bottom","bottom-left","left","top-left",rQ]}],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",rQ]}],"caret-color":[{caret:[A]}],"pointer-events":[{"pointer-events":["none","auto"]}],resize:[{resize:["none","y","x",""]}],"scroll-behavior":[{scroll:["auto","smooth"]}],"scroll-m":[{"scroll-m":BA()}],"scroll-mx":[{"scroll-mx":BA()}],"scroll-my":[{"scroll-my":BA()}],"scroll-ms":[{"scroll-ms":BA()}],"scroll-me":[{"scroll-me":BA()}],"scroll-mt":[{"scroll-mt":BA()}],"scroll-mr":[{"scroll-mr":BA()}],"scroll-mb":[{"scroll-mb":BA()}],"scroll-ml":[{"scroll-ml":BA()}],"scroll-p":[{"scroll-p":BA()}],"scroll-px":[{"scroll-px":BA()}],"scroll-py":[{"scroll-py":BA()}],"scroll-ps":[{"scroll-ps":BA()}],"scroll-pe":[{"scroll-pe":BA()}],"scroll-pt":[{"scroll-pt":BA()}],"scroll-pr":[{"scroll-pr":BA()}],"scroll-pb":[{"scroll-pb":BA()}],"scroll-pl":[{"scroll-pl":BA()}],"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",rQ]}],fill:[{fill:[A,"none"]}],"stroke-w":[{stroke:[YF,Yz,m_A]}],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"]}}},w5Q=(A,{cacheSize:Q,prefix:B,separator:w,experimentalParseClassName:$,extend:f={},override:I={}})=>{Rl(A,"cacheSize",Q),Rl(A,"prefix",B),Rl(A,"separator",w),Rl(A,"experimentalParseClassName",$);for(let D in I)$5Q(A[D],I[D]);for(let D in f)f5Q(A[D],f[D]);return A},Rl=(A,Q,B)=>{if(B!==void 0)A[Q]=B},$5Q=(A,Q)=>{if(Q)for(let B in Q)Rl(A,B,Q[B])},f5Q=(A,Q)=>{if(Q)for(let B in Q){let w=Q[B];if(w!==void 0)A[B]=(A[B]||[]).concat(w)}},EwA=(A,...Q)=>typeof A==="function"?C51(O51,A,...Q):C51(()=>w5Q(O51(),A),...Q);var I5Q=EwA({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 B2(...A){return I5Q(W_(A))}var j51=(A)=>typeof A==="boolean"?`${A}`:A===0?"0":A,_51=W_,rw=(A,Q)=>(B)=>{var w;if((Q===null||Q===void 0?void 0:Q.variants)==null)return _51(A,B===null||B===void 0?void 0:B.class,B===null||B===void 0?void 0:B.className);let{variants:$,defaultVariants:f}=Q,I=Object.keys($).map((Y)=>{let J=B===null||B===void 0?void 0:B[Y],X=f===null||f===void 0?void 0:f[Y];if(J===null)return null;let G=j51(J)||j51(X);return $[Y][G]}),D=B&&Object.entries(B).reduce((Y,J)=>{let[X,G]=J;if(G===void 0)return Y;return Y[X]=G,Y},{}),U=Q===null||Q===void 0?void 0:(w=Q.compoundVariants)===null||w===void 0?void 0:w.reduce((Y,J)=>{let{class:X,className:G,...Z}=J;return Object.entries(Z).every((N)=>{let[L,V]=N;return Array.isArray(V)?V.includes({...f,...D}[L]):{...f,...D}[L]===V})?[...Y,X,G]:Y},[]);return _51(A,I,U,B===null||B===void 0?void 0:B.class,B===null||B===void 0?void 0:B.className)};import{jsxDEV as c_A}from"preact/jsx-dev-runtime";var v51=rw("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 l_A({variant:A,title:Q,children:B,className:w}){return c_A("div",{className:B2(v51({variant:A}),w),role:"alert",children:[Q&&c_A("p",{className:"font-medium text-current opacity-90",children:Q},void 0,!1,void 0,this),c_A("div",{className:B2(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 D5Q}from"preact/jsx-dev-runtime";var T51=rw("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 HM({variant:A,size:Q,className:B,children:w,ssrOnClick:$,type:f="button",...I}){return D5Q("button",{type:f,className:B2(T51({variant:A,size:Q}),B),...I,...$&&{onclick:$},children:w},void 0,!1,void 0,this)}import{jsxDEV as U5Q}from"preact/jsx-dev-runtime";var y51=rw("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 L$({href:A,children:Q,variant:B,size:w,external:$=!1,className:f,"aria-label":I}){let D=$?{target:"_blank",rel:"noopener noreferrer"}:{};return U5Q("a",{href:A,className:B2(y51({variant:B,size:w}),f),"aria-label":I,...D,children:Q},void 0,!1,void 0,this)}import{jsxDEV as MwA}from"preact/jsx-dev-runtime";var x51=rw("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"}}),Y5Q={sm:"w-4 h-4",md:"w-5 h-5",lg:"w-6 h-6"};function K_({variant:A,size:Q,className:B}){let w=Y5Q[Q??"md"];return MwA("button",{onclick:"toggleTheme()",type:"button",className:B2(x51({variant:A,size:Q}),B),"aria-label":"Toggle dark mode",children:MwA("svg",{className:B2(w,"transition-colors"),fill:"none",stroke:"currentColor",strokeWidth:1.6,viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:[MwA("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),MwA("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 p_A}from"preact/jsx-dev-runtime";var S51=rw("flex flex-wrap",{variants:{orientation:{horizontal:"justify-center gap-6 items-center",vertical:"flex-col gap-2.5"}},defaultVariants:{orientation:"horizontal"}});function CwA({items:A,className:Q,linkClassName:B="hover:text-accent transition-colors",orientation:w,children:$}){if(A.length===0&&!$)return null;let f=[...A].sort((I,D)=>I.priority-D.priority);return p_A("ul",{className:B2(S51({orientation:w}),Q),children:[f.map((I)=>p_A("li",{children:p_A("a",{href:I.href,className:B,children:I.label},void 0,!1,void 0,this)},I.href,!1,void 0,this)),$]},void 0,!0,void 0,this)}import{jsxDEV as wOw}from"preact/jsx-dev-runtime";import{jsxDEV as IOw}from"preact/jsx-dev-runtime";import{createContext as J5Q,h as X5Q}from"preact";import{useContext as W5Q}from"preact/hooks";var i_A=J5Q(null);function F_({headCollector:A,children:Q}){return X5Q(i_A.Provider,{value:A},Q)}function g51(){return W5Q(i_A)}function KQ(A){let Q=g51();if(Q)Q.setHeadProps(A);return null}import{createContext as uIQ,h as cIQ}from"preact";import{useContext as lIQ}from"preact/hooks";e3A();var n41=U1(d41(),1),hIQ=new fh({gfm:!0,breaks:!0}),mIQ={allowedTags:["h1","h2","h3","h4","h5","h6","p","br","hr","ul","ol","li","blockquote","cite","code","pre","em","strong","del","ins","sub","sup","a","img","span","table","thead","tbody","tr","th","td","div"],allowedAttributes:{a:["href","title","name"],img:["src","srcset","sizes","alt","title","width","height","class","loading","decoding"],code:["class"],pre:["class"],span:["class"],cite:["class"],div:["class"],th:["align","colspan","rowspan","scope"],td:["align","colspan","rowspan"]},allowedSchemes:["http","https","mailto","tel"],allowedSchemesByTag:{img:["http","https","entity"]},allowProtocolRelative:!1,disallowedTagsMode:"discard"};function GTA(A,Q){let{imageRenderer:B}=Q??{},$=(B?new fh({gfm:!0,breaks:!0}).use({renderer:{image(f,I,D){return B(f,I,D)??!1}}}):hIQ).parse(A);return $=$.replace(/<\/blockquote>\s*<p>(\u2014|--|\u2013)([\s\S]*?)<\/p>/g,`</blockquote>
|
|
4661
4661
|
<cite class="block-attribution"><span class="emdash">$1</span>$2</cite>`),n41.default($,mIQ)}var o41=uIQ(null);function v_({imageRenderer:A,children:Q}){return cIQ(o41.Provider,{value:A??null},Q)}function s41(){return lIQ(o41)}function NF(){let A=s41();return(Q)=>GTA(Q,A?{imageRenderer:A}:void 0)}var pIQ=/<pre><code class="language-mermaid">([\s\S]*?)<\/code><\/pre>/g,iIQ={"&":"&","<":"<",">":">",""":'"',"'":"'"},rIQ=/&(?:amp|lt|gt|quot|#39);/g;function dIQ(A){return A.replace(rIQ,(Q)=>iIQ[Q]??Q)}function KTA(A){return A.replace(pIQ,(Q,B)=>{return`<div class="mermaid">${dIQ(B)}</div>`})}var a41=/<!--\s*\.slide:\s*(.*?)\s*-->/g;function t41(A){let Q={};for(let w of A.matchAll(a41)){let $=w[1]??"";for(let I of $.matchAll(/([\w-]+)=["']([^"']*?)["']/g)){let D=I[1],U=I[2];if(D&&U!==void 0)Q[D]=U}let f=$.replace(/([\w-]+)=["']([^"']*?)["']/g,"").trim();if(f)for(let I of f.matchAll(/(?:^|\s)([\w-]+)(?=\s|$)/g)){let D=I[1];if(D)Q[D]="true"}}let B=A.replace(a41,"").replace(/^\n+/,"").replace(/\n{3,}/g,`
|
|
4662
4662
|
|
|
4663
4663
|
`).trim();return{attributes:Q,markdown:B}}var nIQ=/<!--\s*\.break\s*-->/;function e41(A){let Q=A.split(nIQ);return Q.length>1?Q:null}import{jsxDEV as UH}from"preact/jsx-dev-runtime";var FTA=({markdown:A,deck:Q})=>{let B=NF(),$=A.split(/^---$/gm).map((J)=>J.trim()).map((J)=>{let{attributes:X,markdown:G}=t41(J),Z=e41(G),N;if(Z)N=`<div class="slide-columns">${Z.map((V)=>`<div class="slide-column">${KTA(B(V.trim()))}</div>`).join("")}</div>`;else N=KTA(B(G));return{attributes:X,htmlContent:N}}),f=$.some((J)=>J.htmlContent.includes('class="mermaid"')),I=Q?.frontmatter?.title??Q?.metadata?.title,D=Q?.frontmatter?.description??Q?.metadata?.description,U=Q?.ogImageUrl??Q?.coverImageUrl,Y=$.map(({attributes:J,htmlContent:X},G)=>UH("section",{...J,dangerouslySetInnerHTML:{__html:X}},G,!1,void 0,this));return UH("section",{className:"presentation-section",children:[I&&UH(KQ,{title:I,...D?{description:D}:{},...U?{ogImage:U}:{},ogType:"article"},void 0,!1,void 0,this),UH("link",{rel:"stylesheet",href:"https://cdn.jsdelivr.net/npm/reveal.js@5.1.0/dist/reveal.min.css"},void 0,!1,void 0,this),UH("div",{className:"reveal",children:UH("div",{className:"slides",children:Y},void 0,!1,void 0,this)},void 0,!1,void 0,this),UH("script",{src:"https://cdn.jsdelivr.net/npm/reveal.js@5.1.0/dist/reveal.min.js",defer:!0},void 0,!1,void 0,this),f&&UH("script",{src:"https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js",defer:!0},void 0,!1,void 0,this),UH("script",{dangerouslySetInnerHTML:{__html:`
|
|
@@ -5644,13 +5644,13 @@ ${A.map((f)=>({url:`${Q}${f.path}`,lastmod:B,changefreq:f.path==="/"?"daily":"we
|
|
|
5644
5644
|
`+$:B,I=qH(this.outputDir,"styles","main.css");await this.cssProcessor.process(f,I,this.workingDir,this.outputDir,this.logger);let D=await d9.readFile(I,"utf-8"),U=w.length>0?w:Q;if(U.length>0){let Y=U.join(`
|
|
5645
5645
|
`)+`
|
|
5646
5646
|
|
|
5647
|
-
`+D;await d9.writeFile(I,Y,"utf-8")}this.logger.debug("CSS processed successfully with font imports")}async copyStaticAssets(){this.logger.debug("Copying static assets from public/ directory");let A=qH(process.cwd(),"public");try{await d9.access(A)}catch{this.logger.debug("No public/ directory found, skipping static assets");return}let Q=await d9.readdir(A,{withFileTypes:!0});for(let B of Q){let w=qH(A,B.name),$=qH(this.outputDir,B.name);if(B.isDirectory())await this.copyDirectory(w,$);else await d9.copyFile(w,$),this.logger.debug(`Copied static asset: ${B.name}`)}this.logger.debug("Static assets copied successfully")}async writeInlineStaticAssets(A){if(!A)return;let Q=Object.entries(A);if(Q.length===0)return;this.logger.debug(`Writing ${Q.length} inline static asset(s) from SitePackage`),await Promise.all(Q.map(async([B,w])=>{let $=B.startsWith("/")?B.slice(1):B,f=qH(this.outputDir,$);await d9.mkdir(tqQ(f),{recursive:!0}),await d9.writeFile(f,w,"utf-8"),this.logger.debug(`Wrote inline static asset: ${$}`)}))}async copyDirectory(A,Q){await d9.mkdir(Q,{recursive:!0});let B=await d9.readdir(A,{withFileTypes:!0});for(let w of B){let $=qH(A,w.name),f=qH(Q,w.name);if(w.isDirectory())await this.copyDirectory($,f);else await d9.copyFile($,f)}}}function oxA(A){return new yG1(A)}f5();WA();WA();f5();var xG1=H.object({environment:H.enum(["preview","production"]),outputDir:H.string(),workingDir:H.string().optional(),sharedImagesDir:H.string().default("./dist/images"),enableContentGeneration:H.boolean().default(!1),cleanBeforeBuild:H.boolean().default(!0),siteConfig:LI,layouts:H.record(H.any()),themeCSS:H.string().optional()}),Igw=H.object({success:H.boolean(),outputDir:H.string(),filesGenerated:H.number(),routesBuilt:H.number(),errors:H.array(H.string()).optional(),warnings:H.array(H.string()).optional()});function SG1(A){let Q=A.list(),B=Q.length===0?["No routes registered for site build"]:[];return{routes:Q,warnings:B}}function gG1(A,Q,B){let w=Q.getProfile(),$=B.getNavigationItems("primary"),f=B.getNavigationItems("secondary");return{...A,...w.socialLinks!==void 0&&{socialLinks:w.socialLinks},navigation:{primary:$,secondary:f},copyright:A.copyright??"Powered by Rizom"}}f5();E7();f5();WA();var eqQ=H.object({id:H.string(),entityType:H.string(),content:H.string(),metadata:H.object({slug:H.string()}).passthrough()}).passthrough(),ALQ=H.object({content:H.string(),metadata:H.object({width:H.number().optional(),height:H.number().optional()}).passthrough()});async function Q5A(A,Q){let B=Q.urlGenerator??K7.getInstance();if(A===null||A===void 0)return A;if(Array.isArray(A))return Promise.all(A.map((S)=>Q5A(S,{...Q,urlGenerator:B})));if(typeof A!=="object")return A;let w={},$=Object.entries(A),f=await Promise.all($.map(([,S])=>Q5A(S,{...Q,urlGenerator:B})));for(let S=0;S<$.length;S++){let y=$[S];if(y)w[y[0]]=f[S]}let I=eqQ.safeParse(A);if(!I.success)return w;let D=I.data,U=D.entityType,Y=D.metadata.slug,J=Q.pipelineContext.entityDisplay?.[U],X=J?J.label:U.charAt(0).toUpperCase()+U.slice(1),G=J?J.pluralName??J.label.toLowerCase()+"s":zI(U),Z=`/${G}`,N=G.charAt(0).toUpperCase()+G.slice(1),L=Hg(D),V=await QLQ(L,Q),M=Mt(D)??L,O=await BLQ(M,Q);return{...w,...D,url:B.generateUrl(U,Y),typeLabel:X,listUrl:Z,listLabel:N,...V,...O&&{ogImageUrl:O}}}async function QLQ(A,Q){let B=A?Q.imageBuildService?.get(A):void 0;if(B)return{coverImageUrl:B.src,coverImageWidth:B.width,coverImageHeight:B.height,...B.srcset&&{coverImageSrcset:B.srcset,coverImageSizes:B.sizes}};let w=await mG1(A,Q.pipelineContext.services.entityService);if(!w)return{};return{coverImageUrl:w.url,...w.width&&{coverImageWidth:w.width},...w.height&&{coverImageHeight:w.height}}}async function BLQ(A,Q){if(!A)return;let B=Q.imageBuildService?.get(A);if(B)return hG1(B.src,Q.siteUrl);let w=await mG1(A,Q.pipelineContext.services.entityService);if(!w)return;if(w.url.startsWith("data:"))return;return hG1(w.url,Q.siteUrl)}function hG1(A,Q){if(/^https?:\/\//i.test(A)||A.startsWith("data:"))return A;if(!Q)return A;return`${Q.replace(/\/$/,"")}/${A.replace(/^\//,"")}`}async function mG1(A,Q){if(!A)return;let B=await Q.getEntity({entityType:"image",id:A}),w=ALQ.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 uG1(A,Q){let B=new Set;try{let w=A.getEntityTypes();for(let $ of w){if($==="image")continue;let f=await A.listEntities({entityType:$});for(let I of f){let D=Hg(I);if(D)B.add(D);let U=Mt(I);if(U)B.add(U)}}}catch(w){Q.warn("Failed to collect image IDs for pre-resolution",{error:T0(w)})}return[...B]}async function cG1(A,Q,B,w,$){if(!A.template)return A.content??null;let f=A.template,I=A.dataQuery?{dataParams:A.dataQuery,fallback:A.content,publishedOnly:B,visibilityScope:w}:{savedContent:{entityType:"site-content",entityId:`${Q.id}:${A.id}`},fallback:A.content,visibilityScope:w},D=await $.pipelineContext.services.resolveTemplateContent(f,I);if(!D)return null;return Q5A(D,{pipelineContext:$.pipelineContext,imageBuildService:$.imageBuildService,siteUrl:$.siteUrl,urlGenerator:K7.getInstance()})}function lG1(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 cG1(B,Q,w,"public",{pipelineContext:A.pipelineContext,imageBuildService:A.imageBuildService,siteUrl:A.siteMetadata.url})},getViewTemplate:(Q)=>{return A.pipelineContext.services.getViewTemplate(Q)},layouts:A.parsedOptions.layouts,getSiteLayoutInfo:async()=>{return gG1(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 wLQ}from"path";async function pG1(A){let Q=A.parsedOptions.workingDir??wLQ(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 iG1(A){await new e6A({logger:A.pipelineContext.logger.child("DynamicRouteGenerator"),entityService:A.pipelineContext.services.entityService,listViewTemplateNames:()=>A.pipelineContext.services.listViewTemplateNames()},A.pipelineContext.routeRegistry,A.pipelineContext.entityDisplay,{visibilityScope:"public",...A.publishedOnly!==void 0&&{publishedOnly:A.publishedOnly}}).generateEntityRoutes()}async function rG1(A){let Q=new t6A(A.pipelineContext.services.entityService,A.pipelineContext.logger,A.sharedImagesDir),B=await uG1(A.pipelineContext.services.entityService,A.pipelineContext.logger);if(B.length>0)await Q.resolveAll(B);return Q}async function dG1(A){let Q=A.reporter?.createSub({scale:{start:85,end:95}});await A.staticSiteBuilder.build(A.buildContext,(B)=>{Q?.report(B).catch(()=>{})})}function nG1(A){return{success:!0,outputDir:A.outputDir,filesGenerated:A.routesBuilt+1,routesBuilt:A.routesBuilt,...A.warnings.length>0&&{warnings:A.warnings}}}function oG1(A){return{success:!1,outputDir:A.outputDir,filesGenerated:0,routesBuilt:0,errors:[A.errorMessage]}}async function sG1(A){let Q=xG1.parse(A.buildOptions),B=M9.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 iG1({pipelineContext:A.pipelineContext,publishedOnly:Q.environment==="production"});let $=await pG1({logger:A.pipelineContext.logger,parsedOptions:Q,staticSiteBuilderFactory:A.staticSiteBuilderFactory}),f=SG1(A.pipelineContext.routeRegistry);w.push(...f.warnings);let{routes:I}=f;await B?.report({message:`Building ${I.length} routes`,progress:20,total:100}),await B?.report({message:"Resolving images",progress:25,total:100});let D=await rG1({pipelineContext:A.pipelineContext,sharedImagesDir:Q.sharedImagesDir}),U=lG1({routes:I,parsedOptions:Q,buildOptions:A.buildOptions,pipelineContext:A.pipelineContext,imageBuildService:D,siteMetadata:Q.siteConfig});return await dG1({staticSiteBuilder:$,buildContext:U,reporter:B}),await B?.report({message:"Site build complete",progress:100,total:100}),nG1({outputDir:Q.outputDir,routesBuilt:I.length,warnings:w})}catch($){let f=Error("Site build process failed");return A.pipelineContext.logger.error("Site build failed",{error:f,originalError:$}),oG1({outputDir:Q.outputDir,errorMessage:f.message})}}class GD{static instance=null;static defaultStaticSiteBuilderFactory=oxA;pipelineContext;staticSiteBuilderFactory;static setDefaultStaticSiteBuilderFactory(A){GD.defaultStaticSiteBuilderFactory=A}static getInstance(A,Q,B,w,$=void 0){return GD.instance??=new GD(A,GD.defaultStaticSiteBuilderFactory,Q,B,w,$),GD.instance}static resetInstance(){GD.instance=null}static createFresh(A,Q,B,w,$,f=void 0){return new GD(A,$??GD.defaultStaticSiteBuilderFactory,Q,B,w,f)}constructor(A,Q,B,w,$,f){this.pipelineContext={logger:A,services:B,routeRegistry:w,profileService:$,entityDisplay:f},this.staticSiteBuilderFactory=Q,K7.getInstance().configure(f)}async build(A,Q){return sG1({buildOptions:A,progress:Q,pipelineContext:this.pipelineContext,staticSiteBuilderFactory:this.staticSiteBuilderFactory})}}WA();class sxA{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 GL(()=>{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})}}}f5();function $LQ(A,Q){return A.map((B)=>({...B,template:B.template.includes(":")?B.template:`${Q}:${B.template}`}))}function B5A(A,Q,B){for(let w of A)B.register({...w,pluginId:Q,sections:w.sections?$LQ(w.sections,Q):[]})}function aG1(A,Q,B){A.messaging.subscribe("plugin:site-builder:route:register",async(w)=>{try{let $=Wo.parse(w.payload),{routes:f,pluginId:I}=$;return B5A(f,I,Q),{success:!0}}catch($){return B.error("Failed to register routes",{error:$}),{success:!1,error:"Failed to register routes"}}}),A.messaging.subscribe("plugin:site-builder:route:unregister",async(w)=>{try{let $=Ho.parse(w.payload),{paths:f,pluginId:I}=$;if(f)for(let D of f)Q.unregister(D);else if(I)Q.unregisterByPlugin(I);return{success:!0}}catch($){return B.error("Failed to unregister routes",{error:$}),{success:!1,error:"Failed to unregister routes"}}}),A.messaging.subscribe("plugin:site-builder:route:list",async(w)=>{try{let $=Go.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 $=Ko.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 tG1}from"fs";import{join as eG1}from"path";async function fLQ(A,Q,B){let w=A.siteConfig.url??"https://example.com",$=Q.list(),f=dxA(w,A.environment);await tG1.writeFile(eG1(A.outputDir,"robots.txt"),f,"utf-8"),B.info(`Generated robots.txt for ${A.environment} environment`);let I=nxA($,w);await tG1.writeFile(eG1(A.outputDir,"sitemap.xml"),I,"utf-8"),B.info(`Generated sitemap.xml with ${$.length} URLs`)}function AK1(A){let{context:Q,routeRegistry:B,logger:w}=A;Q.messaging.subscribe("site:build:completed",async($)=>{try{let f=$.payload;return w.info(`Received site:build:completed event for ${f.environment} environment - generating SEO files`),await fLQ(f,B,w),{success:!0}}catch(f){return w.error("Failed to generate SEO files",f),{success:!1}}})}aA();WA();f5();var QK1=H.object({environment:H.enum(["preview","production"]).optional(),outputDir:H.string(),workingDir:H.string().optional(),enableContentGeneration:H.boolean().optional(),siteConfig:LI.optional()});f5();f5();async function sp(A,Q){try{let B=await A({type:$x,payload:void 0});if("success"in B&&B.success&&B.data){let w=LI.safeParse(B.data);if(w.success)return LI.parse({...Q,...w.data})}}catch{}return Q}class axA extends ZB{sendMessage;cfg;constructor(A,Q,B){super(A,{schema:QK1,jobTypeName:"site-build"});this.sendMessage=Q;this.cfg=B}async process(A,Q,B){let w=A.environment??"preview",$=A.enableContentGeneration??!1;try{this.logger.debug("Starting site build job",{jobId:Q,environment:w,outputDir:A.outputDir}),await B.report({progress:0,total:100,message:`Starting site build for ${w} environment`});let f=B.createSub({scale:{start:10,end:90}}),I=await sp(this.sendMessage,A.siteConfig??this.cfg.defaultSiteConfig),D=await this.cfg.siteBuilder.build({outputDir:A.outputDir,workingDir:A.workingDir,sharedImagesDir:this.cfg.sharedImagesDir,enableContentGeneration:$,environment:w,cleanBeforeBuild:!0,siteConfig:I,layouts:this.cfg.layouts,themeCSS:this.cfg.themeCSS,slots:this.cfg.slots,headScripts:this.cfg.getHeadScripts?.(),...this.cfg.staticAssets&&{staticAssets:this.cfg.staticAssets}},f.toCallback());if(await B.report({progress:100,total:100,message:`Site build completed: ${D.routesBuilt} routes built`}),this.logger.debug("Site build job completed",{jobId:Q,environment:w,routesBuilt:D.routesBuilt,success:D.success}),D.success){this.logger.info(`Emitting site:build:completed event for ${w} environment`);let U=w==="preview"?this.cfg.previewUrl??this.cfg.siteUrl:this.cfg.siteUrl;await this.sendMessage({type:"site:build:completed",payload:{outputDir:A.outputDir,environment:w,routesBuilt:D.routesBuilt,siteConfig:{...I,url:U},generateEntityUrl:(Y,J)=>K7.getInstance().generateUrl(Y,J)},broadcast:!0})}return{success:D.success,routesBuilt:D.routesBuilt,outputDir:A.outputDir,environment:w,...D.errors&&{errors:D.errors},...D.warnings&&{warnings:D.warnings}}}catch(f){throw this.logger.error("Site build job failed",f),f}}summarizeDataForLog(A){return{environment:A.environment,outputDir:A.outputDir}}}WA();f5();var ILQ=H.object({slot:H.enum(NL).optional().default("primary"),limit:H.number().optional()});class txA{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=ILQ.parse(A??{});this.logger.debug("NavigationDataSource fetch called",{params:w});let $=this.routeRegistry.getNavigationItems(w.slot),f=w.limit?$.slice(0,w.limit):$,I=f.map((U)=>({label:U.label,href:U.href}));this.logger.debug("NavigationDataSource returning",{slot:w.slot,itemCount:f.length,items:I});let D={navigation:I};return Q.parse(D)}}f5();aA();WA();var DLQ=H.object({environment:H.enum(["preview","production"]).optional().describe("Build environment (defaults to production, or preview if configured)")});function BK1(A,Q){return[oQ(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'.",DLQ,async(B)=>{return Q(B.environment),{success:!0,message:`Site build requested${B.environment?` for ${B.environment}`:""} (debounced)`,data:{}}},{cli:{name:"build"}})]}WA();f5();var wK1=H.object({previewOutputDir:H.string().describe("Output directory for preview builds").default("./dist/site-preview"),productionOutputDir:H.string().describe("Output directory for production builds").default("./dist/site-production"),sharedImagesDir:H.string().describe("Shared directory for optimized images (used by both preview and production)").default("./dist/images"),workingDir:H.string().optional().describe("Working directory for builds").default("./.preact-work"),siteInfo:LI.default({title:"Brain",description:"A knowledge management system"}),themeCSS:H.string().describe("Custom CSS theme overrides to inject into builds").optional(),analyticsScript:H.string().describe("Analytics tracking script to inject into page head (e.g., Cloudflare Web Analytics)").optional(),templates:H.any().optional().describe("Template definitions to register"),routes:H.array(zL).optional().describe("Routes to register"),layouts:H.record(H.any()).optional().describe("Layout components (at least 'default' required)"),autoRebuild:H.boolean().default(!0).describe("Automatically rebuild site when content changes"),rebuildDebounce:H.number().min(100).describe("Debounce time in ms before triggering site rebuild after content changes").default(5000),entityDisplay:H.record(H.object({label:H.string().describe("Display label for entity type (e.g., 'Essay')"),pluralName:H.string().optional().describe("URL path segment (defaults to label.toLowerCase() + 's')"),layout:H.string().optional().describe("Layout name for this entity type's generated routes (defaults to 'default')"),paginate:H.boolean().optional().describe("Enable pagination for list pages"),pageSize:H.number().optional().describe("Items per page (default: 10)"),navigation:H.object({show:H.boolean().optional().describe("Show in navigation"),slot:H.enum(NL).optional().describe("Navigation slot (primary or secondary)"),priority:H.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:H.record(H.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 $K1={name:"@brains/site-builder-plugin",private:!0,version:"0.2.0-alpha.119",description:"Static site generation plugin for Brain system",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint .",clean:"rm -rf dist"},dependencies:{"@brains/image":"workspace:*","@brains/plugins":"workspace:*","@brains/site-composition":"workspace:*","@brains/site-engine":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*","@tailwindcss/typography":"^0.5.19",preact:"^10.27.2","preact-render-to-string":"^6.3.1"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14",eslint:"^8.56.0",typescript:"^5.3.3"}};class exA extends YB{siteBuilder;pluginContext;_routeRegistry;_slotRegistry;profileService;layouts;rebuildManager;headScripts=new Map;get routeRegistry(){if(!this._routeRegistry)throw Error("RouteRegistry not initialized - plugin not registered");return this._routeRegistry}constructor(A={}){let Q=A.layouts??{};super("site-builder",$K1,{...A,layouts:Q},wK1);this.layouts=Q}async onRegister(A){if(this.pluginContext=A,this._routeRegistry=new A5A(A.logger),this._slotRegistry=new v6A,A.messaging.subscribe("plugin:site-builder:slot:register",async(B)=>{let{slotName:w,pluginId:$,render:f,priority:I}=B.payload;return this._slotRegistry?.register(w,{pluginId:$,render:f,...I!==void 0&&{priority:I}}),{success:!0}}),A.messaging.subscribe("plugin:site-builder:head-script:register",async(B)=>{let{pluginId:w,script:$}=B.payload;return this.headScripts.set(w,$),{success:!0}}),A.entities.registerDataSource(new txA(this._routeRegistry,A.logger.child("NavigationDataSource"))),this.profileService=H4.getInstance(A.entityService,A.logger),aG1(A,this._routeRegistry,this.logger),this.config.templates)A.templates.register(this.config.templates);if(this.config.routes)B5A(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=GD.getInstance(A.logger.child("SiteBuilder"),Q,this.routeRegistry,this.profileService,this.config.entityDisplay),A.jobs.registerHandler("site-build",new axA(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 sxA(this.config,A,this.id,this.logger),this.config.autoRebuild)this.logger.debug("Auto-rebuild enabled"),this.rebuildManager.setupAutoRebuild();A.messaging.subscribe(fx,async()=>{let B=await this.getInstructions();if(B)A.registerInstructions(B);return{success:!0}}),AK1({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 BK1(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 sp(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 sp(A.messaging.send,this.config.siteInfo);return`## Your Site
|
|
5647
|
+
`+D;await d9.writeFile(I,Y,"utf-8")}this.logger.debug("CSS processed successfully with font imports")}async copyStaticAssets(){this.logger.debug("Copying static assets from public/ directory");let A=qH(process.cwd(),"public");try{await d9.access(A)}catch{this.logger.debug("No public/ directory found, skipping static assets");return}let Q=await d9.readdir(A,{withFileTypes:!0});for(let B of Q){let w=qH(A,B.name),$=qH(this.outputDir,B.name);if(B.isDirectory())await this.copyDirectory(w,$);else await d9.copyFile(w,$),this.logger.debug(`Copied static asset: ${B.name}`)}this.logger.debug("Static assets copied successfully")}async writeInlineStaticAssets(A){if(!A)return;let Q=Object.entries(A);if(Q.length===0)return;this.logger.debug(`Writing ${Q.length} inline static asset(s) from SitePackage`),await Promise.all(Q.map(async([B,w])=>{let $=B.startsWith("/")?B.slice(1):B,f=qH(this.outputDir,$);await d9.mkdir(tqQ(f),{recursive:!0}),await d9.writeFile(f,w,"utf-8"),this.logger.debug(`Wrote inline static asset: ${$}`)}))}async copyDirectory(A,Q){await d9.mkdir(Q,{recursive:!0});let B=await d9.readdir(A,{withFileTypes:!0});for(let w of B){let $=qH(A,w.name),f=qH(Q,w.name);if(w.isDirectory())await this.copyDirectory($,f);else await d9.copyFile($,f)}}}function oxA(A){return new yG1(A)}f5();WA();WA();f5();var xG1=H.object({environment:H.enum(["preview","production"]),outputDir:H.string(),workingDir:H.string().optional(),sharedImagesDir:H.string().default("./dist/images"),enableContentGeneration:H.boolean().default(!1),cleanBeforeBuild:H.boolean().default(!0),siteConfig:LI,layouts:H.record(H.any()),themeCSS:H.string().optional()}),Igw=H.object({success:H.boolean(),outputDir:H.string(),filesGenerated:H.number(),routesBuilt:H.number(),errors:H.array(H.string()).optional(),warnings:H.array(H.string()).optional()});function SG1(A){let Q=A.list(),B=Q.length===0?["No routes registered for site build"]:[];return{routes:Q,warnings:B}}function gG1(A,Q,B){let w=Q.getProfile(),$=B.getNavigationItems("primary"),f=B.getNavigationItems("secondary");return{...A,...w.socialLinks!==void 0&&{socialLinks:w.socialLinks},navigation:{primary:$,secondary:f},copyright:A.copyright??"Powered by Rizom"}}f5();E7();f5();WA();var eqQ=H.object({id:H.string(),entityType:H.string(),content:H.string(),metadata:H.object({slug:H.string()}).passthrough()}).passthrough(),ALQ=H.object({content:H.string(),metadata:H.object({width:H.number().optional(),height:H.number().optional()}).passthrough()});async function Q5A(A,Q){let B=Q.urlGenerator??K7.getInstance();if(A===null||A===void 0)return A;if(Array.isArray(A))return Promise.all(A.map((S)=>Q5A(S,{...Q,urlGenerator:B})));if(typeof A!=="object")return A;let w={},$=Object.entries(A),f=await Promise.all($.map(([,S])=>Q5A(S,{...Q,urlGenerator:B})));for(let S=0;S<$.length;S++){let y=$[S];if(y)w[y[0]]=f[S]}let I=eqQ.safeParse(A);if(!I.success)return w;let D=I.data,U=D.entityType,Y=D.metadata.slug,J=Q.pipelineContext.entityDisplay?.[U],X=J?J.label:U.charAt(0).toUpperCase()+U.slice(1),G=J?J.pluralName??J.label.toLowerCase()+"s":zI(U),Z=`/${G}`,N=G.charAt(0).toUpperCase()+G.slice(1),L=Hg(D),V=await QLQ(L,Q),M=Mt(D)??L,O=await BLQ(M,Q);return{...w,...D,url:B.generateUrl(U,Y),typeLabel:X,listUrl:Z,listLabel:N,...V,...O&&{ogImageUrl:O}}}async function QLQ(A,Q){let B=A?Q.imageBuildService?.get(A):void 0;if(B)return{coverImageUrl:B.src,coverImageWidth:B.width,coverImageHeight:B.height,...B.srcset&&{coverImageSrcset:B.srcset,coverImageSizes:B.sizes}};let w=await mG1(A,Q.pipelineContext.services.entityService);if(!w)return{};return{coverImageUrl:w.url,...w.width&&{coverImageWidth:w.width},...w.height&&{coverImageHeight:w.height}}}async function BLQ(A,Q){if(!A)return;let B=Q.imageBuildService?.get(A);if(B)return hG1(B.src,Q.siteUrl);let w=await mG1(A,Q.pipelineContext.services.entityService);if(!w)return;if(w.url.startsWith("data:"))return;return hG1(w.url,Q.siteUrl)}function hG1(A,Q){if(/^https?:\/\//i.test(A)||A.startsWith("data:"))return A;if(!Q)return A;return`${Q.replace(/\/$/,"")}/${A.replace(/^\//,"")}`}async function mG1(A,Q){if(!A)return;let B=await Q.getEntity({entityType:"image",id:A}),w=ALQ.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 uG1(A,Q){let B=new Set;try{let w=A.getEntityTypes();for(let $ of w){if($==="image")continue;let f=await A.listEntities({entityType:$});for(let I of f){let D=Hg(I);if(D)B.add(D);let U=Mt(I);if(U)B.add(U)}}}catch(w){Q.warn("Failed to collect image IDs for pre-resolution",{error:T0(w)})}return[...B]}async function cG1(A,Q,B,w,$){if(!A.template)return A.content??null;let f=A.template,I=A.dataQuery?{dataParams:A.dataQuery,fallback:A.content,publishedOnly:B,visibilityScope:w}:{savedContent:{entityType:"site-content",entityId:`${Q.id}:${A.id}`},fallback:A.content,visibilityScope:w},D=await $.pipelineContext.services.resolveTemplateContent(f,I);if(!D)return null;return Q5A(D,{pipelineContext:$.pipelineContext,imageBuildService:$.imageBuildService,siteUrl:$.siteUrl,urlGenerator:K7.getInstance()})}function lG1(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 cG1(B,Q,w,"public",{pipelineContext:A.pipelineContext,imageBuildService:A.imageBuildService,siteUrl:A.siteMetadata.url})},getViewTemplate:(Q)=>{return A.pipelineContext.services.getViewTemplate(Q)},layouts:A.parsedOptions.layouts,getSiteLayoutInfo:async()=>{return gG1(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 wLQ}from"path";async function pG1(A){let Q=A.parsedOptions.workingDir??wLQ(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 iG1(A){await new e6A({logger:A.pipelineContext.logger.child("DynamicRouteGenerator"),entityService:A.pipelineContext.services.entityService,listViewTemplateNames:()=>A.pipelineContext.services.listViewTemplateNames()},A.pipelineContext.routeRegistry,A.pipelineContext.entityDisplay,{visibilityScope:"public",...A.publishedOnly!==void 0&&{publishedOnly:A.publishedOnly}}).generateEntityRoutes()}async function rG1(A){let Q=new t6A(A.pipelineContext.services.entityService,A.pipelineContext.logger,A.sharedImagesDir),B=await uG1(A.pipelineContext.services.entityService,A.pipelineContext.logger);if(B.length>0)await Q.resolveAll(B);return Q}async function dG1(A){let Q=A.reporter?.createSub({scale:{start:85,end:95}});await A.staticSiteBuilder.build(A.buildContext,(B)=>{Q?.report(B).catch(()=>{})})}function nG1(A){return{success:!0,outputDir:A.outputDir,filesGenerated:A.routesBuilt+1,routesBuilt:A.routesBuilt,...A.warnings.length>0&&{warnings:A.warnings}}}function oG1(A){return{success:!1,outputDir:A.outputDir,filesGenerated:0,routesBuilt:0,errors:[A.errorMessage]}}async function sG1(A){let Q=xG1.parse(A.buildOptions),B=M9.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 iG1({pipelineContext:A.pipelineContext,publishedOnly:Q.environment==="production"});let $=await pG1({logger:A.pipelineContext.logger,parsedOptions:Q,staticSiteBuilderFactory:A.staticSiteBuilderFactory}),f=SG1(A.pipelineContext.routeRegistry);w.push(...f.warnings);let{routes:I}=f;await B?.report({message:`Building ${I.length} routes`,progress:20,total:100}),await B?.report({message:"Resolving images",progress:25,total:100});let D=await rG1({pipelineContext:A.pipelineContext,sharedImagesDir:Q.sharedImagesDir}),U=lG1({routes:I,parsedOptions:Q,buildOptions:A.buildOptions,pipelineContext:A.pipelineContext,imageBuildService:D,siteMetadata:Q.siteConfig});return await dG1({staticSiteBuilder:$,buildContext:U,reporter:B}),await B?.report({message:"Site build complete",progress:100,total:100}),nG1({outputDir:Q.outputDir,routesBuilt:I.length,warnings:w})}catch($){let f=Error("Site build process failed");return A.pipelineContext.logger.error("Site build failed",{error:f,originalError:$}),oG1({outputDir:Q.outputDir,errorMessage:f.message})}}class GD{static instance=null;static defaultStaticSiteBuilderFactory=oxA;pipelineContext;staticSiteBuilderFactory;static setDefaultStaticSiteBuilderFactory(A){GD.defaultStaticSiteBuilderFactory=A}static getInstance(A,Q,B,w,$=void 0){return GD.instance??=new GD(A,GD.defaultStaticSiteBuilderFactory,Q,B,w,$),GD.instance}static resetInstance(){GD.instance=null}static createFresh(A,Q,B,w,$,f=void 0){return new GD(A,$??GD.defaultStaticSiteBuilderFactory,Q,B,w,f)}constructor(A,Q,B,w,$,f){this.pipelineContext={logger:A,services:B,routeRegistry:w,profileService:$,entityDisplay:f},this.staticSiteBuilderFactory=Q,K7.getInstance().configure(f)}async build(A,Q){return sG1({buildOptions:A,progress:Q,pipelineContext:this.pipelineContext,staticSiteBuilderFactory:this.staticSiteBuilderFactory})}}WA();class sxA{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 GL(()=>{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})}}}f5();function $LQ(A,Q){return A.map((B)=>({...B,template:B.template.includes(":")?B.template:`${Q}:${B.template}`}))}function B5A(A,Q,B){for(let w of A)B.register({...w,pluginId:Q,sections:w.sections?$LQ(w.sections,Q):[]})}function aG1(A,Q,B){A.messaging.subscribe("plugin:site-builder:route:register",async(w)=>{try{let $=Wo.parse(w.payload),{routes:f,pluginId:I}=$;return B5A(f,I,Q),{success:!0}}catch($){return B.error("Failed to register routes",{error:$}),{success:!1,error:"Failed to register routes"}}}),A.messaging.subscribe("plugin:site-builder:route:unregister",async(w)=>{try{let $=Ho.parse(w.payload),{paths:f,pluginId:I}=$;if(f)for(let D of f)Q.unregister(D);else if(I)Q.unregisterByPlugin(I);return{success:!0}}catch($){return B.error("Failed to unregister routes",{error:$}),{success:!1,error:"Failed to unregister routes"}}}),A.messaging.subscribe("plugin:site-builder:route:list",async(w)=>{try{let $=Go.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 $=Ko.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 tG1}from"fs";import{join as eG1}from"path";async function fLQ(A,Q,B){let w=A.siteConfig.url??"https://example.com",$=Q.list(),f=dxA(w,A.environment);await tG1.writeFile(eG1(A.outputDir,"robots.txt"),f,"utf-8"),B.info(`Generated robots.txt for ${A.environment} environment`);let I=nxA($,w);await tG1.writeFile(eG1(A.outputDir,"sitemap.xml"),I,"utf-8"),B.info(`Generated sitemap.xml with ${$.length} URLs`)}function AK1(A){let{context:Q,routeRegistry:B,logger:w}=A;Q.messaging.subscribe("site:build:completed",async($)=>{try{let f=$.payload;return w.info(`Received site:build:completed event for ${f.environment} environment - generating SEO files`),await fLQ(f,B,w),{success:!0}}catch(f){return w.error("Failed to generate SEO files",f),{success:!1}}})}aA();WA();f5();var QK1=H.object({environment:H.enum(["preview","production"]).optional(),outputDir:H.string(),workingDir:H.string().optional(),enableContentGeneration:H.boolean().optional(),siteConfig:LI.optional()});f5();f5();async function sp(A,Q){try{let B=await A({type:$x,payload:void 0});if("success"in B&&B.success&&B.data){let w=LI.safeParse(B.data);if(w.success)return LI.parse({...Q,...w.data})}}catch{}return Q}class axA extends ZB{sendMessage;cfg;constructor(A,Q,B){super(A,{schema:QK1,jobTypeName:"site-build"});this.sendMessage=Q;this.cfg=B}async process(A,Q,B){let w=A.environment??"preview",$=A.enableContentGeneration??!1;try{this.logger.debug("Starting site build job",{jobId:Q,environment:w,outputDir:A.outputDir}),await B.report({progress:0,total:100,message:`Starting site build for ${w} environment`});let f=B.createSub({scale:{start:10,end:90}}),I=await sp(this.sendMessage,A.siteConfig??this.cfg.defaultSiteConfig),D=await this.cfg.siteBuilder.build({outputDir:A.outputDir,workingDir:A.workingDir,sharedImagesDir:this.cfg.sharedImagesDir,enableContentGeneration:$,environment:w,cleanBeforeBuild:!0,siteConfig:I,layouts:this.cfg.layouts,themeCSS:this.cfg.themeCSS,slots:this.cfg.slots,headScripts:this.cfg.getHeadScripts?.(),...this.cfg.staticAssets&&{staticAssets:this.cfg.staticAssets}},f.toCallback());if(await B.report({progress:100,total:100,message:`Site build completed: ${D.routesBuilt} routes built`}),this.logger.debug("Site build job completed",{jobId:Q,environment:w,routesBuilt:D.routesBuilt,success:D.success}),D.success){this.logger.info(`Emitting site:build:completed event for ${w} environment`);let U=w==="preview"?this.cfg.previewUrl??this.cfg.siteUrl:this.cfg.siteUrl;await this.sendMessage({type:"site:build:completed",payload:{outputDir:A.outputDir,environment:w,routesBuilt:D.routesBuilt,siteConfig:{...I,url:U},generateEntityUrl:(Y,J)=>K7.getInstance().generateUrl(Y,J)},broadcast:!0})}return{success:D.success,routesBuilt:D.routesBuilt,outputDir:A.outputDir,environment:w,...D.errors&&{errors:D.errors},...D.warnings&&{warnings:D.warnings}}}catch(f){throw this.logger.error("Site build job failed",f),f}}summarizeDataForLog(A){return{environment:A.environment,outputDir:A.outputDir}}}WA();f5();var ILQ=H.object({slot:H.enum(NL).optional().default("primary"),limit:H.number().optional()});class txA{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=ILQ.parse(A??{});this.logger.debug("NavigationDataSource fetch called",{params:w});let $=this.routeRegistry.getNavigationItems(w.slot),f=w.limit?$.slice(0,w.limit):$,I=f.map((U)=>({label:U.label,href:U.href}));this.logger.debug("NavigationDataSource returning",{slot:w.slot,itemCount:f.length,items:I});let D={navigation:I};return Q.parse(D)}}f5();aA();WA();var DLQ=H.object({environment:H.enum(["preview","production"]).optional().describe("Build environment (defaults to production, or preview if configured)")});function BK1(A,Q){return[oQ(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'.",DLQ,async(B)=>{return Q(B.environment),{success:!0,message:`Site build requested${B.environment?` for ${B.environment}`:""} (debounced)`,data:{}}},{cli:{name:"build"}})]}WA();f5();var wK1=H.object({previewOutputDir:H.string().describe("Output directory for preview builds").default("./dist/site-preview"),productionOutputDir:H.string().describe("Output directory for production builds").default("./dist/site-production"),sharedImagesDir:H.string().describe("Shared directory for optimized images (used by both preview and production)").default("./dist/images"),workingDir:H.string().optional().describe("Working directory for builds").default("./.preact-work"),siteInfo:LI.default({title:"Brain",description:"A knowledge management system"}),themeCSS:H.string().describe("Custom CSS theme overrides to inject into builds").optional(),analyticsScript:H.string().describe("Analytics tracking script to inject into page head (e.g., Cloudflare Web Analytics)").optional(),templates:H.any().optional().describe("Template definitions to register"),routes:H.array(zL).optional().describe("Routes to register"),layouts:H.record(H.any()).optional().describe("Layout components (at least 'default' required)"),autoRebuild:H.boolean().default(!0).describe("Automatically rebuild site when content changes"),rebuildDebounce:H.number().min(100).describe("Debounce time in ms before triggering site rebuild after content changes").default(5000),entityDisplay:H.record(H.object({label:H.string().describe("Display label for entity type (e.g., 'Essay')"),pluralName:H.string().optional().describe("URL path segment (defaults to label.toLowerCase() + 's')"),layout:H.string().optional().describe("Layout name for this entity type's generated routes (defaults to 'default')"),paginate:H.boolean().optional().describe("Enable pagination for list pages"),pageSize:H.number().optional().describe("Items per page (default: 10)"),navigation:H.object({show:H.boolean().optional().describe("Show in navigation"),slot:H.enum(NL).optional().describe("Navigation slot (primary or secondary)"),priority:H.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:H.record(H.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 $K1={name:"@brains/site-builder-plugin",private:!0,version:"0.2.0-alpha.120",description:"Static site generation plugin for Brain system",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint .",clean:"rm -rf dist"},dependencies:{"@brains/image":"workspace:*","@brains/plugins":"workspace:*","@brains/site-composition":"workspace:*","@brains/site-engine":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*","@tailwindcss/typography":"^0.5.19",preact:"^10.27.2","preact-render-to-string":"^6.3.1"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14",eslint:"^8.56.0",typescript:"^5.3.3"}};class exA extends YB{siteBuilder;pluginContext;_routeRegistry;_slotRegistry;profileService;layouts;rebuildManager;headScripts=new Map;get routeRegistry(){if(!this._routeRegistry)throw Error("RouteRegistry not initialized - plugin not registered");return this._routeRegistry}constructor(A={}){let Q=A.layouts??{};super("site-builder",$K1,{...A,layouts:Q},wK1);this.layouts=Q}async onRegister(A){if(this.pluginContext=A,this._routeRegistry=new A5A(A.logger),this._slotRegistry=new v6A,A.messaging.subscribe("plugin:site-builder:slot:register",async(B)=>{let{slotName:w,pluginId:$,render:f,priority:I}=B.payload;return this._slotRegistry?.register(w,{pluginId:$,render:f,...I!==void 0&&{priority:I}}),{success:!0}}),A.messaging.subscribe("plugin:site-builder:head-script:register",async(B)=>{let{pluginId:w,script:$}=B.payload;return this.headScripts.set(w,$),{success:!0}}),A.entities.registerDataSource(new txA(this._routeRegistry,A.logger.child("NavigationDataSource"))),this.profileService=H4.getInstance(A.entityService,A.logger),aG1(A,this._routeRegistry,this.logger),this.config.templates)A.templates.register(this.config.templates);if(this.config.routes)B5A(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=GD.getInstance(A.logger.child("SiteBuilder"),Q,this.routeRegistry,this.profileService,this.config.entityDisplay),A.jobs.registerHandler("site-build",new axA(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 sxA(this.config,A,this.id,this.logger),this.config.autoRebuild)this.logger.debug("Auto-rebuild enabled"),this.rebuildManager.setupAutoRebuild();A.messaging.subscribe(fx,async()=>{let B=await this.getInstructions();if(B)A.registerInstructions(B);return{success:!0}}),AK1({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 BK1(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 sp(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 sp(A.messaging.send,this.config.siteInfo);return`## Your Site
|
|
5648
5648
|
${[`**Title:** ${B.title}`,`**Description:** ${B.description}`,A.domain&&`**Domain:** ${A.domain}`,A.siteUrl&&`**URL:** ${A.siteUrl}`].filter(Boolean).join(`
|
|
5649
5649
|
`)}
|
|
5650
5650
|
|
|
5651
5651
|
## Site Builder Actions
|
|
5652
5652
|
- When the user asks to build, rebuild, publish, or build the website/site again, call \`site-builder_build-site\` immediately.
|
|
5653
|
-
- 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(),GD.resetInstance(),this.logger.debug("Cleaned up all event subscriptions")}}function sM(A={}){return new exA(A)}aA();f5();WA();aA();f5();var fK1=H.object({}),ap=A2.extend({id:H.literal("site-info"),entityType:H.literal("site-info"),metadata:fK1}),ASA=Zo,Yv=LI.omit({url:!0,analyticsScript:!0});aA();class LH extends q2{constructor(){super({entityType:"site-info",schema:ap,frontmatterSchema:Yv,isSingleton:!0,hasBody:!1})}createSiteInfoContent(A){let Q=Yv.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 VH{static instance=null;logger;entityService;adapter;defaultSiteInfo;static getDefaultSiteInfo(){return{title:"Brain",description:"A knowledge management system"}}static getInstance(A,Q,B){return VH.instance??=new VH(A,Q,B),VH.instance}static resetInstance(){VH.instance=null}static createFresh(A,Q,B){return new VH(A,Q,B)}constructor(A,Q,B){this.entityService=A,this.logger=Q.child("SiteInfoService"),this.adapter=new LH;let w=VH.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 YLQ=new LH;class w5A{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?YLQ.parseSiteInfoBody(D.content):{title:"Brain",description:"A knowledge management system"}}catch{$={title:"Brain",description:"A knowledge management system"}}let f;try{let D=await w.getEntity({entityType:"anchor-profile",id:"anchor-profile"});if(D)f=D.metadata.socialLinks}catch{}let I={...$,socialLinks:f,copyright:$.copyright??"Powered by Rizom"};return this.logger.debug("SiteInfoDataSource returning",{title:I.title,hasSocialLinks:!!I.socialLinks}),Q.parse(I)}}var IK1={name:"@brains/site-info",private:!0,version:"0.2.0-alpha.119",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 XLQ=new LH;class QSA extends jQ{entityType="site-info";schema=ap;adapter=XLQ;defaultSiteInfo;constructor(A){super("site-info",IK1);this.defaultSiteInfo=A?.siteInfo??{}}getEntityTypeConfig(){return{embeddable:!1}}getDataSources(){return[new w5A(this.logger.child("SiteInfoDataSource"))]}async onRegister(A){let Q=VH.createFresh(A.entityService,this.logger,this.defaultSiteInfo);A.messaging.subscribe($x,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:fx,payload:$,broadcast:!0})}return{success:!0}}),A.messaging.subscribe("sync:initial:completed",async()=>{return await Q.initialize(),{success:!0}})}}function aM(A){return new QSA(A)}var WLQ=new LH;async function tp(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 WLQ.parseSiteInfoBody(B.content)}WA();var HLQ=Yv.extend({navigation:H.object({primary:H.array(H.object({label:H.string(),href:H.string(),priority:H.number()})),secondary:H.array(H.object({label:H.string(),href:H.string(),priority:H.number()}))}),copyright:H.string(),socialLinks:H.array(H.object({platform:H.enum(["github","instagram","linkedin","email","website"]).describe("Social media platform"),url:H.string().describe("Profile or contact URL"),label:H.string().optional().describe("Optional display label")})).optional().describe("Social media links from profile entity")});aA();WA();var DK1={lexicon:1,id:"ai.rizom.brain.card",defs:{main:{type:"record",description:"Public discovery card for a Rizom brain. The operational A2A Agent Card is conventionally served at /.well-known/agent-card.json under siteUrl.",key:"literal:self",record:{type:"object",required:["siteUrl","brain","anchor","skills","model","version","createdAt"],properties:{siteUrl:{type:"string",format:"uri",description:"Public site URL. Consumers derive the A2A Agent Card URL from this base."},brain:{type:"object",description:"Brain identity described by this discovery card.",required:["did","name","role","purpose","values"],properties:{did:{type:"string",description:"Public DID for the brain identity."},name:{type:"string",maxLength:200,description:"Human-readable brain name."},role:{type:"string",maxLength:500,description:"Brain role or persona."},purpose:{type:"string",maxLength:2000,description:"Short public description of what this brain is for."},values:{type:"array",description:"Public values or principles for this brain.",items:{type:"string",maxLength:200},maxLength:50}}},anchor:{type:"object",description:"Minimal owner/operator snapshot for discovery grouping and display.",required:["did","name","kind"],properties:{did:{type:"string",description:"Public DID for the owner/operator anchor identity."},name:{type:"string",maxLength:200,description:"Human-readable anchor name."},kind:{type:"string",knownValues:["professional","team","collective"],description:"Anchor type."}}},skills:{type:"array",description:"User-facing skills this brain advertises for discovery.",items:{type:"object",required:["id","name","description"],properties:{id:{type:"string",maxLength:200},name:{type:"string",maxLength:200},description:{type:"string",maxLength:2000},tags:{type:"array",items:{type:"string"},maxLength:50},examples:{type:"array",items:{type:"string"},maxLength:20}}},maxLength:100},model:{type:"string",description:"Rizom brain model identifier."},version:{type:"string",description:"Brain runtime/model implementation version."},createdAt:{type:"string",format:"datetime"},updatedAt:{type:"string",format:"datetime"}}}}}};var UK1={lexicon:1,id:"ai.rizom.brain.deck",defs:{main:{type:"record",description:"Public presentation deck from a Rizom brain.",key:"any",record:{type:"object",required:["title","body","createdAt"],properties:{title:{type:"string",maxLength:300},slug:{type:"string"},description:{type:"string",maxLength:2000},body:{type:"string",maxLength:1e5},format:{type:"string",knownValues:["text/markdown"]},author:{type:"string"},event:{type:"string"},publishedAt:{type:"string",format:"datetime"},brainDid:{type:"string"},anchorDid:{type:"string"},sourceEntityType:{type:"string"},sourceEntityId:{type:"string"},createdAt:{type:"string",format:"datetime"},updatedAt:{type:"string",format:"datetime"}}}}}};var YK1={lexicon:1,id:"ai.rizom.brain.link",defs:{main:{type:"record",description:"Public curated link from a Rizom brain.",key:"any",record:{type:"object",required:["title","url","createdAt"],properties:{title:{type:"string",maxLength:500},url:{type:"string",format:"uri"},description:{type:"string",maxLength:2000},summary:{type:"string",maxLength:1e5},domain:{type:"string"},capturedAt:{type:"string",format:"datetime"},source:{type:"object",required:["ref","label"],properties:{ref:{type:"string"},label:{type:"string"}}},brainDid:{type:"string"},anchorDid:{type:"string"},sourceEntityType:{type:"string"},sourceEntityId:{type:"string"},createdAt:{type:"string",format:"datetime"},updatedAt:{type:"string",format:"datetime"}}}}}};var JK1={lexicon:1,id:"ai.rizom.brain.note",defs:{main:{type:"record",description:"Public knowledge note from a Rizom brain.",key:"any",record:{type:"object",required:["title","body","createdAt"],properties:{title:{type:"string",maxLength:300},body:{type:"string",maxLength:1e5},format:{type:"string",knownValues:["text/markdown"]},brainDid:{type:"string"},anchorDid:{type:"string"},sourceEntityType:{type:"string"},sourceEntityId:{type:"string"},createdAt:{type:"string",format:"datetime"},updatedAt:{type:"string",format:"datetime"}}}}}};var XK1={lexicon:1,id:"ai.rizom.brain.post",defs:{main:{type:"record",description:"Markdown blog post distributed by a Rizom brain.",key:"any",record:{type:"object",required:["title","body","createdAt"],properties:{title:{type:"string",maxLength:300},summary:{type:"string",maxLength:2000},body:{type:"string",maxLength:1e5},format:{type:"string",knownValues:["text/markdown"]},brainDid:{type:"string"},anchorDid:{type:"string"},canonicalUrl:{type:"string",format:"uri"},topics:{type:"array",items:{type:"string"},maxLength:50},coverImage:{type:"object",required:["blob"],properties:{blob:{type:"blob"},alt:{type:"string",maxLength:1000},width:{type:"integer"},height:{type:"integer"}}},series:{type:"string",maxLength:200},seriesIndex:{type:"integer"},sourceEntityType:{type:"string",knownValues:["post"]},sourceEntityId:{type:"string"},createdAt:{type:"string",format:"datetime"},publishedAt:{type:"string",format:"datetime"}}}}}};var WK1={lexicon:1,id:"ai.rizom.brain.project",defs:{main:{type:"record",description:"Public project or case study from a Rizom brain.",key:"any",record:{type:"object",required:["title","body","year","createdAt"],properties:{title:{type:"string",maxLength:300},slug:{type:"string"},description:{type:"string",maxLength:2000},body:{type:"string",maxLength:1e5},format:{type:"string",knownValues:["text/markdown"]},year:{type:"integer"},url:{type:"string",format:"uri"},publishedAt:{type:"string",format:"datetime"},brainDid:{type:"string"},anchorDid:{type:"string"},sourceEntityType:{type:"string"},sourceEntityId:{type:"string"},createdAt:{type:"string",format:"datetime"},updatedAt:{type:"string",format:"datetime"}}}}}};var HK1={lexicon:1,id:"ai.rizom.brain.series",defs:{main:{type:"record",description:"Public content series from a Rizom brain.",key:"any",record:{type:"object",required:["title","createdAt"],properties:{title:{type:"string",maxLength:300},slug:{type:"string"},description:{type:"string",maxLength:1e4},brainDid:{type:"string"},anchorDid:{type:"string"},sourceEntityType:{type:"string"},sourceEntityId:{type:"string"},createdAt:{type:"string",format:"datetime"},updatedAt:{type:"string",format:"datetime"}}}}}};var GK1={lexicon:1,id:"ai.rizom.brain.socialPost",defs:{main:{type:"record",description:"Semantic local social-post entity from a Rizom brain; not a Bluesky feed post.",key:"any",record:{type:"object",required:["title","platform","body","createdAt"],properties:{title:{type:"string",maxLength:300},platform:{type:"string"},body:{type:"string",maxLength:1e5},format:{type:"string",knownValues:["text/markdown"]},status:{type:"string"},publishedAt:{type:"string",format:"datetime"},platformPostId:{type:"string"},sourceLocalEntityType:{type:"string"},sourceLocalEntityId:{type:"string"},brainDid:{type:"string"},anchorDid:{type:"string"},sourceEntityType:{type:"string"},sourceEntityId:{type:"string"},createdAt:{type:"string",format:"datetime"},updatedAt:{type:"string",format:"datetime"}}}}}};var KK1={lexicon:1,id:"ai.rizom.brain.topic",defs:{main:{type:"record",description:"Public topic page from a Rizom brain.",key:"any",record:{type:"object",required:["title","body","createdAt"],properties:{title:{type:"string",maxLength:300},body:{type:"string",maxLength:1e5},format:{type:"string",knownValues:["text/markdown"]},brainDid:{type:"string"},anchorDid:{type:"string"},sourceEntityType:{type:"string"},sourceEntityId:{type:"string"},createdAt:{type:"string",format:"datetime"},updatedAt:{type:"string",format:"datetime"}}}}}};var ELQ=H.object({type:H.string()}).catchall(H.unknown()),MLQ=H.object({lexicon:H.literal(1),id:H.string(),defs:H.object({main:H.object({type:H.literal("record"),key:H.string().min(1),record:H.object({type:H.literal("object"),required:H.array(H.string()).optional(),properties:H.record(ELQ)})})})});function EH(A){return MLQ.parse(A)}var Gw={"ai.rizom.brain.card":EH(DK1),"ai.rizom.brain.deck":EH(UK1),"ai.rizom.brain.link":EH(YK1),"ai.rizom.brain.note":EH(JK1),"ai.rizom.brain.post":EH(XK1),"ai.rizom.brain.project":EH(WK1),"ai.rizom.brain.series":EH(HK1),"ai.rizom.brain.socialPost":EH(GK1),"ai.rizom.brain.topic":EH(KK1)},CLQ="Additive optional fields are compatible; required-field, type, or constraint changes require a migration plan or new NSID.";function xF(A){return{status:"approved",version:"1.0.0",revision:1,owner:"Rizom",steward:"Rizom protocol registry",projectionPackage:A,compatibility:CLQ}}var OLQ={"ai.rizom.brain.card":xF("@brains/atproto"),"ai.rizom.brain.deck":xF("@brains/decks"),"ai.rizom.brain.link":xF("@brains/link"),"ai.rizom.brain.note":xF("@brains/note"),"ai.rizom.brain.post":xF("@brains/blog"),"ai.rizom.brain.project":xF("@brains/portfolio"),"ai.rizom.brain.series":xF("@brains/series"),"ai.rizom.brain.socialPost":xF("@brains/social-media"),"ai.rizom.brain.topic":xF("@brains/topics")};function tM(){return Object.values(Gw)}function $SA(A){return Gw[A]}function fSA(){return Object.entries(OLQ).map(([A,Q])=>({id:A,...Q}))}function wSA(A){return typeof A==="object"&&A!==null&&!Array.isArray(A)}var RLQ=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})$/;function bLQ(A){let Q=H.string(),B=A.maxLength!==void 0?Q.max(A.maxLength):Q;if(A.knownValues)B=B.refine((w)=>A.knownValues?.includes(w),{message:`expected one of ${A.knownValues.join(", ")}`});if(A.format==="datetime")B=B.refine((w)=>RLQ.test(w)&&!Number.isNaN(Date.parse(w)),{message:"expected datetime"});if(A.format==="uri")B=B.refine((w)=>{try{return new URL(w),!0}catch{return!1}},{message:"expected uri"});return B}function FK1(A){switch(A.type){case"string":return bLQ(A);case"integer":return H.number().int();case"boolean":return H.boolean();case"array":{let Q=A.items?FK1(A.items):H.unknown(),B=H.array(Q);if(A.maxLength!==void 0)B=B.max(A.maxLength);return B}case"object":return PLQ(A);case"blob":return H.custom(wSA,{message:"expected blob"});default:return H.unknown()}}function ZK1(A){let Q=new Set(A.required??[]),B={};for(let[w,$]of Object.entries(A.properties??{})){let f=FK1($);B[w]=Q.has(w)?f:f.optional()}return B}function PLQ(A){return H.object(ZK1(A)).passthrough()}function BSA(A,Q,B,w=[]){let $=Object.keys(A).filter((f)=>!Q.has(f));if($.length===0)return;B.addIssue({code:H.ZodIssueCode.custom,path:w,message:`unrecognized field(s): ${$.join(", ")}`})}function kLQ(A,Q){if(BSA(A,new Set(["$type","siteUrl","brain","anchor","skills","model","version","createdAt","updatedAt"]),Q),wSA(A.brain))BSA(A.brain,new Set(["did","name","role","purpose","values"]),Q,["brain"]);if(wSA(A.anchor))BSA(A.anchor,new Set(["did","name","kind"]),Q,["anchor"])}function MH(A){let Q=H.object({...ZK1(A.defs.main.record),$type:H.literal(A.id).optional()}).passthrough();return A.id==="ai.rizom.brain.card"?Q.superRefine(kLQ):Q}var jLQ={"ai.rizom.brain.card":MH(Gw["ai.rizom.brain.card"]),"ai.rizom.brain.deck":MH(Gw["ai.rizom.brain.deck"]),"ai.rizom.brain.link":MH(Gw["ai.rizom.brain.link"]),"ai.rizom.brain.note":MH(Gw["ai.rizom.brain.note"]),"ai.rizom.brain.post":MH(Gw["ai.rizom.brain.post"]),"ai.rizom.brain.project":MH(Gw["ai.rizom.brain.project"]),"ai.rizom.brain.series":MH(Gw["ai.rizom.brain.series"]),"ai.rizom.brain.socialPost":MH(Gw["ai.rizom.brain.socialPost"]),"ai.rizom.brain.topic":MH(Gw["ai.rizom.brain.topic"])};function _LQ(A,Q,B){let w=B.path.join(".");if(w==="$type")return`AT Protocol record $type must match lexicon id: ${String(Q.$type)} !== ${A.id}`;if(B.code==="invalid_type"&&B.received==="undefined")return`Missing required AT Protocol record field: ${w}`;if(B.code==="invalid_type")return`Invalid AT Protocol record field ${w}: expected ${B.expected}`;if(B.code==="too_big")return`Invalid AT Protocol record field ${w}: exceeds maxLength ${B.maximum}`;if(B.code==="custom")return`Invalid AT Protocol record field ${w}: ${B.message}`;if(B.code==="unrecognized_keys")return`Unrecognized AT Protocol record field(s): ${B.keys.join(", ")}`;return`Invalid AT Protocol record field ${w}: ${B.message}`}function Tz(A,Q){let B=MH(A).safeParse(Q);if(B.success)return;let w=B.error.issues[0];if(!w)throw B.error;throw Error(_LQ(A,Q,w))}var $5A="atproto:brain-card-discovered",NK1="atproto:brain-discovered",zK1="atproto:brain-card-refreshed",qK1=H.object({repoDid:H.string().min(1),uri:H.string().min(1),cid:H.string().min(1),record:jLQ["ai.rizom.brain.card"]}).strict(),xmw=H.object({agentId:H.string().min(1),name:H.string().min(1),url:H.string().url(),status:H.enum(["discovered","approved"]),repoDid:H.string().min(1).optional(),brainDid:H.string().min(1).optional(),anchorDid:H.string().min(1).optional(),cardUri:H.string().min(1).optional(),cardCid:H.string().min(1).optional()}).strict();class d6{static instance;projections=new Map;registrationCounts=new Map;static getInstance(){return this.instance??=new d6,this.instance}static createFresh(){return new d6}static resetInstance(){this.instance=void 0}register(A){this.validateProjection(A);let Q=this.projections.get(A.entityType);if(Q){if(!this.isEquivalentProjection(Q,A))throw Error(`AT Protocol projection already registered for entity type ${A.entityType}`);return this.registrationCounts.set(A.entityType,(this.registrationCounts.get(A.entityType)??1)+1),this.createUnregister(A.entityType)}return this.projections.set(A.entityType,A),this.registrationCounts.set(A.entityType,1),this.createUnregister(A.entityType)}get(A){return this.projections.get(A)}has(A){return this.projections.has(A)}list(){return Array.from(this.projections.values())}listLexicons(){return this.list().map((A)=>A.lexicon)}createUnregister(A){let Q=!0;return()=>{if(!Q)return;Q=!1;let B=this.registrationCounts.get(A)??0;if(B<=1){this.registrationCounts.delete(A),this.projections.delete(A);return}this.registrationCounts.set(A,B-1)}}isEquivalentProjection(A,Q){return A.entityType===Q.entityType&&A.collection===Q.collection&&A.lexicon.id===Q.lexicon.id&&A.validate===Q.validate}validateProjection(A){if(A.collection!==A.lexicon.id)throw Error(`AT Protocol projection collection must match lexicon id: ${A.collection} !== ${A.lexicon.id}`);if(!A.lexicon.defs.main.key)throw Error(`AT Protocol projection lexicon must define a record key: ${A.collection}`)}}KD();Xv();WA();var ISA=H.object({defaultPrompt:H.string().default("Write a blog post about my recent work and insights"),paginate:H.boolean().default(!0),pageSize:H.number().default(10)});aA();WA();H6();var yLQ=H.object({prompt:H.string().optional(),title:H.string().optional(),content:H.string().optional(),excerpt:H.string().optional(),coverImageId:H.string().optional(),seriesName:H.string().optional(),seriesIndex:H.number().optional(),skipAi:H.boolean().optional()}),omw=qI.extend({title:H.string().optional(),slug:H.string().optional()});class DSA extends z7{constructor(A,Q){super(A,Q,{schema:yLQ,jobTypeName:"blog-generation",entityType:"post"})}async generate(A,Q){let{prompt:B,coverImageId:w,seriesName:$,seriesIndex:f,skipAi:I}=A,{title:D,content:U,excerpt:Y}=A;if(I){if(!D)this.failEarly("Title is required when skipAi is true");U=U??`## Introduction
|
|
5653
|
+
- 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(),GD.resetInstance(),this.logger.debug("Cleaned up all event subscriptions")}}function sM(A={}){return new exA(A)}aA();f5();WA();aA();f5();var fK1=H.object({}),ap=A2.extend({id:H.literal("site-info"),entityType:H.literal("site-info"),metadata:fK1}),ASA=Zo,Yv=LI.omit({url:!0,analyticsScript:!0});aA();class LH extends q2{constructor(){super({entityType:"site-info",schema:ap,frontmatterSchema:Yv,isSingleton:!0,hasBody:!1})}createSiteInfoContent(A){let Q=Yv.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 VH{static instance=null;logger;entityService;adapter;defaultSiteInfo;static getDefaultSiteInfo(){return{title:"Brain",description:"A knowledge management system"}}static getInstance(A,Q,B){return VH.instance??=new VH(A,Q,B),VH.instance}static resetInstance(){VH.instance=null}static createFresh(A,Q,B){return new VH(A,Q,B)}constructor(A,Q,B){this.entityService=A,this.logger=Q.child("SiteInfoService"),this.adapter=new LH;let w=VH.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 YLQ=new LH;class w5A{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?YLQ.parseSiteInfoBody(D.content):{title:"Brain",description:"A knowledge management system"}}catch{$={title:"Brain",description:"A knowledge management system"}}let f;try{let D=await w.getEntity({entityType:"anchor-profile",id:"anchor-profile"});if(D)f=D.metadata.socialLinks}catch{}let I={...$,socialLinks:f,copyright:$.copyright??"Powered by Rizom"};return this.logger.debug("SiteInfoDataSource returning",{title:I.title,hasSocialLinks:!!I.socialLinks}),Q.parse(I)}}var IK1={name:"@brains/site-info",private:!0,version:"0.2.0-alpha.120",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 XLQ=new LH;class QSA extends jQ{entityType="site-info";schema=ap;adapter=XLQ;defaultSiteInfo;constructor(A){super("site-info",IK1);this.defaultSiteInfo=A?.siteInfo??{}}getEntityTypeConfig(){return{embeddable:!1}}getDataSources(){return[new w5A(this.logger.child("SiteInfoDataSource"))]}async onRegister(A){let Q=VH.createFresh(A.entityService,this.logger,this.defaultSiteInfo);A.messaging.subscribe($x,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:fx,payload:$,broadcast:!0})}return{success:!0}}),A.messaging.subscribe("sync:initial:completed",async()=>{return await Q.initialize(),{success:!0}})}}function aM(A){return new QSA(A)}var WLQ=new LH;async function tp(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 WLQ.parseSiteInfoBody(B.content)}WA();var HLQ=Yv.extend({navigation:H.object({primary:H.array(H.object({label:H.string(),href:H.string(),priority:H.number()})),secondary:H.array(H.object({label:H.string(),href:H.string(),priority:H.number()}))}),copyright:H.string(),socialLinks:H.array(H.object({platform:H.enum(["github","instagram","linkedin","email","website"]).describe("Social media platform"),url:H.string().describe("Profile or contact URL"),label:H.string().optional().describe("Optional display label")})).optional().describe("Social media links from profile entity")});aA();WA();var DK1={lexicon:1,id:"ai.rizom.brain.card",defs:{main:{type:"record",description:"Public discovery card for a Rizom brain. The operational A2A Agent Card is conventionally served at /.well-known/agent-card.json under siteUrl.",key:"literal:self",record:{type:"object",required:["siteUrl","brain","anchor","skills","model","version","createdAt"],properties:{siteUrl:{type:"string",format:"uri",description:"Public site URL. Consumers derive the A2A Agent Card URL from this base."},brain:{type:"object",description:"Brain identity described by this discovery card.",required:["did","name","role","purpose","values"],properties:{did:{type:"string",description:"Public DID for the brain identity."},name:{type:"string",maxLength:200,description:"Human-readable brain name."},role:{type:"string",maxLength:500,description:"Brain role or persona."},purpose:{type:"string",maxLength:2000,description:"Short public description of what this brain is for."},values:{type:"array",description:"Public values or principles for this brain.",items:{type:"string",maxLength:200},maxLength:50}}},anchor:{type:"object",description:"Minimal owner/operator snapshot for discovery grouping and display.",required:["did","name","kind"],properties:{did:{type:"string",description:"Public DID for the owner/operator anchor identity."},name:{type:"string",maxLength:200,description:"Human-readable anchor name."},kind:{type:"string",knownValues:["professional","team","collective"],description:"Anchor type."}}},skills:{type:"array",description:"User-facing skills this brain advertises for discovery.",items:{type:"object",required:["id","name","description"],properties:{id:{type:"string",maxLength:200},name:{type:"string",maxLength:200},description:{type:"string",maxLength:2000},tags:{type:"array",items:{type:"string"},maxLength:50},examples:{type:"array",items:{type:"string"},maxLength:20}}},maxLength:100},model:{type:"string",description:"Rizom brain model identifier."},version:{type:"string",description:"Brain runtime/model implementation version."},createdAt:{type:"string",format:"datetime"},updatedAt:{type:"string",format:"datetime"}}}}}};var UK1={lexicon:1,id:"ai.rizom.brain.deck",defs:{main:{type:"record",description:"Public presentation deck from a Rizom brain.",key:"any",record:{type:"object",required:["title","body","createdAt"],properties:{title:{type:"string",maxLength:300},slug:{type:"string"},description:{type:"string",maxLength:2000},body:{type:"string",maxLength:1e5},format:{type:"string",knownValues:["text/markdown"]},author:{type:"string"},event:{type:"string"},publishedAt:{type:"string",format:"datetime"},brainDid:{type:"string"},anchorDid:{type:"string"},sourceEntityType:{type:"string"},sourceEntityId:{type:"string"},createdAt:{type:"string",format:"datetime"},updatedAt:{type:"string",format:"datetime"}}}}}};var YK1={lexicon:1,id:"ai.rizom.brain.link",defs:{main:{type:"record",description:"Public curated link from a Rizom brain.",key:"any",record:{type:"object",required:["title","url","createdAt"],properties:{title:{type:"string",maxLength:500},url:{type:"string",format:"uri"},description:{type:"string",maxLength:2000},summary:{type:"string",maxLength:1e5},domain:{type:"string"},capturedAt:{type:"string",format:"datetime"},source:{type:"object",required:["ref","label"],properties:{ref:{type:"string"},label:{type:"string"}}},brainDid:{type:"string"},anchorDid:{type:"string"},sourceEntityType:{type:"string"},sourceEntityId:{type:"string"},createdAt:{type:"string",format:"datetime"},updatedAt:{type:"string",format:"datetime"}}}}}};var JK1={lexicon:1,id:"ai.rizom.brain.note",defs:{main:{type:"record",description:"Public knowledge note from a Rizom brain.",key:"any",record:{type:"object",required:["title","body","createdAt"],properties:{title:{type:"string",maxLength:300},body:{type:"string",maxLength:1e5},format:{type:"string",knownValues:["text/markdown"]},brainDid:{type:"string"},anchorDid:{type:"string"},sourceEntityType:{type:"string"},sourceEntityId:{type:"string"},createdAt:{type:"string",format:"datetime"},updatedAt:{type:"string",format:"datetime"}}}}}};var XK1={lexicon:1,id:"ai.rizom.brain.post",defs:{main:{type:"record",description:"Markdown blog post distributed by a Rizom brain.",key:"any",record:{type:"object",required:["title","body","createdAt"],properties:{title:{type:"string",maxLength:300},summary:{type:"string",maxLength:2000},body:{type:"string",maxLength:1e5},format:{type:"string",knownValues:["text/markdown"]},brainDid:{type:"string"},anchorDid:{type:"string"},canonicalUrl:{type:"string",format:"uri"},topics:{type:"array",items:{type:"string"},maxLength:50},coverImage:{type:"object",required:["blob"],properties:{blob:{type:"blob"},alt:{type:"string",maxLength:1000},width:{type:"integer"},height:{type:"integer"}}},series:{type:"string",maxLength:200},seriesIndex:{type:"integer"},sourceEntityType:{type:"string",knownValues:["post"]},sourceEntityId:{type:"string"},createdAt:{type:"string",format:"datetime"},publishedAt:{type:"string",format:"datetime"}}}}}};var WK1={lexicon:1,id:"ai.rizom.brain.project",defs:{main:{type:"record",description:"Public project or case study from a Rizom brain.",key:"any",record:{type:"object",required:["title","body","year","createdAt"],properties:{title:{type:"string",maxLength:300},slug:{type:"string"},description:{type:"string",maxLength:2000},body:{type:"string",maxLength:1e5},format:{type:"string",knownValues:["text/markdown"]},year:{type:"integer"},url:{type:"string",format:"uri"},publishedAt:{type:"string",format:"datetime"},brainDid:{type:"string"},anchorDid:{type:"string"},sourceEntityType:{type:"string"},sourceEntityId:{type:"string"},createdAt:{type:"string",format:"datetime"},updatedAt:{type:"string",format:"datetime"}}}}}};var HK1={lexicon:1,id:"ai.rizom.brain.series",defs:{main:{type:"record",description:"Public content series from a Rizom brain.",key:"any",record:{type:"object",required:["title","createdAt"],properties:{title:{type:"string",maxLength:300},slug:{type:"string"},description:{type:"string",maxLength:1e4},brainDid:{type:"string"},anchorDid:{type:"string"},sourceEntityType:{type:"string"},sourceEntityId:{type:"string"},createdAt:{type:"string",format:"datetime"},updatedAt:{type:"string",format:"datetime"}}}}}};var GK1={lexicon:1,id:"ai.rizom.brain.socialPost",defs:{main:{type:"record",description:"Semantic local social-post entity from a Rizom brain; not a Bluesky feed post.",key:"any",record:{type:"object",required:["title","platform","body","createdAt"],properties:{title:{type:"string",maxLength:300},platform:{type:"string"},body:{type:"string",maxLength:1e5},format:{type:"string",knownValues:["text/markdown"]},status:{type:"string"},publishedAt:{type:"string",format:"datetime"},platformPostId:{type:"string"},sourceLocalEntityType:{type:"string"},sourceLocalEntityId:{type:"string"},brainDid:{type:"string"},anchorDid:{type:"string"},sourceEntityType:{type:"string"},sourceEntityId:{type:"string"},createdAt:{type:"string",format:"datetime"},updatedAt:{type:"string",format:"datetime"}}}}}};var KK1={lexicon:1,id:"ai.rizom.brain.topic",defs:{main:{type:"record",description:"Public topic page from a Rizom brain.",key:"any",record:{type:"object",required:["title","body","createdAt"],properties:{title:{type:"string",maxLength:300},body:{type:"string",maxLength:1e5},format:{type:"string",knownValues:["text/markdown"]},brainDid:{type:"string"},anchorDid:{type:"string"},sourceEntityType:{type:"string"},sourceEntityId:{type:"string"},createdAt:{type:"string",format:"datetime"},updatedAt:{type:"string",format:"datetime"}}}}}};var ELQ=H.object({type:H.string()}).catchall(H.unknown()),MLQ=H.object({lexicon:H.literal(1),id:H.string(),defs:H.object({main:H.object({type:H.literal("record"),key:H.string().min(1),record:H.object({type:H.literal("object"),required:H.array(H.string()).optional(),properties:H.record(ELQ)})})})});function EH(A){return MLQ.parse(A)}var Gw={"ai.rizom.brain.card":EH(DK1),"ai.rizom.brain.deck":EH(UK1),"ai.rizom.brain.link":EH(YK1),"ai.rizom.brain.note":EH(JK1),"ai.rizom.brain.post":EH(XK1),"ai.rizom.brain.project":EH(WK1),"ai.rizom.brain.series":EH(HK1),"ai.rizom.brain.socialPost":EH(GK1),"ai.rizom.brain.topic":EH(KK1)},CLQ="Additive optional fields are compatible; required-field, type, or constraint changes require a migration plan or new NSID.";function xF(A){return{status:"approved",version:"1.0.0",revision:1,owner:"Rizom",steward:"Rizom protocol registry",projectionPackage:A,compatibility:CLQ}}var OLQ={"ai.rizom.brain.card":xF("@brains/atproto"),"ai.rizom.brain.deck":xF("@brains/decks"),"ai.rizom.brain.link":xF("@brains/link"),"ai.rizom.brain.note":xF("@brains/note"),"ai.rizom.brain.post":xF("@brains/blog"),"ai.rizom.brain.project":xF("@brains/portfolio"),"ai.rizom.brain.series":xF("@brains/series"),"ai.rizom.brain.socialPost":xF("@brains/social-media"),"ai.rizom.brain.topic":xF("@brains/topics")};function tM(){return Object.values(Gw)}function $SA(A){return Gw[A]}function fSA(){return Object.entries(OLQ).map(([A,Q])=>({id:A,...Q}))}function wSA(A){return typeof A==="object"&&A!==null&&!Array.isArray(A)}var RLQ=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})$/;function bLQ(A){let Q=H.string(),B=A.maxLength!==void 0?Q.max(A.maxLength):Q;if(A.knownValues)B=B.refine((w)=>A.knownValues?.includes(w),{message:`expected one of ${A.knownValues.join(", ")}`});if(A.format==="datetime")B=B.refine((w)=>RLQ.test(w)&&!Number.isNaN(Date.parse(w)),{message:"expected datetime"});if(A.format==="uri")B=B.refine((w)=>{try{return new URL(w),!0}catch{return!1}},{message:"expected uri"});return B}function FK1(A){switch(A.type){case"string":return bLQ(A);case"integer":return H.number().int();case"boolean":return H.boolean();case"array":{let Q=A.items?FK1(A.items):H.unknown(),B=H.array(Q);if(A.maxLength!==void 0)B=B.max(A.maxLength);return B}case"object":return PLQ(A);case"blob":return H.custom(wSA,{message:"expected blob"});default:return H.unknown()}}function ZK1(A){let Q=new Set(A.required??[]),B={};for(let[w,$]of Object.entries(A.properties??{})){let f=FK1($);B[w]=Q.has(w)?f:f.optional()}return B}function PLQ(A){return H.object(ZK1(A)).passthrough()}function BSA(A,Q,B,w=[]){let $=Object.keys(A).filter((f)=>!Q.has(f));if($.length===0)return;B.addIssue({code:H.ZodIssueCode.custom,path:w,message:`unrecognized field(s): ${$.join(", ")}`})}function kLQ(A,Q){if(BSA(A,new Set(["$type","siteUrl","brain","anchor","skills","model","version","createdAt","updatedAt"]),Q),wSA(A.brain))BSA(A.brain,new Set(["did","name","role","purpose","values"]),Q,["brain"]);if(wSA(A.anchor))BSA(A.anchor,new Set(["did","name","kind"]),Q,["anchor"])}function MH(A){let Q=H.object({...ZK1(A.defs.main.record),$type:H.literal(A.id).optional()}).passthrough();return A.id==="ai.rizom.brain.card"?Q.superRefine(kLQ):Q}var jLQ={"ai.rizom.brain.card":MH(Gw["ai.rizom.brain.card"]),"ai.rizom.brain.deck":MH(Gw["ai.rizom.brain.deck"]),"ai.rizom.brain.link":MH(Gw["ai.rizom.brain.link"]),"ai.rizom.brain.note":MH(Gw["ai.rizom.brain.note"]),"ai.rizom.brain.post":MH(Gw["ai.rizom.brain.post"]),"ai.rizom.brain.project":MH(Gw["ai.rizom.brain.project"]),"ai.rizom.brain.series":MH(Gw["ai.rizom.brain.series"]),"ai.rizom.brain.socialPost":MH(Gw["ai.rizom.brain.socialPost"]),"ai.rizom.brain.topic":MH(Gw["ai.rizom.brain.topic"])};function _LQ(A,Q,B){let w=B.path.join(".");if(w==="$type")return`AT Protocol record $type must match lexicon id: ${String(Q.$type)} !== ${A.id}`;if(B.code==="invalid_type"&&B.received==="undefined")return`Missing required AT Protocol record field: ${w}`;if(B.code==="invalid_type")return`Invalid AT Protocol record field ${w}: expected ${B.expected}`;if(B.code==="too_big")return`Invalid AT Protocol record field ${w}: exceeds maxLength ${B.maximum}`;if(B.code==="custom")return`Invalid AT Protocol record field ${w}: ${B.message}`;if(B.code==="unrecognized_keys")return`Unrecognized AT Protocol record field(s): ${B.keys.join(", ")}`;return`Invalid AT Protocol record field ${w}: ${B.message}`}function Tz(A,Q){let B=MH(A).safeParse(Q);if(B.success)return;let w=B.error.issues[0];if(!w)throw B.error;throw Error(_LQ(A,Q,w))}var $5A="atproto:brain-card-discovered",NK1="atproto:brain-discovered",zK1="atproto:brain-card-refreshed",qK1=H.object({repoDid:H.string().min(1),uri:H.string().min(1),cid:H.string().min(1),record:jLQ["ai.rizom.brain.card"]}).strict(),xmw=H.object({agentId:H.string().min(1),name:H.string().min(1),url:H.string().url(),status:H.enum(["discovered","approved"]),repoDid:H.string().min(1).optional(),brainDid:H.string().min(1).optional(),anchorDid:H.string().min(1).optional(),cardUri:H.string().min(1).optional(),cardCid:H.string().min(1).optional()}).strict();class d6{static instance;projections=new Map;registrationCounts=new Map;static getInstance(){return this.instance??=new d6,this.instance}static createFresh(){return new d6}static resetInstance(){this.instance=void 0}register(A){this.validateProjection(A);let Q=this.projections.get(A.entityType);if(Q){if(!this.isEquivalentProjection(Q,A))throw Error(`AT Protocol projection already registered for entity type ${A.entityType}`);return this.registrationCounts.set(A.entityType,(this.registrationCounts.get(A.entityType)??1)+1),this.createUnregister(A.entityType)}return this.projections.set(A.entityType,A),this.registrationCounts.set(A.entityType,1),this.createUnregister(A.entityType)}get(A){return this.projections.get(A)}has(A){return this.projections.has(A)}list(){return Array.from(this.projections.values())}listLexicons(){return this.list().map((A)=>A.lexicon)}createUnregister(A){let Q=!0;return()=>{if(!Q)return;Q=!1;let B=this.registrationCounts.get(A)??0;if(B<=1){this.registrationCounts.delete(A),this.projections.delete(A);return}this.registrationCounts.set(A,B-1)}}isEquivalentProjection(A,Q){return A.entityType===Q.entityType&&A.collection===Q.collection&&A.lexicon.id===Q.lexicon.id&&A.validate===Q.validate}validateProjection(A){if(A.collection!==A.lexicon.id)throw Error(`AT Protocol projection collection must match lexicon id: ${A.collection} !== ${A.lexicon.id}`);if(!A.lexicon.defs.main.key)throw Error(`AT Protocol projection lexicon must define a record key: ${A.collection}`)}}KD();Xv();WA();var ISA=H.object({defaultPrompt:H.string().default("Write a blog post about my recent work and insights"),paginate:H.boolean().default(!0),pageSize:H.number().default(10)});aA();WA();H6();var yLQ=H.object({prompt:H.string().optional(),title:H.string().optional(),content:H.string().optional(),excerpt:H.string().optional(),coverImageId:H.string().optional(),seriesName:H.string().optional(),seriesIndex:H.number().optional(),skipAi:H.boolean().optional()}),omw=qI.extend({title:H.string().optional(),slug:H.string().optional()});class DSA extends z7{constructor(A,Q){super(A,Q,{schema:yLQ,jobTypeName:"blog-generation",entityType:"post"})}async generate(A,Q){let{prompt:B,coverImageId:w,seriesName:$,seriesIndex:f,skipAi:I}=A,{title:D,content:U,excerpt:Y}=A;if(I){if(!D)this.failEarly("Title is required when skipAi is true");U=U??`## Introduction
|
|
5654
5654
|
|
|
5655
5655
|
Add your introduction here.
|
|
5656
5656
|
|
|
@@ -5870,7 +5870,7 @@ ${B.content}`,templateName:"blog:excerpt"})})}aA();Xv();KD();function $VQ(A){let
|
|
|
5870
5870
|
letter-spacing: 0.02em;
|
|
5871
5871
|
}
|
|
5872
5872
|
.printable-footer a { color: inherit; text-decoration: none; overflow-wrap: anywhere; }
|
|
5873
|
-
`}},void 0,!1,void 0,this),n9("header",{className:"printable-hero",children:[n9("div",{className:"printable-masthead",children:Q.brandLabel&&n9("p",{className:"printable-kicker",children:Q.brandLabel},void 0,!1,void 0,this)},void 0,!1,void 0,this),n9("div",{children:[n9("h1",{className:"printable-title",children:Q.title},void 0,!1,void 0,this),Q.excerpt&&n9("p",{className:"printable-excerpt",children:Q.excerpt},void 0,!1,void 0,this),n9("div",{className:"printable-meta",children:[Q.author&&n9("span",{children:["By ",Q.author]},void 0,!0,void 0,this),B&&n9("span",{children:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Q.coverImageUrl&&n9("figure",{className:"printable-cover-wrap",children:n9("img",{className:"printable-cover",src:Q.coverImageUrl,alt:""},void 0,!1,void 0,this)},void 0,!1,void 0,this),n9(V$,{markdown:Q.body,className:"printable-body"},void 0,!1,void 0,this),(Q.canonicalUrl||Q.brandLabel)&&n9("footer",{className:"printable-footer",children:[n9("span",{children:Q.brandLabel??"Printable PDF"},void 0,!1,void 0,this),Q.canonicalUrl&&n9("a",{href:Q.canonicalUrl,children:Q.canonicalUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}var mVQ=26214400,uVQ=60000;class NSA{context;renderPdf;constructor(A,Q={}){this.context=A;this.renderPdf=Q.renderPdf??$X}async resolve(A){if(A.sourceEntityType!=="post"||A.attachmentType!==U5A)return;let Q=await this.context.entityService.getEntity({entityType:"post",id:A.sourceEntityId});if(!Q)return;let B=cVQ(Q,{brandLabel:this.resolveBrandLabel(),coverImageUrl:await this.resolveCoverImageUrl(Q)}),w=await xVQ(hVQ(gVQ(),"brain-blog-printable-"));try{let $=await ZD({outputDir:w,mediaPath:`/_media/printable/post/${Q.id}`,template:hK1,format:"pdf",content:B,siteConfig:{title:B.title,themeMode:"light"},themeCSS:this.context.themeCSS}),f=await ND({rootDir:w});try{return{type:"document",data:await this.renderPdf(f.urlFor($.urlPath),{maxBytes:mVQ,timeoutMs:uVQ,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${lVQ(Q)}-printable.pdf`}}finally{await f.close()}}finally{await SVQ(w,{recursive:!0,force:!0})}}resolveBrandLabel(){let A=this.context.domain?.trim();if(A&&A.length>0)return A;let Q=this.context.identity.getProfile().name.trim();return Q.length>0?Q:void 0}async resolveCoverImageUrl(A){let{frontmatter:Q}=jB(A.content),B=z8.parse(Q);if(!B.coverImageId)return;let w=await this.context.entityService.getEntity({entityType:"image",id:B.coverImageId});return w?.content.startsWith("data:image/")?w.content:void 0}}function cVQ(A,Q={}){let{frontmatter:B,content:w}=jB(A.content),$=z8.parse(B);return{title:$.title,body:w,...$.excerpt?{excerpt:$.excerpt}:{},...$.author?{author:$.author}:{},...$.publishedAt?{publishedAt:$.publishedAt}:{},...$.canonicalUrl?{canonicalUrl:$.canonicalUrl}:{},...Q.coverImageUrl?{coverImageUrl:Q.coverImageUrl}:{},...Q.brandLabel?{brandLabel:Q.brandLabel}:{}}}function lVQ(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.title)}import{mkdtemp as nVQ,rm as oVQ}from"fs/promises";import{tmpdir as sVQ}from"os";import{join as aVQ}from"path";WA();KD();WA();import{jsxDEV as dVQ}from"preact/jsx-dev-runtime";var fi="og-image",pVQ="blog:og-image",mK1=H.object({title:H.string().min(1),excerpt:H.string().optional(),author:H.string().optional(),publishedAt:H.string().optional(),brandLabel:H.string().optional(),coverImageUrl:H.string().optional()}),uK1={name:pVQ,pluginId:"blog",schema:mK1,renderers:{image:rVQ}};function iVQ(A){if(!A)return;let Q=new Date(A);if(Number.isNaN(Q.getTime()))return;return Q.toLocaleDateString("en-GB",{year:"numeric",month:"short",day:"2-digit"})}function rVQ(A){let Q=mK1.parse(A);return dVQ(zF,{brandLabel:Q.brandLabel??Q.title,eyebrow:"Journal",title:Q.title,subtitle:Q.excerpt,meta:[Q.author],tag:iVQ(Q.publishedAt)},void 0,!1,void 0,this)}var tVQ={width:1200,height:630},eVQ=60000;class zSA{context;screenshotPng;constructor(A,Q={}){this.context=A;this.screenshotPng=Q.screenshotPng??$i}async resolve(A){if(A.sourceEntityType!=="post"||A.attachmentType!==fi)return;let Q=await this.context.entityService.getEntity({entityType:"post",id:A.sourceEntityId});if(!Q)return;let B=AEQ(Q,{brandLabel:this.resolveBrandLabel(),coverImageUrl:await this.resolveCoverImageUrl(Q)}),w=await nVQ(aVQ(sVQ(),"brain-blog-og-image-"));try{let $=await ZD({outputDir:w,mediaPath:`/_media/og/post/${Q.id}`,template:uK1,format:"image",content:B,siteConfig:{title:B.title,themeMode:"light"},themeCSS:this.context.themeCSS}),f=await ND({rootDir:w});try{return{type:"image",data:await this.screenshotPng(f.urlFor($.urlPath),tVQ,{timeoutMs:eVQ,fullPage:!1,omitBackground:!1}),mimeType:"image/png",filename:`${QEQ(Q)}-og.png`}}finally{await f.close()}}finally{await oVQ(w,{recursive:!0,force:!0})}}resolveBrandLabel(){let A=this.context.domain?.trim();if(A&&A.length>0)return A;let Q=this.context.identity.getProfile().name.trim();return Q.length>0?Q:void 0}async resolveCoverImageUrl(A){let{frontmatter:Q}=jB(A.content),B=z8.parse(Q);if(!B.coverImageId)return;let w=await this.context.entityService.getEntity({entityType:"image",id:B.coverImageId});return w?.content.startsWith("data:image/")?w.content:void 0}}function AEQ(A,Q={}){let{frontmatter:B}=jB(A.content),w=z8.parse(B);return{title:w.title,...w.excerpt?{excerpt:w.excerpt}:{},...w.author?{author:w.author}:{},...w.publishedAt?{publishedAt:w.publishedAt}:{},...Q.coverImageUrl?{coverImageUrl:Q.coverImageUrl}:{},...Q.brandLabel?{brandLabel:Q.brandLabel}:{}}}function QEQ(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.title)}var cK1={name:"@brains/blog",private:!0,version:"0.2.0-alpha.119",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/atproto-contracts":"workspace:*","@brains/contracts":"workspace:*","@brains/media-page-composer":"workspace:*","@brains/media-renderer":"workspace:*","@brains/plugins":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class qSA extends jQ{entityType=gF.entityType;schema=Jv;adapter=gF;unregisterAtprotoProjection;unregisterPrintableAttachmentProvider;unregisterOgImageAttachmentProvider;constructor(A={}){super("blog",cK1,A,ISA)}getEntityTypeConfig(){return{weight:2,publish:{publishStatuses:["queued","published"]}}}createGenerationHandler(A){return new DSA(this.logger.child("BlogGenerationJobHandler"),A)}getTemplates(){return CK1()}getDataSources(){return[new YSA(this.logger.child("BlogDataSource"))]}async onRegister(A){let{RSSDataSource:Q}=await Promise.resolve().then(() => (iK1(),pK1));A.entities.registerDataSource(new Q(this.logger.child("RSSDataSource"))),OK1(A,this.logger),RK1(A,this.logger),PK1(A,this.logger),kK1(A),this.unregisterPrintableAttachmentProvider=A.attachments.register("post",U5A,new NSA(A)),this.unregisterOgImageAttachmentProvider=A.attachments.register("post",fi,new zSA(A)),this.deferPublishAssetRegistration(A),this.unregisterAtprotoProjection=d6.getInstance().register(WSA()),this.logger.info("Blog plugin registered (routes auto-generated at /posts/)")}deferPublishAssetRegistration(A){A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"publish-assets:register",payload:{entityType:"post",attachmentType:fi,mediaEntityType:"image",targetEntityField:{location:"frontmatter",field:"ogImageId"},requiredWhen:{status:"published"},autoGenerate:!0,jobType:"image:image-render-source"}}),{success:!0}})}async onShutdown(){this.unregisterPrintableAttachmentProvider?.(),this.unregisterPrintableAttachmentProvider=void 0,this.unregisterOgImageAttachmentProvider?.(),this.unregisterOgImageAttachmentProvider=void 0,this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}}function LSA(A={}){return new qSA(A)}KD();Xv();aA();WA();WA();o$();aA();var pU=H.object({title:H.string(),slug:H.string(),coverImageId:H.string().optional()}),rK1=pU.pick({title:!0,slug:!0}),yz=A2.extend({metadata:rK1}),Y5A=yz.extend({frontmatter:pU}),J5A=Y5A.extend({description:H.string().optional(),postCount:H.number(),coverImageUrl:H.string().optional(),coverImageWidth:H.number().optional(),coverImageHeight:H.number().optional()}),dK1=H.object({description:H.string().optional()});function QC(A){return new lB(dK1,{title:A,mappings:[{key:"description",label:"Description",type:"string"}]})}aA();class VSA extends q2{constructor(){super({entityType:"series",schema:yz,frontmatterSchema:pU,supportsCoverImage:!0,bodyFormatter:QC("")})}toMarkdown(A){let Q,B={};try{Q=this.parseFrontMatter(A.content,pU).coverImageId,B=QC(A.metadata.title).parse(this.extractBody(A.content))}catch{}let w={title:A.metadata.title,slug:A.metadata.slug,...Q&&{coverImageId:Q}},f=QC(A.metadata.title).format(B);return this.buildMarkdown(f,w)}fromMarkdown(A){let Q=this.parseFrontMatter(A,pU);return{content:A,entityType:"series",metadata:{title:Q.title,slug:Q.slug}}}parseBody(A){try{let Q=this.parseFrontMatter(A,pU);return QC(Q.title).parse(this.extractBody(A))}catch{return{}}}generateFrontMatter(){return""}}var xz=new VSA;aA();WA();wU();WA();var $EQ=H.object({seriesName:H.string().optional(),seriesIndex:H.number().optional()});function X5A(A){let Q=$EQ.safeParse(A);return Q.success?Q.data:{}}function BC(A){return X5A(A.metadata).seriesName}function nK1(A){return X5A(A.metadata).seriesIndex}function oK1(A,Q){let B=nK1(A)??Number.MAX_SAFE_INTEGER,w=nK1(Q)??Number.MAX_SAFE_INTEGER;return B-w}class ESA{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"}),B=new Map(Q.map(($)=>[$.id,$])),w=new Set;for(let $ of A){let f=X1($);w.add(f);let I=B.get(f),D=I?.content??this.createSeriesContent($),U=gB(D);if(I?.contentHash===U)continue;let Y={id:f,entityType:"series",content:D,contentHash:U,created:I?.created??new Date().toISOString(),updated:new Date().toISOString(),visibility:"public",metadata:{title:$,slug:X1($)}};await this.entityService.upsertEntity({entity:Y}),this.logger.debug(`Upserted series: ${$}`)}for(let $ of Q)if(!w.has($.id))await this.entityService.deleteEntity({entityType:"series",id:$.id}),this.logger.debug(`Deleted orphaned series: ${$.id}`)}async handleEntityChange(A,Q){let B=BC(A);if(B)await this.ensureSeriesExists(B);if(Q&&Q!==B)await this.cleanupOrphanedSeries(Q)}async handleEntityDeleted(){await this.syncAllSeries()}async ensureSeriesExists(A){let Q=X1(A);if(await this.entityService.getEntity({entityType:"series",id:Q}))return;let w=this.createSeriesContent(A),$={id:Q,entityType:"series",content:w,contentHash:gB(w),created:new Date().toISOString(),updated:new Date().toISOString(),visibility:"public",metadata:{title:A,slug:X1(A)}};await this.entityService.upsertEntity({entity:$}),this.logger.debug(`Created series: ${A}`)}async cleanupOrphanedSeries(A){let Q=X1(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});for(let $ of w){let f=BC($);if(f)A.add(f)}}return A}createSeriesContent(A){let Q={title:A,slug:X1(A)};return b9("",Q)}}aA();WA();var fEQ=H.object({entityType:H.literal("series"),query:H.object({id:H.string().optional(),limit:H.number().optional(),page:H.number().optional(),pageSize:H.number().optional()}).passthrough()}),IEQ=H.object({type:H.enum(["list","detail"]),seriesName:H.string().optional()});function DEQ(A){let Q=IEQ.safeParse(A);if(Q.success)return{type:Q.data.type,seriesName:Q.data.seriesName};let B=fEQ.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 sK1(A){let Q=R2(A.content,pU);return Y5A.parse({...A,frontmatter:Q.metadata})}class MSA{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=DEQ(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"}),w=await this.countEntitiesPerSeries(Q),$=B.map((f)=>{let I=sK1(f),D=xz.parseBody(f.content);return{...I,description:D.description,postCount:w.get(f.metadata.title)??0}});return this.logger.debug(`Found ${$.length} series entities`),A.parse({series:$})}async fetchSeriesDetail(A,Q,B,w){if(!w)w=(await B.listEntities({entityType:"series",options:{filter:{metadata:{title:A}}}}))[0];if(!w)throw Error(`Series not found: ${A}`);let $=sK1(w),f=xz.parseBody(w.content),I=await this.getSeriesMembers(A,B);return this.logger.debug(`Found ${I.length} entities in series "${A}"`),Q.parse({seriesName:A,posts:I,series:{...$,description:f.description,postCount:I.length},description:f.description})}async fetchSeriesDetailBySlug(A,Q,B){let $=(await B.listEntities({entityType:"series",options:{filter:{metadata:{slug:A}}}}))[0];if(!$)throw Error(`Series not found with slug: ${A}`);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});for(let f of $){let I=BC(f);if(I)Q.set(I,(Q.get(I)??0)+1)}}return Q}async getSeriesMembers(A,Q){let B=[],w=Q.getEntityTypes();for(let $ of w){if($==="series")continue;let f=await Q.listEntities({entityType:$,options:{filter:{metadata:{seriesName:A}}}});B.push(...f)}return B.sort(oK1),B}}aA();WA();wU();var UEQ=H.object({prompt:H.string().optional(),title:H.string().optional(),seriesId:H.string().optional()}),YEQ=H.object({title:H.string().optional(),excerpt:H.string().optional()});class W5A{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}
|
|
5873
|
+
`}},void 0,!1,void 0,this),n9("header",{className:"printable-hero",children:[n9("div",{className:"printable-masthead",children:Q.brandLabel&&n9("p",{className:"printable-kicker",children:Q.brandLabel},void 0,!1,void 0,this)},void 0,!1,void 0,this),n9("div",{children:[n9("h1",{className:"printable-title",children:Q.title},void 0,!1,void 0,this),Q.excerpt&&n9("p",{className:"printable-excerpt",children:Q.excerpt},void 0,!1,void 0,this),n9("div",{className:"printable-meta",children:[Q.author&&n9("span",{children:["By ",Q.author]},void 0,!0,void 0,this),B&&n9("span",{children:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Q.coverImageUrl&&n9("figure",{className:"printable-cover-wrap",children:n9("img",{className:"printable-cover",src:Q.coverImageUrl,alt:""},void 0,!1,void 0,this)},void 0,!1,void 0,this),n9(V$,{markdown:Q.body,className:"printable-body"},void 0,!1,void 0,this),(Q.canonicalUrl||Q.brandLabel)&&n9("footer",{className:"printable-footer",children:[n9("span",{children:Q.brandLabel??"Printable PDF"},void 0,!1,void 0,this),Q.canonicalUrl&&n9("a",{href:Q.canonicalUrl,children:Q.canonicalUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}var mVQ=26214400,uVQ=60000;class NSA{context;renderPdf;constructor(A,Q={}){this.context=A;this.renderPdf=Q.renderPdf??$X}async resolve(A){if(A.sourceEntityType!=="post"||A.attachmentType!==U5A)return;let Q=await this.context.entityService.getEntity({entityType:"post",id:A.sourceEntityId});if(!Q)return;let B=cVQ(Q,{brandLabel:this.resolveBrandLabel(),coverImageUrl:await this.resolveCoverImageUrl(Q)}),w=await xVQ(hVQ(gVQ(),"brain-blog-printable-"));try{let $=await ZD({outputDir:w,mediaPath:`/_media/printable/post/${Q.id}`,template:hK1,format:"pdf",content:B,siteConfig:{title:B.title,themeMode:"light"},themeCSS:this.context.themeCSS}),f=await ND({rootDir:w});try{return{type:"document",data:await this.renderPdf(f.urlFor($.urlPath),{maxBytes:mVQ,timeoutMs:uVQ,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${lVQ(Q)}-printable.pdf`}}finally{await f.close()}}finally{await SVQ(w,{recursive:!0,force:!0})}}resolveBrandLabel(){let A=this.context.domain?.trim();if(A&&A.length>0)return A;let Q=this.context.identity.getProfile().name.trim();return Q.length>0?Q:void 0}async resolveCoverImageUrl(A){let{frontmatter:Q}=jB(A.content),B=z8.parse(Q);if(!B.coverImageId)return;let w=await this.context.entityService.getEntity({entityType:"image",id:B.coverImageId});return w?.content.startsWith("data:image/")?w.content:void 0}}function cVQ(A,Q={}){let{frontmatter:B,content:w}=jB(A.content),$=z8.parse(B);return{title:$.title,body:w,...$.excerpt?{excerpt:$.excerpt}:{},...$.author?{author:$.author}:{},...$.publishedAt?{publishedAt:$.publishedAt}:{},...$.canonicalUrl?{canonicalUrl:$.canonicalUrl}:{},...Q.coverImageUrl?{coverImageUrl:Q.coverImageUrl}:{},...Q.brandLabel?{brandLabel:Q.brandLabel}:{}}}function lVQ(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.title)}import{mkdtemp as nVQ,rm as oVQ}from"fs/promises";import{tmpdir as sVQ}from"os";import{join as aVQ}from"path";WA();KD();WA();import{jsxDEV as dVQ}from"preact/jsx-dev-runtime";var fi="og-image",pVQ="blog:og-image",mK1=H.object({title:H.string().min(1),excerpt:H.string().optional(),author:H.string().optional(),publishedAt:H.string().optional(),brandLabel:H.string().optional(),coverImageUrl:H.string().optional()}),uK1={name:pVQ,pluginId:"blog",schema:mK1,renderers:{image:rVQ}};function iVQ(A){if(!A)return;let Q=new Date(A);if(Number.isNaN(Q.getTime()))return;return Q.toLocaleDateString("en-GB",{year:"numeric",month:"short",day:"2-digit"})}function rVQ(A){let Q=mK1.parse(A);return dVQ(zF,{brandLabel:Q.brandLabel??Q.title,eyebrow:"Journal",title:Q.title,subtitle:Q.excerpt,meta:[Q.author],tag:iVQ(Q.publishedAt)},void 0,!1,void 0,this)}var tVQ={width:1200,height:630},eVQ=60000;class zSA{context;screenshotPng;constructor(A,Q={}){this.context=A;this.screenshotPng=Q.screenshotPng??$i}async resolve(A){if(A.sourceEntityType!=="post"||A.attachmentType!==fi)return;let Q=await this.context.entityService.getEntity({entityType:"post",id:A.sourceEntityId});if(!Q)return;let B=AEQ(Q,{brandLabel:this.resolveBrandLabel(),coverImageUrl:await this.resolveCoverImageUrl(Q)}),w=await nVQ(aVQ(sVQ(),"brain-blog-og-image-"));try{let $=await ZD({outputDir:w,mediaPath:`/_media/og/post/${Q.id}`,template:uK1,format:"image",content:B,siteConfig:{title:B.title,themeMode:"light"},themeCSS:this.context.themeCSS}),f=await ND({rootDir:w});try{return{type:"image",data:await this.screenshotPng(f.urlFor($.urlPath),tVQ,{timeoutMs:eVQ,fullPage:!1,omitBackground:!1}),mimeType:"image/png",filename:`${QEQ(Q)}-og.png`}}finally{await f.close()}}finally{await oVQ(w,{recursive:!0,force:!0})}}resolveBrandLabel(){let A=this.context.domain?.trim();if(A&&A.length>0)return A;let Q=this.context.identity.getProfile().name.trim();return Q.length>0?Q:void 0}async resolveCoverImageUrl(A){let{frontmatter:Q}=jB(A.content),B=z8.parse(Q);if(!B.coverImageId)return;let w=await this.context.entityService.getEntity({entityType:"image",id:B.coverImageId});return w?.content.startsWith("data:image/")?w.content:void 0}}function AEQ(A,Q={}){let{frontmatter:B}=jB(A.content),w=z8.parse(B);return{title:w.title,...w.excerpt?{excerpt:w.excerpt}:{},...w.author?{author:w.author}:{},...w.publishedAt?{publishedAt:w.publishedAt}:{},...Q.coverImageUrl?{coverImageUrl:Q.coverImageUrl}:{},...Q.brandLabel?{brandLabel:Q.brandLabel}:{}}}function QEQ(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.title)}var cK1={name:"@brains/blog",private:!0,version:"0.2.0-alpha.120",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/atproto-contracts":"workspace:*","@brains/contracts":"workspace:*","@brains/media-page-composer":"workspace:*","@brains/media-renderer":"workspace:*","@brains/plugins":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class qSA extends jQ{entityType=gF.entityType;schema=Jv;adapter=gF;unregisterAtprotoProjection;unregisterPrintableAttachmentProvider;unregisterOgImageAttachmentProvider;constructor(A={}){super("blog",cK1,A,ISA)}getEntityTypeConfig(){return{weight:2,publish:{publishStatuses:["queued","published"]}}}createGenerationHandler(A){return new DSA(this.logger.child("BlogGenerationJobHandler"),A)}getTemplates(){return CK1()}getDataSources(){return[new YSA(this.logger.child("BlogDataSource"))]}async onRegister(A){let{RSSDataSource:Q}=await Promise.resolve().then(() => (iK1(),pK1));A.entities.registerDataSource(new Q(this.logger.child("RSSDataSource"))),OK1(A,this.logger),RK1(A,this.logger),PK1(A,this.logger),kK1(A),this.unregisterPrintableAttachmentProvider=A.attachments.register("post",U5A,new NSA(A)),this.unregisterOgImageAttachmentProvider=A.attachments.register("post",fi,new zSA(A)),this.deferPublishAssetRegistration(A),this.unregisterAtprotoProjection=d6.getInstance().register(WSA()),this.logger.info("Blog plugin registered (routes auto-generated at /posts/)")}deferPublishAssetRegistration(A){A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"publish-assets:register",payload:{entityType:"post",attachmentType:fi,mediaEntityType:"image",targetEntityField:{location:"frontmatter",field:"ogImageId"},requiredWhen:{status:"published"},autoGenerate:!0,jobType:"image:image-render-source"}}),{success:!0}})}async onShutdown(){this.unregisterPrintableAttachmentProvider?.(),this.unregisterPrintableAttachmentProvider=void 0,this.unregisterOgImageAttachmentProvider?.(),this.unregisterOgImageAttachmentProvider=void 0,this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}}function LSA(A={}){return new qSA(A)}KD();Xv();aA();WA();WA();o$();aA();var pU=H.object({title:H.string(),slug:H.string(),coverImageId:H.string().optional()}),rK1=pU.pick({title:!0,slug:!0}),yz=A2.extend({metadata:rK1}),Y5A=yz.extend({frontmatter:pU}),J5A=Y5A.extend({description:H.string().optional(),postCount:H.number(),coverImageUrl:H.string().optional(),coverImageWidth:H.number().optional(),coverImageHeight:H.number().optional()}),dK1=H.object({description:H.string().optional()});function QC(A){return new lB(dK1,{title:A,mappings:[{key:"description",label:"Description",type:"string"}]})}aA();class VSA extends q2{constructor(){super({entityType:"series",schema:yz,frontmatterSchema:pU,supportsCoverImage:!0,bodyFormatter:QC("")})}toMarkdown(A){let Q,B={};try{Q=this.parseFrontMatter(A.content,pU).coverImageId,B=QC(A.metadata.title).parse(this.extractBody(A.content))}catch{}let w={title:A.metadata.title,slug:A.metadata.slug,...Q&&{coverImageId:Q}},f=QC(A.metadata.title).format(B);return this.buildMarkdown(f,w)}fromMarkdown(A){let Q=this.parseFrontMatter(A,pU);return{content:A,entityType:"series",metadata:{title:Q.title,slug:Q.slug}}}parseBody(A){try{let Q=this.parseFrontMatter(A,pU);return QC(Q.title).parse(this.extractBody(A))}catch{return{}}}generateFrontMatter(){return""}}var xz=new VSA;aA();WA();wU();WA();var $EQ=H.object({seriesName:H.string().optional(),seriesIndex:H.number().optional()});function X5A(A){let Q=$EQ.safeParse(A);return Q.success?Q.data:{}}function BC(A){return X5A(A.metadata).seriesName}function nK1(A){return X5A(A.metadata).seriesIndex}function oK1(A,Q){let B=nK1(A)??Number.MAX_SAFE_INTEGER,w=nK1(Q)??Number.MAX_SAFE_INTEGER;return B-w}class ESA{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"}),B=new Map(Q.map(($)=>[$.id,$])),w=new Set;for(let $ of A){let f=X1($);w.add(f);let I=B.get(f),D=I?.content??this.createSeriesContent($),U=gB(D);if(I?.contentHash===U)continue;let Y={id:f,entityType:"series",content:D,contentHash:U,created:I?.created??new Date().toISOString(),updated:new Date().toISOString(),visibility:"public",metadata:{title:$,slug:X1($)}};await this.entityService.upsertEntity({entity:Y}),this.logger.debug(`Upserted series: ${$}`)}for(let $ of Q)if(!w.has($.id))await this.entityService.deleteEntity({entityType:"series",id:$.id}),this.logger.debug(`Deleted orphaned series: ${$.id}`)}async handleEntityChange(A,Q){let B=BC(A);if(B)await this.ensureSeriesExists(B);if(Q&&Q!==B)await this.cleanupOrphanedSeries(Q)}async handleEntityDeleted(){await this.syncAllSeries()}async ensureSeriesExists(A){let Q=X1(A);if(await this.entityService.getEntity({entityType:"series",id:Q}))return;let w=this.createSeriesContent(A),$={id:Q,entityType:"series",content:w,contentHash:gB(w),created:new Date().toISOString(),updated:new Date().toISOString(),visibility:"public",metadata:{title:A,slug:X1(A)}};await this.entityService.upsertEntity({entity:$}),this.logger.debug(`Created series: ${A}`)}async cleanupOrphanedSeries(A){let Q=X1(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});for(let $ of w){let f=BC($);if(f)A.add(f)}}return A}createSeriesContent(A){let Q={title:A,slug:X1(A)};return b9("",Q)}}aA();WA();var fEQ=H.object({entityType:H.literal("series"),query:H.object({id:H.string().optional(),limit:H.number().optional(),page:H.number().optional(),pageSize:H.number().optional()}).passthrough()}),IEQ=H.object({type:H.enum(["list","detail"]),seriesName:H.string().optional()});function DEQ(A){let Q=IEQ.safeParse(A);if(Q.success)return{type:Q.data.type,seriesName:Q.data.seriesName};let B=fEQ.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 sK1(A){let Q=R2(A.content,pU);return Y5A.parse({...A,frontmatter:Q.metadata})}class MSA{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=DEQ(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"}),w=await this.countEntitiesPerSeries(Q),$=B.map((f)=>{let I=sK1(f),D=xz.parseBody(f.content);return{...I,description:D.description,postCount:w.get(f.metadata.title)??0}});return this.logger.debug(`Found ${$.length} series entities`),A.parse({series:$})}async fetchSeriesDetail(A,Q,B,w){if(!w)w=(await B.listEntities({entityType:"series",options:{filter:{metadata:{title:A}}}}))[0];if(!w)throw Error(`Series not found: ${A}`);let $=sK1(w),f=xz.parseBody(w.content),I=await this.getSeriesMembers(A,B);return this.logger.debug(`Found ${I.length} entities in series "${A}"`),Q.parse({seriesName:A,posts:I,series:{...$,description:f.description,postCount:I.length},description:f.description})}async fetchSeriesDetailBySlug(A,Q,B){let $=(await B.listEntities({entityType:"series",options:{filter:{metadata:{slug:A}}}}))[0];if(!$)throw Error(`Series not found with slug: ${A}`);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});for(let f of $){let I=BC(f);if(I)Q.set(I,(Q.get(I)??0)+1)}}return Q}async getSeriesMembers(A,Q){let B=[],w=Q.getEntityTypes();for(let $ of w){if($==="series")continue;let f=await Q.listEntities({entityType:$,options:{filter:{metadata:{seriesName:A}}}});B.push(...f)}return B.sort(oK1),B}}aA();WA();wU();var UEQ=H.object({prompt:H.string().optional(),title:H.string().optional(),seriesId:H.string().optional()}),YEQ=H.object({title:H.string().optional(),excerpt:H.string().optional()});class W5A{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}
|
|
5874
5874
|
|
|
5875
5875
|
Content in this series:
|
|
5876
5876
|
${w.join(`
|
|
@@ -5882,7 +5882,7 @@ Your task is to write a series description (2-3 sentences) that:
|
|
|
5882
5882
|
3. Is engaging and makes readers want to explore the content
|
|
5883
5883
|
4. Works well as a series overview on a website
|
|
5884
5884
|
|
|
5885
|
-
Be concise and focus on what makes this series unique and valuable.`});async function wF1({entity:A,config:Q}){let B=yz.parse(A),w=xz.parseBody(B.content);return{$type:"ai.rizom.brain.series",title:B.metadata.title,slug:B.metadata.slug,...w.description&&{description:w.description},...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"series",sourceEntityId:B.id,createdAt:B.created,...B.updated&&{updatedAt:B.updated}}}function CSA(){return{entityType:"series",collection:"ai.rizom.brain.series",lexicon:Gw["ai.rizom.brain.series"],validate:!1,buildRecord:wF1}}var $F1={name:"@brains/series",private:!0,version:"0.2.0-alpha.
|
|
5885
|
+
Be concise and focus on what makes this series unique and valuable.`});async function wF1({entity:A,config:Q}){let B=yz.parse(A),w=xz.parseBody(B.content);return{$type:"ai.rizom.brain.series",title:B.metadata.title,slug:B.metadata.slug,...w.description&&{description:w.description},...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"series",sourceEntityId:B.id,createdAt:B.created,...B.updated&&{updatedAt:B.updated}}}function CSA(){return{entityType:"series",collection:"ai.rizom.brain.series",lexicon:Gw["ai.rizom.brain.series"],validate:!1,buildRecord:wF1}}var $F1={name:"@brains/series",private:!0,version:"0.2.0-alpha.120",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/atproto-contracts":"workspace:*","@brains/content-formatters":"workspace:*","@brains/entity-service":"workspace:*","@brains/job-queue":"workspace:*","@brains/plugins":"workspace:*","@brains/templates":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var fF1=H.discriminatedUnion("mode",[H.object({mode:H.literal("derive"),reason:H.string().optional()}),H.object({mode:H.literal("source"),entityId:H.string(),entityType:H.string(),seriesName:H.string().optional(),previousSeriesName:H.string().optional()})]);class OSA extends jQ{entityType="series";schema=yz;adapter=xz;manager;unregisterAtprotoProjection;constructor(){super("series",$F1)}getEntityTypeConfig(){return{weight:0.5}}createGenerationHandler(A){return new W5A(this.logger.child("SeriesGenerationHandler"),A)}getTemplates(){return{...QF1(),description:BF1}}getDataSources(){return[new MSA(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)return null;let B=BC(Q.entity),w=X5A(Q.previousMetadata).seriesName;if(!B&&!w)return null;return{mode:"source",entityId:Q.entity.id,entityType:Q.entity.entityType,...B?{seriesName:B}:{},...w&&w!==B?{previousSeriesName:w}:{}}},jobOptions:(Q)=>{if(!Q.entity)return;return this.getSourceProjectionJobOptions(Q.entity)}}}]}async onRegister(A){this.manager=new ESA(A.entityService,this.logger.child("SeriesManager")),this.unregisterAtprotoProjection=d6.getInstance().register(CSA())}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}createSeriesProjectionHandler(A){return{process:async(Q)=>{let B=fF1.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,B.previousSeriesName);else{let $=this.requireManager();for(let f of[B.seriesName,B.previousSeriesName])if(f)await $.cleanupOrphanedSeries(f)}return{success:!0}},validateAndParse:(Q)=>{let B=fF1.safeParse(Q??{});return B.success?B.data:null}}}requireManager(){if(!this.manager)throw Error("SeriesPlugin not registered");return this.manager}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,Q){await this.requireManager().handleEntityChange(A,Q)}async projectAll(A){await this.requireManager().syncAllSeries();let Q=new W5A(this.logger.child("SeriesGenerationHandler"),A),B=await A.entityService.listEntities({entityType:"series"});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 RSA(){return new OSA}aA();WA();aA();WA();WA();aA();var GEQ=H.enum(["generating","draft","queued","published","failed"]),IF1="publishedAt is required when deck status is published",DF1=(A)=>A.status==="published"&&!A.publishedAt,bSA=(A)=>{if(DF1(A))throw Error(IF1)},iU=H.object({title:H.string(),slug:H.string().optional(),description:H.string().optional(),author:H.string().optional(),status:GEQ,publishedAt:H.string().datetime().optional(),event:H.string().optional(),coverImageId:H.string().optional(),ogImageId:H.string().optional()}),KEQ=iU.pick({title:!0,description:!0,status:!0,publishedAt:!0,coverImageId:!0}).extend({slug:H.string(),error:H.string().optional()}).superRefine((A,Q)=>{if(!DF1(A))return;Q.addIssue({code:H.ZodIssueCode.custom,path:["publishedAt"],message:IF1})}),Hv=A2.extend({entityType:H.literal("deck"),metadata:KEQ}),H5A=Hv.extend({frontmatter:iU,body:H.string(),ogImageUrl:H.string().optional()}),wC=H5A.extend({url:H.string().optional(),typeLabel:H.string().optional(),listUrl:H.string().optional(),listLabel:H.string().optional(),coverImageUrl:H.string().optional(),ogImageUrl:H.string().optional(),coverImageWidth:H.number().optional(),coverImageHeight:H.number().optional()});class PSA extends q2{constructor(){super({entityType:"deck",schema:Hv,frontmatterSchema:iU,supportsCoverImage:!0})}validateSlideStructure(A){if(!/^---$/gm.test(A))throw Error("Invalid deck: markdown must contain slide separators (---) to be a valid presentation")}toMarkdown(A){let Q=this.extractBody(A.content);this.validateSlideStructure(Q);let B=this.parseFrontMatter(A.content,iU);bSA(B);let w={...B,slug:B.slug??A.metadata.slug};return this.buildMarkdown(Q,w)}fromMarkdown(A){let Q=this.parseFrontmatter(A),B=this.extractBody(A);bSA(Q),this.validateSlideStructure(B);let w=Q.slug??X1(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)}buildStub(A){let Q={title:A.title,slug:A.id,status:"generating"};return{content:this.buildMarkdown(`---
|
|
5886
5886
|
`,Q),metadata:{title:A.title,slug:A.id,status:"generating"}}}}var Ii=new PSA;WA();Ew();var FEQ=H.object({markdown:H.string().describe("Markdown content with slide separators (---)"),deck:wC.optional()}),kSA=P1({name:"deck-detail",description:"Render a presentation deck as Reveal.js slides",schema:FEQ,dataSourceId:"decks:entities",requiredPermission:"public",layout:{component:FTA,fullscreen:!0}});Ew();WA();var jSA=H.object({decks:H.array(H5A)}),_SA=H.object({decks:H.array(wC),pageTitle:H.string().optional(),pageLabel:H.string().optional()});import{jsxDEV as vSA}from"preact/jsx-dev-runtime";var ZEQ="Presentations",TSA=({decks:A,pageLabel:Q})=>{let B=A.map(($)=>({id:$.id,url:$.url,title:$.frontmatter.title,date:$.frontmatter.publishedAt??$.created,description:$.frontmatter.description}));return vSA("div",{className:"deck-list bg-theme",children:vSA("div",{className:"container mx-auto max-w-[1100px] px-6 py-16 md:px-12 md:py-24",children:vSA(Qp,{label:Q&&Q!=="Decks"?Q:ZEQ,items:B},void 0,!1,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)};o$();class G5A extends lB{constructor(){super(jSA,{title:"Deck List",mappings:[{key:"decks",label:"Decks",type:"array",itemType:"object"}]})}}var ySA=P1({name:"deck-list",description:"List view of all presentation decks",schema:_SA,dataSourceId:"decks:entities",requiredPermission:"public",formatter:new G5A,layout:{component:TSA}});WA();aA();var NEQ=H.object({title:H.string().max(80).describe("A short, punchy title (2-5 words) that's memorable and evocative"),content:H.string().describe("Full slide deck content in markdown format with slide separators (---). Each slide should have a header and focused content."),description:H.string().describe("A concise 1-2 sentence summary that captures the essence of the talk")}),UF1=P1({name:"decks:generation",description:"Template for AI to generate complete slide decks from prompts",schema:NEQ,dataSourceId:"shell:ai-content",requiredPermission:"public",useKnowledgeContext:!0,basePrompt:`You are creating slide decks in a distinctive voice that blends philosophy, technology, and culture.
|
|
5887
5887
|
|
|
5888
5888
|
Your task is to generate a complete slide deck based on the user's prompt.
|
|
@@ -6190,14 +6190,14 @@ ${D}`,templateName:"decks:description"})).description,await this.reportProgress(
|
|
|
6190
6190
|
color: var(--carousel-accent);
|
|
6191
6191
|
font-weight: 600;
|
|
6192
6192
|
}
|
|
6193
|
-
`}},void 0,!1,void 0,this),$.map((Y,J)=>m7("section",{className:`deck-carousel-slide${J===0?" is-cover":""}`,children:[m7("header",{className:"deck-carousel-header",children:m7("span",{className:"deck-carousel-wordmark","aria-label":B??Q,children:[m7("span",{className:"wm-primary",children:f.primary},void 0,!1,void 0,this),f.secondary!==void 0&&m7(MEQ,{children:[m7("span",{className:"wm-dot",children:"."},void 0,!1,void 0,this),m7("span",{className:"wm-secondary",children:f.secondary},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),m7("div",{className:"deck-carousel-body",children:m7("div",{className:"deck-carousel-content",dangerouslySetInnerHTML:{__html:U(Y.markdown)}},void 0,!1,void 0,this)},void 0,!1,void 0,this),m7("footer",{className:"deck-carousel-footer",children:[m7("span",{className:"deck-carousel-footer-meta",children:w??Q},void 0,!1,void 0,this),m7("span",{className:"deck-carousel-counter","aria-label":`Slide ${J+1} of ${I}`,children:[m7("span",{className:"deck-carousel-counter-current",children:String(J+1).padStart(2,"0")},void 0,!1,void 0,this)," / ",m7("span",{children:D},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},J,!0,void 0,this))]},void 0,!0,void 0,this)}import{mkdtemp as CEQ,rm as OEQ}from"fs/promises";import{tmpdir as REQ}from"os";import{join as bEQ}from"path";WA();var PEQ=26214400,kEQ=60000,HF1=20;class gSA{context;renderPdf;getThemeMode;constructor(A,Q={}){this.context=A;this.renderPdf=Q.renderPdf??$X,this.getThemeMode=Q.getThemeMode??(async()=>"dark")}async resolve(A){if(A.sourceEntityType!=="deck")return;let Q=await this.context.entityService.getEntity({entityType:"deck",id:A.sourceEntityId});if(!Q)return;let B=jEQ(Q,{brandLabel:this.resolveBrandLabel()});if(B.slides.length>HF1)throw Error(`Refusing to render carousel with ${B.slides.length} slides; maxSlides=${HF1}`);let w=await this.getThemeMode(),$=await CEQ(bEQ(REQ(),"brain-deck-carousel-"));try{let f=await ZD({outputDir:$,mediaPath:`/_media/carousel/${Q.id}`,template:WF1,format:"pdf",content:B,siteConfig:{title:B.title,themeMode:w},themeCSS:this.context.themeCSS}),I=await ND({rootDir:$});try{return{type:"document",data:await this.renderPdf(I.urlFor(f.urlPath),{maxBytes:PEQ,timeoutMs:kEQ,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${_EQ(Q)}-carousel.pdf`}}finally{await I.close()}}finally{await OEQ($,{recursive:!0,force:!0})}}resolveBrandLabel(){let A=this.context.domain?.trim();if(A&&A.length>0)return A;let Q=this.context.identity.getProfile().name;return Q.length>0?Q:void 0}}function jEQ(A,Q={}){let{frontmatter:B,content:w}=jB(A.content),$=typeof B.title==="string"?B.title:A.metadata.title,f=typeof B.event==="string"&&B.event.length>0?B.event:void 0,I=w.split(/^---$/gm).map((D)=>D.trim()).filter((D)=>D.length>0).map((D)=>({markdown:D}));return{title:$,slides:I,...Q.brandLabel?{brandLabel:Q.brandLabel}:{},...f?{eyebrow:f}:{}}}function _EQ(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.title)}WA();import{jsxDEV as yEQ}from"preact/jsx-dev-runtime";var K5A="og-image",vEQ="decks:og-image",GF1=H.object({title:H.string().min(1),description:H.string().optional(),event:H.string().optional(),brandLabel:H.string().optional(),slideCount:H.number().int().positive().optional(),coverImageUrl:H.string().optional()}),KF1={name:vEQ,pluginId:"decks",schema:GF1,renderers:{image:TEQ}};function TEQ(A){let Q=GF1.parse(A),B=Q.slideCount?`${Q.slideCount} slide${Q.slideCount===1?"":"s"}`:void 0;return yEQ(zF,{brandLabel:Q.brandLabel??Q.title,eyebrow:"Deck",title:Q.title,subtitle:Q.description,meta:[Q.event],tag:B},void 0,!1,void 0,this)}WA();class hSA{context;deps;constructor(A,Q={}){this.context=A;this.deps=Q}async resolve(A){if(A.sourceEntityType!=="deck"||A.attachmentType!==K5A)return;let Q=await this.context.entityService.getEntity({entityType:"deck",id:A.sourceEntityId});if(!Q)return;let{frontmatter:B,content:w}=jB(Q.content),$=iU.parse(B),f=xEQ(w),I=this.resolveBrandLabel(),D=await this.resolveCoverImageUrl($.coverImageId),U={title:$.title,...$.description?{description:$.description}:{},...$.event?{event:$.event}:{},...f?{slideCount:f}:{},...D?{coverImageUrl:D}:{},...I?{brandLabel:I}:{}};return{type:"image",data:await AC({mediaPath:`/_media/og/deck/${Q.id}`,template:KF1,content:U,title:U.title,themeMode:"dark",themeCSS:this.context.themeCSS,tmpPrefix:"brain-deck-og-image-",...this.deps.screenshotPng&&{screenshotPng:this.deps.screenshotPng}}),mimeType:"image/png",filename:`${SEQ(Q)}-og.png`}}resolveBrandLabel(){let A=this.context.domain?.trim();if(A&&A.length>0)return A;let Q=this.context.identity.getProfile().name.trim();return Q.length>0?Q:void 0}async resolveCoverImageUrl(A){if(!A)return;let Q=await this.context.entityService.getEntity({entityType:"image",id:A});return Q?.content.startsWith("data:image/")?Q.content:void 0}}function xEQ(A){return A.split(/^---$/gm).map((Q)=>Q.trim()).filter((Q)=>Q.length>0).length}function SEQ(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.title)}aA();async function FF1({entity:A,config:Q}){let B=Hv.parse(A),w=R2(B.content,iU),$=w.metadata;return{$type:"ai.rizom.brain.deck",title:$.title,...$.slug&&{slug:$.slug},...$.description&&{description:$.description},body:w.content,format:"text/markdown",...$.author&&{author:$.author},...$.event&&{event:$.event},...$.publishedAt&&{publishedAt:$.publishedAt},...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"deck",sourceEntityId:B.id,createdAt:B.created,...B.updated&&{updatedAt:B.updated}}}function mSA(){return{entityType:"deck",collection:"ai.rizom.brain.deck",lexicon:Gw["ai.rizom.brain.deck"],validate:!1,buildRecord:FF1}}var ZF1={name:"@brains/decks",private:!0,version:"0.2.0-alpha.
|
|
6193
|
+
`}},void 0,!1,void 0,this),$.map((Y,J)=>m7("section",{className:`deck-carousel-slide${J===0?" is-cover":""}`,children:[m7("header",{className:"deck-carousel-header",children:m7("span",{className:"deck-carousel-wordmark","aria-label":B??Q,children:[m7("span",{className:"wm-primary",children:f.primary},void 0,!1,void 0,this),f.secondary!==void 0&&m7(MEQ,{children:[m7("span",{className:"wm-dot",children:"."},void 0,!1,void 0,this),m7("span",{className:"wm-secondary",children:f.secondary},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),m7("div",{className:"deck-carousel-body",children:m7("div",{className:"deck-carousel-content",dangerouslySetInnerHTML:{__html:U(Y.markdown)}},void 0,!1,void 0,this)},void 0,!1,void 0,this),m7("footer",{className:"deck-carousel-footer",children:[m7("span",{className:"deck-carousel-footer-meta",children:w??Q},void 0,!1,void 0,this),m7("span",{className:"deck-carousel-counter","aria-label":`Slide ${J+1} of ${I}`,children:[m7("span",{className:"deck-carousel-counter-current",children:String(J+1).padStart(2,"0")},void 0,!1,void 0,this)," / ",m7("span",{children:D},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},J,!0,void 0,this))]},void 0,!0,void 0,this)}import{mkdtemp as CEQ,rm as OEQ}from"fs/promises";import{tmpdir as REQ}from"os";import{join as bEQ}from"path";WA();var PEQ=26214400,kEQ=60000,HF1=20;class gSA{context;renderPdf;getThemeMode;constructor(A,Q={}){this.context=A;this.renderPdf=Q.renderPdf??$X,this.getThemeMode=Q.getThemeMode??(async()=>"dark")}async resolve(A){if(A.sourceEntityType!=="deck")return;let Q=await this.context.entityService.getEntity({entityType:"deck",id:A.sourceEntityId});if(!Q)return;let B=jEQ(Q,{brandLabel:this.resolveBrandLabel()});if(B.slides.length>HF1)throw Error(`Refusing to render carousel with ${B.slides.length} slides; maxSlides=${HF1}`);let w=await this.getThemeMode(),$=await CEQ(bEQ(REQ(),"brain-deck-carousel-"));try{let f=await ZD({outputDir:$,mediaPath:`/_media/carousel/${Q.id}`,template:WF1,format:"pdf",content:B,siteConfig:{title:B.title,themeMode:w},themeCSS:this.context.themeCSS}),I=await ND({rootDir:$});try{return{type:"document",data:await this.renderPdf(I.urlFor(f.urlPath),{maxBytes:PEQ,timeoutMs:kEQ,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${_EQ(Q)}-carousel.pdf`}}finally{await I.close()}}finally{await OEQ($,{recursive:!0,force:!0})}}resolveBrandLabel(){let A=this.context.domain?.trim();if(A&&A.length>0)return A;let Q=this.context.identity.getProfile().name;return Q.length>0?Q:void 0}}function jEQ(A,Q={}){let{frontmatter:B,content:w}=jB(A.content),$=typeof B.title==="string"?B.title:A.metadata.title,f=typeof B.event==="string"&&B.event.length>0?B.event:void 0,I=w.split(/^---$/gm).map((D)=>D.trim()).filter((D)=>D.length>0).map((D)=>({markdown:D}));return{title:$,slides:I,...Q.brandLabel?{brandLabel:Q.brandLabel}:{},...f?{eyebrow:f}:{}}}function _EQ(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.title)}WA();import{jsxDEV as yEQ}from"preact/jsx-dev-runtime";var K5A="og-image",vEQ="decks:og-image",GF1=H.object({title:H.string().min(1),description:H.string().optional(),event:H.string().optional(),brandLabel:H.string().optional(),slideCount:H.number().int().positive().optional(),coverImageUrl:H.string().optional()}),KF1={name:vEQ,pluginId:"decks",schema:GF1,renderers:{image:TEQ}};function TEQ(A){let Q=GF1.parse(A),B=Q.slideCount?`${Q.slideCount} slide${Q.slideCount===1?"":"s"}`:void 0;return yEQ(zF,{brandLabel:Q.brandLabel??Q.title,eyebrow:"Deck",title:Q.title,subtitle:Q.description,meta:[Q.event],tag:B},void 0,!1,void 0,this)}WA();class hSA{context;deps;constructor(A,Q={}){this.context=A;this.deps=Q}async resolve(A){if(A.sourceEntityType!=="deck"||A.attachmentType!==K5A)return;let Q=await this.context.entityService.getEntity({entityType:"deck",id:A.sourceEntityId});if(!Q)return;let{frontmatter:B,content:w}=jB(Q.content),$=iU.parse(B),f=xEQ(w),I=this.resolveBrandLabel(),D=await this.resolveCoverImageUrl($.coverImageId),U={title:$.title,...$.description?{description:$.description}:{},...$.event?{event:$.event}:{},...f?{slideCount:f}:{},...D?{coverImageUrl:D}:{},...I?{brandLabel:I}:{}};return{type:"image",data:await AC({mediaPath:`/_media/og/deck/${Q.id}`,template:KF1,content:U,title:U.title,themeMode:"dark",themeCSS:this.context.themeCSS,tmpPrefix:"brain-deck-og-image-",...this.deps.screenshotPng&&{screenshotPng:this.deps.screenshotPng}}),mimeType:"image/png",filename:`${SEQ(Q)}-og.png`}}resolveBrandLabel(){let A=this.context.domain?.trim();if(A&&A.length>0)return A;let Q=this.context.identity.getProfile().name.trim();return Q.length>0?Q:void 0}async resolveCoverImageUrl(A){if(!A)return;let Q=await this.context.entityService.getEntity({entityType:"image",id:A});return Q?.content.startsWith("data:image/")?Q.content:void 0}}function xEQ(A){return A.split(/^---$/gm).map((Q)=>Q.trim()).filter((Q)=>Q.length>0).length}function SEQ(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.title)}aA();async function FF1({entity:A,config:Q}){let B=Hv.parse(A),w=R2(B.content,iU),$=w.metadata;return{$type:"ai.rizom.brain.deck",title:$.title,...$.slug&&{slug:$.slug},...$.description&&{description:$.description},body:w.content,format:"text/markdown",...$.author&&{author:$.author},...$.event&&{event:$.event},...$.publishedAt&&{publishedAt:$.publishedAt},...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"deck",sourceEntityId:B.id,createdAt:B.created,...B.updated&&{updatedAt:B.updated}}}function mSA(){return{entityType:"deck",collection:"ai.rizom.brain.deck",lexicon:Gw["ai.rizom.brain.deck"],validate:!1,buildRecord:FF1}}var ZF1={name:"@brains/decks",private:!0,version:"0.2.0-alpha.120",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/atproto-contracts":"workspace:*","@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/image":"workspace:*","@brains/media-page-composer":"workspace:*","@brains/media-renderer":"workspace:*","@brains/plugins":"workspace:*","@brains/site-info":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class uSA extends jQ{deps;entityType=Ii.entityType;schema=Ii.schema;adapter=Ii;unregisterCarouselAttachmentProvider;unregisterOgImageAttachmentProvider;unregisterAtprotoProjection;constructor(A={}){super("decks",ZF1);this.deps=A}createGenerationHandler(A){return new SSA(this.logger.child("DeckGenerationJobHandler"),A)}getTemplates(){return{"deck-detail":kSA,"deck-list":ySA,generation:UF1,description:YF1}}getDataSources(){return[new xSA(this.logger)]}getEntityTypeConfig(){return{weight:1.5}}async onRegister(A){this.deferPublishRegistration(A),this.subscribeToPublishExecute(A),this.registerCarouselAttachmentProvider(A),this.registerOgImageAttachmentProvider(A),this.registerEvalHandlers(A),this.unregisterAtprotoProjection=d6.getInstance().register(mSA()),this.logger.info("Decks plugin registered")}async onShutdown(){this.unregisterCarouselAttachmentProvider?.(),this.unregisterCarouselAttachmentProvider=void 0,this.unregisterOgImageAttachmentProvider?.(),this.unregisterOgImageAttachmentProvider=void 0,this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}deferPublishRegistration(A){A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"publish:register",payload:{entityType:"deck",provider:{name:"internal",publish:async()=>({id:"internal"})},config:{executionMode:"provider"}}}),{success:!0}})}subscribeToPublishExecute(A){A.messaging.subscribe("publish:execute",async(Q)=>{let{entityType:B,entityId:w}=Q.payload;if(B!=="deck")return{success:!0};try{let $=await A.entityService.getEntity({entityType:"deck",id:w});if(!$)return await A.messaging.send({type:"publish:report:failure",payload:{entityType:B,entityId:w,error:`Deck not found: ${w}`}}),{success:!0};if($.metadata.status==="published")return{success:!0};let f=new Date().toISOString(),I={...$,metadata:{...$.metadata,status:"published",publishedAt:f}};await A.entityService.updateEntity({entity:{...I,content:this.adapter.toMarkdown(I)}}),await A.messaging.send({type:"publish:report:success",payload:{entityType:B,entityId:w,result:{id:w}}})}catch($){await A.messaging.send({type:"publish:report:failure",payload:{entityType:B,entityId:w,error:T0($)}})}return{success:!0}})}registerCarouselAttachmentProvider(A){let Q={...this.deps,getThemeMode:this.deps.getThemeMode??(async()=>{try{return(await tp(A.entityService)).themeMode??"dark"}catch{return"dark"}})};this.unregisterCarouselAttachmentProvider=A.attachments.register("deck",JF1,new gSA(A,Q))}registerOgImageAttachmentProvider(A){this.unregisterOgImageAttachmentProvider=A.attachments.register("deck",K5A,new hSA(A))}registerEvalHandlers(A){A.eval.registerHandler("generateDeck",async(Q)=>{let B=H.object({prompt:H.string(),event:H.string().optional()}).parse(Q);return A.ai.generate({prompt:`${B.prompt}${B.event?`
|
|
6194
6194
|
|
|
6195
6195
|
Note: This presentation is for "${B.event}".`:""}`,templateName:"decks:generation"})}),A.eval.registerHandler("generateDescription",async(Q)=>{let B=H.object({title:H.string(),content:H.string()}).parse(Q);return A.ai.generate({prompt:`Title: ${B.title}
|
|
6196
6196
|
|
|
6197
6197
|
Content:
|
|
6198
6198
|
${B.content}`,templateName:"decks:description"})})}}function Ui(){return new uSA}aA();WA();WA();Y8();var cSA=H.literal("application/pdf"),lSA=H.object({title:H.string().optional(),mimeType:cSA,filename:H.string().min(1),pageCount:H.number().int().min(0).optional(),sourceEntityType:H.string().min(1).optional(),sourceEntityId:H.string().min(1).optional(),attachmentType:H.string().min(1).optional(),dedupKey:H.string().min(1).optional()}),Gv=A2.extend({entityType:H.literal("document"),content:H.string().regex(/^data:application\/pdf;base64,.+$/),metadata:lSA});function Yi(A){let Q=A.match(/^data:(application\/pdf);base64,(.+)$/i);if(!Q?.[1]||!Q[2])throw Error("Invalid PDF document data URL");return{mimeType:"application/pdf",base64:Q[2]}}function F5A(A){return`data:application/pdf;base64,${Buffer.from(A).toString("base64")}`}function pSA(A){let Q=Buffer.from(A).toString("latin1"),B=0,w=/\/Type\s*\/Pages\b[^]*?\/Count\s+(\d+)|\/Count\s+(\d+)[^]*?\/Type\s*\/Pages\b/g;for(let f of Q.matchAll(w)){let I=parseInt(f[1]??f[2]??"0",10);if(I>B)B=I}if(B>0)return B;return Q.match(/\/Type\s*\/Page(?!\w)/g)?.length??0}class Z5A{entityType="document";schema=Gv;toMarkdown(A){return A.content}fromMarkdown(A){return Yi(A),{entityType:"document",content:A}}extractMetadata(A){return A.metadata}parseFrontMatter(A,Q){return Q.parse({})}generateFrontMatter(A){return""}getBodyTemplate(){return""}createDocumentEntity(A){let{dataUrl:Q,...B}=A,{mimeType:w}=Yi(Q);return{entityType:"document",content:Q,metadata:{mimeType:w,...B}}}}var Sz=new Z5A;async function bgA(A,Q={}){let B=Q.maxBytes??5000000;if(A.byteLength>B)throw Error(`Uploaded PDF is too large for synchronous markdown extraction (${A.byteLength} bytes; max ${B} bytes)`);let $=await(await Promise.resolve().then(() => (ON1(),CN1))).getDocument({data:new Uint8Array(A),disableFontFace:!1,useSystemFonts:!0,useWorkerFetch:!1}).promise;try{let f=Q.maxPages??50;if($.numPages>f)throw Error(`Uploaded PDF has ${$.numPages} pages; maximum supported for synchronous markdown extraction is ${f}`);let I=[];for(let U=1;U<=$.numPages;U+=1){let X=(await(await $.getPage(U)).getTextContent()).items.flatMap((G)=>("str"in G)?[G.str]:[]).join(" ").replace(/\s+/g," ").trim();if(X.length>0)I.push(X)}let D=I.join(`
|
|
6199
6199
|
|
|
6200
|
-
`).trim();if(!D)throw Error("Could not extract text from the uploaded PDF");return D}finally{await $.destroy()}}aA();WA();import{createHash as LMQ}from"crypto";var VMQ=26214400,EMQ=20,MMQ=60000,RN1=80,CMQ=10,$$A=H.object({renderUrl:H.string().url().optional(),sourceEntityType:H.string().min(1),sourceEntityId:H.string().min(1),attachmentType:H.string().min(1),documentId:H.string().min(1).optional(),title:H.string().min(1).optional(),filename:H.string().min(1).optional(),dedupKey:H.string().min(1).optional(),replace:H.boolean().optional(),pageCount:H.number().int().min(0).optional(),maxPageCount:H.number().int().positive().optional(),maxBytes:H.number().int().positive().optional(),timeoutMs:H.number().int().positive().optional(),width:H.union([H.string(),H.number()]).optional(),height:H.union([H.string(),H.number()]).optional(),format:H.string().optional(),targetEntityType:H.string().min(1).optional(),targetEntityId:H.string().min(1).optional()}),bv=$$A.refine((A)=>A.targetEntityType===void 0&&A.targetEntityId===void 0||A.targetEntityType!==void 0&&A.targetEntityId!==void 0,{message:"targetEntityType and targetEntityId must be provided together",path:["targetEntityId"]});class f$A extends ZB{context;renderPdf;constructor(A,Q,B={}){super(A,{schema:bv,jobTypeName:"document-generate"});this.context=Q;this.renderPdf=B.renderPdf??$X}async getDedupKey(A){if(A.dedupKey!==void 0)return A.dedupKey;if(A.renderUrl!==void 0)return`${A.attachmentType}:${A.sourceEntityType}:${A.sourceEntityId}:${A.renderUrl}`;let Q=`${A.attachmentType}:${A.sourceEntityType}:${A.sourceEntityId}:resolved-attachment`,B=await this.context.entityService.getEntity({entityType:A.sourceEntityType,id:A.sourceEntityId});return B?`${Q}:${B.contentHash}`:Q}async process(A,Q,B){this.logger.debug("Starting document generation job",{jobId:Q,sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType});let w=A.maxPageCount??EMQ,$=A.maxBytes??VMQ,f=A.timeoutMs??MMQ;if(A.pageCount!==void 0&&A.pageCount>w)throw Error(`Refusing to render ${A.pageCount} page PDF; maxPageCount=${w}`);let I=await this.getDedupKey(A),D=yi(A,I),U=A.documentId!==void 0||A.filename!==void 0;if(A.replace!==!0){let Y=await this.findDocumentByDedupKey(I,U?D:void 0);if(Y&&(!U||Y.id===D)){if(A.targetEntityType&&A.targetEntityId)await this.attachDocumentToTarget(A.targetEntityType,A.targetEntityId,Y.id,A);return await this.reportProgress(B,{progress:100,message:"Reusing existing generated document"}),{success:!0,documentId:Y.id,reused:!0}}}await this.reportProgress(B,{progress:20,message:"Rendering PDF document"});try{let Y=await this.resolveDocumentAttachment(A,D,{timeoutMs:f,maxBytes:$}),J=Y.data;if(J.byteLength>$)throw Error(`Rendered PDF exceeds maxBytes=${$}: ${J.byteLength} bytes`);let X=pSA(J);if(X>w)throw Error(`Rendered PDF has ${X} pages, exceeding maxPageCount=${w}`);let G=X>0?X:A.pageCount;await this.reportProgress(B,{progress:70,message:"Storing PDF document"});let Z=A.filename??(A.renderUrl===void 0?Y.filename:`${D}.pdf`),N=Sz.createDocumentEntity({dataUrl:F5A(J),filename:Z,...A.title&&{title:A.title},...G!==void 0&&{pageCount:G},sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType,dedupKey:I});if(await this.context.entityService.getEntity({entityType:"document",id:D}))await this.context.entityService.deleteEntity({entityType:"document",id:D});if(await this.context.entityService.createEntity({entity:{...N,id:D}}),A.targetEntityType&&A.targetEntityId)await this.attachDocumentToTarget(A.targetEntityType,A.targetEntityId,D,A);return await this.reportProgress(B,{progress:100,message:"PDF document generation complete"}),{success:!0,documentId:D,reused:!1}}catch(Y){throw this.logger.error("Document generation failed",{jobId:Q,error:T0(Y)}),Y}}async resolveDocumentAttachment(A,Q,B){if(A.renderUrl!==void 0)return{type:"document",data:await this.renderPdf(A.renderUrl,{timeoutMs:B.timeoutMs,maxBytes:B.maxBytes,printBackground:!0,preferCSSPageSize:!0,...A.width!==void 0&&{width:A.width},...A.height!==void 0&&{height:A.height},...A.format!==void 0&&{format:A.format}}),mimeType:"application/pdf",filename:A.filename??`${Q}.pdf`};let w=await this.context.attachments.resolve({sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType});if(!w)throw Error(`No attachment provider found for ${A.sourceEntityType}/${A.attachmentType}`);if(w.type!=="document")throw Error(`Attachment provider returned ${w.type}; expected document`);return w}async findDocumentByDedupKey(A,Q){let B=await this.context.entityService.listEntities({entityType:"document",options:{filter:{metadata:{dedupKey:A}}}});if(B.length>1)this.logger.warn("Multiple documents share dedupKey; using first",{dedupKey:A,count:B.length,ids:B.map((w)=>w.id),preferredDocumentId:Q});return B.find((w)=>w.id===Q)??B[0]}async attachDocumentToTarget(A,Q,B,w){let $=await this.context.entityService.getEntity({entityType:A,id:Q});if(!$)throw Error(`Target entity not found: ${A}/${Q}`);let{frontmatter:f}=jB($.content),I=Array.isArray(f.documents)?f.documents.filter(RMQ):[],D=w.replace?await this.removeReferencesForSameSourceAttachment(I,B,w):I,U=D.some((Y)=>Y.id===B)?D:[...D,{id:B}];await this.context.entityService.updateEntity({entity:{...$,content:Y4($.content,"documents",U)}})}async removeReferencesForSameSourceAttachment(A,Q,B){let w=[];for(let $ of A){if($.id===Q){w.push($);continue}let f=await this.context.entityService.getEntity({entityType:"document",id:$.id});if(!f||!bMQ(f,B))w.push($)}return w}}function yi(A,Q){let B=`${A.attachmentType}:${A.sourceEntityType}:${A.sourceEntityId}:${A.renderUrl??"resolved-attachment"}`,w=A.documentId??A.filename?.replace(/\.pdf$/i,"")??Q??B,$=A.replace===!0&&A.documentId===void 0?`${w}-${Date.now()}`:w;return OMQ($)}function OMQ(A){let Q=X1(A.replace(/[/:]+/g," "))||`document-${bN1(A)}`;if(Q.length<=RN1)return Q;let B=`-${bN1(A)}`;return`${Q.slice(0,RN1-B.length).replace(/-+$/g,"")}${B}`}function bN1(A){return LMQ("sha256").update(A).digest("hex").slice(0,CMQ)}function RMQ(A){return typeof A==="object"&&A!==null&&"id"in A&&typeof A.id==="string"&&A.id.length>0}function bMQ(A,Q){return A.metadata.sourceEntityType===Q.sourceEntityType&&A.metadata.sourceEntityId===Q.sourceEntityId&&A.metadata.attachmentType===Q.attachmentType}aA();function PgA(A,Q){return[oQ(A,"generate",'Preview or prepare a PDF document attachment from a source attachment or render URL. For save/regenerate durable document requests, including deck carousel PDFs and printable post/project/product PDFs, prefer system_create with entityType: "document" and from.',$$A,async(B,w)=>{let $=bv.safeParse(B);if(!$.success)return X$($.error.message);let f=yi($.data),I=await Q({...$.data,documentId:f},w),D=$.data.filename??`${f}.pdf`;return U8({jobId:I,documentId:f,attachment:{mediaType:"application/pdf",url:`/api/chat/attachments/document?id=${encodeURIComponent(f)}`,downloadUrl:`/api/chat/attachments/document?id=${encodeURIComponent(f)}&download=1`,filename:D,source:{entityType:"document",entityId:f,attachmentType:$.data.attachmentType}}})},{cli:{name:"document-generate"}})]}var PN1={name:"@brains/document-plugin",private:!0,version:"0.2.0-alpha.119",description:"Document entity type for generated PDFs and publishable document attachments",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/contracts":"workspace:*","@brains/document":"workspace:*","@brains/media-renderer":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/typescript-config":"workspace:*","bun-types":"latest",typescript:"^5.3.3"}};var kMQ=H.object({}),kgA={namespace:"upload",refKind:"upload",routePath:"/api/chat/uploads"};function jMQ(A,Q){let B=A.title?.trim();if(B)return B;return Q.replace(/\.[^.]+$/,"").trim()||Q}function _MQ(A,Q){return`data:${A};base64,${Q.toString("base64")}`}function vMQ(A){let Q=encodeURIComponent(A.entityId);return{mediaType:"application/pdf",url:`/api/chat/attachments/document?id=${Q}`,downloadUrl:`/api/chat/attachments/document?id=${Q}&download=1`,filename:A.filename,source:{entityType:"document",entityId:A.entityId,attachmentType:"uploaded"}}}class jgA extends YB{entityType=Sz.entityType;schema=Gv;adapter=Sz;pluginContext;constructor(){super("document",PN1,{},kMQ)}async onRegister(A){this.pluginContext=A,A.entities.register(this.entityType,this.schema,this.adapter,{embeddable:!1}),A.entities.registerCreateInterceptor(this.entityType,(Q)=>this.interceptCreate(Q)),A.jobs.registerHandler("generate",new f$A(this.logger.child("DocumentGenerationJobHandler"),A))}async interceptCreate(A){let Q=this.pluginContext;if(A.from?.kind===kgA.refKind){if(!Q)return{kind:"handled",result:{success:!1,error:"Plugin context not initialized"}};return this.promoteUpload(A,Q)}if(!A.from)return{kind:"continue",input:A};if(!Q)return{kind:"handled",result:{success:!1,error:"Plugin context not initialized"}};let B=bv.parse({sourceEntityType:A.from.sourceEntityType,sourceEntityId:A.from.sourceEntityId,attachmentType:A.from.attachmentType,...A.title&&{title:A.title},...A.replace===!0&&{replace:!0},...A.targetEntityType&&{targetEntityType:A.targetEntityType},...A.targetEntityId&&{targetEntityId:A.targetEntityId}}),w=await this.getDedupKey(B,Q),f=(B.replace===!0?void 0:await this.findExistingDocument(w,Q))?.id??yi(B,w),I=await Q.jobs.enqueue({type:"generate",data:{...B,dedupKey:w,documentId:f}}),D=`${f}.pdf`;return{kind:"handled",result:{success:!0,data:{entityId:f,jobId:I,status:"generating",attachment:{mediaType:"application/pdf",url:`/api/chat/attachments/document?id=${encodeURIComponent(f)}`,downloadUrl:`/api/chat/attachments/document?id=${encodeURIComponent(f)}&download=1`,filename:D,source:{entityType:"document",entityId:f,attachmentType:B.attachmentType}}}}}}async promoteUpload(A,Q){let B=A.from;if(B?.kind!==kgA.refKind)return{kind:"handled",result:{success:!1,error:"Unsupported upload ref kind"}};let w;try{w=await Q.uploads.scoped(kgA).read(B.id)}catch{return{kind:"handled",result:{success:!1,error:"Upload ref not found"}}}if(w.record.mediaType!=="application/pdf")return{kind:"handled",result:{success:!1,error:"Only PDF uploads can be promoted to document entities"}};let $=jMQ(A,w.record.filename),f=X1($);if(!f)return{kind:"handled",result:{success:!1,error:"Could not derive a document id from the uploaded filename. Provide a title."}};let I=new Date().toISOString(),D=Sz.createDocumentEntity({dataUrl:_MQ(w.record.mediaType,w.content),filename:w.record.filename,title:$,attachmentType:"uploaded",dedupKey:`upload:${B.kind}:${B.id}`}),U=await Q.entityService.createEntity({entity:{id:f,...D,created:I,updated:I},options:{deduplicateId:!0}});return{kind:"handled",result:{success:!0,data:{entityId:U.entityId,status:"created",attachment:vMQ({entityId:U.entityId,filename:w.record.filename})}}}}async getDedupKey(A,Q){if(A.dedupKey!==void 0)return A.dedupKey;if(A.renderUrl!==void 0)return`${A.attachmentType}:${A.sourceEntityType}:${A.sourceEntityId}:${A.renderUrl}`;let B=`${A.attachmentType}:${A.sourceEntityType}:${A.sourceEntityId}:resolved-attachment`,w=await Q.entityService.getEntity({entityType:A.sourceEntityType,id:A.sourceEntityId});return w?`${B}:${w.contentHash}`:B}async findExistingDocument(A,Q){return(await Q.entityService.listEntities({entityType:"document",options:{filter:{metadata:{dedupKey:A}}}}))[0]}async getInstructions(){return'For durable raw PDF saves/promotions from uploaded PDFs, call system_create with entityType: "document", the exact upload object shown in the current turn or conversation "Available upload refs" hint, and no transform. Do this only after the user explicitly asks to save/import/promote the raw PDF as a document. If that hint is absent, omit upload entirely; never invent upload IDs or placeholder upload refs. Uploaded PDFs are not decks; raw upload promotion preserves the PDF as a document. Do not use entityType: "base" or transform: "extract-markdown" unless the user asks to turn the upload into a note/markdown. For generated/source-derived PDFs, call system_create with entityType: "document" and sourceAttachment. Deck carousel PDFs use sourceAttachment: { sourceEntityType: "deck", sourceEntityId: <deck ID>, attachmentType: "carousel" }. Printable PDFs for blog posts, projects, and products use sourceAttachment with attachmentType: "printable" and sourceEntityType "post", "project", or "product". Omit upload and sourceAttachment entirely for ordinary direct document creates that use content, prompt, or url. Include targetEntityType/targetEntityId when the user asks to attach the saved document to another entity. Use replace: true when they ask to regenerate or replace a saved PDF. Only use document_generate for explicit preview/prepare requests where they need an immediate PDF attachment. Do not use generic attachment types like "document".'}async getTools(){let A=this.pluginContext;if(!A)throw Error("Plugin context not initialized");return PgA(this.id,(Q,B)=>A.jobs.enqueue({type:"generate",data:Q,toolContext:B}))}}function _gA(){return new jgA}aA();WA();WA();aA();var TMQ=H.enum(["generating","failed"]),lF=H.object({title:H.string().optional(),status:TMQ.optional(),error:H.string().optional()}),kN1=lF.pick({title:!0,status:!0,error:!0}).extend({title:H.string()}),lz=A2.extend({entityType:H.literal("base"),metadata:kN1}),yMQ=lz.extend({frontmatter:lF,body:H.string()});aA();WA();class vgA extends q2{constructor(){super({entityType:"base",schema:lz,frontmatterSchema:lF})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,lF);if(B.title)return this.buildMarkdown(Q,B)}catch{}return Q}fromMarkdown(A){let Q=this.parseMarkdownFrontmatter(A),B=Q.title??this.extractH1(A)??"Untitled";return{content:A,entityType:"base",metadata:{title:B,...Q.status&&{status:Q.status},...Q.error&&{error:Q.error}}}}parseNoteFrontmatter(A){return this.parseMarkdownFrontmatter(A.content)}parseMarkdownFrontmatter(A){try{return this.parseFrontMatter(A,lF)}catch{return{}}}buildStub(A){let Q={title:A.title,status:"generating"};return{content:this.buildMarkdown("",Q),metadata:{title:A.title,status:"generating"}}}createNoteContent(A,Q){try{let B=this.parseFrontMatter(Q,H.record(H.unknown()));if(Object.keys(B).length===0)return Q;let w={...B,title:B.title??A},$=this.extractBody(Q);return this.buildMarkdown($,w)}catch{return Q}}extractH1(A){return A.match(/^#\s+(.+)$/m)?.[1]?.trim()??null}}var pz=new vgA;WA();var TgA=H.object({defaultPrompt:H.string().default("Create a note summarizing key concepts from my knowledge base")});WA();aA();var jN1=H.object({title:H.string().max(80).describe("A clear, descriptive title for the note (3-8 words)"),body:H.string().describe("Note content in markdown format with clear organization and structure")}),ygA=P1({name:"note:generation",description:"Template for AI to generate notes from prompts",schema:jN1,dataSourceId:"shell:ai-content",requiredPermission:"public",useKnowledgeContext:!0,basePrompt:`You are helping to create personal knowledge notes for research and reference.
|
|
6200
|
+
`).trim();if(!D)throw Error("Could not extract text from the uploaded PDF");return D}finally{await $.destroy()}}aA();WA();import{createHash as LMQ}from"crypto";var VMQ=26214400,EMQ=20,MMQ=60000,RN1=80,CMQ=10,$$A=H.object({renderUrl:H.string().url().optional(),sourceEntityType:H.string().min(1),sourceEntityId:H.string().min(1),attachmentType:H.string().min(1),documentId:H.string().min(1).optional(),title:H.string().min(1).optional(),filename:H.string().min(1).optional(),dedupKey:H.string().min(1).optional(),replace:H.boolean().optional(),pageCount:H.number().int().min(0).optional(),maxPageCount:H.number().int().positive().optional(),maxBytes:H.number().int().positive().optional(),timeoutMs:H.number().int().positive().optional(),width:H.union([H.string(),H.number()]).optional(),height:H.union([H.string(),H.number()]).optional(),format:H.string().optional(),targetEntityType:H.string().min(1).optional(),targetEntityId:H.string().min(1).optional()}),bv=$$A.refine((A)=>A.targetEntityType===void 0&&A.targetEntityId===void 0||A.targetEntityType!==void 0&&A.targetEntityId!==void 0,{message:"targetEntityType and targetEntityId must be provided together",path:["targetEntityId"]});class f$A extends ZB{context;renderPdf;constructor(A,Q,B={}){super(A,{schema:bv,jobTypeName:"document-generate"});this.context=Q;this.renderPdf=B.renderPdf??$X}async getDedupKey(A){if(A.dedupKey!==void 0)return A.dedupKey;if(A.renderUrl!==void 0)return`${A.attachmentType}:${A.sourceEntityType}:${A.sourceEntityId}:${A.renderUrl}`;let Q=`${A.attachmentType}:${A.sourceEntityType}:${A.sourceEntityId}:resolved-attachment`,B=await this.context.entityService.getEntity({entityType:A.sourceEntityType,id:A.sourceEntityId});return B?`${Q}:${B.contentHash}`:Q}async process(A,Q,B){this.logger.debug("Starting document generation job",{jobId:Q,sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType});let w=A.maxPageCount??EMQ,$=A.maxBytes??VMQ,f=A.timeoutMs??MMQ;if(A.pageCount!==void 0&&A.pageCount>w)throw Error(`Refusing to render ${A.pageCount} page PDF; maxPageCount=${w}`);let I=await this.getDedupKey(A),D=yi(A,I),U=A.documentId!==void 0||A.filename!==void 0;if(A.replace!==!0){let Y=await this.findDocumentByDedupKey(I,U?D:void 0);if(Y&&(!U||Y.id===D)){if(A.targetEntityType&&A.targetEntityId)await this.attachDocumentToTarget(A.targetEntityType,A.targetEntityId,Y.id,A);return await this.reportProgress(B,{progress:100,message:"Reusing existing generated document"}),{success:!0,documentId:Y.id,reused:!0}}}await this.reportProgress(B,{progress:20,message:"Rendering PDF document"});try{let Y=await this.resolveDocumentAttachment(A,D,{timeoutMs:f,maxBytes:$}),J=Y.data;if(J.byteLength>$)throw Error(`Rendered PDF exceeds maxBytes=${$}: ${J.byteLength} bytes`);let X=pSA(J);if(X>w)throw Error(`Rendered PDF has ${X} pages, exceeding maxPageCount=${w}`);let G=X>0?X:A.pageCount;await this.reportProgress(B,{progress:70,message:"Storing PDF document"});let Z=A.filename??(A.renderUrl===void 0?Y.filename:`${D}.pdf`),N=Sz.createDocumentEntity({dataUrl:F5A(J),filename:Z,...A.title&&{title:A.title},...G!==void 0&&{pageCount:G},sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType,dedupKey:I});if(await this.context.entityService.getEntity({entityType:"document",id:D}))await this.context.entityService.deleteEntity({entityType:"document",id:D});if(await this.context.entityService.createEntity({entity:{...N,id:D}}),A.targetEntityType&&A.targetEntityId)await this.attachDocumentToTarget(A.targetEntityType,A.targetEntityId,D,A);return await this.reportProgress(B,{progress:100,message:"PDF document generation complete"}),{success:!0,documentId:D,reused:!1}}catch(Y){throw this.logger.error("Document generation failed",{jobId:Q,error:T0(Y)}),Y}}async resolveDocumentAttachment(A,Q,B){if(A.renderUrl!==void 0)return{type:"document",data:await this.renderPdf(A.renderUrl,{timeoutMs:B.timeoutMs,maxBytes:B.maxBytes,printBackground:!0,preferCSSPageSize:!0,...A.width!==void 0&&{width:A.width},...A.height!==void 0&&{height:A.height},...A.format!==void 0&&{format:A.format}}),mimeType:"application/pdf",filename:A.filename??`${Q}.pdf`};let w=await this.context.attachments.resolve({sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType});if(!w)throw Error(`No attachment provider found for ${A.sourceEntityType}/${A.attachmentType}`);if(w.type!=="document")throw Error(`Attachment provider returned ${w.type}; expected document`);return w}async findDocumentByDedupKey(A,Q){let B=await this.context.entityService.listEntities({entityType:"document",options:{filter:{metadata:{dedupKey:A}}}});if(B.length>1)this.logger.warn("Multiple documents share dedupKey; using first",{dedupKey:A,count:B.length,ids:B.map((w)=>w.id),preferredDocumentId:Q});return B.find((w)=>w.id===Q)??B[0]}async attachDocumentToTarget(A,Q,B,w){let $=await this.context.entityService.getEntity({entityType:A,id:Q});if(!$)throw Error(`Target entity not found: ${A}/${Q}`);let{frontmatter:f}=jB($.content),I=Array.isArray(f.documents)?f.documents.filter(RMQ):[],D=w.replace?await this.removeReferencesForSameSourceAttachment(I,B,w):I,U=D.some((Y)=>Y.id===B)?D:[...D,{id:B}];await this.context.entityService.updateEntity({entity:{...$,content:Y4($.content,"documents",U)}})}async removeReferencesForSameSourceAttachment(A,Q,B){let w=[];for(let $ of A){if($.id===Q){w.push($);continue}let f=await this.context.entityService.getEntity({entityType:"document",id:$.id});if(!f||!bMQ(f,B))w.push($)}return w}}function yi(A,Q){let B=`${A.attachmentType}:${A.sourceEntityType}:${A.sourceEntityId}:${A.renderUrl??"resolved-attachment"}`,w=A.documentId??A.filename?.replace(/\.pdf$/i,"")??Q??B,$=A.replace===!0&&A.documentId===void 0?`${w}-${Date.now()}`:w;return OMQ($)}function OMQ(A){let Q=X1(A.replace(/[/:]+/g," "))||`document-${bN1(A)}`;if(Q.length<=RN1)return Q;let B=`-${bN1(A)}`;return`${Q.slice(0,RN1-B.length).replace(/-+$/g,"")}${B}`}function bN1(A){return LMQ("sha256").update(A).digest("hex").slice(0,CMQ)}function RMQ(A){return typeof A==="object"&&A!==null&&"id"in A&&typeof A.id==="string"&&A.id.length>0}function bMQ(A,Q){return A.metadata.sourceEntityType===Q.sourceEntityType&&A.metadata.sourceEntityId===Q.sourceEntityId&&A.metadata.attachmentType===Q.attachmentType}aA();function PgA(A,Q){return[oQ(A,"generate",'Preview or prepare a PDF document attachment from a source attachment or render URL. For save/regenerate durable document requests, including deck carousel PDFs and printable post/project/product PDFs, prefer system_create with entityType: "document" and from.',$$A,async(B,w)=>{let $=bv.safeParse(B);if(!$.success)return X$($.error.message);let f=yi($.data),I=await Q({...$.data,documentId:f},w),D=$.data.filename??`${f}.pdf`;return U8({jobId:I,documentId:f,attachment:{mediaType:"application/pdf",url:`/api/chat/attachments/document?id=${encodeURIComponent(f)}`,downloadUrl:`/api/chat/attachments/document?id=${encodeURIComponent(f)}&download=1`,filename:D,source:{entityType:"document",entityId:f,attachmentType:$.data.attachmentType}}})},{cli:{name:"document-generate"}})]}var PN1={name:"@brains/document-plugin",private:!0,version:"0.2.0-alpha.120",description:"Document entity type for generated PDFs and publishable document attachments",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/contracts":"workspace:*","@brains/document":"workspace:*","@brains/media-renderer":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/typescript-config":"workspace:*","bun-types":"latest",typescript:"^5.3.3"}};var kMQ=H.object({}),kgA={namespace:"upload",refKind:"upload",routePath:"/api/chat/uploads"};function jMQ(A,Q){let B=A.title?.trim();if(B)return B;return Q.replace(/\.[^.]+$/,"").trim()||Q}function _MQ(A,Q){return`data:${A};base64,${Q.toString("base64")}`}function vMQ(A){let Q=encodeURIComponent(A.entityId);return{mediaType:"application/pdf",url:`/api/chat/attachments/document?id=${Q}`,downloadUrl:`/api/chat/attachments/document?id=${Q}&download=1`,filename:A.filename,source:{entityType:"document",entityId:A.entityId,attachmentType:"uploaded"}}}class jgA extends YB{entityType=Sz.entityType;schema=Gv;adapter=Sz;pluginContext;constructor(){super("document",PN1,{},kMQ)}async onRegister(A){this.pluginContext=A,A.entities.register(this.entityType,this.schema,this.adapter,{embeddable:!1}),A.entities.registerCreateInterceptor(this.entityType,(Q)=>this.interceptCreate(Q)),A.jobs.registerHandler("generate",new f$A(this.logger.child("DocumentGenerationJobHandler"),A))}async interceptCreate(A){let Q=this.pluginContext;if(A.from?.kind===kgA.refKind){if(!Q)return{kind:"handled",result:{success:!1,error:"Plugin context not initialized"}};return this.promoteUpload(A,Q)}if(!A.from)return{kind:"continue",input:A};if(!Q)return{kind:"handled",result:{success:!1,error:"Plugin context not initialized"}};let B=bv.parse({sourceEntityType:A.from.sourceEntityType,sourceEntityId:A.from.sourceEntityId,attachmentType:A.from.attachmentType,...A.title&&{title:A.title},...A.replace===!0&&{replace:!0},...A.targetEntityType&&{targetEntityType:A.targetEntityType},...A.targetEntityId&&{targetEntityId:A.targetEntityId}}),w=await this.getDedupKey(B,Q),f=(B.replace===!0?void 0:await this.findExistingDocument(w,Q))?.id??yi(B,w),I=await Q.jobs.enqueue({type:"generate",data:{...B,dedupKey:w,documentId:f}}),D=`${f}.pdf`;return{kind:"handled",result:{success:!0,data:{entityId:f,jobId:I,status:"generating",attachment:{mediaType:"application/pdf",url:`/api/chat/attachments/document?id=${encodeURIComponent(f)}`,downloadUrl:`/api/chat/attachments/document?id=${encodeURIComponent(f)}&download=1`,filename:D,source:{entityType:"document",entityId:f,attachmentType:B.attachmentType}}}}}}async promoteUpload(A,Q){let B=A.from;if(B?.kind!==kgA.refKind)return{kind:"handled",result:{success:!1,error:"Unsupported upload ref kind"}};let w;try{w=await Q.uploads.scoped(kgA).read(B.id)}catch{return{kind:"handled",result:{success:!1,error:"Upload ref not found"}}}if(w.record.mediaType!=="application/pdf")return{kind:"handled",result:{success:!1,error:"Only PDF uploads can be promoted to document entities"}};let $=jMQ(A,w.record.filename),f=X1($);if(!f)return{kind:"handled",result:{success:!1,error:"Could not derive a document id from the uploaded filename. Provide a title."}};let I=new Date().toISOString(),D=Sz.createDocumentEntity({dataUrl:_MQ(w.record.mediaType,w.content),filename:w.record.filename,title:$,attachmentType:"uploaded",dedupKey:`upload:${B.kind}:${B.id}`}),U=await Q.entityService.createEntity({entity:{id:f,...D,created:I,updated:I},options:{deduplicateId:!0}});return{kind:"handled",result:{success:!0,data:{entityId:U.entityId,status:"created",attachment:vMQ({entityId:U.entityId,filename:w.record.filename})}}}}async getDedupKey(A,Q){if(A.dedupKey!==void 0)return A.dedupKey;if(A.renderUrl!==void 0)return`${A.attachmentType}:${A.sourceEntityType}:${A.sourceEntityId}:${A.renderUrl}`;let B=`${A.attachmentType}:${A.sourceEntityType}:${A.sourceEntityId}:resolved-attachment`,w=await Q.entityService.getEntity({entityType:A.sourceEntityType,id:A.sourceEntityId});return w?`${B}:${w.contentHash}`:B}async findExistingDocument(A,Q){return(await Q.entityService.listEntities({entityType:"document",options:{filter:{metadata:{dedupKey:A}}}}))[0]}async getInstructions(){return'For durable raw PDF saves/promotions from uploaded PDFs, call system_create with entityType: "document", the exact upload object shown in the current turn or conversation "Available upload refs" hint, and no transform. Do this only after the user explicitly asks to save/import/promote the raw PDF as a document. If that hint is absent, omit upload entirely; never invent upload IDs or placeholder upload refs. Uploaded PDFs are not decks; raw upload promotion preserves the PDF as a document. Do not use entityType: "base" or transform: "extract-markdown" unless the user asks to turn the upload into a note/markdown. For generated/source-derived PDFs, call system_create with entityType: "document" and sourceAttachment. Deck carousel PDFs use sourceAttachment: { sourceEntityType: "deck", sourceEntityId: <deck ID>, attachmentType: "carousel" }. Printable PDFs for blog posts, projects, and products use sourceAttachment with attachmentType: "printable" and sourceEntityType "post", "project", or "product". Omit upload and sourceAttachment entirely for ordinary direct document creates that use content, prompt, or url. Include targetEntityType/targetEntityId when the user asks to attach the saved document to another entity. Use replace: true when they ask to regenerate or replace a saved PDF. Only use document_generate for explicit preview/prepare requests where they need an immediate PDF attachment. Do not use generic attachment types like "document".'}async getTools(){let A=this.pluginContext;if(!A)throw Error("Plugin context not initialized");return PgA(this.id,(Q,B)=>A.jobs.enqueue({type:"generate",data:Q,toolContext:B}))}}function _gA(){return new jgA}aA();WA();WA();aA();var TMQ=H.enum(["generating","failed"]),lF=H.object({title:H.string().optional(),status:TMQ.optional(),error:H.string().optional()}),kN1=lF.pick({title:!0,status:!0,error:!0}).extend({title:H.string()}),lz=A2.extend({entityType:H.literal("base"),metadata:kN1}),yMQ=lz.extend({frontmatter:lF,body:H.string()});aA();WA();class vgA extends q2{constructor(){super({entityType:"base",schema:lz,frontmatterSchema:lF})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,lF);if(B.title)return this.buildMarkdown(Q,B)}catch{}return Q}fromMarkdown(A){let Q=this.parseMarkdownFrontmatter(A),B=Q.title??this.extractH1(A)??"Untitled";return{content:A,entityType:"base",metadata:{title:B,...Q.status&&{status:Q.status},...Q.error&&{error:Q.error}}}}parseNoteFrontmatter(A){return this.parseMarkdownFrontmatter(A.content)}parseMarkdownFrontmatter(A){try{return this.parseFrontMatter(A,lF)}catch{return{}}}buildStub(A){let Q={title:A.title,status:"generating"};return{content:this.buildMarkdown("",Q),metadata:{title:A.title,status:"generating"}}}createNoteContent(A,Q){try{let B=this.parseFrontMatter(Q,H.record(H.unknown()));if(Object.keys(B).length===0)return Q;let w={...B,title:B.title??A},$=this.extractBody(Q);return this.buildMarkdown($,w)}catch{return Q}}extractH1(A){return A.match(/^#\s+(.+)$/m)?.[1]?.trim()??null}}var pz=new vgA;WA();var TgA=H.object({defaultPrompt:H.string().default("Create a note summarizing key concepts from my knowledge base")});WA();aA();var jN1=H.object({title:H.string().max(80).describe("A clear, descriptive title for the note (3-8 words)"),body:H.string().describe("Note content in markdown format with clear organization and structure")}),ygA=P1({name:"note:generation",description:"Template for AI to generate notes from prompts",schema:jN1,dataSourceId:"shell:ai-content",requiredPermission:"public",useKnowledgeContext:!0,basePrompt:`You are helping to create personal knowledge notes for research and reference.
|
|
6201
6201
|
|
|
6202
6202
|
Your task is to generate a well-structured note based on the user's prompt.
|
|
6203
6203
|
|
|
@@ -6212,7 +6212,7 @@ title: ${JSON.stringify(A)}
|
|
|
6212
6212
|
---
|
|
6213
6213
|
|
|
6214
6214
|
${Q.trim()}
|
|
6215
|
-
`}var mMQ={namespace:"upload",refKind:"upload",routePath:"/api/chat/uploads"},uMQ=H.object({uploadId:H.string().min(1),title:H.string().optional()});class SgA extends ZB{context;constructor(A,Q){super(A,{schema:uMQ,jobTypeName:"upload-import"});this.context=Q}async process(A,Q,B){await this.reportProgress(B,{progress:10,message:"Reading uploaded file"});let w=await this.context.uploads.scoped(mMQ).read(A.uploadId);await this.reportProgress(B,{progress:35,message:"Extracting markdown from upload"});let $=await yN1({upload:w,...A.title!==void 0?{title:A.title}:{}});await this.reportProgress(B,{progress:80,message:"Saving imported note"});let f=new Date().toISOString(),I=pz.fromMarkdown($.content),D=await this.context.entityService.createEntity({entity:{id:$.id,entityType:"base",content:$.content,metadata:{title:$.title,...I.metadata},created:f,updated:f},options:{deduplicateId:!0}});return await this.reportProgress(B,{progress:100,message:"Upload imported as markdown note"}),{entityId:D.entityId,status:"created"}}summarizeDataForLog(A){return{uploadId:A.uploadId,hasTitle:A.title!==void 0}}}aA();async function xN1({entity:A,config:Q}){let B=lz.parse(A),w=R2(B.content,lF);return{$type:"ai.rizom.brain.note",title:B.metadata.title,body:w.content,format:"text/markdown",...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"base",sourceEntityId:B.id,createdAt:B.created,...B.updated&&{updatedAt:B.updated}}}function ggA(){return{entityType:"base",collection:"ai.rizom.brain.note",lexicon:Gw["ai.rizom.brain.note"],validate:!1,buildRecord:xN1}}var SN1={name:"@brains/note",private:!0,version:"0.2.0-alpha.
|
|
6215
|
+
`}var mMQ={namespace:"upload",refKind:"upload",routePath:"/api/chat/uploads"},uMQ=H.object({uploadId:H.string().min(1),title:H.string().optional()});class SgA extends ZB{context;constructor(A,Q){super(A,{schema:uMQ,jobTypeName:"upload-import"});this.context=Q}async process(A,Q,B){await this.reportProgress(B,{progress:10,message:"Reading uploaded file"});let w=await this.context.uploads.scoped(mMQ).read(A.uploadId);await this.reportProgress(B,{progress:35,message:"Extracting markdown from upload"});let $=await yN1({upload:w,...A.title!==void 0?{title:A.title}:{}});await this.reportProgress(B,{progress:80,message:"Saving imported note"});let f=new Date().toISOString(),I=pz.fromMarkdown($.content),D=await this.context.entityService.createEntity({entity:{id:$.id,entityType:"base",content:$.content,metadata:{title:$.title,...I.metadata},created:f,updated:f},options:{deduplicateId:!0}});return await this.reportProgress(B,{progress:100,message:"Upload imported as markdown note"}),{entityId:D.entityId,status:"created"}}summarizeDataForLog(A){return{uploadId:A.uploadId,hasTitle:A.title!==void 0}}}aA();async function xN1({entity:A,config:Q}){let B=lz.parse(A),w=R2(B.content,lF);return{$type:"ai.rizom.brain.note",title:B.metadata.title,body:w.content,format:"text/markdown",...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"base",sourceEntityId:B.id,createdAt:B.created,...B.updated&&{updatedAt:B.updated}}}function ggA(){return{entityType:"base",collection:"ai.rizom.brain.note",lexicon:Gw["ai.rizom.brain.note"],validate:!1,buildRecord:xN1}}var SN1={name:"@brains/note",private:!0,version:"0.2.0-alpha.120",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/atproto-contracts":"workspace:*","@brains/contracts":"workspace:*","@brains/document":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var gN1={namespace:"upload",refKind:"upload",routePath:"/api/chat/uploads"};class hgA extends jQ{entityType=pz.entityType;schema=lz;adapter=pz;unregisterAtprotoProjection;constructor(A={}){super("note",SN1,A,TgA)}async interceptCreate(A,Q,B){if(A.from?.kind!==gN1.refKind)return{kind:"continue",input:A};if(A.transform!=="extract-markdown")return{kind:"handled",result:{success:!1,error:'Importing an upload as a note requires transform: "extract-markdown"'}};let w=A.from.id,$;try{$=await B.uploads.scoped(gN1).readRecord(w)}catch{return{kind:"handled",result:{success:!1,error:"Upload ref not found"}}}try{if(!TN1($.mediaType))return{kind:"handled",result:{success:!1,error:"Only text, JSON, and PDF uploads can be imported as markdown notes"}};let f=xgA({filename:$.filename,...A.title!==void 0?{title:A.title}:{}}),I=await B.jobs.enqueue({type:"upload-import",data:{uploadId:w,...A.title!==void 0?{title:A.title}:{}}});return{kind:"handled",result:{success:!0,data:{entityId:f.id,status:"generating",jobId:I}}}}catch(f){return{kind:"handled",result:{success:!1,error:f instanceof Error?f.message:"Failed to import upload as markdown"}}}}createGenerationHandler(A){return new I$A(this.logger.child("NoteGenerationJobHandler"),A)}getTemplates(){return{generation:ygA}}async onRegister(A){A.jobs.registerHandler("upload-import",new SgA(this.logger.child("UploadMarkdownImportJobHandler"),A)),A.eval.registerHandler("generateNote",async(Q)=>{let B=H.object({prompt:H.string()}).parse(Q);return A.ai.generate({prompt:B.prompt,templateName:"note:generation"})}),this.unregisterAtprotoProjection=d6.getInstance().register(ggA())}async getInstructions(){return'To turn an uploaded text or PDF file into an editable markdown note, call system_create with entityType: "base", the exact upload object from the current turn or conversation upload refs hint, and transform: "extract-markdown". Use this only when the user explicitly asks to import, extract, or turn the upload into a note/markdown. Do not use this note-import pattern for raw file saves/promotions such as saving a PDF as a document or saving an image as an image; those use the raw upload with entityType "document" or "image" and no transform. Omit transform for ordinary direct note creates.'}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}}function YC(A={}){return new hgA(A)}aA();WA();WA();aA();var hN1=H.object({ref:H.string(),label:H.string()}),mN1=H.enum(["pending","draft","published"]),pF=H.object({status:mN1,title:H.string(),url:H.string().url(),description:H.string().optional(),domain:H.string(),capturedAt:H.string().datetime(),source:hN1}),uN1=pF.pick({title:!0,status:!0}),JC=A2.extend({entityType:H.literal("link"),metadata:uN1}),mgA=H.object({enableSummarization:H.boolean().default(!0).describe("Generate AI summaries for captured links"),jinaApiKey:H.string().optional().describe("Jina Reader API key for higher rate limits (500 RPM vs 20 RPM without key)")});aA();class iz extends q2{constructor(){super({entityType:"link",schema:JC,frontmatterSchema:pF})}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,pF),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 Pv=new iz;aA();WA();var lMQ=H.object({success:H.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:H.string().describe("If success is false, explain why content could not be extracted. Use an empty string when success is true."),title:H.string().max(80).describe("The page title - extract from the content or create a descriptive one. Leave empty string if success is false."),description:H.string().describe("A one-sentence description of what the page is about. Leave empty string if success is false."),summary:H.string().describe("A 1-2 paragraph summary of the main content. Leave empty string if success is false.")}),cN1=P1({name:"link:extraction",description:"Extract structured content from webpage markdown",dataSourceId:"shell:ai-content",schema:lMQ,basePrompt:`You are an expert at extracting key information from webpage content.
|
|
6216
6216
|
|
|
6217
6217
|
You will receive webpage content in markdown format. Your job is to extract structured information from it.
|
|
6218
6218
|
|
|
@@ -6234,7 +6234,7 @@ Accuracy rules:
|
|
|
6234
6234
|
|
|
6235
6235
|
`))return{success:!1,error:I.trim(),errorType:"fetch_failed"};return{success:!0,content:I}}catch(B){return this.handleFetchError(B,A)}}handleHttpError(A,Q){if(A===400)return{success:!1,error:`Invalid or non-existent URL: ${Q}`,errorType:"url_not_found"};if(A===404)return{success:!1,error:`Page not found: ${Q}`,errorType:"url_not_found"};if(A>=500)return{success:!1,error:`Server error while fetching ${Q}`,errorType:"url_unreachable"};return{success:!1,error:`HTTP ${A} error while fetching ${Q}`,errorType:"fetch_failed"}}handleFetchError(A,Q){if(A instanceof Error){if(A.name==="AbortError")return{success:!1,error:`Request timeout while fetching ${Q}`,errorType:"url_unreachable"};if(A.message.includes("ENOTFOUND")||A.message.includes("getaddrinfo"))return{success:!1,error:`Domain not found: ${new URL(Q).hostname}`,errorType:"url_not_found"};if(A.message.includes("ECONNREFUSED")||A.message.includes("ETIMEDOUT"))return{success:!1,error:`Could not connect to ${Q}`,errorType:"url_unreachable"};return{success:!1,error:`Failed to fetch ${Q}: ${A.message}`,errorType:"fetch_failed"}}return{success:!1,error:`Unknown error fetching ${Q}`,errorType:"fetch_failed"}}}import{createHash as dMQ}from"crypto";class XC{static URL_PATTERN=/https?:\/\/[^\s<>"{}|\\^`[\]]+?(?=[,;:\s]|$)/gi;static extractUrls(A){let Q=A.match(XC.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=dMQ("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}}}aA();WA();H6();var nMQ=H.object({url:H.string().url(),metadata:H.object({interfaceId:H.string().optional(),userId:H.string().optional(),channelId:H.string().optional(),channelName:H.string().optional(),timestamp:H.string().optional()}).optional()}),oow=H.object({success:H.boolean(),entityId:H.string().optional(),title:H.string().optional(),url:H.string().optional(),status:H.enum(["pending","draft","published"]).optional(),error:H.string().optional()});class U$A extends ZB{context;linkAdapter;urlFetcher;constructor(A,Q,B){super(A,{schema:nMQ,jobTypeName:"link-capture"});this.context=Q,this.linkAdapter=new iz,this.urlFetcher=new kv(B?.jinaApiKey?{jinaApiKey:B.jinaApiKey}:void 0)}async process(A,Q,B){let{url:w,metadata:$}=A;try{await B.report({progress:zQ.START,total:100,message:"Starting link capture"});let f=XC.generateEntityId(w);await B.report({progress:zQ.INIT,total:100,message:"Checking for existing link"});let I=await this.context.entityService.getEntity({entityType:"link",id:f});if(I){this.logger.info("Link already captured, returning existing",{url:w,entityId:f});let{frontmatter:Z}=this.linkAdapter.parseLinkContent(I.content);return{success:!0,entityId:I.id,title:Z.title,url:w,status:I.metadata.status}}await B.report({progress:zQ.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:zQ.PROCESS,total:100,message:"Extracting content with AI"});let U=await this.context.ai.generate({templateName:"link:extraction",prompt:D.success?`Extract structured information from this webpage content:
|
|
6236
6236
|
|
|
6237
|
-
${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:U}),await B.report({progress:zQ.EXTRACT,total:100,message:"Processing extraction results"});let Y=this.resolveSource($),J=new Date().toISOString();if(U.success===!1||!U.title||!U.description||!U.summary){let Z=U.title||new URL(w).hostname;this.logger.info("Incomplete extraction, saving as pending",{url:w}),await B.report({progress:zQ.SAVE,total:100,message:"Saving link as pending"});let N=this.linkAdapter.createLinkContent({status:"pending",title:Z,url:w,description:U.description,summary:U.summary,domain:new URL(w).hostname,capturedAt:J,source:Y}),L=await this.context.entityService.createEntity({entity:{id:f,entityType:"link",content:N,metadata:{status:"pending",title:Z}}});return await B.report({progress:zQ.COMPLETE,total:100,message:"Link saved (pending)"}),{success:!0,entityId:L.entityId,title:Z,url:w,status:"pending"}}await B.report({progress:zQ.SAVE,total:100,message:`Saving link: "${U.title}"`});let X=this.linkAdapter.createLinkContent({status:"draft",title:U.title,url:w,description:U.description,summary:U.summary,domain:new URL(w).hostname,capturedAt:J,source:Y}),G=await this.context.entityService.createEntity({entity:{id:f,entityType:"link",content:X,metadata:{status:"draft",title:U.title}}});return await B.report({progress:zQ.COMPLETE,total:100,message:`Link captured: "${U.title}"`}),{success:!0,entityId:G.entityId,title:U.title,url:w,status:"draft"}}catch(f){return this.logger.error("Link capture job failed",{error:f,jobId:Q,data:A}),$5.failure(f)}}resolveSource(A){let Q=A?.channelId,B=A?.channelName;if(Q)return{ref:`matrix:${Q}`,label:B??Q};let w=A?.interfaceId??"cli";return{ref:`${w}:local`,label:w.toUpperCase()}}summarizeDataForLog(A){return{url:A.url,interfaceId:A.metadata?.interfaceId}}}async function iN1({entity:A,config:Q}){let B=JC.parse(A),{frontmatter:w,summary:$}=Pv.parseLinkContent(B.content);return{$type:"ai.rizom.brain.link",title:w.title,url:w.url,...w.description&&{description:w.description},...$&&{summary:$},domain:w.domain,capturedAt:w.capturedAt,source:w.source,...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"link",sourceEntityId:B.id,createdAt:B.created,...B.updated&&{updatedAt:B.updated}}}function rgA(){return{entityType:"link",collection:"ai.rizom.brain.link",lexicon:Gw["ai.rizom.brain.link"],validate:!1,buildRecord:iN1}}var rN1={name:"@brains/link",private:!0,version:"0.2.0-alpha.
|
|
6237
|
+
${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:U}),await B.report({progress:zQ.EXTRACT,total:100,message:"Processing extraction results"});let Y=this.resolveSource($),J=new Date().toISOString();if(U.success===!1||!U.title||!U.description||!U.summary){let Z=U.title||new URL(w).hostname;this.logger.info("Incomplete extraction, saving as pending",{url:w}),await B.report({progress:zQ.SAVE,total:100,message:"Saving link as pending"});let N=this.linkAdapter.createLinkContent({status:"pending",title:Z,url:w,description:U.description,summary:U.summary,domain:new URL(w).hostname,capturedAt:J,source:Y}),L=await this.context.entityService.createEntity({entity:{id:f,entityType:"link",content:N,metadata:{status:"pending",title:Z}}});return await B.report({progress:zQ.COMPLETE,total:100,message:"Link saved (pending)"}),{success:!0,entityId:L.entityId,title:Z,url:w,status:"pending"}}await B.report({progress:zQ.SAVE,total:100,message:`Saving link: "${U.title}"`});let X=this.linkAdapter.createLinkContent({status:"draft",title:U.title,url:w,description:U.description,summary:U.summary,domain:new URL(w).hostname,capturedAt:J,source:Y}),G=await this.context.entityService.createEntity({entity:{id:f,entityType:"link",content:X,metadata:{status:"draft",title:U.title}}});return await B.report({progress:zQ.COMPLETE,total:100,message:`Link captured: "${U.title}"`}),{success:!0,entityId:G.entityId,title:U.title,url:w,status:"draft"}}catch(f){return this.logger.error("Link capture job failed",{error:f,jobId:Q,data:A}),$5.failure(f)}}resolveSource(A){let Q=A?.channelId,B=A?.channelName;if(Q)return{ref:`matrix:${Q}`,label:B??Q};let w=A?.interfaceId??"cli";return{ref:`${w}:local`,label:w.toUpperCase()}}summarizeDataForLog(A){return{url:A.url,interfaceId:A.metadata?.interfaceId}}}async function iN1({entity:A,config:Q}){let B=JC.parse(A),{frontmatter:w,summary:$}=Pv.parseLinkContent(B.content);return{$type:"ai.rizom.brain.link",title:w.title,url:w.url,...w.description&&{description:w.description},...$&&{summary:$},domain:w.domain,capturedAt:w.capturedAt,source:w.source,...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"link",sourceEntityId:B.id,createdAt:B.created,...B.updated&&{updatedAt:B.updated}}}function rgA(){return{entityType:"link",collection:"ai.rizom.brain.link",lexicon:Gw["ai.rizom.brain.link"],validate:!1,buildRecord:iN1}}var rN1={name:"@brains/link",private:!0,version:"0.2.0-alpha.120",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/atproto-contracts":"workspace:*","@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class dgA extends jQ{entityType=Pv.entityType;schema=JC;adapter=Pv;shell;unregisterAtprotoProjection;constructor(A={}){super("link",rN1,A,mgA)}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 U$A(this.logger.child("LinkCaptureJobHandler"),this.context,this.config.jinaApiKey?{jinaApiKey:this.config.jinaApiKey}:void 0),this.id),Q}async interceptCreate(A,Q,B){if(A.content)try{let f=this.adapter.fromMarkdown(A.content).metadata,I=typeof f?.title==="string"?f.title:void 0,D=typeof f?.status==="string"?f.status:void 0,U=this.extractFirstUrl(A.content);if(I&&D&&U){let Y=X1(U)||X1(I)||`${A.entityType}-${Date.now()}`,J=new Date().toISOString();return{kind:"handled",result:{success:!0,data:{entityId:(await B.entityService.createEntity({entity:{id:Y,entityType:A.entityType,content:A.content,metadata:{title:I,status:D},created:J,updated:J}})).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 U$A(this.logger.child("LinkCaptureJobHandler"),A,this.config.jinaApiKey?{jinaApiKey:this.config.jinaApiKey}:void 0)}getTemplates(){return{extraction:cN1,"link-list":lN1,"link-detail":pN1}}getDataSources(){return[new igA(this.logger.child("LinksDataSource"))]}async onRegister(A){this.unregisterAtprotoProjection=d6.getInstance().register(rgA()),A.eval.registerHandler("extractContent",async(Q)=>{let{url:B}=H.object({url:H.string().url()}).parse(Q),$=await new kv(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:
|
|
6238
6238
|
|
|
6239
6239
|
${$.content}`,data:{url:B,hasContent:!0},interfacePermissionGrant:"public"})})}extractFirstUrl(...A){for(let Q of A){if(!Q)continue;let[B]=XC.extractUrls(Q);if(B)return B}return}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}}function dN1(A={}){return new dgA(A)}var WC=dN1;WA();var Lsw=H.object({id:H.string().optional(),metadata:H.object({conversationId:H.string().optional(),interfaceId:H.string().optional(),userId:H.string().optional(),messageId:H.string().optional(),timestamp:H.string().optional()}).optional()});aA();WA();Ew();WA();aA();var nN1=H.enum(["generating","draft","published","failed"]),O$=H.object({title:H.string(),slug:H.string().optional(),status:nN1,publishedAt:H.string().datetime().optional(),description:H.string(),year:H.number(),coverImageId:H.string().optional(),ogImageId:H.string().optional(),url:H.string().url().optional()}),oN1=O$.pick({title:!0,status:!0,publishedAt:!0,year:!0}).extend({slug:H.string(),error:H.string().optional()}),rz=A2.extend({entityType:H.literal("project"),metadata:oN1}),Y$A=H.object({context:H.string(),problem:H.string(),solution:H.string(),outcome:H.string()}),Si=rz.extend({frontmatter:O$,body:H.string(),structuredContent:Y$A.optional(),coverImageUrl:H.string().optional(),ogImageUrl:H.string().optional()}),jv=Si.extend({url:H.string().optional(),typeLabel:H.string().optional(),coverImageUrl:H.string().optional(),ogImageUrl:H.string().optional(),coverImageWidth:H.number().optional(),coverImageHeight:H.number().optional()}),sMQ=Si.extend({url:H.string(),typeLabel:H.string(),coverImageUrl:H.string().optional(),ogImageUrl:H.string().optional(),coverImageWidth:H.number().optional(),coverImageHeight:H.number().optional()});aA();WA();o$();class ngA extends lB{constructor(){super(Y$A,{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 ogA=new ngA;class sgA extends q2{constructor(){super({entityType:"project",schema:rz,frontmatterSchema:O$,supportsCoverImage:!0,bodyFormatter:ogA})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,O$),w={...B,slug:B.slug??A.metadata.slug};return this.buildMarkdown(Q,w)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,O$),B=Q.slug??X1(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,O$)}parseStructuredContent(A){return ogA.parse(this.extractBody(A.content))}createProjectContent(A,Q){let B=ogA.format(Q);return this.buildMarkdown(B,A)}buildStub(A){let Q=new Date().getUTCFullYear(),B={title:A.title,slug:A.id,status:"generating",description:"",year:Q};return{content:this.buildMarkdown("",B),metadata:{title:A.title,slug:A.id,status:"generating",year:Q}}}}var dz=new sgA;WA();var agA=H.object({});import{jsxDEV as MD,Fragment as tMQ}from"preact/jsx-dev-runtime";var aMQ=({project:A})=>{let{frontmatter:Q,url:B,coverImageUrl:w}=A;return MD(PB,{href:B,children:[w&&MD("img",{src:w,alt:Q.title,className:"w-full h-56 object-cover rounded-md mb-4"},void 0,!1,void 0,this),MD(Y9,{children:Q.title},void 0,!1,void 0,this),MD("p",{className:"text-theme leading-relaxed",children:Q.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},tgA=({projects:A,pageTitle:Q,pagination:B,baseUrl:w="/projects"})=>{let $=Q??"Projects",f=B?.totalItems??A.length,I=`Browse all ${f} ${f===1?"project":"projects"}`;return MD(tMQ,{children:[MD(KQ,{title:$,description:I},void 0,!1,void 0,this),MD("div",{className:"project-list bg-theme",children:MD("div",{className:"container mx-auto px-6 md:px-12 max-w-5xl py-16 md:py-24",children:[MD("h1",{className:"text-4xl font-bold text-heading mb-12",children:$},void 0,!1,void 0,this),MD("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-8",children:A.map((D)=>MD(aMQ,{project:D},D.id,!1,void 0,this))},void 0,!1,void 0,this),B&&B.totalPages>1&&MD("div",{className:"mt-12",children:MD(VF,{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 fw,Fragment as sN1}from"preact/jsx-dev-runtime";var eMQ=({prevProject:A,nextProject:Q})=>{if(!A&&!Q)return null;return fw("nav",{className:"pt-12 mt-12 border-t border-theme-muted",children:fw("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[A?fw(PB,{href:A.url,variant:"compact",children:[fw("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Previous"},void 0,!1,void 0,this),fw("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):fw("div",{},void 0,!1,void 0,this),Q&&fw(PB,{href:Q.url,variant:"compact",className:"md:text-right",children:[fw("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Next"},void 0,!1,void 0,this),fw("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)},J$A=({title:A,content:Q})=>{if(!Q)return null;return fw("section",{className:"mb-12",children:[fw("h2",{className:"text-2xl font-bold text-heading mb-4",children:A},void 0,!1,void 0,this),fw(V$,{markdown:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},egA=({project:A,prevProject:Q,nextProject:B})=>{let{frontmatter:w,structuredContent:$,metadata:f,coverImageUrl:I}=A,D=A.ogImageUrl??I;return fw(sN1,{children:[fw(KQ,{title:w.title,description:w.description,...D?{ogImage:D}:{},ogType:"article"},void 0,!1,void 0,this),fw("article",{className:"project-detail",children:fw("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:fw("div",{className:"max-w-3xl mx-auto",children:[I&&A.coverImageWidth&&A.coverImageHeight&&fw(qF,{src:I,alt:w.title,width:A.coverImageWidth,height:A.coverImageHeight,className:"mb-8 shadow-lg"},void 0,!1,void 0,this),fw("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),fw("div",{className:"flex flex-wrap items-center gap-4 text-theme-muted mb-8",children:[fw("span",{className:"text-sm",children:f.year},void 0,!1,void 0,this),w.url&&fw(sN1,{children:[fw("span",{className:"text-theme-muted",children:"|"},void 0,!1,void 0,this),fw("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),fw("p",{className:"text-lg text-theme mb-12 leading-relaxed",children:w.description},void 0,!1,void 0,this),$&&fw("div",{className:"case-study",children:[fw(J$A,{title:"Context",content:$.context},void 0,!1,void 0,this),fw(J$A,{title:"Problem",content:$.problem},void 0,!1,void 0,this),fw(J$A,{title:"Solution",content:$.solution},void 0,!1,void 0,this),fw(J$A,{title:"Outcome",content:$.outcome},void 0,!1,void 0,this)]},void 0,!0,void 0,this),fw(eMQ,{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)};WA();aA();var ACQ=H.object({title:H.string().max(80).describe("A clear, compelling project title (3-8 words). Should capture the essence of the project."),description:H.string().describe("A 1-2 sentence summary of the project for portfolio cards. Focus on the core value delivered."),context:H.string().describe("Background information: Who was the client/user? What was the situation? What constraints existed? (2-4 paragraphs)"),problem:H.string().describe("The challenge: What specific problem needed solving? What were the pain points? (2-3 paragraphs)"),solution:H.string().describe("The approach: What was built? What technologies/methods were used? How did it work? (3-5 paragraphs)"),outcome:H.string().describe("The results: What impact did this have? What metrics improved? What was learned? (2-3 paragraphs)")}),AhA=P1({name:"portfolio:generation",description:"Template for AI to generate portfolio project case studies",schema:ACQ,dataSourceId:"shell:ai-content",requiredPermission:"public",useKnowledgeContext:!0,basePrompt:`You are helping to create a professional portfolio case study based on REAL project information.
|
|
6240
6240
|
|
|
@@ -6410,7 +6410,7 @@ Use the project request as the primary source of truth. If retrieved knowledge c
|
|
|
6410
6410
|
font: 10px/1.45 var(--font-mono, "JetBrains Mono", ui-monospace, monospace);
|
|
6411
6411
|
}
|
|
6412
6412
|
.printable-footer a { color: inherit; text-decoration: none; overflow-wrap: anywhere; }
|
|
6413
|
-
`}},void 0,!1,void 0,this),R$("section",{className:"project-shell",children:[R$("header",{className:"project-hero",children:[R$("div",{className:"project-index",children:[Q.brandLabel&&R$("p",{className:"printable-kicker",children:Q.brandLabel},void 0,!1,void 0,this),Q.year&&R$("span",{className:"project-year",children:Q.year},void 0,!1,void 0,this)]},void 0,!0,void 0,this),R$("div",{className:"project-title-panel",children:[R$("span",{className:"printable-kind",children:"Case study dossier"},void 0,!1,void 0,this),R$("h1",{className:"printable-title",children:Q.title},void 0,!1,void 0,this),Q.description&&R$("p",{className:"printable-description",children:Q.description},void 0,!1,void 0,this),R$("div",{className:"printable-meta",children:[Q.year&&R$("span",{children:Q.year},void 0,!1,void 0,this),Q.url&&R$("span",{children:Q.url},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Q.coverImageUrl&&R$("img",{className:"printable-cover",src:Q.coverImageUrl,alt:""},void 0,!1,void 0,this),R$(V$,{markdown:Q.body,className:"printable-body"},void 0,!1,void 0,this),(Q.canonicalUrl||Q.url||Q.brandLabel)&&R$("footer",{className:"printable-footer",children:[R$("span",{children:Q.brandLabel??"Project printable"},void 0,!1,void 0,this),Q.canonicalUrl||Q.url?R$("a",{href:Q.canonicalUrl??Q.url,children:Q.canonicalUrl??Q.url},void 0,!1,void 0,this):null]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}var YCQ=26214400,JCQ=60000;class whA{context;renderPdf;constructor(A,Q={}){this.context=A;this.renderPdf=Q.renderPdf??$X}async resolve(A){if(A.sourceEntityType!=="project"||A.attachmentType!==H$A)return;let Q=await this.context.entityService.getEntity({entityType:"project",id:A.sourceEntityId});if(!Q)return;let B=XCQ(Q,{brandLabel:this.resolveBrandLabel(),coverImageUrl:await this.resolveCoverImageUrl(Q)}),w=await fCQ(UCQ(DCQ(),"brain-project-printable-"));try{let $=await ZD({outputDir:w,mediaPath:`/_media/printable/project/${Q.id}`,template:eN1,format:"pdf",content:B,siteConfig:{title:B.title,themeMode:"light"},themeCSS:this.context.themeCSS}),f=await ND({rootDir:w});try{return{type:"document",data:await this.renderPdf(f.urlFor($.urlPath),{maxBytes:YCQ,timeoutMs:JCQ,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${WCQ(Q)}-printable.pdf`}}finally{await f.close()}}finally{await ICQ(w,{recursive:!0,force:!0})}}resolveBrandLabel(){let A=this.context.domain?.trim();if(A&&A.length>0)return A;let Q=this.context.identity.getProfile().name.trim();return Q.length>0?Q:void 0}async resolveCoverImageUrl(A){let{frontmatter:Q}=jB(A.content),B=O$.parse(Q);if(!B.coverImageId)return;let w=await this.context.entityService.getEntity({entityType:"image",id:B.coverImageId});return w?.content.startsWith("data:image/")?w.content:void 0}}function XCQ(A,Q={}){let{frontmatter:B,content:w}=jB(A.content),$=O$.parse(B);return{title:$.title,body:w,...$.description?{description:$.description}:{},year:$.year,...$.publishedAt?{publishedAt:$.publishedAt}:{},...$.url?{url:$.url,canonicalUrl:$.url}:{},...Q.coverImageUrl?{coverImageUrl:Q.coverImageUrl}:{},...Q.brandLabel?{brandLabel:Q.brandLabel}:{}}}function WCQ(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.title)}WA();WA();import{jsxDEV as KCQ}from"preact/jsx-dev-runtime";var G$A="og-image",HCQ="portfolio:og-image",A31=H.object({title:H.string().min(1),description:H.string().optional(),year:H.number().optional(),brandLabel:H.string().optional(),coverImageUrl:H.string().optional()}),Q31={name:HCQ,pluginId:"portfolio",schema:A31,renderers:{image:GCQ}};function GCQ(A){let Q=A31.parse(A);return KCQ(zF,{brandLabel:Q.brandLabel??Q.title,eyebrow:"Project",title:Q.title,subtitle:Q.description,tag:Q.year},void 0,!1,void 0,this)}class $hA{context;deps;constructor(A,Q={}){this.context=A;this.deps=Q}async resolve(A){if(A.sourceEntityType!=="project"||A.attachmentType!==G$A)return;let Q=await this.context.entityService.getEntity({entityType:"project",id:A.sourceEntityId});if(!Q)return;let{frontmatter:B}=jB(Q.content),w=O$.parse(B),$=this.resolveBrandLabel(),f=await this.resolveCoverImageUrl(w.coverImageId),I={title:w.title,...w.description?{description:w.description}:{},year:w.year,...f?{coverImageUrl:f}:{},...$?{brandLabel:$}:{}};return{type:"image",data:await AC({mediaPath:`/_media/og/project/${Q.id}`,template:Q31,content:I,title:I.title,themeMode:"light",themeCSS:this.context.themeCSS,tmpPrefix:"brain-project-og-image-",...this.deps.screenshotPng&&{screenshotPng:this.deps.screenshotPng}}),mimeType:"image/png",filename:`${FCQ(Q)}-og.png`}}resolveBrandLabel(){let A=this.context.domain?.trim();if(A&&A.length>0)return A;let Q=this.context.identity.getProfile().name.trim();return Q.length>0?Q:void 0}async resolveCoverImageUrl(A){if(!A)return;let Q=await this.context.entityService.getEntity({entityType:"image",id:A});return Q?.content.startsWith("data:image/")?Q.content:void 0}}function FCQ(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.title)}var B31={name:"@brains/portfolio",private:!0,version:"0.2.0-alpha.119",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/atproto-contracts":"workspace:*","@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/media-page-composer":"workspace:*","@brains/media-renderer":"workspace:*","@brains/plugins":"workspace:*","@brains/templates":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest",typescript:"^5.3.3"}};var NCQ=H.object({projects:H.array(jv),pageTitle:H.string().optional(),pagination:Z7.nullable(),baseUrl:H.string().optional()});function zCQ(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 fhA extends jQ{entityType=dz.entityType;schema=rz;adapter=dz;unregisterAtprotoProjection;unregisterPrintableAttachmentProvider;unregisterOgImageAttachmentProvider;constructor(A={}){super("portfolio",B31,A,agA)}async interceptCreate(A,Q,B){if(!A.prompt||A.content)return{kind:"continue",input:A};let w=zCQ(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 X$A(this.logger.child("ProjectGenerationJobHandler"),A)}getTemplates(){return{"project-list":P1({name:"project-list",description:"Portfolio project list page template",schema:NCQ,dataSourceId:"portfolio:entities",requiredPermission:"public",layout:{component:tgA}}),"project-detail":P1({name:"project-detail",description:"Individual project case study template",schema:H.object({project:jv,prevProject:jv.nullable(),nextProject:jv.nullable()}),dataSourceId:"portfolio:entities",requiredPermission:"public",layout:{component:egA}}),generation:AhA}}getDataSources(){return[new W$A(this.logger.child("ProjectDataSource"))]}async onRegister(A){this.registerEvalHandlers(A),this.unregisterPrintableAttachmentProvider=A.attachments.register("project",H$A,new whA(A)),this.unregisterOgImageAttachmentProvider=A.attachments.register("project",G$A,new $hA(A)),this.deferPublishRegistration(A),this.subscribeToPublishExecute(A),this.unregisterAtprotoProjection=d6.getInstance().register(BhA())}async onShutdown(){this.unregisterPrintableAttachmentProvider?.(),this.unregisterPrintableAttachmentProvider=void 0,this.unregisterOgImageAttachmentProvider?.(),this.unregisterOgImageAttachmentProvider=void 0,this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}registerEvalHandlers(A){A.eval.registerHandler("generateProject",async(Q)=>{let B=H.object({prompt:H.string(),year:H.number()}).parse(Q);return A.ai.generate({prompt:QhA(B),templateName:"portfolio:generation"})})}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:"project",provider:Q,config:{executionMode:"provider"}}}),{success:!0}})}subscribeToPublishExecute(A){A.messaging.subscribe("publish:execute",async(Q)=>{let{entityType:B,entityId:w}=Q.payload;if(B!=="project")return{success:!0};try{let $=await A.entityService.getEntity({entityType:"project",id:w});if(!$)return await A.messaging.send({type:"publish:report:failure",payload:{entityType:B,entityId:w,error:`Project not found: ${w}`}}),{success:!0};if($.metadata.status==="published")return{success:!0};let f=R2($.content,O$),I=new Date().toISOString(),D=b9(f.content,{...f.metadata,status:"published",publishedAt:I});await A.entityService.updateEntity({entity:{...$,content:D,metadata:{...$.metadata,status:"published",publishedAt:I}}}),await A.messaging.send({type:"publish:report:success",payload:{entityType:B,entityId:w,publishedAt:I}})}catch($){await A.messaging.send({type:"publish:report:failure",payload:{entityType:B,entityId:w,error:T0($)}})}return{success:!0}})}}function IhA(A={}){return new fhA(A)}aA();WA();var qCQ=H.enum(["public","shared","restricted"]),w31=H.object({includeEntityTypes:H.array(H.string()).default([]),minRelevanceScore:H.number().min(0).max(1).default(0.5),mergeSimilarityThreshold:H.number().min(0).max(1).default(0.85),autoMerge:H.boolean().default(!0),extractableStatuses:H.array(H.string()).default(["published"]),enableAutoExtraction:H.boolean().default(!0),extractionVisibility:qCQ.default("public"),sourceChangeBatchDelayMs:H.number().int().min(0).default(1000)});aA();WA();aA();var LCQ=H.object({}),_v=A2.extend({entityType:H.literal("topic"),metadata:LCQ}),Ftw=H.object({content:H.string()}),$31=H.object({title:H.string().describe("Topic title")});var HC="topics",Iw="topic",DhA="topics-projection",f31="topic:project",K$A="topics-plugin",I31="topics:batch-completed",D31="topics-source-batch";class IX extends q2{constructor(){super({entityType:Iw,schema:_v,frontmatterSchema:$31})}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:Iw}}extractMetadata(A){return{}}generateFrontMatter(A){let Q=this.parseTopicBody(A.content),w=this.buildMarkdown("",this.buildFrontmatter(Q.title)).match(/^---\n[\s\S]*?\n---/);return w?w[0]:""}parseTopicBody(A){if(A.startsWith("---"))try{let Q=this.parseFrontmatter(A);return{content:this.extractBody(A).replace(/\n*## Sources[\s\S]*$/,"").trim(),formatted:A,title:Q.title}}catch{return{content:A,formatted:A,title:"Unknown Topic"}}return{content:A,formatted:A,title:"Unknown Topic"}}createTopicBody(A){return this.buildMarkdown(A.content,this.buildFrontmatter(A.title))}}aA();WA();WA();var VCQ=H.object({title:H.string().max(100),content:H.string(),relevanceScore:H.number().min(0).max(1)}),U31=H.array(VCQ);var ECQ=H.object({topics:U31}),Y31=P1({name:"topics:extraction",description:"Extract topics from conversation text",dataSourceId:"shell:ai-content",schema:ECQ,basePrompt:`You are an expert at analyzing content and extracting key topics.
|
|
6413
|
+
`}},void 0,!1,void 0,this),R$("section",{className:"project-shell",children:[R$("header",{className:"project-hero",children:[R$("div",{className:"project-index",children:[Q.brandLabel&&R$("p",{className:"printable-kicker",children:Q.brandLabel},void 0,!1,void 0,this),Q.year&&R$("span",{className:"project-year",children:Q.year},void 0,!1,void 0,this)]},void 0,!0,void 0,this),R$("div",{className:"project-title-panel",children:[R$("span",{className:"printable-kind",children:"Case study dossier"},void 0,!1,void 0,this),R$("h1",{className:"printable-title",children:Q.title},void 0,!1,void 0,this),Q.description&&R$("p",{className:"printable-description",children:Q.description},void 0,!1,void 0,this),R$("div",{className:"printable-meta",children:[Q.year&&R$("span",{children:Q.year},void 0,!1,void 0,this),Q.url&&R$("span",{children:Q.url},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Q.coverImageUrl&&R$("img",{className:"printable-cover",src:Q.coverImageUrl,alt:""},void 0,!1,void 0,this),R$(V$,{markdown:Q.body,className:"printable-body"},void 0,!1,void 0,this),(Q.canonicalUrl||Q.url||Q.brandLabel)&&R$("footer",{className:"printable-footer",children:[R$("span",{children:Q.brandLabel??"Project printable"},void 0,!1,void 0,this),Q.canonicalUrl||Q.url?R$("a",{href:Q.canonicalUrl??Q.url,children:Q.canonicalUrl??Q.url},void 0,!1,void 0,this):null]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}var YCQ=26214400,JCQ=60000;class whA{context;renderPdf;constructor(A,Q={}){this.context=A;this.renderPdf=Q.renderPdf??$X}async resolve(A){if(A.sourceEntityType!=="project"||A.attachmentType!==H$A)return;let Q=await this.context.entityService.getEntity({entityType:"project",id:A.sourceEntityId});if(!Q)return;let B=XCQ(Q,{brandLabel:this.resolveBrandLabel(),coverImageUrl:await this.resolveCoverImageUrl(Q)}),w=await fCQ(UCQ(DCQ(),"brain-project-printable-"));try{let $=await ZD({outputDir:w,mediaPath:`/_media/printable/project/${Q.id}`,template:eN1,format:"pdf",content:B,siteConfig:{title:B.title,themeMode:"light"},themeCSS:this.context.themeCSS}),f=await ND({rootDir:w});try{return{type:"document",data:await this.renderPdf(f.urlFor($.urlPath),{maxBytes:YCQ,timeoutMs:JCQ,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${WCQ(Q)}-printable.pdf`}}finally{await f.close()}}finally{await ICQ(w,{recursive:!0,force:!0})}}resolveBrandLabel(){let A=this.context.domain?.trim();if(A&&A.length>0)return A;let Q=this.context.identity.getProfile().name.trim();return Q.length>0?Q:void 0}async resolveCoverImageUrl(A){let{frontmatter:Q}=jB(A.content),B=O$.parse(Q);if(!B.coverImageId)return;let w=await this.context.entityService.getEntity({entityType:"image",id:B.coverImageId});return w?.content.startsWith("data:image/")?w.content:void 0}}function XCQ(A,Q={}){let{frontmatter:B,content:w}=jB(A.content),$=O$.parse(B);return{title:$.title,body:w,...$.description?{description:$.description}:{},year:$.year,...$.publishedAt?{publishedAt:$.publishedAt}:{},...$.url?{url:$.url,canonicalUrl:$.url}:{},...Q.coverImageUrl?{coverImageUrl:Q.coverImageUrl}:{},...Q.brandLabel?{brandLabel:Q.brandLabel}:{}}}function WCQ(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.title)}WA();WA();import{jsxDEV as KCQ}from"preact/jsx-dev-runtime";var G$A="og-image",HCQ="portfolio:og-image",A31=H.object({title:H.string().min(1),description:H.string().optional(),year:H.number().optional(),brandLabel:H.string().optional(),coverImageUrl:H.string().optional()}),Q31={name:HCQ,pluginId:"portfolio",schema:A31,renderers:{image:GCQ}};function GCQ(A){let Q=A31.parse(A);return KCQ(zF,{brandLabel:Q.brandLabel??Q.title,eyebrow:"Project",title:Q.title,subtitle:Q.description,tag:Q.year},void 0,!1,void 0,this)}class $hA{context;deps;constructor(A,Q={}){this.context=A;this.deps=Q}async resolve(A){if(A.sourceEntityType!=="project"||A.attachmentType!==G$A)return;let Q=await this.context.entityService.getEntity({entityType:"project",id:A.sourceEntityId});if(!Q)return;let{frontmatter:B}=jB(Q.content),w=O$.parse(B),$=this.resolveBrandLabel(),f=await this.resolveCoverImageUrl(w.coverImageId),I={title:w.title,...w.description?{description:w.description}:{},year:w.year,...f?{coverImageUrl:f}:{},...$?{brandLabel:$}:{}};return{type:"image",data:await AC({mediaPath:`/_media/og/project/${Q.id}`,template:Q31,content:I,title:I.title,themeMode:"light",themeCSS:this.context.themeCSS,tmpPrefix:"brain-project-og-image-",...this.deps.screenshotPng&&{screenshotPng:this.deps.screenshotPng}}),mimeType:"image/png",filename:`${FCQ(Q)}-og.png`}}resolveBrandLabel(){let A=this.context.domain?.trim();if(A&&A.length>0)return A;let Q=this.context.identity.getProfile().name.trim();return Q.length>0?Q:void 0}async resolveCoverImageUrl(A){if(!A)return;let Q=await this.context.entityService.getEntity({entityType:"image",id:A});return Q?.content.startsWith("data:image/")?Q.content:void 0}}function FCQ(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.title)}var B31={name:"@brains/portfolio",private:!0,version:"0.2.0-alpha.120",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/atproto-contracts":"workspace:*","@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/media-page-composer":"workspace:*","@brains/media-renderer":"workspace:*","@brains/plugins":"workspace:*","@brains/templates":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest",typescript:"^5.3.3"}};var NCQ=H.object({projects:H.array(jv),pageTitle:H.string().optional(),pagination:Z7.nullable(),baseUrl:H.string().optional()});function zCQ(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 fhA extends jQ{entityType=dz.entityType;schema=rz;adapter=dz;unregisterAtprotoProjection;unregisterPrintableAttachmentProvider;unregisterOgImageAttachmentProvider;constructor(A={}){super("portfolio",B31,A,agA)}async interceptCreate(A,Q,B){if(!A.prompt||A.content)return{kind:"continue",input:A};let w=zCQ(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 X$A(this.logger.child("ProjectGenerationJobHandler"),A)}getTemplates(){return{"project-list":P1({name:"project-list",description:"Portfolio project list page template",schema:NCQ,dataSourceId:"portfolio:entities",requiredPermission:"public",layout:{component:tgA}}),"project-detail":P1({name:"project-detail",description:"Individual project case study template",schema:H.object({project:jv,prevProject:jv.nullable(),nextProject:jv.nullable()}),dataSourceId:"portfolio:entities",requiredPermission:"public",layout:{component:egA}}),generation:AhA}}getDataSources(){return[new W$A(this.logger.child("ProjectDataSource"))]}async onRegister(A){this.registerEvalHandlers(A),this.unregisterPrintableAttachmentProvider=A.attachments.register("project",H$A,new whA(A)),this.unregisterOgImageAttachmentProvider=A.attachments.register("project",G$A,new $hA(A)),this.deferPublishRegistration(A),this.subscribeToPublishExecute(A),this.unregisterAtprotoProjection=d6.getInstance().register(BhA())}async onShutdown(){this.unregisterPrintableAttachmentProvider?.(),this.unregisterPrintableAttachmentProvider=void 0,this.unregisterOgImageAttachmentProvider?.(),this.unregisterOgImageAttachmentProvider=void 0,this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}registerEvalHandlers(A){A.eval.registerHandler("generateProject",async(Q)=>{let B=H.object({prompt:H.string(),year:H.number()}).parse(Q);return A.ai.generate({prompt:QhA(B),templateName:"portfolio:generation"})})}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:"project",provider:Q,config:{executionMode:"provider"}}}),{success:!0}})}subscribeToPublishExecute(A){A.messaging.subscribe("publish:execute",async(Q)=>{let{entityType:B,entityId:w}=Q.payload;if(B!=="project")return{success:!0};try{let $=await A.entityService.getEntity({entityType:"project",id:w});if(!$)return await A.messaging.send({type:"publish:report:failure",payload:{entityType:B,entityId:w,error:`Project not found: ${w}`}}),{success:!0};if($.metadata.status==="published")return{success:!0};let f=R2($.content,O$),I=new Date().toISOString(),D=b9(f.content,{...f.metadata,status:"published",publishedAt:I});await A.entityService.updateEntity({entity:{...$,content:D,metadata:{...$.metadata,status:"published",publishedAt:I}}}),await A.messaging.send({type:"publish:report:success",payload:{entityType:B,entityId:w,publishedAt:I}})}catch($){await A.messaging.send({type:"publish:report:failure",payload:{entityType:B,entityId:w,error:T0($)}})}return{success:!0}})}}function IhA(A={}){return new fhA(A)}aA();WA();var qCQ=H.enum(["public","shared","restricted"]),w31=H.object({includeEntityTypes:H.array(H.string()).default([]),minRelevanceScore:H.number().min(0).max(1).default(0.5),mergeSimilarityThreshold:H.number().min(0).max(1).default(0.85),autoMerge:H.boolean().default(!0),extractableStatuses:H.array(H.string()).default(["published"]),enableAutoExtraction:H.boolean().default(!0),extractionVisibility:qCQ.default("public"),sourceChangeBatchDelayMs:H.number().int().min(0).default(1000)});aA();WA();aA();var LCQ=H.object({}),_v=A2.extend({entityType:H.literal("topic"),metadata:LCQ}),Ftw=H.object({content:H.string()}),$31=H.object({title:H.string().describe("Topic title")});var HC="topics",Iw="topic",DhA="topics-projection",f31="topic:project",K$A="topics-plugin",I31="topics:batch-completed",D31="topics-source-batch";class IX extends q2{constructor(){super({entityType:Iw,schema:_v,frontmatterSchema:$31})}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:Iw}}extractMetadata(A){return{}}generateFrontMatter(A){let Q=this.parseTopicBody(A.content),w=this.buildMarkdown("",this.buildFrontmatter(Q.title)).match(/^---\n[\s\S]*?\n---/);return w?w[0]:""}parseTopicBody(A){if(A.startsWith("---"))try{let Q=this.parseFrontmatter(A);return{content:this.extractBody(A).replace(/\n*## Sources[\s\S]*$/,"").trim(),formatted:A,title:Q.title}}catch{return{content:A,formatted:A,title:"Unknown Topic"}}return{content:A,formatted:A,title:"Unknown Topic"}}createTopicBody(A){return this.buildMarkdown(A.content,this.buildFrontmatter(A.title))}}aA();WA();WA();var VCQ=H.object({title:H.string().max(100),content:H.string(),relevanceScore:H.number().min(0).max(1)}),U31=H.array(VCQ);var ECQ=H.object({topics:U31}),Y31=P1({name:"topics:extraction",description:"Extract topics from conversation text",dataSourceId:"shell:ai-content",schema:ECQ,basePrompt:`You are an expert at analyzing content and extracting key topics.
|
|
6414
6414
|
|
|
6415
6415
|
Analyze the provided content and extract meaningful topics discussed.
|
|
6416
6416
|
|
|
@@ -6513,13 +6513,13 @@ ${A.incomingTopic.content}`})}}function TCQ(A){if(A.length===0)return"";return A
|
|
|
6513
6513
|
|
|
6514
6514
|
${Q.content}`}).join(`
|
|
6515
6515
|
|
|
6516
|
-
`)}async function GC(A,Q,B,w={}){if(A.length===0)return{created:0,merged:0,skipped:0,batches:0};let $=w.minRelevanceScore??0,f=w.autoMerge??!1,I=w.mergeSimilarityThreshold??0.85,D=w.targetVisibility??"public",U=q31(A),Y=new DX(Q.entityService,B),J=w.topicMergeSynthesizer??new HhA(Q,B),X=await q$A(Q.entityService,void 0,D),G=new Map,Z=0,N=0,L=0;for(let M of U){B.info(`Processing batch of ${M.length} entities`);let O=TCQ(M),E=L$A({entityTitle:`Batch of ${M.length} entities`,entityType:"batch",content:O,existingTopicTitles:X});try{let y=(await Q.ai.generate({prompt:E,templateName:"topics:extraction"})).topics.filter((T)=>T.relevanceScore>=$);for(let T of y)try{if(f){let g=await Y.findMergeCandidate({incoming:T,threshold:I,additionalCandidates:Array.from(G.values()),targetVisibility:D});if(g){let n=await J.synthesize({existingTopic:g.topic,incomingTopic:T}),m=await Y.applySynthesizedMerge({existingId:g.topic.id,synthesized:{...n,title:g.title},visibility:D});if(!m)throw Error(`Failed to merge topic: ${T.title}`);G.set(m.id,m),N++;continue}}let _=Y.getTopicIdForTitle(T.title,D);if(G.has(_)){L++;continue}let x=await Y.createTopicOptimistic({title:T.title,content:T.content,visibility:D});if(x.topic)G.set(x.topic.id,x.topic);if(x.created)Z++;else L++}catch(_){B.error("Topic batch item failed",{title:T.title,error:T0(_)})}}catch(S){B.error("Batch topic extraction failed",{batchSize:M.length,promptChars:E.length,error:T0(S)})}}let V={created:Z,merged:N,skipped:L,batches:U.length};if(Z>0||N>0)await Q.messaging.send({type:I31,payload:V,broadcast:!0});return V}aA();WA();var yCQ=H.discriminatedUnion("mode",[H.object({mode:H.literal("derive"),reason:H.string().optional()}),H.object({mode:H.literal("rebuild"),reason:H.string().optional()}),H.object({mode:H.literal("source-batch"),minRelevanceScore:H.number().min(0).max(1).optional()})]);class GhA{refs=new Map;add(A){this.refs.set(`${A.entityType}:${A.entityId}`,A)}drain(){let A=Array.from(this.refs.values());return this.refs.clear(),A}}function O31(A){let{context:Q,logger:B,config:w}=A;return{process:async($)=>{if($.mode==="derive")return await A.extractAllTopics(),{success:!0};if($.mode==="rebuild")return await A.rebuildAllTopics(),{success:!0};return xCQ({context:Q,logger:B,config:w,sourceBatch:A.sourceBatch,isEntityPublished:A.isEntityPublished,minRelevanceScore:$.minRelevanceScore??w.minRelevanceScore})},validateAndParse:($)=>{let f=yCQ.safeParse($??{});return f.success?f.data:null}}}async function xCQ(A){let Q=A.sourceBatch.drain(),B=await Promise.all(Q.map(async(Y)=>({ref:Y,entity:await A.context.entityService.getEntity({entityType:Y.entityType,id:Y.entityId})}))),w=0,$=0,f=0,I=0,D=[];for(let{ref:Y,entity:J}of B){if(!J){$++;continue}if(J.contentHash!==Y.contentHash){w++;continue}if(!A.isEntityPublished(J)){f++;continue}if(!KN(J.visibility,A.config.extractionVisibility)){I++;continue}D.push(J)}if(D.length===0)return{success:!0,sources:Q.length,created:0,merged:0,skipped:0,batches:0,stale:w,missing:$,unpublished:f,hidden:I};let U=await GC(D,A.context,A.logger,{minRelevanceScore:A.minRelevanceScore,autoMerge:A.config.autoMerge,mergeSimilarityThreshold:A.config.mergeSimilarityThreshold,targetVisibility:A.config.extractionVisibility});return{success:!0,sources:Q.length,...U,stale:w,missing:$,unpublished:f,hidden:I}}function R31(){return{priority:5,source:K$A,deduplication:"coalesce",deduplicationKey:"topics-initial-derivation",metadata:{operationType:"data_processing",operationTarget:"topics-initial-derivation",pluginId:HC}}}async function b31(A){let Q=await k31(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 GC(Q,A.context,A.logger,{minRelevanceScore:A.config.minRelevanceScore,autoMerge:A.config.autoMerge,mergeSimilarityThreshold:A.config.mergeSimilarityThreshold,targetVisibility:A.config.extractionVisibility});A.logger.info("Batch topic extraction complete",B)}async function P31(A){let Q=await k31(A),B=await KhA(Q,A.context,A.logger,A.config);A.logger.info("Topic rebuild complete",B)}async function KhA(A,Q,B,w){let $=new DX(Q.entityService,B),f=await $.listTopics({visibility:w.extractionVisibility});for(let D of f)await $.deleteTopic(D.id);if(A.length===0)return{deleted:f.length,created:0,merged:0,skipped:0,batches:0};let I=await GC(A,Q,B,{minRelevanceScore:w.minRelevanceScore,autoMerge:w.autoMerge,mergeSimilarityThreshold:w.mergeSimilarityThreshold,targetVisibility:w.extractionVisibility});return{deleted:f.length,...I}}async function k31(A){let Q=SCQ(A),B=[];for(let w of Q){let $=await A.context.entityService.listEntities({entityType:w,options:{filter:{visibilityScope:A.config.extractionVisibility}}});for(let f of $){if(!A.isEntityPublished(f))continue;B.push(f)}}return B}function SCQ(A){return A.context.entityService.getEntityTypes().filter((B)=>A.shouldProcessEntityType(B))}var yv=H.object({entityType:H.string(),content:H.string(),metadata:H.record(H.unknown()).optional()}),gCQ=yv.extend({minRelevanceScore:H.number().optional()}),hCQ=H.object({contentA:yv,contentB:yv,minRelevanceScore:H.number().optional(),threshold:H.number().min(0).max(1).optional()}),ui=H.object({title:H.string(),content:H.string()}),mCQ=H.object({existingTopics:H.array(ui),incomingTopic:ui,threshold:H.number().optional()}),uCQ=H.object({existingTopics:H.array(ui).default([]),incomingTopic:ui.extend({relevanceScore:H.number().min(0).max(1).optional()}),threshold:H.number().optional()}),cCQ=H.object({entities:H.array(yv).min(1),minRelevanceScore:H.number().optional()}),lCQ=H.object({existingTopics:H.array(ui).optional(),entities:H.array(yv)}),pCQ=H.object({entities:H.array(yv)});function Tv(A,Q=""){return{id:`eval${Q}-${Date.now()}`,entityType:A.entityType,content:A.content,contentHash:gB(A.content),visibility:"public",metadata:A.metadata??{},created:new Date().toISOString(),updated:new Date().toISOString()}}function j31(A){return{title:A.title,relevanceScore:A.relevanceScore}}function iCQ(A){let Q=A.metadata.title;return typeof Q==="string"?Q:A.id}function rCQ(A,Q){return{...A,sources:[{id:Q.id,type:Q.entityType,title:iCQ(Q)}]}}async function KC(A){let Q=await A.entityService.listEntities({entityType:Iw});await Promise.all(Q.map((B)=>A.entityService.deleteEntity({entityType:Iw,id:B.id})))}async function dCQ(A){for(;;){if((await A.jobs.getActiveJobs(["shell:embedding"])).length===0)return;await new Promise((B)=>setTimeout(B,100))}}function _31(A){let{context:Q,logger:B,config:w}=A,$=new WhA(Q,B),f=async(I,D,U="")=>{let Y=Tv(I,U);return $.extractFromEntity(Y,D)};Q.eval.registerHandler("extractFromEntity",async(I)=>{await KC(Q);let D=gCQ.parse(I),U=D.minRelevanceScore??w.minRelevanceScore,Y=Tv(D);return(await $.extractFromEntity(Y,U)).map((X)=>rCQ(X,Y))}),Q.eval.registerHandler("checkMergeSimilarity",async(I)=>{await KC(Q);let D=hCQ.parse(I),U=D.minRelevanceScore??w.minRelevanceScore,Y=D.threshold??w.mergeSimilarityThreshold,[J,X]=await Promise.all([f(D.contentA,U,"-a"),f(D.contentB,U,"-b")]),G=new DX(Q.entityService,B),Z=[];for(let V of J){let M=await G.createTopic(V);if(M)Z.push(M)}let N=(await Promise.all(X.map(async(V)=>{let M=await G.findMergeCandidate({incoming:V,threshold:Y,additionalCandidates:Z});if(!M)return null;return{incomingTitle:V.title,candidateTitle:M.title,candidateScore:M.score}}))).filter((V)=>V!==null),L=N.map((V)=>V.candidateTitle);return{topicsA:J.map(j31),topicsB:X.map(j31),matchingTitles:L,mergeCandidates:N,wouldMerge:N.length>0}}),Q.eval.registerHandler("detectMergeCandidate",async(I)=>{await KC(Q);let D=mCQ.parse(I),U=D.threshold??w.mergeSimilarityThreshold,Y=new DX(Q.entityService,B),J=[];for(let G of D.existingTopics){let Z=await Y.createTopic(G);if(Z)J.push(Z)}let X=await Y.findMergeCandidate({incoming:{title:D.incomingTopic.title},threshold:U,additionalCandidates:J});return{found:X!==null,candidateTitle:X?.title,candidateScore:X?.score}}),Q.eval.registerHandler("processTopicWithAutoMerge",async(I)=>{await KC(Q);let D=uCQ.parse(I),U=new DX(Q.entityService,B);for(let G of D.existingTopics)await U.createTopic({title:G.title,content:G.content});await dCQ(Q);let Y=Tv({entityType:"post",content:D.incomingTopic.content,metadata:{title:D.incomingTopic.title}},"-source"),J=await GC([Y],Q,B,{minRelevanceScore:0,autoMerge:!0,mergeSimilarityThreshold:D.threshold??w.mergeSimilarityThreshold}),X=await Q.entityService.listEntities({entityType:Iw});return{...J,topicCount:X.length,topics:X.map(JhA)}}),Q.eval.registerHandler("rebuildTopics",async(I)=>{await KC(Q);let D=lCQ.parse(I),U=new DX(Q.entityService,B);for(let G of D.existingTopics??[])await U.createTopic(G);let Y=D.entities.map((G,Z)=>Tv(G,`-rebuild-${Z}`)),J=await KhA(Y,Q,B,w),X=await Q.entityService.listEntities({entityType:Iw});return{...J,topicCount:X.length,topics:X.map(JhA)}}),Q.eval.registerHandler("extractSequentially",async(I)=>{await KC(Q);let D=cCQ.parse(I),U=D.minRelevanceScore??w.minRelevanceScore,Y=new DX(Q.entityService,B),J=[];for(let[G,Z]of D.entities.entries()){let N=Tv(Z,`-sequential-${G}`),L=await $.extractFromEntity(N,U);for(let V of L)await Y.createTopic({title:V.title,content:V.content});J.push({extractedTitles:L.map((V)=>V.title)})}let X=await Q.entityService.listEntities({entityType:Iw});return{totalTopics:X.length,perEntity:J,topics:X.map(vv)}}),Q.eval.registerHandler("batchExtract",async(I)=>{await KC(Q);let U=pCQ.parse(I).entities.map((X,G)=>Tv(X,`-batch-${G}`)),Y=await GC(U,Q,B,{minRelevanceScore:w.minRelevanceScore}),J=await Q.entityService.listEntities({entityType:Iw});return{...Y,topics:J.map(vv)}})}var nCQ=new IX;async function v31({entity:A,config:Q}){let B=_v.parse(A),w=nCQ.parseTopicBody(B.content);return{$type:"ai.rizom.brain.topic",title:w.title,body:w.content,format:"text/markdown",...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"topic",sourceEntityId:B.id,createdAt:B.created,...B.updated&&{updatedAt:B.updated}}}function FhA(){return{entityType:"topic",collection:"ai.rizom.brain.topic",lexicon:Gw["ai.rizom.brain.topic"],validate:!1,buildRecord:v31}}var T31={name:"@brains/topics",private:!0,version:"0.2.0-alpha.119",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/atproto-contracts":"workspace:*","@brains/content-formatters":"workspace:*","@brains/plugins":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","@types/node":"^20.0.0",typescript:"^5.3.3"}};var sCQ=new IX;class y31 extends jQ{entityType=Iw;schema=_v;adapter=sCQ;unregisterAtprotoProjection;sourceBatch=new GhA;constructor(A={}){super(HC,T31,A,w31)}getEntityTypeConfig(){return{weight:0.5,projectionSource:!1}}getTemplates(){return{extraction:Y31,"merge-synthesis":J31,"topic-list":X31,"topic-detail":W31}}getDataSources(){return[new XhA(this.logger.child("TopicsDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableAutoExtraction)return[];return[{id:DhA,targetType:Iw,job:{type:f31,handler:O31({context:A,logger:this.logger,config:this.config,extractAllTopics:()=>this.extractAllTopics(A),rebuildAllTopics:()=>this.rebuildAllTopics(A),sourceBatch:this.sourceBatch,isEntityPublished:(Q)=>this.isEntityPublished(Q)})},initialSync:{shouldEnqueue:async()=>!await OL(A,Iw,{visibility:this.config.extractionVisibility}),jobData:{mode:"derive",reason:"initial-sync"},jobOptions:R31()},sourceChange:{sourceTypes:this.config.includeEntityTypes,requireInitialSync:!0,jobData:(Q)=>{let B=Q.entity;if(!B)return null;if(!this.shouldProcessEntityType(B.entityType,A.entityService))return null;if(!this.isEntityPublished(B))return null;if(!KN(B.visibility,this.config.extractionVisibility))return null;return this.sourceBatch.add({entityId:B.id,entityType:B.entityType,contentHash:B.contentHash}),{mode:"source-batch"}},jobOptions:()=>({priority:5,source:K$A,delayMs:this.config.sourceChangeBatchDelayMs,deduplication:"skip",deduplicationKey:D31,metadata:{operationType:"data_processing",operationTarget:"topic-source-batch",pluginId:HC}})}}]}async onRegister(A){A.insights.register("topic-distribution",K31()),F31({context:A,pluginId:this.id}),_31({context:A,logger:this.logger,config:this.config}),this.unregisterAtprotoProjection=d6.getInstance().register(FhA())}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}hasRunInitialDerivation(){return this.getDerivedEntityProjectionController(DhA)?.hasQueuedInitialSync()??!1}shouldProcessEntityType(A,Q){if(A===Iw)return!1;if(!this.config.includeEntityTypes.includes(A))return!1;return Q.getEntityTypeConfig(A).projectionSource!==!1}isEntityPublished(A){let B=A.metadata.status;if(B===void 0||B===null)return!0;if(typeof B!=="string")return!1;return this.config.extractableStatuses.includes(B)}async extractAllTopics(A){await b31({context:A,logger:this.logger,config:this.config,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q,A.entityService),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}async rebuildAllTopics(A){await P31({context:A,logger:this.logger,config:this.config,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q,A.entityService),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}}function V$A(A){return new y31(A)}aA();WA();aA();var ZhA=H.enum(["linkedin"]),NhA=H.enum(["generating","draft","queued","published","failed"]),x31=H.enum(["post","deck"]),S31=H.object({id:H.string().min(1).describe("Document entity ID")}),oU=H.object({title:H.string().describe("Short descriptive title (3-6 words) for file naming"),platform:ZhA.describe("Target platform"),status:NhA,coverImageId:H.string().optional().describe("Image entity ID for post image"),documents:H.array(S31).optional().describe("Document attachments for publishing"),publishedAt:H.string().datetime().optional(),platformPostId:H.string().optional().describe("ID from platform after publishing"),sourceEntityId:H.string().optional().describe("Source entity ID if auto-generated"),sourceEntityType:x31.optional().describe("Source entity type (post, deck)")}),g31=oU.extend({platform:ZhA.optional(),status:NhA.optional()}),h31=oU.pick({title:!0,platform:!0,status:!0,publishedAt:!0,platformPostId:!0}).extend({slug:H.string().describe("URL-friendly identifier: {platform}-{title}"),error:H.string().optional()}),nz=A2.extend({entityType:H.literal("social-post"),metadata:h31}),E$A=nz.extend({frontmatter:oU,body:H.string()}),M$A=E$A.extend({url:H.string().optional(),listUrl:H.string().optional(),listLabel:H.string().optional(),typeLabel:H.string().optional(),coverImageUrl:H.string().optional(),coverImageWidth:H.number().optional(),coverImageHeight:H.number().optional()});aA();WA();class zhA extends q2{constructor(){super({entityType:"social-post",schema:nz,frontmatterSchema:oU,supportsCoverImage:!0})}toMarkdown(A){let Q="",B={};try{B=this.parseFrontMatter(A.content,oU),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,g31),B=Q.platform??"linkedin",w=Q.status??"draft",$=`${B}-${X1(Q.title)}`;return{content:A,entityType:"social-post",metadata:{title:Q.title,slug:$,platform:B,status:w,publishedAt:Q.publishedAt,platformPostId:Q.platformPostId}}}parsePostFrontmatter(A){return this.parseFrontMatter(A.content,oU)}getPostContent(A){return this.extractBody(A.content)}createPostContent(A,Q){return this.buildMarkdown(Q,A)}buildStub(A){let B={title:A.title,platform:"linkedin",status:"generating"};return{content:this.buildMarkdown("",B),metadata:{title:A.title,slug:`linkedin-${X1(A.title)}`,platform:"linkedin",status:"generating"}}}}var s9=new zhA;aA();aA();WA();var aCQ=QW.extend({platform:H.enum(["linkedin"]).optional(),status:H.enum(["generating","draft","queued","published","failed"]).optional(),sortByQueue:H.boolean().optional(),nextInQueue:H.boolean().optional()}),tCQ=BW.extend({query:aCQ.optional()});function m31(A){let Q=R2(A.content,oU);return E$A.parse({...A,frontmatter:Q.metadata,body:Q.content})}class C$A extends m5{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=tCQ.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}transformEntity(A){return m31(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:J}=await this.fetchDetail(w.id,$);return Q.parse(this.buildDetailResult(J,null))}let f={};if(w.platform)f.platform=w.platform;if(w.status)f.status=w.status;let I=Object.keys(f).length>0,D=w.sortByQueue?[{field:"queueOrder",direction:"asc"}]:this.config.defaultSort,{items:U,pagination:Y}=await this.fetchList(w,$,{...I&&{filter:{metadata:f}},sortFields:D});return Q.parse(this.buildListResult(U,Y,w))}async fetchNextInQueue(A,Q){let w=(await Q.listEntities({entityType:this.config.entityType,options:{filter:{metadata:{status:"queued"}},sortFields:[{field:"queueOrder",direction:"asc"}],limit:1}}))[0],$=w?m31(w):null;return A.parse({post:$})}}WA();var u31=H.object({accessToken:H.string().optional(),refreshToken:H.string().optional(),organizationId:H.string().optional(),apiVersion:H.string().regex(/^\d{6}$/).optional()}),qhA=H.object({linkedin:u31.optional(),publishInterval:H.number().default(3600000),enabled:H.boolean().default(!0),defaultPrompt:H.string().default("Create an engaging social media post that drives engagement"),maxRetries:H.number().default(3),autoGenerateOnBlogPublish:H.boolean().default(!1)});aA();WA();H6();VhA();import{jsxDEV as N5,Fragment as QOQ}from"preact/jsx-dev-runtime";function eCQ(A,Q){if(A.length<=Q)return A;return A.slice(0,Q).trim()+"..."}function AOQ(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"})}var R$A=({posts:A,pageTitle:Q,pagination:B,baseUrl:w="/social-posts"})=>{let $=Q??"Social Posts",f=B?.totalItems??A.length,I=`Browse all ${f} social ${f===1?"post":"posts"}`;return N5(QOQ,{children:[N5(KQ,{title:$,description:I},void 0,!1,void 0,this),N5("div",{className:"social-post-list bg-theme",children:N5("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[N5("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:$},void 0,!1,void 0,this),A.length===0?N5("p",{className:"text-theme-muted italic",children:"No social posts yet."},void 0,!1,void 0,this):N5("ul",{className:"space-y-6",children:A.map((D)=>N5("li",{children:N5(PB,{href:D.url,variant:"horizontal",children:N5("div",{className:"flex flex-col sm:flex-row gap-4",children:[D.coverImageUrl&&N5("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),N5("div",{className:"flex-1 min-w-0",children:[N5("div",{className:"flex items-start justify-between gap-4 mb-2",children:[N5("h2",{className:"text-lg font-semibold text-heading",children:D.frontmatter.title},void 0,!1,void 0,this),N5("time",{className:"text-sm text-theme-muted shrink-0",children:AOQ(D.frontmatter.publishedAt??D.created)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),N5("div",{className:"flex items-center gap-2 mb-3",children:[N5(gf,{status:D.frontmatter.status},void 0,!1,void 0,this),N5("span",{className:"text-xs text-theme-muted uppercase",children:D.frontmatter.platform},void 0,!1,void 0,this),N5("span",{className:"text-xs text-theme-muted font-mono",children:D.id},void 0,!1,void 0,this)]},void 0,!0,void 0,this),N5("p",{className:"text-theme leading-relaxed",children:eCQ(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&&N5(VF,{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 z5,Fragment as BOQ}from"preact/jsx-dev-runtime";function c31(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric",hour:"numeric",minute:"2-digit"})}var b$A=({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 z5(BOQ,{children:[z5(KQ,{title:Q,description:B},void 0,!1,void 0,this),z5("section",{className:"social-post-detail",children:z5("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:z5("div",{className:"max-w-3xl mx-auto",children:[z5(YH,{items:w},void 0,!1,void 0,this),z5("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-4",children:A.frontmatter.title},void 0,!1,void 0,this),z5("div",{className:"flex flex-wrap items-center gap-3 mb-6",children:[z5(gf,{status:A.frontmatter.status},void 0,!1,void 0,this),z5("span",{className:"text-sm text-theme-muted uppercase",children:A.frontmatter.platform},void 0,!1,void 0,this),z5("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&&z5(qF,{src:A.coverImageUrl,alt:A.frontmatter.title,width:A.coverImageWidth,height:A.coverImageHeight,className:"mb-8"},void 0,!1,void 0,this),z5(PB,{className:"p-8 mb-8",children:z5("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),z5("div",{className:"space-y-4 text-sm text-theme-muted",children:[z5("div",{children:[z5("span",{className:"font-medium",children:"Created:"},void 0,!1,void 0,this)," ",c31(A.created)]},void 0,!0,void 0,this),A.frontmatter.publishedAt&&z5("div",{children:[z5("span",{className:"font-medium",children:"Published:"},void 0,!1,void 0,this)," ",c31(A.frontmatter.publishedAt)]},void 0,!0,void 0,this),A.frontmatter.platformPostId&&z5("div",{children:z5("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 ci(A){return`social-media:${A}`}var wOQ=H.union([H.boolean(),H.object({generate:H.boolean().optional(),prompt:H.string().optional()})]),EhA=H.object({prompt:H.string().optional(),platform:H.enum(["linkedin"]).optional(),sourceEntityType:H.enum(["post","deck"]).optional(),sourceEntityId:H.string().optional(),title:H.string().optional().describe("Required when content is provided directly"),content:H.string().optional(),addToQueue:H.boolean().optional(),generateImage:H.boolean().optional().describe("Auto-generate cover image for post"),coverImage:wOQ.optional().describe("Generic cover image generation request")}),$OQ=qI.extend({slug:H.string().optional()});class FC extends z7{constructor(A,Q){super(A,Q,{schema:EhA,jobTypeName:"social-post-generation",entityType:"social-post"})}async generate(A,Q){let B=A.platform??"linkedin",w=A.addToQueue??!1,{prompt:$,sourceEntityType:f,sourceEntityId:I}=A,{content:D,title:U}=A;if(D&&U)await this.reportProgress(Q,{progress:50,message:"Using provided content"});else if(D&&!U){await this.reportProgress(Q,{progress:10,message:"Shaping content with AI"});let V=await this.context.ai.generate({prompt:D,templateName:ci(B)});U=V.title,D=V.content,await this.reportProgress(Q,{progress:50,message:"Social post shaped from content"})}else if(I&&f){await this.reportProgress(Q,{progress:10,message:`Fetching source ${f}`});let V=await this.context.entityService.getEntity({entityType:f,id:I});if(!V)this.failEarly(`Source entity not found: ${f}/${I}`);await this.reportProgress(Q,{progress:30,message:"Generating social post from source content"});let O=H.object({slug:H.string()}).safeParse(V.metadata),E=O.success?O.data.slug:I,S=await this.context.ai.generate({prompt:`Create an engaging ${B} post to promote this ${f}:
|
|
6516
|
+
`)}async function GC(A,Q,B,w={}){if(A.length===0)return{created:0,merged:0,skipped:0,batches:0};let $=w.minRelevanceScore??0,f=w.autoMerge??!1,I=w.mergeSimilarityThreshold??0.85,D=w.targetVisibility??"public",U=q31(A),Y=new DX(Q.entityService,B),J=w.topicMergeSynthesizer??new HhA(Q,B),X=await q$A(Q.entityService,void 0,D),G=new Map,Z=0,N=0,L=0;for(let M of U){B.info(`Processing batch of ${M.length} entities`);let O=TCQ(M),E=L$A({entityTitle:`Batch of ${M.length} entities`,entityType:"batch",content:O,existingTopicTitles:X});try{let y=(await Q.ai.generate({prompt:E,templateName:"topics:extraction"})).topics.filter((T)=>T.relevanceScore>=$);for(let T of y)try{if(f){let g=await Y.findMergeCandidate({incoming:T,threshold:I,additionalCandidates:Array.from(G.values()),targetVisibility:D});if(g){let n=await J.synthesize({existingTopic:g.topic,incomingTopic:T}),m=await Y.applySynthesizedMerge({existingId:g.topic.id,synthesized:{...n,title:g.title},visibility:D});if(!m)throw Error(`Failed to merge topic: ${T.title}`);G.set(m.id,m),N++;continue}}let _=Y.getTopicIdForTitle(T.title,D);if(G.has(_)){L++;continue}let x=await Y.createTopicOptimistic({title:T.title,content:T.content,visibility:D});if(x.topic)G.set(x.topic.id,x.topic);if(x.created)Z++;else L++}catch(_){B.error("Topic batch item failed",{title:T.title,error:T0(_)})}}catch(S){B.error("Batch topic extraction failed",{batchSize:M.length,promptChars:E.length,error:T0(S)})}}let V={created:Z,merged:N,skipped:L,batches:U.length};if(Z>0||N>0)await Q.messaging.send({type:I31,payload:V,broadcast:!0});return V}aA();WA();var yCQ=H.discriminatedUnion("mode",[H.object({mode:H.literal("derive"),reason:H.string().optional()}),H.object({mode:H.literal("rebuild"),reason:H.string().optional()}),H.object({mode:H.literal("source-batch"),minRelevanceScore:H.number().min(0).max(1).optional()})]);class GhA{refs=new Map;add(A){this.refs.set(`${A.entityType}:${A.entityId}`,A)}drain(){let A=Array.from(this.refs.values());return this.refs.clear(),A}}function O31(A){let{context:Q,logger:B,config:w}=A;return{process:async($)=>{if($.mode==="derive")return await A.extractAllTopics(),{success:!0};if($.mode==="rebuild")return await A.rebuildAllTopics(),{success:!0};return xCQ({context:Q,logger:B,config:w,sourceBatch:A.sourceBatch,isEntityPublished:A.isEntityPublished,minRelevanceScore:$.minRelevanceScore??w.minRelevanceScore})},validateAndParse:($)=>{let f=yCQ.safeParse($??{});return f.success?f.data:null}}}async function xCQ(A){let Q=A.sourceBatch.drain(),B=await Promise.all(Q.map(async(Y)=>({ref:Y,entity:await A.context.entityService.getEntity({entityType:Y.entityType,id:Y.entityId})}))),w=0,$=0,f=0,I=0,D=[];for(let{ref:Y,entity:J}of B){if(!J){$++;continue}if(J.contentHash!==Y.contentHash){w++;continue}if(!A.isEntityPublished(J)){f++;continue}if(!KN(J.visibility,A.config.extractionVisibility)){I++;continue}D.push(J)}if(D.length===0)return{success:!0,sources:Q.length,created:0,merged:0,skipped:0,batches:0,stale:w,missing:$,unpublished:f,hidden:I};let U=await GC(D,A.context,A.logger,{minRelevanceScore:A.minRelevanceScore,autoMerge:A.config.autoMerge,mergeSimilarityThreshold:A.config.mergeSimilarityThreshold,targetVisibility:A.config.extractionVisibility});return{success:!0,sources:Q.length,...U,stale:w,missing:$,unpublished:f,hidden:I}}function R31(){return{priority:5,source:K$A,deduplication:"coalesce",deduplicationKey:"topics-initial-derivation",metadata:{operationType:"data_processing",operationTarget:"topics-initial-derivation",pluginId:HC}}}async function b31(A){let Q=await k31(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 GC(Q,A.context,A.logger,{minRelevanceScore:A.config.minRelevanceScore,autoMerge:A.config.autoMerge,mergeSimilarityThreshold:A.config.mergeSimilarityThreshold,targetVisibility:A.config.extractionVisibility});A.logger.info("Batch topic extraction complete",B)}async function P31(A){let Q=await k31(A),B=await KhA(Q,A.context,A.logger,A.config);A.logger.info("Topic rebuild complete",B)}async function KhA(A,Q,B,w){let $=new DX(Q.entityService,B),f=await $.listTopics({visibility:w.extractionVisibility});for(let D of f)await $.deleteTopic(D.id);if(A.length===0)return{deleted:f.length,created:0,merged:0,skipped:0,batches:0};let I=await GC(A,Q,B,{minRelevanceScore:w.minRelevanceScore,autoMerge:w.autoMerge,mergeSimilarityThreshold:w.mergeSimilarityThreshold,targetVisibility:w.extractionVisibility});return{deleted:f.length,...I}}async function k31(A){let Q=SCQ(A),B=[];for(let w of Q){let $=await A.context.entityService.listEntities({entityType:w,options:{filter:{visibilityScope:A.config.extractionVisibility}}});for(let f of $){if(!A.isEntityPublished(f))continue;B.push(f)}}return B}function SCQ(A){return A.context.entityService.getEntityTypes().filter((B)=>A.shouldProcessEntityType(B))}var yv=H.object({entityType:H.string(),content:H.string(),metadata:H.record(H.unknown()).optional()}),gCQ=yv.extend({minRelevanceScore:H.number().optional()}),hCQ=H.object({contentA:yv,contentB:yv,minRelevanceScore:H.number().optional(),threshold:H.number().min(0).max(1).optional()}),ui=H.object({title:H.string(),content:H.string()}),mCQ=H.object({existingTopics:H.array(ui),incomingTopic:ui,threshold:H.number().optional()}),uCQ=H.object({existingTopics:H.array(ui).default([]),incomingTopic:ui.extend({relevanceScore:H.number().min(0).max(1).optional()}),threshold:H.number().optional()}),cCQ=H.object({entities:H.array(yv).min(1),minRelevanceScore:H.number().optional()}),lCQ=H.object({existingTopics:H.array(ui).optional(),entities:H.array(yv)}),pCQ=H.object({entities:H.array(yv)});function Tv(A,Q=""){return{id:`eval${Q}-${Date.now()}`,entityType:A.entityType,content:A.content,contentHash:gB(A.content),visibility:"public",metadata:A.metadata??{},created:new Date().toISOString(),updated:new Date().toISOString()}}function j31(A){return{title:A.title,relevanceScore:A.relevanceScore}}function iCQ(A){let Q=A.metadata.title;return typeof Q==="string"?Q:A.id}function rCQ(A,Q){return{...A,sources:[{id:Q.id,type:Q.entityType,title:iCQ(Q)}]}}async function KC(A){let Q=await A.entityService.listEntities({entityType:Iw});await Promise.all(Q.map((B)=>A.entityService.deleteEntity({entityType:Iw,id:B.id})))}async function dCQ(A){for(;;){if((await A.jobs.getActiveJobs(["shell:embedding"])).length===0)return;await new Promise((B)=>setTimeout(B,100))}}function _31(A){let{context:Q,logger:B,config:w}=A,$=new WhA(Q,B),f=async(I,D,U="")=>{let Y=Tv(I,U);return $.extractFromEntity(Y,D)};Q.eval.registerHandler("extractFromEntity",async(I)=>{await KC(Q);let D=gCQ.parse(I),U=D.minRelevanceScore??w.minRelevanceScore,Y=Tv(D);return(await $.extractFromEntity(Y,U)).map((X)=>rCQ(X,Y))}),Q.eval.registerHandler("checkMergeSimilarity",async(I)=>{await KC(Q);let D=hCQ.parse(I),U=D.minRelevanceScore??w.minRelevanceScore,Y=D.threshold??w.mergeSimilarityThreshold,[J,X]=await Promise.all([f(D.contentA,U,"-a"),f(D.contentB,U,"-b")]),G=new DX(Q.entityService,B),Z=[];for(let V of J){let M=await G.createTopic(V);if(M)Z.push(M)}let N=(await Promise.all(X.map(async(V)=>{let M=await G.findMergeCandidate({incoming:V,threshold:Y,additionalCandidates:Z});if(!M)return null;return{incomingTitle:V.title,candidateTitle:M.title,candidateScore:M.score}}))).filter((V)=>V!==null),L=N.map((V)=>V.candidateTitle);return{topicsA:J.map(j31),topicsB:X.map(j31),matchingTitles:L,mergeCandidates:N,wouldMerge:N.length>0}}),Q.eval.registerHandler("detectMergeCandidate",async(I)=>{await KC(Q);let D=mCQ.parse(I),U=D.threshold??w.mergeSimilarityThreshold,Y=new DX(Q.entityService,B),J=[];for(let G of D.existingTopics){let Z=await Y.createTopic(G);if(Z)J.push(Z)}let X=await Y.findMergeCandidate({incoming:{title:D.incomingTopic.title},threshold:U,additionalCandidates:J});return{found:X!==null,candidateTitle:X?.title,candidateScore:X?.score}}),Q.eval.registerHandler("processTopicWithAutoMerge",async(I)=>{await KC(Q);let D=uCQ.parse(I),U=new DX(Q.entityService,B);for(let G of D.existingTopics)await U.createTopic({title:G.title,content:G.content});await dCQ(Q);let Y=Tv({entityType:"post",content:D.incomingTopic.content,metadata:{title:D.incomingTopic.title}},"-source"),J=await GC([Y],Q,B,{minRelevanceScore:0,autoMerge:!0,mergeSimilarityThreshold:D.threshold??w.mergeSimilarityThreshold}),X=await Q.entityService.listEntities({entityType:Iw});return{...J,topicCount:X.length,topics:X.map(JhA)}}),Q.eval.registerHandler("rebuildTopics",async(I)=>{await KC(Q);let D=lCQ.parse(I),U=new DX(Q.entityService,B);for(let G of D.existingTopics??[])await U.createTopic(G);let Y=D.entities.map((G,Z)=>Tv(G,`-rebuild-${Z}`)),J=await KhA(Y,Q,B,w),X=await Q.entityService.listEntities({entityType:Iw});return{...J,topicCount:X.length,topics:X.map(JhA)}}),Q.eval.registerHandler("extractSequentially",async(I)=>{await KC(Q);let D=cCQ.parse(I),U=D.minRelevanceScore??w.minRelevanceScore,Y=new DX(Q.entityService,B),J=[];for(let[G,Z]of D.entities.entries()){let N=Tv(Z,`-sequential-${G}`),L=await $.extractFromEntity(N,U);for(let V of L)await Y.createTopic({title:V.title,content:V.content});J.push({extractedTitles:L.map((V)=>V.title)})}let X=await Q.entityService.listEntities({entityType:Iw});return{totalTopics:X.length,perEntity:J,topics:X.map(vv)}}),Q.eval.registerHandler("batchExtract",async(I)=>{await KC(Q);let U=pCQ.parse(I).entities.map((X,G)=>Tv(X,`-batch-${G}`)),Y=await GC(U,Q,B,{minRelevanceScore:w.minRelevanceScore}),J=await Q.entityService.listEntities({entityType:Iw});return{...Y,topics:J.map(vv)}})}var nCQ=new IX;async function v31({entity:A,config:Q}){let B=_v.parse(A),w=nCQ.parseTopicBody(B.content);return{$type:"ai.rizom.brain.topic",title:w.title,body:w.content,format:"text/markdown",...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"topic",sourceEntityId:B.id,createdAt:B.created,...B.updated&&{updatedAt:B.updated}}}function FhA(){return{entityType:"topic",collection:"ai.rizom.brain.topic",lexicon:Gw["ai.rizom.brain.topic"],validate:!1,buildRecord:v31}}var T31={name:"@brains/topics",private:!0,version:"0.2.0-alpha.120",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/atproto-contracts":"workspace:*","@brains/content-formatters":"workspace:*","@brains/plugins":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","@types/node":"^20.0.0",typescript:"^5.3.3"}};var sCQ=new IX;class y31 extends jQ{entityType=Iw;schema=_v;adapter=sCQ;unregisterAtprotoProjection;sourceBatch=new GhA;constructor(A={}){super(HC,T31,A,w31)}getEntityTypeConfig(){return{weight:0.5,projectionSource:!1}}getTemplates(){return{extraction:Y31,"merge-synthesis":J31,"topic-list":X31,"topic-detail":W31}}getDataSources(){return[new XhA(this.logger.child("TopicsDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableAutoExtraction)return[];return[{id:DhA,targetType:Iw,job:{type:f31,handler:O31({context:A,logger:this.logger,config:this.config,extractAllTopics:()=>this.extractAllTopics(A),rebuildAllTopics:()=>this.rebuildAllTopics(A),sourceBatch:this.sourceBatch,isEntityPublished:(Q)=>this.isEntityPublished(Q)})},initialSync:{shouldEnqueue:async()=>!await OL(A,Iw,{visibility:this.config.extractionVisibility}),jobData:{mode:"derive",reason:"initial-sync"},jobOptions:R31()},sourceChange:{sourceTypes:this.config.includeEntityTypes,requireInitialSync:!0,jobData:(Q)=>{let B=Q.entity;if(!B)return null;if(!this.shouldProcessEntityType(B.entityType,A.entityService))return null;if(!this.isEntityPublished(B))return null;if(!KN(B.visibility,this.config.extractionVisibility))return null;return this.sourceBatch.add({entityId:B.id,entityType:B.entityType,contentHash:B.contentHash}),{mode:"source-batch"}},jobOptions:()=>({priority:5,source:K$A,delayMs:this.config.sourceChangeBatchDelayMs,deduplication:"skip",deduplicationKey:D31,metadata:{operationType:"data_processing",operationTarget:"topic-source-batch",pluginId:HC}})}}]}async onRegister(A){A.insights.register("topic-distribution",K31()),F31({context:A,pluginId:this.id}),_31({context:A,logger:this.logger,config:this.config}),this.unregisterAtprotoProjection=d6.getInstance().register(FhA())}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}hasRunInitialDerivation(){return this.getDerivedEntityProjectionController(DhA)?.hasQueuedInitialSync()??!1}shouldProcessEntityType(A,Q){if(A===Iw)return!1;if(!this.config.includeEntityTypes.includes(A))return!1;return Q.getEntityTypeConfig(A).projectionSource!==!1}isEntityPublished(A){let B=A.metadata.status;if(B===void 0||B===null)return!0;if(typeof B!=="string")return!1;return this.config.extractableStatuses.includes(B)}async extractAllTopics(A){await b31({context:A,logger:this.logger,config:this.config,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q,A.entityService),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}async rebuildAllTopics(A){await P31({context:A,logger:this.logger,config:this.config,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q,A.entityService),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}}function V$A(A){return new y31(A)}aA();WA();aA();var ZhA=H.enum(["linkedin"]),NhA=H.enum(["generating","draft","queued","published","failed"]),x31=H.enum(["post","deck"]),S31=H.object({id:H.string().min(1).describe("Document entity ID")}),oU=H.object({title:H.string().describe("Short descriptive title (3-6 words) for file naming"),platform:ZhA.describe("Target platform"),status:NhA,coverImageId:H.string().optional().describe("Image entity ID for post image"),documents:H.array(S31).optional().describe("Document attachments for publishing"),publishedAt:H.string().datetime().optional(),platformPostId:H.string().optional().describe("ID from platform after publishing"),sourceEntityId:H.string().optional().describe("Source entity ID if auto-generated"),sourceEntityType:x31.optional().describe("Source entity type (post, deck)")}),g31=oU.extend({platform:ZhA.optional(),status:NhA.optional()}),h31=oU.pick({title:!0,platform:!0,status:!0,publishedAt:!0,platformPostId:!0}).extend({slug:H.string().describe("URL-friendly identifier: {platform}-{title}"),error:H.string().optional()}),nz=A2.extend({entityType:H.literal("social-post"),metadata:h31}),E$A=nz.extend({frontmatter:oU,body:H.string()}),M$A=E$A.extend({url:H.string().optional(),listUrl:H.string().optional(),listLabel:H.string().optional(),typeLabel:H.string().optional(),coverImageUrl:H.string().optional(),coverImageWidth:H.number().optional(),coverImageHeight:H.number().optional()});aA();WA();class zhA extends q2{constructor(){super({entityType:"social-post",schema:nz,frontmatterSchema:oU,supportsCoverImage:!0})}toMarkdown(A){let Q="",B={};try{B=this.parseFrontMatter(A.content,oU),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,g31),B=Q.platform??"linkedin",w=Q.status??"draft",$=`${B}-${X1(Q.title)}`;return{content:A,entityType:"social-post",metadata:{title:Q.title,slug:$,platform:B,status:w,publishedAt:Q.publishedAt,platformPostId:Q.platformPostId}}}parsePostFrontmatter(A){return this.parseFrontMatter(A.content,oU)}getPostContent(A){return this.extractBody(A.content)}createPostContent(A,Q){return this.buildMarkdown(Q,A)}buildStub(A){let B={title:A.title,platform:"linkedin",status:"generating"};return{content:this.buildMarkdown("",B),metadata:{title:A.title,slug:`linkedin-${X1(A.title)}`,platform:"linkedin",status:"generating"}}}}var s9=new zhA;aA();aA();WA();var aCQ=QW.extend({platform:H.enum(["linkedin"]).optional(),status:H.enum(["generating","draft","queued","published","failed"]).optional(),sortByQueue:H.boolean().optional(),nextInQueue:H.boolean().optional()}),tCQ=BW.extend({query:aCQ.optional()});function m31(A){let Q=R2(A.content,oU);return E$A.parse({...A,frontmatter:Q.metadata,body:Q.content})}class C$A extends m5{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=tCQ.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}transformEntity(A){return m31(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:J}=await this.fetchDetail(w.id,$);return Q.parse(this.buildDetailResult(J,null))}let f={};if(w.platform)f.platform=w.platform;if(w.status)f.status=w.status;let I=Object.keys(f).length>0,D=w.sortByQueue?[{field:"queueOrder",direction:"asc"}]:this.config.defaultSort,{items:U,pagination:Y}=await this.fetchList(w,$,{...I&&{filter:{metadata:f}},sortFields:D});return Q.parse(this.buildListResult(U,Y,w))}async fetchNextInQueue(A,Q){let w=(await Q.listEntities({entityType:this.config.entityType,options:{filter:{metadata:{status:"queued"}},sortFields:[{field:"queueOrder",direction:"asc"}],limit:1}}))[0],$=w?m31(w):null;return A.parse({post:$})}}WA();var u31=H.object({accessToken:H.string().optional(),refreshToken:H.string().optional(),organizationId:H.string().optional(),apiVersion:H.string().regex(/^\d{6}$/).optional()}),qhA=H.object({linkedin:u31.optional(),publishInterval:H.number().default(3600000),enabled:H.boolean().default(!0),defaultPrompt:H.string().default("Create an engaging social media post that drives engagement"),maxRetries:H.number().default(3),autoGenerateOnBlogPublish:H.boolean().default(!1)});aA();WA();H6();VhA();import{jsxDEV as N5,Fragment as QOQ}from"preact/jsx-dev-runtime";function eCQ(A,Q){if(A.length<=Q)return A;return A.slice(0,Q).trim()+"..."}function AOQ(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"})}var R$A=({posts:A,pageTitle:Q,pagination:B,baseUrl:w="/social-posts"})=>{let $=Q??"Social Posts",f=B?.totalItems??A.length,I=`Browse all ${f} social ${f===1?"post":"posts"}`;return N5(QOQ,{children:[N5(KQ,{title:$,description:I},void 0,!1,void 0,this),N5("div",{className:"social-post-list bg-theme",children:N5("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[N5("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:$},void 0,!1,void 0,this),A.length===0?N5("p",{className:"text-theme-muted italic",children:"No social posts yet."},void 0,!1,void 0,this):N5("ul",{className:"space-y-6",children:A.map((D)=>N5("li",{children:N5(PB,{href:D.url,variant:"horizontal",children:N5("div",{className:"flex flex-col sm:flex-row gap-4",children:[D.coverImageUrl&&N5("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),N5("div",{className:"flex-1 min-w-0",children:[N5("div",{className:"flex items-start justify-between gap-4 mb-2",children:[N5("h2",{className:"text-lg font-semibold text-heading",children:D.frontmatter.title},void 0,!1,void 0,this),N5("time",{className:"text-sm text-theme-muted shrink-0",children:AOQ(D.frontmatter.publishedAt??D.created)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),N5("div",{className:"flex items-center gap-2 mb-3",children:[N5(gf,{status:D.frontmatter.status},void 0,!1,void 0,this),N5("span",{className:"text-xs text-theme-muted uppercase",children:D.frontmatter.platform},void 0,!1,void 0,this),N5("span",{className:"text-xs text-theme-muted font-mono",children:D.id},void 0,!1,void 0,this)]},void 0,!0,void 0,this),N5("p",{className:"text-theme leading-relaxed",children:eCQ(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&&N5(VF,{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 z5,Fragment as BOQ}from"preact/jsx-dev-runtime";function c31(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric",hour:"numeric",minute:"2-digit"})}var b$A=({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 z5(BOQ,{children:[z5(KQ,{title:Q,description:B},void 0,!1,void 0,this),z5("section",{className:"social-post-detail",children:z5("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:z5("div",{className:"max-w-3xl mx-auto",children:[z5(YH,{items:w},void 0,!1,void 0,this),z5("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-4",children:A.frontmatter.title},void 0,!1,void 0,this),z5("div",{className:"flex flex-wrap items-center gap-3 mb-6",children:[z5(gf,{status:A.frontmatter.status},void 0,!1,void 0,this),z5("span",{className:"text-sm text-theme-muted uppercase",children:A.frontmatter.platform},void 0,!1,void 0,this),z5("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&&z5(qF,{src:A.coverImageUrl,alt:A.frontmatter.title,width:A.coverImageWidth,height:A.coverImageHeight,className:"mb-8"},void 0,!1,void 0,this),z5(PB,{className:"p-8 mb-8",children:z5("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),z5("div",{className:"space-y-4 text-sm text-theme-muted",children:[z5("div",{children:[z5("span",{className:"font-medium",children:"Created:"},void 0,!1,void 0,this)," ",c31(A.created)]},void 0,!0,void 0,this),A.frontmatter.publishedAt&&z5("div",{children:[z5("span",{className:"font-medium",children:"Published:"},void 0,!1,void 0,this)," ",c31(A.frontmatter.publishedAt)]},void 0,!0,void 0,this),A.frontmatter.platformPostId&&z5("div",{children:z5("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 ci(A){return`social-media:${A}`}var wOQ=H.union([H.boolean(),H.object({generate:H.boolean().optional(),prompt:H.string().optional()})]),EhA=H.object({prompt:H.string().optional(),platform:H.enum(["linkedin"]).optional(),sourceEntityType:H.enum(["post","deck"]).optional(),sourceEntityId:H.string().optional(),title:H.string().optional().describe("Required when content is provided directly"),content:H.string().optional(),addToQueue:H.boolean().optional(),generateImage:H.boolean().optional().describe("Auto-generate cover image for post"),coverImage:wOQ.optional().describe("Generic cover image generation request")}),$OQ=qI.extend({slug:H.string().optional()});class FC extends z7{constructor(A,Q){super(A,Q,{schema:EhA,jobTypeName:"social-post-generation",entityType:"social-post"})}async generate(A,Q){let B=A.platform??"linkedin",w=A.addToQueue??!1,{prompt:$,sourceEntityType:f,sourceEntityId:I}=A,{content:D,title:U}=A;if(D&&U)await this.reportProgress(Q,{progress:50,message:"Using provided content"});else if(D&&!U){await this.reportProgress(Q,{progress:10,message:"Shaping content with AI"});let V=await this.context.ai.generate({prompt:D,templateName:ci(B)});U=V.title,D=V.content,await this.reportProgress(Q,{progress:50,message:"Social post shaped from content"})}else if(I&&f){await this.reportProgress(Q,{progress:10,message:`Fetching source ${f}`});let V=await this.context.entityService.getEntity({entityType:f,id:I});if(!V)this.failEarly(`Source entity not found: ${f}/${I}`);await this.reportProgress(Q,{progress:30,message:"Generating social post from source content"});let O=H.object({slug:H.string()}).safeParse(V.metadata),E=O.success?O.data.slug:I,S=await this.context.ai.generate({prompt:`Create an engaging ${B} post to promote this ${f}:
|
|
6517
6517
|
|
|
6518
6518
|
Source: ${f}/${E}
|
|
6519
6519
|
|
|
6520
6520
|
${V.content}`,templateName:ci(B)});U=S.title,D=S.content,await this.reportProgress(Q,{progress:50,message:"Social post generated from source"})}else if($){await this.reportProgress(Q,{progress:10,message:"Generating social post with AI"});let V=await this.context.ai.generate({prompt:$,templateName:ci(B)});U=V.title,D=V.content,await this.reportProgress(Q,{progress:50,message:"Social post generated"})}else this.failEarly("No content source provided (prompt, sourceEntityId, or content)");if(!D||!U)this.failEarly("Content or title was not generated");let J={title:U,platform:B,status:w?"queued":"draft",...I&&{sourceEntityId:I},...f&&{sourceEntityType:f}},X=s9.createPostContent(J,D),Z=s9.fromMarkdown(X).metadata;if(!Z)this.failEarly("Failed to parse social post metadata");let N=await rG({entityType:"social-post",title:U,deriveId:(V)=>`${B}-${X1(V)}`,regeneratePrompt:"Generate a different social media post title on the same topic.",context:this.context}),L=X;if(N!==U){Z.title=N,Z.slug=`${B}-${X1(N)}`;let V={...J,title:N};L=s9.createPostContent(V,D)}return{id:Z.slug,content:L,metadata:Z,title:N,resultExtras:{slug:Z.slug},createOptions:{deduplicateId:!0}}}async onGenerationFailure(A,Q){await this.context.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:Q}})}async afterCreate(A,Q,B,w){if(A.generateImage){await this.reportProgress(B,{progress:90,message:"Queueing image generation"});let $=w.title??"Social Post";await this.context.jobs.enqueue({type:"image:image-generate",data:{prompt:`Social media graphic for: ${$}`,title:`${$} Image`,aspectRatio:"16:9",targetEntityType:"social-post",targetEntityId:Q},toolContext:{interfaceType:"job",userId:"system"}})}await this.context.messaging.send({type:"generate:report:success",payload:{entityType:"social-post",entityId:Q}})}summarizeDataForLog(A){return{platform:A.platform??"linkedin",hasPrompt:!!A.prompt,sourceEntityType:A.sourceEntityType,addToQueue:A.addToQueue??!1,generateImage:A.generateImage??!1,coverImage:!!A.coverImage}}}function li(A){if(A.length<=200)return A;return`${A.slice(0,200)}\u2026 (truncated, ${A.length} bytes)`}function fOQ(A){let Q={status:"READY",media:A.urn};if(A.title)Q.title={text:A.title};return Q}function IOQ(A){if(!MhA(A))return null;let Q=P$A(A,"value");if(!Q)return null;let B=P$A(Q,"uploadMechanism");if(!B)return null;let w=P$A(B,"com.linkedin.digitalmedia.uploading.MediaUploadHttpRequest");if(!w)return null;let $=w.uploadUrl,f=Q.asset;if(typeof $!=="string"||typeof f!=="string")return null;return{uploadUrl:$,assetUrn:f}}function DOQ(A){if(!MhA(A))return null;let Q=P$A(A,"value");if(!Q)return null;let{uploadUrl:B,document:w}=Q;if(typeof B!=="string"||typeof w!=="string")return null;return{uploadUrl:B,documentUrn:w}}function P$A(A,Q){let B=A[Q];return MhA(B)?B:null}function MhA(A){return typeof A==="object"&&A!==null}var UOQ="202604";class ChA{config;logger;name="linkedin";apiBaseUrl="https://api.linkedin.com/v2";restApiBaseUrl="https://api.linkedin.com/rest";fetch;cachedUserId=null;constructor(A,Q,B={}){this.config=A;this.logger=Q;this.fetch=B.fetch??globalThis.fetch.bind(globalThis)}async publish(A,Q,B,w){if(!this.config.accessToken)throw Error("LinkedIn access token not configured");let $=await this.getAuthor(),f=w?.[0];if(w&&w.length>1)this.logger.warn("LinkedIn document publishing supports one PDF",{count:w.length});let I=null;if(f){let X=await this.uploadDocument($,f);return this.publishDocumentPost($,A,X,f.filename)}else if(B){let X=await this.uploadImage($,B);if(X)I={category:"IMAGE",urn:X}}let D={shareCommentary:{text:A},shareMediaCategory:I?.category??"NONE",...I&&{media:[fOQ(I)]}},U=await this.fetch(`${this.apiBaseUrl}/ugcPosts`,{method:"POST",headers:{Authorization:`Bearer ${this.config.accessToken}`,"Content-Type":"application/json","X-Restli-Protocol-Version":"2.0.0"},body:JSON.stringify({author:$,lifecycleState:"PUBLISHED",specificContent:{"com.linkedin.ugc.ShareContent":D},visibility:{"com.linkedin.ugc.MemberNetworkVisibility":"PUBLIC"}})});if(!U.ok){let X=li(await U.text());throw this.logger.error("LinkedIn API error",{status:U.status,error:X}),Error(`LinkedIn API error: ${U.status} - ${X}`)}let Y=U.headers.get("X-RestLi-Id")??"";this.logger.info("LinkedIn post created",{postId:Y,mediaCategory:I?.category??"NONE"});let J={id:Y};if(Y)J.url=`https://www.linkedin.com/feed/update/${Y}`;return J}getRestHeaders(){return{Authorization:`Bearer ${this.config.accessToken}`,"Content-Type":"application/json","Linkedin-Version":this.config.apiVersion??UOQ,"X-Restli-Protocol-Version":"2.0.0"}}async uploadImage(A,Q){try{let B=await this.fetch(`${this.apiBaseUrl}/assets?action=registerUpload`,{method:"POST",headers:{Authorization:`Bearer ${this.config.accessToken}`,"Content-Type":"application/json","X-Restli-Protocol-Version":"2.0.0"},body:JSON.stringify({registerUploadRequest:{recipes:["urn:li:digitalmediaRecipe:feedshare-image"],owner:A,serviceRelationships:[{relationshipType:"OWNER",identifier:"urn:li:userGeneratedContent"}]}})});if(!B.ok){let D=li(await B.text());return this.logger.warn("LinkedIn image upload registration failed",{status:B.status,error:D}),null}let w=IOQ(await B.json());if(!w)return this.logger.warn("LinkedIn image upload registration was malformed"),null;let{uploadUrl:$,assetUrn:f}=w,I=await this.fetch($,{method:"PUT",headers:{Authorization:`Bearer ${this.config.accessToken}`,"Content-Type":Q.mimeType},body:new Uint8Array(Q.data)});if(!I.ok)return this.logger.warn("LinkedIn image binary upload failed",{status:I.status}),null;return this.logger.info("LinkedIn image uploaded",{assetUrn:f}),f}catch(B){return this.logger.warn("LinkedIn image upload error",{error:B}),null}}async uploadDocument(A,Q){let B=await this.fetch(`${this.restApiBaseUrl}/documents?action=initializeUpload`,{method:"POST",headers:this.getRestHeaders(),body:JSON.stringify({initializeUploadRequest:{owner:A}})});if(!B.ok){let f=li(await B.text());throw Error(`LinkedIn document upload initialization failed: ${B.status} - ${f}`)}let w=DOQ(await B.json());if(!w)throw Error("LinkedIn document upload initialization was malformed");let $=await this.fetch(w.uploadUrl,{method:"PUT",headers:{Authorization:`Bearer ${this.config.accessToken}`,"Content-Type":Q.mimeType},body:new Uint8Array(Q.data)});if(!$.ok)throw Error(`LinkedIn document binary upload failed: ${$.status}`);return this.logger.info("LinkedIn document uploaded",{documentUrn:w.documentUrn,filename:Q.filename}),w.documentUrn}async publishDocumentPost(A,Q,B,w){let $=await this.fetch(`${this.restApiBaseUrl}/posts`,{method:"POST",headers:this.getRestHeaders(),body:JSON.stringify({author:A,commentary:Q,visibility:"PUBLIC",distribution:{feedDistribution:"MAIN_FEED",targetEntities:[],thirdPartyDistributionChannels:[]},content:{media:{id:B,title:w}},lifecycleState:"PUBLISHED",isReshareDisabledByAuthor:!1})});if(!$.ok){let D=li(await $.text());throw this.logger.error("LinkedIn document post API error",{status:$.status,error:D}),Error(`LinkedIn document post API error: ${$.status} - ${D}`)}let f=$.headers.get("X-RestLi-Id")??"";this.logger.info("LinkedIn document post created",{postId:f,documentUrn:B});let I={id:f};if(f)I.url=`https://www.linkedin.com/feed/update/${f}`;return I}async validateCredentials(){if(!this.config.accessToken)return!1;try{if(this.config.organizationId)return(await this.fetch(`${this.apiBaseUrl}/organizations/${this.config.organizationId}`,{headers:{Authorization:`Bearer ${this.config.accessToken}`}})).ok;return await this.getUserId(),!0}catch{return!1}}async getAuthor(){if(this.config.organizationId)return`urn:li:organization:${this.config.organizationId}`;return this.getUserId()}async getUserId(){if(this.cachedUserId)return this.cachedUserId;if(!this.config.accessToken)throw Error("LinkedIn access token not configured");try{let B=await this.fetch("https://api.linkedin.com/v2/userinfo",{headers:{Authorization:`Bearer ${this.config.accessToken}`}});if(B.ok){let w=await B.json();return this.cachedUserId=`urn:li:person:${w.sub}`,this.cachedUserId}}catch{}let A=await this.fetch("https://api.linkedin.com/v2/me",{headers:{Authorization:`Bearer ${this.config.accessToken}`}});if(!A.ok){let B=li(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 OhA(A,Q,B={}){return new ChA(A,Q,B)}aA();WA();Ew();VhA();var YOQ=H.object({posts:H.array(M$A),totalCount:H.number().optional(),pagination:Z7.nullable(),baseUrl:H.string().optional()}),JOQ=H.object({post:M$A});function l31(){return{linkedin:O$A,"social-post-list":P1({name:"social-post-list",description:"Social post list page template",schema:YOQ,dataSourceId:"social-media:posts",requiredPermission:"public",layout:{component:R$A}}),"social-post-detail":P1({name:"social-post-detail",description:"Individual social post template",schema:JOQ,dataSourceId:"social-media:posts",requiredPermission:"public",layout:{component:b$A}})}}WA();var XOQ=H.object({prompt:H.string().optional(),content:H.string().optional(),platform:H.enum(["linkedin"]).default("linkedin")}),WOQ=H.object({prompt:H.string().optional(),content:H.string().optional(),title:H.string().optional(),platform:H.enum(["linkedin"]).optional()});function p31(A){A.eval.registerHandler("generation",async(Q)=>{let B=XOQ.parse(Q),w=B.content?`Create an engaging LinkedIn post to share this content:
|
|
6521
6521
|
|
|
6522
|
-
${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=WOQ.parse(Q),w=[],$=M9.from(async(Y)=>{let J={progress:Y.progress};if(Y.message!==void 0)J.message=Y.message;w.push(J)});if(!$)throw Error("Failed to create progress reporter");let I=await new FC(A.logger,A).process(B,`eval-${Date.now()}`,$),D=!1,U;if(I.success&&I.entityId){let Y=await A.entityService.getEntity({entityType:"social-post",id:I.entityId});D=!!Y,U=Y?.content.slice(0,300)}return{...I,entityExists:D,entityPreview:U,progressSteps:w}})}WA();aA();class pi{sendMessage;logger;entityService;providers;permissions;resolveAttachment;constructor(A){this.sendMessage=A.sendMessage,this.logger=A.logger,this.entityService=A.entityService,this.providers=A.providers,this.permissions=A.permissions,this.resolveAttachment=A.resolveAttachment}async handle(A){let{entityType:Q,entityId:B}=A;if(Q!=="social-post")return;this.permissions.assertEntityActionAllowed(Q,"publish",A.authContext??{userPermissionLevel:"anchor"}),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}let $=w;if($.metadata.status==="published"){this.logger.debug("Post already published, skipping",{entityId:B});return}let f=$.metadata.platform,I=this.providers.get(f);if(!I){await this.reportFailure(Q,B,`No provider configured for platform: ${f}`);return}let D=R2($.content,oU),U;if(D.metadata.coverImageId)U=await this.fetchImageData(D.metadata.coverImageId);let Y=D.metadata.documents??[],J=await this.fetchDocumentData(Y);try{if(Y.length>0&&J.length===0)throw Error(`Refusing to publish: ${Y.length} document(s) referenced but none could be fetched`);let X=Y.length===0?await this.resolveSourceAttachment(D.metadata):[],G=J.length>0?J:X,Z=G.length?await I.publish(D.content,$.metadata,U,G):await I.publish(D.content,$.metadata,U),N=new Date().toISOString(),L=Z.id||void 0,V={...D.metadata,status:"published",publishedAt:N,...L&&{platformPostId:L}},M=s9.createPostContent(V,D.content);await this.entityService.updateEntity({entity:{...$,content:M,metadata:{...$.metadata,status:"published",publishedAt:N,platformPostId:L}}}),await this.reportSuccess(Q,B,Z.id),this.logger.info(`Post published successfully: ${B}`,{platform:f,platformPostId:L})}catch(X){let G=X instanceof Error?X.message:String(X),Z={...D.metadata,status:"failed"},N=s9.createPostContent(Z,D.content);await this.entityService.updateEntity({entity:{...$,content:N,metadata:{...$.metadata,status:"failed"}}}),await this.reportFailure(Q,B,G),this.logger.error(`Post publish failed: ${B}`,{platform:f,error:G})}}catch(w){let $=T0(w);this.logger.error("Unexpected error in publish handler",{entityId:B,error:$}),await this.reportFailure(Q,B,$)}}async reportSuccess(A,Q,B){await this.sendMessage({type:"publish:report:success",payload:{entityType:A,entityId:Q,result:{id:B}}})}async reportFailure(A,Q,B){await this.sendMessage({type:"publish:report:failure",payload:{entityType:A,entityId:Q,error:B}})}async resolveSourceAttachment(A){if(!this.resolveAttachment||!A.sourceEntityType||!A.sourceEntityId)return[];let Q=await this.resolveAttachment({sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:"carousel"});return Q?[Q]:[]}async fetchDocumentData(A){if(!A?.length)return[];let Q=[];for(let B of A){let w=await this.fetchSingleDocumentData(B.id);if(w)Q.push(w)}return Q}async fetchSingleDocumentData(A){try{let Q=await this.entityService.getEntity({entityType:"document",id:A});if(!Q){this.logger.warn("Document not found",{documentId:A});return}let B=Q.content.match(/^data:application\/pdf;base64,(.+)$/);if(!B?.[1]){this.logger.warn("Invalid document data URL format",{documentId:A});return}let w=typeof Q.metadata.filename==="string"?Q.metadata.filename:`${A}.pdf`;return{type:"document",data:Buffer.from(B[1],"base64"),mimeType:"application/pdf",filename:w}}catch(Q){this.logger.warn("Failed to fetch document",{documentId:A,error:Q});return}}async fetchImageData(A){try{let Q=await this.entityService.getEntity({entityType:"image",id:A});if(!Q){this.logger.warn("Cover image not found",{imageId:A});return}let w=Q.content.match(/^data:([^;]+);base64,(.+)$/);if(!w?.[1]||!w[2]){this.logger.warn("Invalid image data URL format",{imageId:A});return}let $=w[1],f=w[2];return{data:Buffer.from(f,"base64"),mimeType:$}}catch(Q){this.logger.warn("Failed to fetch cover image",{imageId:A,error:Q});return}}}function i31(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,config:{publishResultIdField:"platformPostId"}}}),B.info("Registered social-post with publish-pipeline"),{success:!0}})}function r31(A,Q,B){let w=new pi({sendMessage:A.messaging.send,logger:B.child("PublishExecuteHandler"),entityService:A.entityService,providers:Q,permissions:A.permissions,resolveAttachment:A.attachments.resolve});A.messaging.subscribe("publish:execute",async($)=>{return await w.handle($.payload),{success:!0}}),B.debug("Subscribed to publish:execute messages")}WA();function d31(A,Q){A.messaging.subscribe("entity:updated",async(B)=>{let{entityType:w,entityId:$,entity:f}=B.payload;if(w!=="post")return{success:!0};if(f.metadata?.status!=="queued")return{success:!0};try{if((await A.entityService.listEntities({entityType:"social-post",options:{filter:{metadata:{sourceEntityType:"post",sourceEntityId:$}},limit:1}})).length>0)return Q.debug(`Social post already exists for ${$}, skipping auto-generate`),{success:!0};return await A.messaging.send({type:"social:auto-generate",payload:{sourceEntityType:w,sourceEntityId:$,platform:"linkedin"}}),Q.info(`Auto-generate social post triggered for queued post ${$}`),{success:!0}}catch(D){let U=T0(D);return Q.error(`Failed to trigger auto-generate for ${$}:`,{error:U}),{success:!0}}}),Q.debug("Subscribed to entity:updated for auto-generation")}function n31(A,Q){A.messaging.subscribe("social:auto-generate",async(B)=>{let{sourceEntityType:w,sourceEntityId:$,platform:f}=B.payload;try{let I=await A.jobs.enqueue({type:`${s9.entityType}:generation`,data:{sourceEntityType:w,sourceEntityId:$,platform:f,addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}});return Q.info(`Social post generation job enqueued for ${w}/${$}`,{jobId:I}),{success:!0,jobId:I}}catch(I){let D=T0(I);return Q.error(`Failed to enqueue social post generation for ${$}:`,{error:D}),{success:!1}}}),Q.debug("Subscribed to social:auto-generate messages")}function o31(A,Q){A.messaging.subscribe("generate:execute",async(B)=>{let{entityType:w}=B.payload;if(w!=="social-post")return{success:!0};Q.info("Received generate:execute for social-post");try{let $=await A.entityService.listEntities({entityType:"post",options:{filter:{metadata:{status:"published"}},limit:5}});if($.length===0)return Q.info("No published posts found for social post generation"),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:"No published posts available for social post generation"}}),{success:!0};let f=null;for(let D of $)if((await A.entityService.listEntities({entityType:"social-post",options:{filter:{metadata:{sourceEntityType:"post",sourceEntityId:D.id}},limit:1}})).length===0){f=D;break}if(!f)return Q.info("All recent posts already have social posts"),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:"All recent posts already have social posts generated"}}),{success:!0};let I=await A.jobs.enqueue({type:`${s9.entityType}:generation`,data:{sourceEntityType:"post",sourceEntityId:f.id,platform:"linkedin",addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}});return Q.info("Social post generation job queued",{jobId:I,sourcePostId:f.id}),{success:!0}}catch($){let f=T0($);return Q.error("Failed to handle generate:execute:",{error:f}),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:f}}),{success:!0}}}),Q.debug("Subscribed to generate:execute messages")}async function s31({entity:A,config:Q}){let B=nz.parse(A),w=s9.parsePostFrontmatter(B),$=s9.getPostContent(B);return{$type:"ai.rizom.brain.socialPost",title:w.title,platform:w.platform,body:$,format:"text/markdown",status:w.status,...w.publishedAt&&{publishedAt:w.publishedAt},...w.platformPostId&&{platformPostId:w.platformPostId},...w.sourceEntityType&&{sourceLocalEntityType:w.sourceEntityType},...w.sourceEntityId&&{sourceLocalEntityId:w.sourceEntityId},...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"social-post",sourceEntityId:B.id,createdAt:B.created,...B.updated&&{updatedAt:B.updated}}}function RhA(){return{entityType:"social-post",collection:"ai.rizom.brain.socialPost",lexicon:Gw["ai.rizom.brain.socialPost"],validate:!1,buildRecord:s31}}var a31={name:"@brains/social-media",private:!0,version:"0.2.0-alpha.119",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/atproto-contracts":"workspace:*","@brains/contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class bhA extends jQ{entityType=s9.entityType;schema=nz;adapter=s9;providers=new Map;unregisterAtprotoProjection;constructor(A){super("social-media",a31,A,qhA)}createGenerationHandler(A){return new FC(this.logger.child("GenerationJobHandler"),A)}getTemplates(){return l31()}getDataSources(){return[new C$A(this.logger.child("SocialPostDataSource"))]}getEntityTypeConfig(){return{publish:{publishStatuses:["queued","published","failed"]}}}async onRegister(A){if(this.initializeProviders(),i31(A,this.providers,this.logger),r31(A,this.providers,this.logger),this.config.autoGenerateOnBlogPublish)d31(A,this.logger),n31(A,this.logger),this.logger.info("Auto-generate on blog publish enabled");o31(A,this.logger),p31(A),this.unregisterAtprotoProjection=d6.getInstance().register(RhA()),this.logger.info("Social media plugin registered successfully")}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}initializeProviders(){if(this.config.linkedin?.accessToken){let A=OhA(this.config.linkedin,this.logger.child("LinkedInClient"));this.providers.set("linkedin",A),this.logger.info("LinkedIn provider initialized")}}}function ii(A){return new bhA(A)}WA();var GOQ=H.enum(["draft","queued","published","failed"]),t31=H.object({status:GOQ.default("draft"),queueOrder:H.number().optional().describe("Position in publish queue (lower = sooner)"),publishedAt:H.string().datetime().optional()});class PhA{name="internal";async publish(A,Q){return{id:"internal"}}}var ri={interfaceType:"system",userId:"system",userPermissionLevel:"anchor",authorization:"system"},c4={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",QUEUED:"publish:queued",COMPLETED:"publish:completed",FAILED:"publish:failed",LIST_RESPONSE:"publish:list:response"},oz={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"},e31={REGISTER:"publish-assets:register"};WA();var KOQ=H.enum(["provider"]),Az1=H.object({executionMode:KOQ.optional(),publishResultIdField:H.string().min(1).optional(),publishTimestampField:H.string().min(1).optional(),enabled:H.boolean().optional()}).strict();var FOQ=H.object({skipIfDraftExists:H.boolean().optional(),minSourceEntities:H.number().optional(),maxUnpublishedDrafts:H.number().optional(),sourceEntityType:H.string().optional()}),Qz1=H.object({entitySchedules:H.record(H.string(),H.string()).optional(),generationSchedules:H.record(H.string(),H.string()).optional(),generationConditions:H.record(H.string(),FOQ).optional()});class vH{static instance=null;queues=new Map;static getInstance(){return vH.instance??=new vH,vH.instance}static resetInstance(){vH.instance=null}static createFresh(){return new vH}constructor(){}async add(A,Q,B=ri){let w=this.getOrCreateQueue(A),$=w.find((D)=>D.entityId===Q);if($)return{position:$.position};let f=w.length+1,I={entityId:Q,entityType:A,position:f,queuedAt:new Date().toISOString(),authContext:{...B}};return w.push(I),{position:f}}async remove(A,Q){let B=this.queues.get(A);if(!B)return;let w=B.findIndex(($)=>$.entityId===Q);if(w===-1)return;B.splice(w,1),this.recalculatePositions(B)}async reorder(A,Q,B){let w=this.queues.get(A);if(!w)return;let $=w.findIndex((D)=>D.entityId===Q);if($===-1)return;let[f]=w.splice($,1);if(!f)return;let I=Math.max(0,Math.min(B-1,w.length));w.splice(I,0,f),this.recalculatePositions(w)}async list(A){let Q=this.queues.get(A);if(!Q)return[];return[...Q]}async getNext(A){let Q=this.queues.get(A);if(!Q||Q.length===0)return null;return Q[0]??null}async getNextAcrossTypes(){let A=null;for(let Q of this.queues.values()){let B=Q[0];if(!B)continue;if(!A||B.queuedAt<A.queuedAt)A=B}return A}async popNext(A){let Q=this.queues.get(A);if(!Q||Q.length===0)return null;let B=Q.shift()??null;if(B)this.recalculatePositions(Q);return B}getRegisteredTypes(){return Array.from(this.queues.keys())}async getQueuedEntityTypes(){let A=[];for(let[Q,B]of this.queues.entries())if(B.length>0)A.push(Q);return A}getOrCreateQueue(A){let Q=this.queues.get(A);if(!Q)Q=[],this.queues.set(A,Q);return Q}recalculatePositions(A){A.forEach((Q,B)=>{Q.position=B+1})}}class TH{static instance=null;providers=new Map;executionModes=new Map;publishResultIdFields=new Map;publishTimestampFields=new Map;defaultProvider=new PhA;static getInstance(){return TH.instance??=new TH,TH.instance}static resetInstance(){TH.instance=null}static createFresh(){return new TH}constructor(){}register(A,Q,B){let w=this.providers.get(A);if(w&&w.name!=="internal"&&Q.name==="internal")return;if(this.providers.set(A,Q),this.executionModes.set(A,B?.executionMode??"provider"),B?.publishResultIdField)this.publishResultIdFields.set(A,B.publishResultIdField);else this.publishResultIdFields.delete(A);if(B?.publishTimestampField)this.publishTimestampFields.set(A,B.publishTimestampField);else this.publishTimestampFields.delete(A)}get(A){return this.providers.get(A)??this.defaultProvider}getExecutionMode(A){return this.executionModes.get(A)??"provider"}getPublishResultIdField(A){return this.publishResultIdFields.get(A)}getPublishTimestampField(A){return this.publishTimestampFields.get(A)}has(A){return this.providers.has(A)}unregister(A){this.providers.delete(A),this.executionModes.delete(A),this.publishResultIdFields.delete(A),this.publishTimestampFields.delete(A)}getRegisteredTypes(){return Array.from(this.providers.keys())}}WA();WA();async function Bz1(A,Q){if(!Q.publishExecutor){Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:"Publish executor not configured",retryCount:0,willRetry:!1});return}await ZOQ(A,Q)}async function ZOQ(A,Q){if(!Q.publishExecutor)return;try{let B=await Q.publishExecutor.publish({entityType:A.entityType,id:A.entityId});if("error"in B){let w={entityType:A.entityType,entityId:A.entityId,error:B.error,retryCount:0,willRetry:!1};if(Q.messageBus)await Q.messageBus.send({type:c4.FAILED,payload:w,sender:"publish-service"});Q.onFailed?.(w);return}khA(A.entityType,A.entityId,B.result,Q)}catch(B){let w=T0(B);Q.retryTracker.recordFailure(A.entityId,w);let $=Q.retryTracker.getRetryInfo(A.entityId);Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:w,retryCount:$?.retryCount??1,willRetry:!1})}}function khA(A,Q,B,w){if(w.retryTracker.clearRetries(Q),w.messageBus)w.messageBus.send({type:c4.COMPLETED,payload:{entityType:A,entityId:Q,result:B},sender:"publish-service"});w.onPublish?.({entityType:A,entityId:Q,result:B})}function wz1(A,Q,B,w){w.retryTracker.recordFailure(Q,B);let $=w.retryTracker.getRetryInfo(Q),f={entityType:A,entityId:Q,error:B,retryCount:$?.retryCount??1,willRetry:!1};if(w.messageBus)w.messageBus.send({type:c4.FAILED,payload:f,sender:"publish-service"});w.onFailed?.(f)}async function $z1(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:oz.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:oz.EXECUTE,payload:w,sender:"content-pipeline"});Q.onGenerate?.(w)}function fz1(A,Q,B){if(B)B.send({type:oz.COMPLETED,payload:{entityType:A,entityId:Q},sender:"content-pipeline"})}function Iz1(A,Q,B){if(B)B.send({type:oz.FAILED,payload:{entityType:A,error:Q},sender:"content-pipeline"})}var NOQ=1000;class jhA{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(NOQ,()=>this.processUnscheduledTypes())}stop(){if(zOQ(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){await this.deps.config.queueManager.remove(A.entityType,A.entityId);let Q=this.deps.getPublishDeps();await Bz1(A,Q)}get entitySchedules(){return this.deps.config.entitySchedules}}function zOQ(A){for(let Q of A.values())Q.stop();A.clear()}class _hA{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(){qOQ(this.generationJobs)}async handleTriggerGeneration(A){if(!this.deps.isRunning())return;try{await $z1(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 qOQ(A){for(let Q of A.values())Q.stop();A.clear()}class UX{static instance=null;config;publishRunner;generationRunner;running=!1;static getInstance(A){return UX.instance??=new UX(A),UX.instance}static resetInstance(){if(UX.instance)UX.instance.stop();UX.instance=null}static createFresh(A){return new UX(A)}constructor(A){this.config={...A,entitySchedules:A.entitySchedules??{},generationSchedules:A.generationSchedules??{},generationConditions:A.generationConditions??{}},this.validateCronExpressions(),this.publishRunner=new jhA({config:this.config,getPublishDeps:()=>this.publishDeps,isRunning:()=>this.running}),this.generationRunner=new _hA({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){khA(A,Q,B,this.publishDeps)}failPublish(A,Q,B){wz1(A,Q,B,this.publishDeps)}async publishDirect(A,Q,B,w){return this.config.providerRegistry.get(A).publish(B,w)}completeGeneration(A,Q){fz1(A,Q,this.config.messageBus)}failGeneration(A,Q){Iz1(A,Q,this.config.messageBus)}get entitySchedules(){return this.config.entitySchedules}get generationSchedules(){return this.config.generationSchedules}get publishDeps(){return{retryTracker:this.config.retryTracker,messageBus:this.config.messageBus,publishExecutor:this.config.publishExecutor,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}" - ${T0(w)}`)}}}class yH{static instance=null;retries=new Map;static getInstance(){return yH.instance??=new yH,yH.instance}static resetInstance(){yH.instance=null}static createFresh(){return new yH}constructor(){}recordFailure(A,Q){let w=(this.retries.get(A)?.retryCount??0)+1;this.retries.set(A,{entityId:A,retryCount:w,lastError:Q})}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}}}function u7(A,Q,B,w,$,f,I,D){return u7.fromTZ(u7.tp(A,Q,B,w,$,f,I),D)}u7.fromTZISO=(A,Q,B)=>u7.fromTZ(LOQ(A,Q),B);u7.fromTZ=function(A,Q){let B=new Date(Date.UTC(A.y,A.m-1,A.d,A.h,A.i,A.s)),w=vhA(A.tz,B),$=new Date(B.getTime()-w),f=vhA(A.tz,$);if(f-w===0)return $;{let I=new Date(B.getTime()-f),D=vhA(A.tz,I);if(D-f===0)return I;if(!Q&&D-f>0)return I;if(Q)throw Error("Invalid date passed to fromTZ()");return $}};u7.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}};u7.tp=(A,Q,B,w,$,f,I)=>({y:A,m:Q,d:B,h:w,i:$,s:f,tz:I});function vhA(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 LOQ(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("+")?u7.tp(B.getUTCFullYear(),B.getUTCMonth()+1,B.getUTCDate(),B.getUTCHours(),B.getUTCMinutes(),B.getUTCSeconds(),"Etc/UTC"):u7.tp(B.getFullYear(),B.getMonth()+1,B.getDate(),B.getHours(),B.getMinutes(),B.getSeconds(),Q)}u7.minitz=u7;var ThA=32,ni=31|ThA,Jz1=[1,2,4,8,16],Dz1=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 sU(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,ni),this.dayOfWeek[7]&&(this.dayOfWeek[0]=this.dayOfWeek[7])}partToArray(A,Q,B,w){let $=this[A],f=A==="day"&&this.lastDayOfMonth;if(Q===""&&!f)throw TypeError("CronPattern: configuration entry "+A+" ("+Q+") is empty, check for trailing spaces.");if(Q==="*")return $.fill(w);let I=Q.split(",");if(I.length>1)for(let D=0;D<I.length;D++)this.partToArray(A,I[D],B,w);else Q.indexOf("-")!==-1&&Q.indexOf("/")!==-1?this.handleRangeWithStepping(Q,A,B,w):Q.indexOf("-")!==-1?this.handleRange(Q,A,B,w):Q.indexOf("/")!==-1?this.handleStepping(Q,A,B,w):Q!==""&&this.handleNumber(Q,A,B,w)}throwAtIllegalCharacters(A){for(let Q=0;Q<A.length;Q++)if((Q===5?/[^/*0-9,\-#L]+/:/[^/*0-9,-]+/).test(A[Q]))throw TypeError("CronPattern: configuration entry "+Q+" ("+A[Q]+") contains illegal characters.")}handleNumber(A,Q,B,w){let $=this.extractNth(A,Q),f=parseInt($[0],10)+B;if(isNaN(f))throw TypeError("CronPattern: "+Q+" is not a number: '"+A+"'");this.setPart(Q,f,$[1]||w)}setPart(A,Q,B){if(!Object.prototype.hasOwnProperty.call(this,A))throw TypeError("CronPattern: Invalid part specified: "+A);if(A==="dayOfWeek"){if(Q===7&&(Q=0),Q<0||Q>6)throw RangeError("CronPattern: Invalid value for dayOfWeek: "+Q);this.setNthWeekdayOfMonth(Q,B);return}if(A==="second"||A==="minute"){if(Q<0||Q>=60)throw RangeError("CronPattern: Invalid value for "+A+": "+Q)}else if(A==="hour"){if(Q<0||Q>=24)throw RangeError("CronPattern: Invalid value for "+A+": "+Q)}else if(A==="day"){if(Q<0||Q>=31)throw RangeError("CronPattern: Invalid value for "+A+": "+Q)}else if(A==="month"&&(Q<0||Q>=12))throw RangeError("CronPattern: Invalid value for "+A+": "+Q);this[A][Q]=B}handleRangeWithStepping(A,Q,B,w){let $=this.extractNth(A,Q),f=$[0].match(/^(\d+)-(\d+)\/(\d+)$/);if(f===null)throw TypeError("CronPattern: Syntax error, illegal range with stepping: '"+A+"'");let[,I,D,U]=f,Y=parseInt(I,10)+B,J=parseInt(D,10)+B,X=parseInt(U,10);if(isNaN(Y))throw TypeError("CronPattern: Syntax error, illegal lower range (NaN)");if(isNaN(J))throw TypeError("CronPattern: Syntax error, illegal upper range (NaN)");if(isNaN(X))throw TypeError("CronPattern: Syntax error, illegal stepping: (NaN)");if(X===0)throw TypeError("CronPattern: Syntax error, illegal stepping: 0");if(X>this[Q].length)throw TypeError("CronPattern: Syntax error, steps cannot be greater than maximum value of part ("+this[Q].length+")");if(Y>J)throw TypeError("CronPattern: From value is larger than to value: '"+A+"'");for(let G=Y;G<=J;G+=X)this.setPart(Q,G,$[1]||w)}extractNth(A,Q){let B=A,w;if(B.includes("#")){if(Q!=="dayOfWeek")throw Error("CronPattern: nth (#) only allowed in day-of-week field");w=B.split("#")[1],B=B.split("#")[0]}return[B,w]}handleRange(A,Q,B,w){let $=this.extractNth(A,Q),f=$[0].split("-");if(f.length!==2)throw TypeError("CronPattern: Syntax error, illegal range: '"+A+"'");let I=parseInt(f[0],10)+B,D=parseInt(f[1],10)+B;if(isNaN(I))throw TypeError("CronPattern: Syntax error, illegal lower range (NaN)");if(isNaN(D))throw TypeError("CronPattern: Syntax error, illegal upper range (NaN)");if(I>D)throw TypeError("CronPattern: From value is larger than to value: '"+A+"'");for(let U=I;U<=D;U++)this.setPart(Q,U,$[1]||w)}handleStepping(A,Q,B,w){let $=this.extractNth(A,Q),f=$[0].split("/");if(f.length!==2)throw TypeError("CronPattern: Syntax error, illegal stepping: '"+A+"'");f[0]===""&&(f[0]="*");let I=0;f[0]!=="*"&&(I=parseInt(f[0],10)+B);let D=parseInt(f[1],10);if(isNaN(D))throw TypeError("CronPattern: Syntax error, illegal stepping: (NaN)");if(D===0)throw TypeError("CronPattern: Syntax error, illegal stepping: 0");if(D>this[Q].length)throw TypeError("CronPattern: Syntax error, max steps for part is ("+this[Q].length+")");for(let U=I;U<this[Q].length;U+=D)this.setPart(Q,U,$[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]|ThA;else if(Q===ni)this.dayOfWeek[A]=ni;else if(Q<6&&Q>0)this.dayOfWeek[A]=this.dayOfWeek[A]|Jz1[Q-1];else throw TypeError(`CronPattern: nth weekday out of range, should be 1-5 or L. Value: ${Q}, Type: ${typeof Q}`)}},Uz1=[31,28,31,30,31,30,31,31,30,31,30,31],iF=[["month","year",0],["day","month",-1],["hour","day",0],["minute","hour",0],["second","minute",0]],sU=class A{tz;ms;second;minute;hour;day;month;year;constructor(Q,B){if(this.tz=B,Q&&Q instanceof Date)if(!isNaN(Q))this.fromDate(Q);else throw TypeError("CronDate: Invalid date passed to CronDate constructor");else if(Q===void 0)this.fromDate(new Date);else if(Q&&typeof Q=="string")this.fromString(Q);else if(Q instanceof A)this.fromCronDate(Q);else throw TypeError("CronDate: Invalid type ("+typeof Q+") passed to CronDate constructor")}isNthWeekdayOfMonth(Q,B,w,$){let f=new Date(Date.UTC(Q,B,w)).getUTCDay(),I=0;for(let D=1;D<=w;D++)new Date(Date.UTC(Q,B,D)).getUTCDay()===f&&I++;if($&ni&&Jz1[I-1]&$)return!0;if($&ThA){let D=new Date(Date.UTC(Q,B+1,0)).getUTCDate();for(let U=w+1;U<=D;U++)if(new Date(Date.UTC(Q,B,U)).getUTCDay()===f)return!1;return!0}return!1}fromDate(Q){if(this.tz!==void 0)if(typeof this.tz=="number")this.ms=Q.getUTCMilliseconds(),this.second=Q.getUTCSeconds(),this.minute=Q.getUTCMinutes()+this.tz,this.hour=Q.getUTCHours(),this.day=Q.getUTCDate(),this.month=Q.getUTCMonth(),this.year=Q.getUTCFullYear(),this.apply();else{let B=u7.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>Uz1[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=u7.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(u7.fromTZISO(Q,this.tz))}findNext(Q,B,w,$){let f=this[B],I;w.lastDayOfMonth&&(this.month!==1?I=Uz1[this.month]:I=new Date(Date.UTC(this.year,this.month+1,0,0,0,0,0)).getUTCDate());let D=!w.starDOW&&B=="day"?new Date(Date.UTC(this.year,this.month,1,0,0,0,0)).getUTCDay():void 0;for(let U=this[B]+$;U<w[B].length;U++){let Y=w[B][U];if(B==="day"&&w.lastDayOfMonth&&U-$==I&&(Y=1),B==="day"&&!w.starDOW){let J=w.dayOfWeek[(D+(U-$-1))%7];if(J&&J&ni)J=this.isNthWeekdayOfMonth(this.year,this.month,U-$,J)?1:0;else if(J)throw Error(`CronDate: Invalid value for dayOfWeek encountered. ${J}`);Q.legacyMode&&!w.starDOM?Y=Y||J:Y=Y&&J}if(Y)return this[B]=U-$,f!==this[B]?2:1}return 3}recurse(Q,B,w){let $=this.findNext(B,iF[w][0],Q,iF[w][2]);if($>1){let f=w+1;for(;f<iF.length;)this[iF[f][0]]=-iF[f][2],f++;if($===3)return this[iF[w][1]]++,this[iF[w][0]]=-iF[w][2],this.apply(),this.recurse(Q,B,0);if(this.apply())return this.recurse(Q,B,w-1)}return w+=1,w>=iF.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)):u7.fromTZ(u7.tp(this.year,this.month+1,this.day,this.hour,this.minute,this.second,this.tz),!1)}getTime(){return this.getDate(!1).getTime()}};function VOQ(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 sU(A.startAt,A.timezone)),A.stopAt&&(A.stopAt=new sU(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 di(A){return Object.prototype.toString.call(A)==="[object Function]"||typeof A=="function"||A instanceof Function}function EOQ(A){return di(A)}function MOQ(A){typeof Deno<"u"&&typeof Deno.unrefTimer<"u"?Deno.unrefTimer(A):A&&typeof A.unref<"u"&&A.unref()}var Yz1=30000,k$A=[],yhA=class{name;options;_states;fn;constructor(A,Q,B){let w,$;if(di(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(di(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=VOQ(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 Dz1("* * * * *")},A&&(A instanceof Date||typeof A=="string"&&A.indexOf(":")>0)?this._states.once=new sU(A,this.options.timezone||this.options.utcOffset):this._states.pattern=new Dz1(A,this.options.timezone),this.name){if(k$A.find((f)=>f.name===this.name))throw Error("Cron: Tried to initialize new named job '"+this.name+"', but name already taken.");k$A.push(this)}return $!==void 0&&EOQ($)&&(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 sU||A instanceof Date?Q.getTime()-A.getTime():Q.getTime()-new sU(A).getTime():null}stop(){this._states.kill=!0,this._states.currentTimeout&&clearTimeout(this._states.currentTimeout);let A=k$A.indexOf(this);A>=0&&k$A.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>Yz1&&(Q=Yz1),this._states.currentTimeout=setTimeout(()=>this._checkTrigger(B),Q),this._states.currentTimeout&&this.options.unref&&MOQ(this._states.currentTimeout),this)}async _trigger(A){if(this._states.blocking=!0,this._states.currentRun=new sU(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){di(this.options.catch)&&this.options.catch(Q,this)}else this.fn!==void 0&&await this.fn(this,this.options.context);this._states.previousRun=new sU(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&&di(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 sU(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 sU(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 sU(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 sU(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 j$A{scheduleCron(A,Q){let B=new yhA(A,()=>{Q()});return{stop:()=>B.stop()}}scheduleInterval(A,Q){let B=setInterval(()=>{Q()},A);return{stop:()=>clearInterval(B)}}validateCron(A){new yhA(A).stop()}}WA();var Xz1=H.union([H.string().min(1),H.object({location:H.enum(["metadata","frontmatter"]),field:H.string().min(1)})]),_$A=H.object({entityType:H.string().min(1),attachmentType:H.string().min(1),mediaEntityType:H.enum(["image","document"]),targetEntityField:Xz1.optional(),requiredWhen:H.object({status:H.string().min(1).optional(),visibility:H.string().min(1).optional()}).optional(),autoGenerate:H.boolean().optional(),requiredForPublish:H.boolean().optional(),jobType:H.string().min(1).optional()});function xhA(A){return`${A.entityType}:${A.attachmentType}`}class xH{static instance=null;definitions=new Map;static getInstance(){return xH.instance??=new xH,xH.instance}static resetInstance(){xH.instance=null}static createFresh(){return new xH}constructor(){}register(A){let Q=_$A.parse(A),B=xhA(Q);return this.definitions.set(B,Q),()=>this.unregister(Q.entityType,Q.attachmentType)}get(A,Q){return this.definitions.get(xhA({entityType:A,attachmentType:Q}))}list(A){let Q=Array.from(this.definitions.values());return A?Q.filter((B)=>B.entityType===A):Q}has(A,Q){return this.get(A,Q)!==void 0}unregister(A,Q){this.definitions.delete(xhA({entityType:A,attachmentType:Q}))}clear(){this.definitions.clear()}}WA();class v$A{deps;constructor(A){this.deps=A}async ensureForEntity(A,Q={}){let B=this.deps.registry.list(A.entityType).filter(($)=>$.autoGenerate===!0).filter(($)=>!Q.attachmentType||$.attachmentType===Q.attachmentType),w={checked:B.length,enqueued:0,skipped:0};for(let $ of B)if(await this.ensureDefinition(A,$))w.enqueued+=1;else w.skipped+=1;return w}async ensureDefinition(A,Q){if(!this.matchesPolicy(A,Q))return!1;if(this.hasTargetField(A,Q.targetEntityField))return!1;if(!this.deps.context.attachments.hasProvider(A.entityType,Q.attachmentType))return!1;let B=this.resolveJobType(Q);if(!B)return!1;let w=this.getPredictedMediaId(A,Q),$=this.getDeduplicationKey(A,Q);return await this.deps.context.jobs.enqueue({type:B,data:{sourceEntityType:A.entityType,sourceEntityId:A.id,attachmentType:Q.attachmentType,imageId:w,dedupKey:$,targetEntityType:A.entityType,targetEntityId:A.id,...this.getTargetImageFieldData(Q.targetEntityField)},options:{source:"content-pipeline",metadata:{operationType:"content_operations"},deduplication:"skip",deduplicationKey:$}}),this.deps.context.logger.debug("Queued publish asset generation",{entityType:A.entityType,entityId:A.id,attachmentType:Q.attachmentType,jobType:B}),!0}matchesPolicy(A,Q){let{requiredWhen:B}=Q;if(!B)return!0;if(B.status&&A.metadata.status!==B.status)return!1;if(B.visibility&&A.visibility!==B.visibility)return!1;return!0}hasTargetField(A,Q){if(!Q)return!1;if(typeof Q==="string")return ShA(A.metadata[Q]);if(Q.location==="metadata")return ShA(A.metadata[Q.field]);let{frontmatter:B}=jB(A.content);return ShA(B[Q.field])}resolveJobType(A){if(A.jobType)return A.jobType;if(A.mediaEntityType==="image")return"image:image-render-source";return}getPredictedMediaId(A,Q){let B=Q.attachmentType==="og-image"?"og":Q.attachmentType;return X1(`${B}-${A.entityType}-${A.id}`)}getDeduplicationKey(A,Q){return`publish-asset:${Q.attachmentType}:${A.entityType}:${A.id}`}getTargetImageFieldData(A){let Q=typeof A==="string"?A:A?.field;if(Q==="coverImageId"||Q==="ogImageId")return{targetImageField:Q};return{}}}function ShA(A){return typeof A==="string"?A.length>0:A!==void 0}aA();WA();var COQ=H.object({id:H.string().min(1)});async function Hz1(A,Q){let{bodyContent:B,coverImageId:w,documents:$,sourceEntityType:f,sourceEntityId:I}=OOQ(Q.content),D=w?await POQ(A,w):void 0,U;if($&&$.length>0){let J=await kOQ(A,$);if(J.length>0)U=J}U??=await bOQ(A,f,I);let Y={bodyContent:B};if(D)Y.imageData=D;if(U&&U.length>0)Y.documentData=U;return Y}function OOQ(A){try{let Q=R2(A,H.record(H.unknown())),B=Q.metadata.coverImageId,w=typeof B==="string"?B:void 0,$=ROQ(Q.metadata.documents),f=Wz1(Q.metadata.sourceEntityType),I=Wz1(Q.metadata.sourceEntityId);return{bodyContent:Q.content,...w&&{coverImageId:w},...$.length>0&&{documents:$},...f&&{sourceEntityType:f},...I&&{sourceEntityId:I}}}catch{return{bodyContent:A}}}function ROQ(A){if(!Array.isArray(A))return[];return A.flatMap((Q)=>{let B=COQ.safeParse(Q);return B.success?[B.data]:[]})}function Wz1(A){return typeof A==="string"&&A.length>0?A:void 0}async function bOQ(A,Q,B){if(!Q||!B)return;let w=await A.attachments.resolve({sourceEntityType:Q,sourceEntityId:B,attachmentType:"carousel"});return w?[w]:void 0}async function POQ(A,Q){let B=await A.entityService.getEntity({entityType:"image",id:Q});if(!B?.content)return;let w=Gz1(B.content);if(!w?.mimeType.startsWith("image/"))return;return{data:w.data,mimeType:w.mimeType}}async function kOQ(A,Q){return(await Promise.all(Q.map((w)=>jOQ(A,w)))).filter((w)=>w!==void 0)}async function jOQ(A,Q){let B=await A.entityService.getEntity({entityType:"document",id:Q.id});if(!B?.content)return;let w=Gz1(B.content);if(w?.mimeType!=="application/pdf")return;return{type:"document",data:w.data,mimeType:"application/pdf",filename:_OQ(B,Q.id)}}function Gz1(A){let Q=A.match(/^data:([^;]+);base64,(.+)$/);if(!Q?.[1]||!Q[2])return;return{mimeType:Q[1],data:Buffer.from(Q[2],"base64")}}function _OQ(A,Q){let B=A.metadata.filename;return typeof B==="string"&&B.length>0?B:`${Q}.pdf`}WA();var vOQ=/^---\r?\n[\s\S]*?\r?\n---(?:\r?\n|$)/;async function ghA(A,Q,B,w={}){let $=w.publishedAt??new Date().toISOString(),f=w.publishTimestampField??"publishedAt",I={...Q.metadata,status:"published",[f]:$,platformId:B.id,...TOQ(B.id,w.publishResultIdField)},D={...Q,content:Kz1(Q.content,$,B.id,w.publishResultIdField,f),metadata:I};return await A.entityService.updateEntity({entity:D}),D}function Kz1(A,Q,B,w,$="publishedAt"){if(!vOQ.test(A))return A;let f=Y4(Y4(A,"status","published"),$,Q);if(!B||!w)return f;return Y4(f,w,B)}function TOQ(A,Q){if(!Q||Q==="platformId")return{};return{[Q]:A}}class xv{deps;constructor(A){this.deps=A}async resolveCandidate(A){let{entityType:Q,id:B,slug:w}=A;if(!B&&!w)return{error:"Either 'id' or 'slug' must be provided"};let $=await this.findPublishableEntity(Q,B,w);if(!$)return{error:`Entity not found: ${Q}:${B??w}`};if($.visibility!=="public")return{error:`Cannot publish ${Q}:${$.id} to a public provider because visibility is ${$.visibility}`};if($.metadata.status==="published")return{error:"Entity is already published"};if(!this.deps.providerRegistry.has(Q))return{error:`No publish provider registered for ${Q}. Check that the required credentials are configured.`};return{entity:$}}async publish(A){let Q=await this.resolveCandidate(A);if("error"in Q)return Q;let{entity:B}=Q,{entityType:w}=A,$=this.deps.providerRegistry.get(w),{bodyContent:f,imageData:I,documentData:D}=await Hz1(this.deps.context,B),U=await $.publish(f,B.metadata,I,D),Y=this.deps.providerRegistry.getPublishResultIdField(w),J=this.deps.providerRegistry.getPublishTimestampField(w),X=await ghA(this.deps.context,B,U,{...Y?{publishResultIdField:Y}:{},...J?{publishTimestampField:J}:{}});return await this.runPublishAssetPreflight(X),{entity:X,result:U}}async runPublishAssetPreflight(A){if(!this.deps.publishAssetPreflight)return;try{await this.deps.publishAssetPreflight.ensureForEntity(A)}catch(Q){this.deps.context.logger.warn("Publish asset preflight failed",{entityType:A.entityType,entityId:A.id,error:Q instanceof Error?Q.message:String(Q)})}}async findPublishableEntity(A,Q,B){if(Q)return this.deps.context.entityService.getEntity({entityType:A,id:Q});if(!B)return null;return(await this.deps.context.entityService.listEntities({entityType:A,options:{filter:{metadata:{slug:B}},limit:1}}))[0]??null}}aA();WA();var hhA=H.object({action:H.enum(["list","add","remove","reorder"]).describe("Queue action to perform"),entityType:H.string().optional().describe("Entity type (required for add/remove/reorder, optional for list)"),entityId:H.string().optional().describe("Entity ID (required for add/remove/reorder)"),position:H.number().optional().describe("New position for reorder action (1-based)")}),mhA=H.object({position:H.number(),entityType:H.string(),entityId:H.string(),queuedAt:H.string()}),yOQ=H.object({success:H.literal(!0),message:H.string().optional(),data:H.object({queue:H.array(mhA).optional(),entityType:H.string().optional(),entityId:H.string().optional(),position:H.number().optional()}).optional()}),xOQ=H.object({success:H.literal(!1),error:H.string(),code:H.string().optional()}),uhA=H.union([yOQ,xOQ]);function T$A(A,Q,B){return{...oQ(Q,"queue","Manage the publish queue for all entity types (list, add, remove, reorder)",hhA,async($,f)=>{let{action:I,entityType:D,entityId:U,position:Y}=$;switch(I){case"list":return SOQ(B,D);case"add":return gOQ(A,B,D,U,f);case"remove":return hOQ(A,B,D,U,f);case"reorder":return mOQ(A,B,D,U,Y,f);default:return{success:!1,error:`Unknown action: ${I}`}}}),outputSchema:uhA}}async function SOQ(A,Q){let B=[];if(Q)B=await A.list(Q);else{let $=A.getRegisteredTypes();for(let f of $){let I=await A.list(f);B.push(...I)}B.sort((f,I)=>new Date(f.queuedAt).getTime()-new Date(I.queuedAt).getTime())}if(B.length===0)return{success:!0,data:{queue:[]},message:"No items in queue"};return{success:!0,data:{queue:B.map(($,f)=>({position:f+1,entityType:$.entityType,entityId:$.entityId,queuedAt:$.queuedAt}))},message:`${B.length} items in queue`}}async function gOQ(A,Q,B,w,$){let f=chA("add",B,w);if(!f.success)return f.error;A.permissions.assertEntityActionAllowed(f.entityType,"publish",$??{});let I=await Q.add(f.entityType,f.entityId,{...$,authorization:"user"});return{success:!0,data:{entityType:f.entityType,entityId:f.entityId,position:I.position},message:`Added to queue at position ${I.position}`}}async function hOQ(A,Q,B,w,$){let f=chA("remove",B,w);if(!f.success)return f.error;return A.permissions.assertEntityActionAllowed(f.entityType,"update",$??{}),await Q.remove(f.entityType,f.entityId),{success:!0,data:{entityType:f.entityType,entityId:f.entityId},message:"Removed from queue"}}async function mOQ(A,Q,B,w,$,f){let I=chA("reorder",B,w);if(!I.success)return I.error;let D=uOQ($);if(!D.success)return D.error;return A.permissions.assertEntityActionAllowed(I.entityType,"update",f??{}),await Q.reorder(I.entityType,I.entityId,D.position),{success:!0,data:{entityType:I.entityType,entityId:I.entityId,position:D.position},message:`Moved to position ${D.position}`}}function chA(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 uOQ(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}}WA();var y$A=H.object({entityType:H.string().describe("Entity type to publish (e.g., social-post, post, deck)"),id:H.string().optional().describe("Entity ID to publish"),slug:H.string().optional().describe("Entity slug to publish"),confirmed:H.boolean().optional(),confirmationToken:H.string().optional(),contentHash:H.string().optional()}),cOQ=H.object({success:H.literal(!0),message:H.string().optional(),data:H.object({entityType:H.string().optional(),entityId:H.string().optional(),platformId:H.string().optional(),url:H.string().optional()}).optional()}),lOQ=H.object({success:H.literal(!1),error:H.string(),code:H.string().optional()}),pOQ=H.object({success:H.literal(!1).optional(),error:H.string().optional(),needsConfirmation:H.literal(!0),toolName:H.string(),summary:H.string(),preview:H.string().optional(),args:H.unknown()}),lhA=H.union([cOQ,lOQ,pOQ]),iOQ=900000,rOQ=1000;class Zz1{tokens=new Map;add(A){if(this.prune(),this.tokens.size>=rOQ){let Q=this.tokens.keys().next().value;if(Q!==void 0)this.tokens.delete(Q)}this.tokens.set(A,Date.now()+iOQ)}has(A){let Q=this.tokens.get(A);if(Q===void 0)return!1;if(Q<=Date.now())return this.tokens.delete(A),!1;return!0}delete(A){this.tokens.delete(A)}prune(){let A=Date.now();for(let[Q,B]of this.tokens)if(B<=A)this.tokens.delete(Q)}}function x$A(A,Q,B,w){let $=w??new xv({context:A,providerRegistry:B}),f=new Zz1,I=`${Q}_publish`;return{name:I,description:"Publish an entity directly to its platform. Call this when the user asks to publish; the tool will request confirmation itself. Works with any registered entity type (social-post, post, deck, etc.)",inputSchema:y$A.shape,outputSchema:lhA,visibility:"anchor",handler:async(D,U)=>{let Y=y$A.safeParse(D);if(!Y.success)return{success:!1,error:`Invalid input: ${Y.error.errors.map((V)=>`${V.path.join(".")}: ${V.message}`).join(", ")}`};let J=Y.data,{entityType:X,id:G,slug:Z}=J;try{A.permissions.assertEntityActionAllowed(X,"publish",U)}catch(V){return{success:!1,error:V instanceof Error?V.message:String(V)}}let N=await $.resolveCandidate({entityType:X,id:G,slug:Z});if("error"in N)return{success:!1,error:N.error};let{entity:L}=N;if(J.confirmed){let V=J.confirmationToken;if(!V||!f.has(V))return Fz1(I,J,L,f);if(f.delete(V),J.contentHash&&J.contentHash!==L.contentHash)return{success:!1,error:`Cannot publish ${X}:${L.id} because it changed after confirmation. Review it and try again.`};let M;try{M=await $.publish({entityType:X,id:L.id})}catch(S){return{success:!1,error:S instanceof Error?S.message:String(S)}}if("error"in M)return{success:!1,error:M.error};let{entity:O,result:E}=M;return{success:!0,data:{entityType:X,entityId:O.id,platformId:E.id,url:E.url},message:`Published ${X}:${O.id}`}}return Fz1(I,J,L,f)}}}function Fz1(A,Q,B,w){let $=crypto.randomUUID();w.add($);let f=dOQ(B);return{needsConfirmation:!0,toolName:A,summary:`Publish "${f}"?`,preview:`This will publish ${B.entityType}:${B.id} to its registered public publish provider.`,args:{...Q,id:B.id,slug:void 0,confirmed:!0,confirmationToken:$,contentHash:B.contentHash}}}function dOQ(A){let Q=A.metadata.title;if(typeof Q==="string"&&Q.length>0)return Q;let B=A.metadata.subject;if(typeof B==="string"&&B.length>0)return B;let w=A.metadata.slug;if(typeof w==="string"&&w.length>0)return w;return A.id}aA();WA();var phA=H.object({entityType:H.string().min(1).describe("Entity type to reconcile"),status:H.string().min(1).optional().describe("Optional metadata status filter, e.g. published"),assetType:H.string().min(1).optional().describe("Optional attachment type filter, e.g. og-image")}),ihA=H.object({success:H.literal(!0),data:H.object({entityType:H.string(),assetType:H.string().optional(),checkedEntities:H.number(),checkedAssets:H.number(),enqueued:H.number(),skipped:H.number()}),message:H.string().optional()});function S$A(A,Q,B,w){return{...oQ(Q,"ensure-assets","Reconcile configured publish assets for existing entities, queueing missing generated assets such as OG images.",phA,async(f,I)=>{if(A.permissions.assertEntityActionAllowed(f.entityType,"publish",I),B.list(f.entityType).filter((G)=>G.autoGenerate===!0).filter((G)=>!f.assetType||G.attachmentType===f.assetType).length===0)return{success:!0,data:{entityType:f.entityType,...f.assetType&&{assetType:f.assetType},checkedEntities:0,checkedAssets:0,enqueued:0,skipped:0},message:`No publish assets configured for ${f.entityType}`};let U=await A.entityService.listEntities({entityType:f.entityType,options:{...f.status&&{filter:{metadata:{status:f.status}}}}}),Y=0,J=0,X=0;for(let G of U){let Z=await w.ensureForEntity(G,{...f.assetType&&{attachmentType:f.assetType}});Y+=Z.checked,J+=Z.enqueued,X+=Z.skipped}return{success:!0,data:{entityType:f.entityType,...f.assetType&&{assetType:f.assetType},checkedEntities:U.length,checkedAssets:Y,enqueued:J,skipped:X},message:`Queued ${J} publish asset job(s)`}}),outputSchema:ihA}}aA();WA();function Nz1(A,Q){nOQ(A,Q),oOQ(A,Q),sOQ(A,Q),aOQ(A,Q)}function nOQ(A,Q){A.messaging.subscribe(c4.REGISTER,async(B)=>tOQ(Q,B.payload)),A.messaging.subscribe(c4.QUEUE,async(B)=>BRQ(A,Q,B.payload)),A.messaging.subscribe(c4.DIRECT,async(B)=>wRQ(A,Q,B.payload)),A.messaging.subscribe(c4.REMOVE,async(B)=>$RQ(Q,B.payload)),A.messaging.subscribe(c4.REORDER,async(B)=>fRQ(Q,B.payload)),A.messaging.subscribe(c4.LIST,async(B)=>IRQ(A,Q,B.payload)),A.messaging.subscribe(c4.REPORT_SUCCESS,async(B)=>DRQ(Q,B.payload)),A.messaging.subscribe(c4.REPORT_FAILURE,async(B)=>URQ(Q,B.payload)),Q.logger.debug("Subscribed to publish messages")}function oOQ(A,Q){A.messaging.subscribe(oz.REPORT_SUCCESS,async(B)=>YRQ(Q,B.payload)),A.messaging.subscribe(oz.REPORT_FAILURE,async(B)=>JRQ(Q,B.payload)),Q.logger.debug("Subscribed to generation messages")}function sOQ(A,Q){A.messaging.subscribe(e31.REGISTER,async(B)=>eOQ(Q,B.payload)),Q.logger.debug("Subscribed to publish asset messages")}function aOQ(A,Q){let B=async(w)=>ARQ(A,Q,w.payload);A.messaging.subscribe("entity:created",B),A.messaging.subscribe("entity:updated",B),Q.logger.debug("Subscribed to entity change messages for publish assets")}async function tOQ(A,Q){let{entityType:B,provider:w,config:$}=Q;try{let f=$?Az1.safeParse($):void 0;if(f&&!f.success)return A.logger.warn("Invalid publish provider config",{entityType:B,error:f.error.message}),{success:!1};if(w)A.providerRegistry.register(B,w,f?.data),A.logger.info(`Registered provider for entity type: ${B}`,{providerName:w.name,executionMode:A.providerRegistry.getExecutionMode(B)});return{success:!0}}catch(f){let I=T0(f);return A.logger.error(`Failed to register provider: ${I}`),{success:!1}}}async function eOQ(A,Q){let B=_$A.safeParse(Q);if(!B.success)return A.logger.warn("Invalid publish asset registration",{error:B.error.message}),{success:!1};return A.publishAssetRegistry.register(B.data),A.logger.info("Registered publish asset",{entityType:B.data.entityType,attachmentType:B.data.attachmentType,mediaEntityType:B.data.mediaEntityType}),{success:!0}}async function ARQ(A,Q,B){try{if(Q.publishAssetRegistry.list(B.entityType).length===0)return{success:!0};let w=B.entity??await A.entityService.getEntity({entityType:B.entityType,id:B.entityId});if(!QRQ(w))return{success:!0};return await Q.publishAssetPreflight.ensureForEntity(w),{success:!0}}catch(w){return Q.logger.warn("Failed to run publish asset preflight for entity event",{entityType:B.entityType,entityId:B.entityId,error:T0(w)}),{success:!1}}}function QRQ(A){if(!A)return!1;let Q=t31.safeParse(A.metadata);return Q.success&&Q.data.status==="published"}async function BRQ(A,Q,B){let{entityType:w,entityId:$}=B;try{let f=B.authContext??ri;A.permissions.assertEntityActionAllowed(w,"publish",f);let I=await Q.queueManager.add(w,$,f);return await A.messaging.send({type:c4.QUEUED,payload:{entityType:w,entityId:$,position:I.position}}),Q.logger.debug(`Entity queued: ${$}`,{entityType:w,position:I.position}),{success:!0}}catch(f){let I=T0(f);return Q.logger.error(`Failed to queue entity: ${I}`),{success:!1}}}async function wRQ(A,Q,B){let{entityType:w,entityId:$}=B,f=B.authContext??ri;try{if(A.permissions.assertEntityActionAllowed(w,"publish",f),!Q.providerRegistry.has(w))return Q.scheduler.failPublish(w,$,`No publish provider registered for ${w}`),{success:!1};let I=await Q.publishExecutor.publish({entityType:w,id:$});if("error"in I)return Q.scheduler.failPublish(w,$,I.error),{success:!1};return Q.scheduler.completePublish(w,$,I.result),Q.logger.debug(`Direct publish completed: ${$}`,{entityType:w}),{success:!0}}catch(I){let D=T0(I);return Q.logger.error(`Failed direct publish request: ${D}`),{success:!1}}}async function $RQ(A,Q){let{entityType:B,entityId:w}=Q;try{return await A.queueManager.remove(B,w),A.logger.debug(`Entity removed from queue: ${w}`,{entityType:B}),{success:!0}}catch($){let f=T0($);return A.logger.error(`Failed to remove entity: ${f}`),{success:!1}}}async function fRQ(A,Q){let{entityType:B,entityId:w,position:$}=Q;try{return await A.queueManager.reorder(B,w,$),A.logger.debug(`Entity reordered: ${w}`,{entityType:B,newPosition:$}),{success:!0}}catch(f){let I=T0(f);return A.logger.error(`Failed to reorder entity: ${I}`),{success:!1}}}async function IRQ(A,Q,B){let{entityType:w}=B;try{let $=await Q.queueManager.list(w);return await A.messaging.send({type:c4.LIST_RESPONSE,payload:{entityType:w,queue:$.map((f)=>({entityId:f.entityId,position:f.position,queuedAt:f.queuedAt}))}}),{success:!0}}catch($){let f=T0($);return Q.logger.error(`Failed to list queue: ${f}`),{success:!1}}}async function DRQ(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 URQ(A,Q){let{entityType:B,entityId:w,error:$}=Q;A.scheduler.failPublish(B,w,$);let f=A.retryTracker.getRetryInfo(w);return A.logger.info(`Publish reported failure: ${w}`,{entityType:B,error:$,retryCount:f?.retryCount}),{success:!0}}async function YRQ(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 JRQ(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}}WA();async function zz1(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:T0($)}),{shouldGenerate:!1,reason:`Condition check failed: ${T0($)}`}}}function qz1(A){let{context:Q,config:B,queueManager:w,providerRegistry:$,retryTracker:f,publishExecutor:I,logger:D}=A,U=XRQ(Q);return UX.createFresh({queueManager:w,providerRegistry:$,retryTracker:f,logger:D,backend:new j$A,...B.entitySchedules&&{entitySchedules:B.entitySchedules},...B.generationSchedules&&{generationSchedules:B.generationSchedules},...B.generationConditions&&{generationConditions:B.generationConditions},messageBus:U,publishExecutor:I,onCheckGenerationConditions:(Y,J)=>zz1(Q.entityService,D,Y,J)})}function XRQ(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 Lz1(A,Q,B){let w=A.getEntityTypes();for(let f of w){let I=await A.listEntities({entityType:f,options:{filter:{metadata:{status:"queued"}}}});for(let D of I)await Q.add(D.entityType,D.id)}let $=0;for(let f of w){let I=await Q.list(f);$+=I.length}if($>0)B.info(`Rebuilt queue with ${$} queued entities`)}var WRQ=["draft","queued","published","failed"];async function Vz1(A,Q){await A.messaging.send({type:"dashboard:register-widget",payload:{id:"publication-pipeline",pluginId:Q,title:"Publication Pipeline",section:"secondary",priority:100,rendererName:"PipelineWidget",visibility:"anchor",dataProvider:()=>HRQ(A)}})}async function HRQ(A){let Q=A.entityService.getEntityTypes(),B=[],w={draft:0,queued:0,published:0,failed:0};for(let $ of Q){let f=await A.entityService.listEntities({entityType:$});for(let I of f){let D=GRQ(I.metadata.status);if(!D)continue;w[D]++,B.push({id:I.id,title:KRQ(I.id,I.metadata.title),type:$,status:D})}}return{summary:w,items:B}}function GRQ(A){return WRQ.find((Q)=>Q===A)}function KRQ(A,Q){return typeof Q==="string"?Q:A}var Ez1={name:"@brains/content-pipeline",private:!0,version:"0.2.0-alpha.119",description:"Content pipeline plugin for managing entity publishing queues, scheduling, and generation",type:"module",main:"src/index.ts",types:"src/index.ts",scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*",croner:"^9.1.0"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14",typescript:"^5.3.3"},exports:{".":{types:"./src/index.ts",default:"./src/index.ts"}},files:["src"]};class rhA extends YB{pluginContext;queueManager;providerRegistry;retryTracker;publishExecutor;publishAssetRegistry;publishAssetPreflight;scheduler;constructor(A){super("content-pipeline",Ez1,A??{},Qz1)}async onRegister(A){this.pluginContext=A,this.queueManager=vH.createFresh(),this.providerRegistry=TH.createFresh(),this.retryTracker=yH.createFresh(),this.publishAssetRegistry=xH.createFresh(),this.publishAssetPreflight=new v$A({context:A,registry:this.publishAssetRegistry}),this.publishExecutor=new xv({context:A,providerRegistry:this.providerRegistry,publishAssetPreflight:this.publishAssetPreflight}),this.scheduler=qz1({context:A,config:this.config,queueManager:this.queueManager,providerRegistry:this.providerRegistry,retryTracker:this.retryTracker,publishExecutor:this.publishExecutor,logger:this.logger}),Nz1(A,{queueManager:this.queueManager,providerRegistry:this.providerRegistry,retryTracker:this.retryTracker,publishExecutor:this.publishExecutor,publishAssetRegistry:this.publishAssetRegistry,publishAssetPreflight:this.publishAssetPreflight,scheduler:this.scheduler,logger:this.logger})}async onReady(A){await Lz1(A.entityService,this.queueManager,this.logger),await Vz1(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[T$A(this.pluginContext,this.id,this.queueManager),x$A(this.pluginContext,this.id,this.providerRegistry,this.publishExecutor),S$A(this.pluginContext,this.id,this.publishAssetRegistry,this.publishAssetPreflight)]}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). This tool has its own confirmation flow; call it without `confirmed` when the user asks to publish instead of asking for plain-text confirmation.\n- Use `content-pipeline_ensure-assets` to reconcile missing publish assets such as generated OG images for already-published content.\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}getPublishAssetRegistry(){return this.publishAssetRegistry}getScheduler(){return this.scheduler}async onShutdown(){await this.scheduler.stop(),vH.resetInstance(),TH.resetInstance(),yH.resetInstance(),xH.resetInstance()}}function dhA(A){return new rhA(A)}aA();WA();var Mz1=H.object({accountId:H.string().describe("Cloudflare account ID"),apiToken:H.string().describe("Cloudflare API token with Analytics:Read permission"),siteTag:H.string().describe("Cloudflare Web Analytics site tag")}),nhA=H.object({cloudflare:Mz1.optional()});aA();WA();var ZRQ=H.object({date:H.string().describe("Single date in YYYY-MM-DD format").optional(),days:H.number().min(1).max(365).describe("Number of days back from yesterday (e.g., 7 for last week)").optional(),startDate:H.string().describe("Start date in YYYY-MM-DD format (use with endDate)").optional(),endDate:H.string().describe("End date in YYYY-MM-DD format (use with startDate)").optional(),limit:H.number().min(1).max(100).default(20).describe("Maximum items for breakdowns (pages, referrers, countries)")});function NRQ(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 Cz1(A,Q,B){let w=[];if(!B)return w;return w.push(oQ(A,"query",`Query website analytics from Cloudflare.
|
|
6522
|
+
${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=WOQ.parse(Q),w=[],$=M9.from(async(Y)=>{let J={progress:Y.progress};if(Y.message!==void 0)J.message=Y.message;w.push(J)});if(!$)throw Error("Failed to create progress reporter");let I=await new FC(A.logger,A).process(B,`eval-${Date.now()}`,$),D=!1,U;if(I.success&&I.entityId){let Y=await A.entityService.getEntity({entityType:"social-post",id:I.entityId});D=!!Y,U=Y?.content.slice(0,300)}return{...I,entityExists:D,entityPreview:U,progressSteps:w}})}WA();aA();class pi{sendMessage;logger;entityService;providers;permissions;resolveAttachment;constructor(A){this.sendMessage=A.sendMessage,this.logger=A.logger,this.entityService=A.entityService,this.providers=A.providers,this.permissions=A.permissions,this.resolveAttachment=A.resolveAttachment}async handle(A){let{entityType:Q,entityId:B}=A;if(Q!=="social-post")return;this.permissions.assertEntityActionAllowed(Q,"publish",A.authContext??{userPermissionLevel:"anchor"}),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}let $=w;if($.metadata.status==="published"){this.logger.debug("Post already published, skipping",{entityId:B});return}let f=$.metadata.platform,I=this.providers.get(f);if(!I){await this.reportFailure(Q,B,`No provider configured for platform: ${f}`);return}let D=R2($.content,oU),U;if(D.metadata.coverImageId)U=await this.fetchImageData(D.metadata.coverImageId);let Y=D.metadata.documents??[],J=await this.fetchDocumentData(Y);try{if(Y.length>0&&J.length===0)throw Error(`Refusing to publish: ${Y.length} document(s) referenced but none could be fetched`);let X=Y.length===0?await this.resolveSourceAttachment(D.metadata):[],G=J.length>0?J:X,Z=G.length?await I.publish(D.content,$.metadata,U,G):await I.publish(D.content,$.metadata,U),N=new Date().toISOString(),L=Z.id||void 0,V={...D.metadata,status:"published",publishedAt:N,...L&&{platformPostId:L}},M=s9.createPostContent(V,D.content);await this.entityService.updateEntity({entity:{...$,content:M,metadata:{...$.metadata,status:"published",publishedAt:N,platformPostId:L}}}),await this.reportSuccess(Q,B,Z.id),this.logger.info(`Post published successfully: ${B}`,{platform:f,platformPostId:L})}catch(X){let G=X instanceof Error?X.message:String(X),Z={...D.metadata,status:"failed"},N=s9.createPostContent(Z,D.content);await this.entityService.updateEntity({entity:{...$,content:N,metadata:{...$.metadata,status:"failed"}}}),await this.reportFailure(Q,B,G),this.logger.error(`Post publish failed: ${B}`,{platform:f,error:G})}}catch(w){let $=T0(w);this.logger.error("Unexpected error in publish handler",{entityId:B,error:$}),await this.reportFailure(Q,B,$)}}async reportSuccess(A,Q,B){await this.sendMessage({type:"publish:report:success",payload:{entityType:A,entityId:Q,result:{id:B}}})}async reportFailure(A,Q,B){await this.sendMessage({type:"publish:report:failure",payload:{entityType:A,entityId:Q,error:B}})}async resolveSourceAttachment(A){if(!this.resolveAttachment||!A.sourceEntityType||!A.sourceEntityId)return[];let Q=await this.resolveAttachment({sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:"carousel"});return Q?[Q]:[]}async fetchDocumentData(A){if(!A?.length)return[];let Q=[];for(let B of A){let w=await this.fetchSingleDocumentData(B.id);if(w)Q.push(w)}return Q}async fetchSingleDocumentData(A){try{let Q=await this.entityService.getEntity({entityType:"document",id:A});if(!Q){this.logger.warn("Document not found",{documentId:A});return}let B=Q.content.match(/^data:application\/pdf;base64,(.+)$/);if(!B?.[1]){this.logger.warn("Invalid document data URL format",{documentId:A});return}let w=typeof Q.metadata.filename==="string"?Q.metadata.filename:`${A}.pdf`;return{type:"document",data:Buffer.from(B[1],"base64"),mimeType:"application/pdf",filename:w}}catch(Q){this.logger.warn("Failed to fetch document",{documentId:A,error:Q});return}}async fetchImageData(A){try{let Q=await this.entityService.getEntity({entityType:"image",id:A});if(!Q){this.logger.warn("Cover image not found",{imageId:A});return}let w=Q.content.match(/^data:([^;]+);base64,(.+)$/);if(!w?.[1]||!w[2]){this.logger.warn("Invalid image data URL format",{imageId:A});return}let $=w[1],f=w[2];return{data:Buffer.from(f,"base64"),mimeType:$}}catch(Q){this.logger.warn("Failed to fetch cover image",{imageId:A,error:Q});return}}}function i31(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,config:{publishResultIdField:"platformPostId"}}}),B.info("Registered social-post with publish-pipeline"),{success:!0}})}function r31(A,Q,B){let w=new pi({sendMessage:A.messaging.send,logger:B.child("PublishExecuteHandler"),entityService:A.entityService,providers:Q,permissions:A.permissions,resolveAttachment:A.attachments.resolve});A.messaging.subscribe("publish:execute",async($)=>{return await w.handle($.payload),{success:!0}}),B.debug("Subscribed to publish:execute messages")}WA();function d31(A,Q){A.messaging.subscribe("entity:updated",async(B)=>{let{entityType:w,entityId:$,entity:f}=B.payload;if(w!=="post")return{success:!0};if(f.metadata?.status!=="queued")return{success:!0};try{if((await A.entityService.listEntities({entityType:"social-post",options:{filter:{metadata:{sourceEntityType:"post",sourceEntityId:$}},limit:1}})).length>0)return Q.debug(`Social post already exists for ${$}, skipping auto-generate`),{success:!0};return await A.messaging.send({type:"social:auto-generate",payload:{sourceEntityType:w,sourceEntityId:$,platform:"linkedin"}}),Q.info(`Auto-generate social post triggered for queued post ${$}`),{success:!0}}catch(D){let U=T0(D);return Q.error(`Failed to trigger auto-generate for ${$}:`,{error:U}),{success:!0}}}),Q.debug("Subscribed to entity:updated for auto-generation")}function n31(A,Q){A.messaging.subscribe("social:auto-generate",async(B)=>{let{sourceEntityType:w,sourceEntityId:$,platform:f}=B.payload;try{let I=await A.jobs.enqueue({type:`${s9.entityType}:generation`,data:{sourceEntityType:w,sourceEntityId:$,platform:f,addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}});return Q.info(`Social post generation job enqueued for ${w}/${$}`,{jobId:I}),{success:!0,jobId:I}}catch(I){let D=T0(I);return Q.error(`Failed to enqueue social post generation for ${$}:`,{error:D}),{success:!1}}}),Q.debug("Subscribed to social:auto-generate messages")}function o31(A,Q){A.messaging.subscribe("generate:execute",async(B)=>{let{entityType:w}=B.payload;if(w!=="social-post")return{success:!0};Q.info("Received generate:execute for social-post");try{let $=await A.entityService.listEntities({entityType:"post",options:{filter:{metadata:{status:"published"}},limit:5}});if($.length===0)return Q.info("No published posts found for social post generation"),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:"No published posts available for social post generation"}}),{success:!0};let f=null;for(let D of $)if((await A.entityService.listEntities({entityType:"social-post",options:{filter:{metadata:{sourceEntityType:"post",sourceEntityId:D.id}},limit:1}})).length===0){f=D;break}if(!f)return Q.info("All recent posts already have social posts"),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:"All recent posts already have social posts generated"}}),{success:!0};let I=await A.jobs.enqueue({type:`${s9.entityType}:generation`,data:{sourceEntityType:"post",sourceEntityId:f.id,platform:"linkedin",addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}});return Q.info("Social post generation job queued",{jobId:I,sourcePostId:f.id}),{success:!0}}catch($){let f=T0($);return Q.error("Failed to handle generate:execute:",{error:f}),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:f}}),{success:!0}}}),Q.debug("Subscribed to generate:execute messages")}async function s31({entity:A,config:Q}){let B=nz.parse(A),w=s9.parsePostFrontmatter(B),$=s9.getPostContent(B);return{$type:"ai.rizom.brain.socialPost",title:w.title,platform:w.platform,body:$,format:"text/markdown",status:w.status,...w.publishedAt&&{publishedAt:w.publishedAt},...w.platformPostId&&{platformPostId:w.platformPostId},...w.sourceEntityType&&{sourceLocalEntityType:w.sourceEntityType},...w.sourceEntityId&&{sourceLocalEntityId:w.sourceEntityId},...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"social-post",sourceEntityId:B.id,createdAt:B.created,...B.updated&&{updatedAt:B.updated}}}function RhA(){return{entityType:"social-post",collection:"ai.rizom.brain.socialPost",lexicon:Gw["ai.rizom.brain.socialPost"],validate:!1,buildRecord:s31}}var a31={name:"@brains/social-media",private:!0,version:"0.2.0-alpha.120",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/atproto-contracts":"workspace:*","@brains/contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class bhA extends jQ{entityType=s9.entityType;schema=nz;adapter=s9;providers=new Map;unregisterAtprotoProjection;constructor(A){super("social-media",a31,A,qhA)}createGenerationHandler(A){return new FC(this.logger.child("GenerationJobHandler"),A)}getTemplates(){return l31()}getDataSources(){return[new C$A(this.logger.child("SocialPostDataSource"))]}getEntityTypeConfig(){return{publish:{publishStatuses:["queued","published","failed"]}}}async onRegister(A){if(this.initializeProviders(),i31(A,this.providers,this.logger),r31(A,this.providers,this.logger),this.config.autoGenerateOnBlogPublish)d31(A,this.logger),n31(A,this.logger),this.logger.info("Auto-generate on blog publish enabled");o31(A,this.logger),p31(A),this.unregisterAtprotoProjection=d6.getInstance().register(RhA()),this.logger.info("Social media plugin registered successfully")}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}initializeProviders(){if(this.config.linkedin?.accessToken){let A=OhA(this.config.linkedin,this.logger.child("LinkedInClient"));this.providers.set("linkedin",A),this.logger.info("LinkedIn provider initialized")}}}function ii(A){return new bhA(A)}WA();var GOQ=H.enum(["draft","queued","published","failed"]),t31=H.object({status:GOQ.default("draft"),queueOrder:H.number().optional().describe("Position in publish queue (lower = sooner)"),publishedAt:H.string().datetime().optional()});class PhA{name="internal";async publish(A,Q){return{id:"internal"}}}var ri={interfaceType:"system",userId:"system",userPermissionLevel:"anchor",authorization:"system"},c4={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",QUEUED:"publish:queued",COMPLETED:"publish:completed",FAILED:"publish:failed",LIST_RESPONSE:"publish:list:response"},oz={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"},e31={REGISTER:"publish-assets:register"};WA();var KOQ=H.enum(["provider"]),Az1=H.object({executionMode:KOQ.optional(),publishResultIdField:H.string().min(1).optional(),publishTimestampField:H.string().min(1).optional(),enabled:H.boolean().optional()}).strict();var FOQ=H.object({skipIfDraftExists:H.boolean().optional(),minSourceEntities:H.number().optional(),maxUnpublishedDrafts:H.number().optional(),sourceEntityType:H.string().optional()}),Qz1=H.object({entitySchedules:H.record(H.string(),H.string()).optional(),generationSchedules:H.record(H.string(),H.string()).optional(),generationConditions:H.record(H.string(),FOQ).optional()});class vH{static instance=null;queues=new Map;static getInstance(){return vH.instance??=new vH,vH.instance}static resetInstance(){vH.instance=null}static createFresh(){return new vH}constructor(){}async add(A,Q,B=ri){let w=this.getOrCreateQueue(A),$=w.find((D)=>D.entityId===Q);if($)return{position:$.position};let f=w.length+1,I={entityId:Q,entityType:A,position:f,queuedAt:new Date().toISOString(),authContext:{...B}};return w.push(I),{position:f}}async remove(A,Q){let B=this.queues.get(A);if(!B)return;let w=B.findIndex(($)=>$.entityId===Q);if(w===-1)return;B.splice(w,1),this.recalculatePositions(B)}async reorder(A,Q,B){let w=this.queues.get(A);if(!w)return;let $=w.findIndex((D)=>D.entityId===Q);if($===-1)return;let[f]=w.splice($,1);if(!f)return;let I=Math.max(0,Math.min(B-1,w.length));w.splice(I,0,f),this.recalculatePositions(w)}async list(A){let Q=this.queues.get(A);if(!Q)return[];return[...Q]}async getNext(A){let Q=this.queues.get(A);if(!Q||Q.length===0)return null;return Q[0]??null}async getNextAcrossTypes(){let A=null;for(let Q of this.queues.values()){let B=Q[0];if(!B)continue;if(!A||B.queuedAt<A.queuedAt)A=B}return A}async popNext(A){let Q=this.queues.get(A);if(!Q||Q.length===0)return null;let B=Q.shift()??null;if(B)this.recalculatePositions(Q);return B}getRegisteredTypes(){return Array.from(this.queues.keys())}async getQueuedEntityTypes(){let A=[];for(let[Q,B]of this.queues.entries())if(B.length>0)A.push(Q);return A}getOrCreateQueue(A){let Q=this.queues.get(A);if(!Q)Q=[],this.queues.set(A,Q);return Q}recalculatePositions(A){A.forEach((Q,B)=>{Q.position=B+1})}}class TH{static instance=null;providers=new Map;executionModes=new Map;publishResultIdFields=new Map;publishTimestampFields=new Map;defaultProvider=new PhA;static getInstance(){return TH.instance??=new TH,TH.instance}static resetInstance(){TH.instance=null}static createFresh(){return new TH}constructor(){}register(A,Q,B){let w=this.providers.get(A);if(w&&w.name!=="internal"&&Q.name==="internal")return;if(this.providers.set(A,Q),this.executionModes.set(A,B?.executionMode??"provider"),B?.publishResultIdField)this.publishResultIdFields.set(A,B.publishResultIdField);else this.publishResultIdFields.delete(A);if(B?.publishTimestampField)this.publishTimestampFields.set(A,B.publishTimestampField);else this.publishTimestampFields.delete(A)}get(A){return this.providers.get(A)??this.defaultProvider}getExecutionMode(A){return this.executionModes.get(A)??"provider"}getPublishResultIdField(A){return this.publishResultIdFields.get(A)}getPublishTimestampField(A){return this.publishTimestampFields.get(A)}has(A){return this.providers.has(A)}unregister(A){this.providers.delete(A),this.executionModes.delete(A),this.publishResultIdFields.delete(A),this.publishTimestampFields.delete(A)}getRegisteredTypes(){return Array.from(this.providers.keys())}}WA();WA();async function Bz1(A,Q){if(!Q.publishExecutor){Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:"Publish executor not configured",retryCount:0,willRetry:!1});return}await ZOQ(A,Q)}async function ZOQ(A,Q){if(!Q.publishExecutor)return;try{let B=await Q.publishExecutor.publish({entityType:A.entityType,id:A.entityId});if("error"in B){let w={entityType:A.entityType,entityId:A.entityId,error:B.error,retryCount:0,willRetry:!1};if(Q.messageBus)await Q.messageBus.send({type:c4.FAILED,payload:w,sender:"publish-service"});Q.onFailed?.(w);return}khA(A.entityType,A.entityId,B.result,Q)}catch(B){let w=T0(B);Q.retryTracker.recordFailure(A.entityId,w);let $=Q.retryTracker.getRetryInfo(A.entityId);Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:w,retryCount:$?.retryCount??1,willRetry:!1})}}function khA(A,Q,B,w){if(w.retryTracker.clearRetries(Q),w.messageBus)w.messageBus.send({type:c4.COMPLETED,payload:{entityType:A,entityId:Q,result:B},sender:"publish-service"});w.onPublish?.({entityType:A,entityId:Q,result:B})}function wz1(A,Q,B,w){w.retryTracker.recordFailure(Q,B);let $=w.retryTracker.getRetryInfo(Q),f={entityType:A,entityId:Q,error:B,retryCount:$?.retryCount??1,willRetry:!1};if(w.messageBus)w.messageBus.send({type:c4.FAILED,payload:f,sender:"publish-service"});w.onFailed?.(f)}async function $z1(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:oz.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:oz.EXECUTE,payload:w,sender:"content-pipeline"});Q.onGenerate?.(w)}function fz1(A,Q,B){if(B)B.send({type:oz.COMPLETED,payload:{entityType:A,entityId:Q},sender:"content-pipeline"})}function Iz1(A,Q,B){if(B)B.send({type:oz.FAILED,payload:{entityType:A,error:Q},sender:"content-pipeline"})}var NOQ=1000;class jhA{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(NOQ,()=>this.processUnscheduledTypes())}stop(){if(zOQ(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){await this.deps.config.queueManager.remove(A.entityType,A.entityId);let Q=this.deps.getPublishDeps();await Bz1(A,Q)}get entitySchedules(){return this.deps.config.entitySchedules}}function zOQ(A){for(let Q of A.values())Q.stop();A.clear()}class _hA{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(){qOQ(this.generationJobs)}async handleTriggerGeneration(A){if(!this.deps.isRunning())return;try{await $z1(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 qOQ(A){for(let Q of A.values())Q.stop();A.clear()}class UX{static instance=null;config;publishRunner;generationRunner;running=!1;static getInstance(A){return UX.instance??=new UX(A),UX.instance}static resetInstance(){if(UX.instance)UX.instance.stop();UX.instance=null}static createFresh(A){return new UX(A)}constructor(A){this.config={...A,entitySchedules:A.entitySchedules??{},generationSchedules:A.generationSchedules??{},generationConditions:A.generationConditions??{}},this.validateCronExpressions(),this.publishRunner=new jhA({config:this.config,getPublishDeps:()=>this.publishDeps,isRunning:()=>this.running}),this.generationRunner=new _hA({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){khA(A,Q,B,this.publishDeps)}failPublish(A,Q,B){wz1(A,Q,B,this.publishDeps)}async publishDirect(A,Q,B,w){return this.config.providerRegistry.get(A).publish(B,w)}completeGeneration(A,Q){fz1(A,Q,this.config.messageBus)}failGeneration(A,Q){Iz1(A,Q,this.config.messageBus)}get entitySchedules(){return this.config.entitySchedules}get generationSchedules(){return this.config.generationSchedules}get publishDeps(){return{retryTracker:this.config.retryTracker,messageBus:this.config.messageBus,publishExecutor:this.config.publishExecutor,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}" - ${T0(w)}`)}}}class yH{static instance=null;retries=new Map;static getInstance(){return yH.instance??=new yH,yH.instance}static resetInstance(){yH.instance=null}static createFresh(){return new yH}constructor(){}recordFailure(A,Q){let w=(this.retries.get(A)?.retryCount??0)+1;this.retries.set(A,{entityId:A,retryCount:w,lastError:Q})}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}}}function u7(A,Q,B,w,$,f,I,D){return u7.fromTZ(u7.tp(A,Q,B,w,$,f,I),D)}u7.fromTZISO=(A,Q,B)=>u7.fromTZ(LOQ(A,Q),B);u7.fromTZ=function(A,Q){let B=new Date(Date.UTC(A.y,A.m-1,A.d,A.h,A.i,A.s)),w=vhA(A.tz,B),$=new Date(B.getTime()-w),f=vhA(A.tz,$);if(f-w===0)return $;{let I=new Date(B.getTime()-f),D=vhA(A.tz,I);if(D-f===0)return I;if(!Q&&D-f>0)return I;if(Q)throw Error("Invalid date passed to fromTZ()");return $}};u7.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}};u7.tp=(A,Q,B,w,$,f,I)=>({y:A,m:Q,d:B,h:w,i:$,s:f,tz:I});function vhA(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 LOQ(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("+")?u7.tp(B.getUTCFullYear(),B.getUTCMonth()+1,B.getUTCDate(),B.getUTCHours(),B.getUTCMinutes(),B.getUTCSeconds(),"Etc/UTC"):u7.tp(B.getFullYear(),B.getMonth()+1,B.getDate(),B.getHours(),B.getMinutes(),B.getSeconds(),Q)}u7.minitz=u7;var ThA=32,ni=31|ThA,Jz1=[1,2,4,8,16],Dz1=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 sU(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,ni),this.dayOfWeek[7]&&(this.dayOfWeek[0]=this.dayOfWeek[7])}partToArray(A,Q,B,w){let $=this[A],f=A==="day"&&this.lastDayOfMonth;if(Q===""&&!f)throw TypeError("CronPattern: configuration entry "+A+" ("+Q+") is empty, check for trailing spaces.");if(Q==="*")return $.fill(w);let I=Q.split(",");if(I.length>1)for(let D=0;D<I.length;D++)this.partToArray(A,I[D],B,w);else Q.indexOf("-")!==-1&&Q.indexOf("/")!==-1?this.handleRangeWithStepping(Q,A,B,w):Q.indexOf("-")!==-1?this.handleRange(Q,A,B,w):Q.indexOf("/")!==-1?this.handleStepping(Q,A,B,w):Q!==""&&this.handleNumber(Q,A,B,w)}throwAtIllegalCharacters(A){for(let Q=0;Q<A.length;Q++)if((Q===5?/[^/*0-9,\-#L]+/:/[^/*0-9,-]+/).test(A[Q]))throw TypeError("CronPattern: configuration entry "+Q+" ("+A[Q]+") contains illegal characters.")}handleNumber(A,Q,B,w){let $=this.extractNth(A,Q),f=parseInt($[0],10)+B;if(isNaN(f))throw TypeError("CronPattern: "+Q+" is not a number: '"+A+"'");this.setPart(Q,f,$[1]||w)}setPart(A,Q,B){if(!Object.prototype.hasOwnProperty.call(this,A))throw TypeError("CronPattern: Invalid part specified: "+A);if(A==="dayOfWeek"){if(Q===7&&(Q=0),Q<0||Q>6)throw RangeError("CronPattern: Invalid value for dayOfWeek: "+Q);this.setNthWeekdayOfMonth(Q,B);return}if(A==="second"||A==="minute"){if(Q<0||Q>=60)throw RangeError("CronPattern: Invalid value for "+A+": "+Q)}else if(A==="hour"){if(Q<0||Q>=24)throw RangeError("CronPattern: Invalid value for "+A+": "+Q)}else if(A==="day"){if(Q<0||Q>=31)throw RangeError("CronPattern: Invalid value for "+A+": "+Q)}else if(A==="month"&&(Q<0||Q>=12))throw RangeError("CronPattern: Invalid value for "+A+": "+Q);this[A][Q]=B}handleRangeWithStepping(A,Q,B,w){let $=this.extractNth(A,Q),f=$[0].match(/^(\d+)-(\d+)\/(\d+)$/);if(f===null)throw TypeError("CronPattern: Syntax error, illegal range with stepping: '"+A+"'");let[,I,D,U]=f,Y=parseInt(I,10)+B,J=parseInt(D,10)+B,X=parseInt(U,10);if(isNaN(Y))throw TypeError("CronPattern: Syntax error, illegal lower range (NaN)");if(isNaN(J))throw TypeError("CronPattern: Syntax error, illegal upper range (NaN)");if(isNaN(X))throw TypeError("CronPattern: Syntax error, illegal stepping: (NaN)");if(X===0)throw TypeError("CronPattern: Syntax error, illegal stepping: 0");if(X>this[Q].length)throw TypeError("CronPattern: Syntax error, steps cannot be greater than maximum value of part ("+this[Q].length+")");if(Y>J)throw TypeError("CronPattern: From value is larger than to value: '"+A+"'");for(let G=Y;G<=J;G+=X)this.setPart(Q,G,$[1]||w)}extractNth(A,Q){let B=A,w;if(B.includes("#")){if(Q!=="dayOfWeek")throw Error("CronPattern: nth (#) only allowed in day-of-week field");w=B.split("#")[1],B=B.split("#")[0]}return[B,w]}handleRange(A,Q,B,w){let $=this.extractNth(A,Q),f=$[0].split("-");if(f.length!==2)throw TypeError("CronPattern: Syntax error, illegal range: '"+A+"'");let I=parseInt(f[0],10)+B,D=parseInt(f[1],10)+B;if(isNaN(I))throw TypeError("CronPattern: Syntax error, illegal lower range (NaN)");if(isNaN(D))throw TypeError("CronPattern: Syntax error, illegal upper range (NaN)");if(I>D)throw TypeError("CronPattern: From value is larger than to value: '"+A+"'");for(let U=I;U<=D;U++)this.setPart(Q,U,$[1]||w)}handleStepping(A,Q,B,w){let $=this.extractNth(A,Q),f=$[0].split("/");if(f.length!==2)throw TypeError("CronPattern: Syntax error, illegal stepping: '"+A+"'");f[0]===""&&(f[0]="*");let I=0;f[0]!=="*"&&(I=parseInt(f[0],10)+B);let D=parseInt(f[1],10);if(isNaN(D))throw TypeError("CronPattern: Syntax error, illegal stepping: (NaN)");if(D===0)throw TypeError("CronPattern: Syntax error, illegal stepping: 0");if(D>this[Q].length)throw TypeError("CronPattern: Syntax error, max steps for part is ("+this[Q].length+")");for(let U=I;U<this[Q].length;U+=D)this.setPart(Q,U,$[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]|ThA;else if(Q===ni)this.dayOfWeek[A]=ni;else if(Q<6&&Q>0)this.dayOfWeek[A]=this.dayOfWeek[A]|Jz1[Q-1];else throw TypeError(`CronPattern: nth weekday out of range, should be 1-5 or L. Value: ${Q}, Type: ${typeof Q}`)}},Uz1=[31,28,31,30,31,30,31,31,30,31,30,31],iF=[["month","year",0],["day","month",-1],["hour","day",0],["minute","hour",0],["second","minute",0]],sU=class A{tz;ms;second;minute;hour;day;month;year;constructor(Q,B){if(this.tz=B,Q&&Q instanceof Date)if(!isNaN(Q))this.fromDate(Q);else throw TypeError("CronDate: Invalid date passed to CronDate constructor");else if(Q===void 0)this.fromDate(new Date);else if(Q&&typeof Q=="string")this.fromString(Q);else if(Q instanceof A)this.fromCronDate(Q);else throw TypeError("CronDate: Invalid type ("+typeof Q+") passed to CronDate constructor")}isNthWeekdayOfMonth(Q,B,w,$){let f=new Date(Date.UTC(Q,B,w)).getUTCDay(),I=0;for(let D=1;D<=w;D++)new Date(Date.UTC(Q,B,D)).getUTCDay()===f&&I++;if($&ni&&Jz1[I-1]&$)return!0;if($&ThA){let D=new Date(Date.UTC(Q,B+1,0)).getUTCDate();for(let U=w+1;U<=D;U++)if(new Date(Date.UTC(Q,B,U)).getUTCDay()===f)return!1;return!0}return!1}fromDate(Q){if(this.tz!==void 0)if(typeof this.tz=="number")this.ms=Q.getUTCMilliseconds(),this.second=Q.getUTCSeconds(),this.minute=Q.getUTCMinutes()+this.tz,this.hour=Q.getUTCHours(),this.day=Q.getUTCDate(),this.month=Q.getUTCMonth(),this.year=Q.getUTCFullYear(),this.apply();else{let B=u7.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>Uz1[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=u7.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(u7.fromTZISO(Q,this.tz))}findNext(Q,B,w,$){let f=this[B],I;w.lastDayOfMonth&&(this.month!==1?I=Uz1[this.month]:I=new Date(Date.UTC(this.year,this.month+1,0,0,0,0,0)).getUTCDate());let D=!w.starDOW&&B=="day"?new Date(Date.UTC(this.year,this.month,1,0,0,0,0)).getUTCDay():void 0;for(let U=this[B]+$;U<w[B].length;U++){let Y=w[B][U];if(B==="day"&&w.lastDayOfMonth&&U-$==I&&(Y=1),B==="day"&&!w.starDOW){let J=w.dayOfWeek[(D+(U-$-1))%7];if(J&&J&ni)J=this.isNthWeekdayOfMonth(this.year,this.month,U-$,J)?1:0;else if(J)throw Error(`CronDate: Invalid value for dayOfWeek encountered. ${J}`);Q.legacyMode&&!w.starDOM?Y=Y||J:Y=Y&&J}if(Y)return this[B]=U-$,f!==this[B]?2:1}return 3}recurse(Q,B,w){let $=this.findNext(B,iF[w][0],Q,iF[w][2]);if($>1){let f=w+1;for(;f<iF.length;)this[iF[f][0]]=-iF[f][2],f++;if($===3)return this[iF[w][1]]++,this[iF[w][0]]=-iF[w][2],this.apply(),this.recurse(Q,B,0);if(this.apply())return this.recurse(Q,B,w-1)}return w+=1,w>=iF.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)):u7.fromTZ(u7.tp(this.year,this.month+1,this.day,this.hour,this.minute,this.second,this.tz),!1)}getTime(){return this.getDate(!1).getTime()}};function VOQ(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 sU(A.startAt,A.timezone)),A.stopAt&&(A.stopAt=new sU(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 di(A){return Object.prototype.toString.call(A)==="[object Function]"||typeof A=="function"||A instanceof Function}function EOQ(A){return di(A)}function MOQ(A){typeof Deno<"u"&&typeof Deno.unrefTimer<"u"?Deno.unrefTimer(A):A&&typeof A.unref<"u"&&A.unref()}var Yz1=30000,k$A=[],yhA=class{name;options;_states;fn;constructor(A,Q,B){let w,$;if(di(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(di(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=VOQ(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 Dz1("* * * * *")},A&&(A instanceof Date||typeof A=="string"&&A.indexOf(":")>0)?this._states.once=new sU(A,this.options.timezone||this.options.utcOffset):this._states.pattern=new Dz1(A,this.options.timezone),this.name){if(k$A.find((f)=>f.name===this.name))throw Error("Cron: Tried to initialize new named job '"+this.name+"', but name already taken.");k$A.push(this)}return $!==void 0&&EOQ($)&&(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 sU||A instanceof Date?Q.getTime()-A.getTime():Q.getTime()-new sU(A).getTime():null}stop(){this._states.kill=!0,this._states.currentTimeout&&clearTimeout(this._states.currentTimeout);let A=k$A.indexOf(this);A>=0&&k$A.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>Yz1&&(Q=Yz1),this._states.currentTimeout=setTimeout(()=>this._checkTrigger(B),Q),this._states.currentTimeout&&this.options.unref&&MOQ(this._states.currentTimeout),this)}async _trigger(A){if(this._states.blocking=!0,this._states.currentRun=new sU(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){di(this.options.catch)&&this.options.catch(Q,this)}else this.fn!==void 0&&await this.fn(this,this.options.context);this._states.previousRun=new sU(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&&di(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 sU(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 sU(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 sU(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 sU(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 j$A{scheduleCron(A,Q){let B=new yhA(A,()=>{Q()});return{stop:()=>B.stop()}}scheduleInterval(A,Q){let B=setInterval(()=>{Q()},A);return{stop:()=>clearInterval(B)}}validateCron(A){new yhA(A).stop()}}WA();var Xz1=H.union([H.string().min(1),H.object({location:H.enum(["metadata","frontmatter"]),field:H.string().min(1)})]),_$A=H.object({entityType:H.string().min(1),attachmentType:H.string().min(1),mediaEntityType:H.enum(["image","document"]),targetEntityField:Xz1.optional(),requiredWhen:H.object({status:H.string().min(1).optional(),visibility:H.string().min(1).optional()}).optional(),autoGenerate:H.boolean().optional(),requiredForPublish:H.boolean().optional(),jobType:H.string().min(1).optional()});function xhA(A){return`${A.entityType}:${A.attachmentType}`}class xH{static instance=null;definitions=new Map;static getInstance(){return xH.instance??=new xH,xH.instance}static resetInstance(){xH.instance=null}static createFresh(){return new xH}constructor(){}register(A){let Q=_$A.parse(A),B=xhA(Q);return this.definitions.set(B,Q),()=>this.unregister(Q.entityType,Q.attachmentType)}get(A,Q){return this.definitions.get(xhA({entityType:A,attachmentType:Q}))}list(A){let Q=Array.from(this.definitions.values());return A?Q.filter((B)=>B.entityType===A):Q}has(A,Q){return this.get(A,Q)!==void 0}unregister(A,Q){this.definitions.delete(xhA({entityType:A,attachmentType:Q}))}clear(){this.definitions.clear()}}WA();class v$A{deps;constructor(A){this.deps=A}async ensureForEntity(A,Q={}){let B=this.deps.registry.list(A.entityType).filter(($)=>$.autoGenerate===!0).filter(($)=>!Q.attachmentType||$.attachmentType===Q.attachmentType),w={checked:B.length,enqueued:0,skipped:0};for(let $ of B)if(await this.ensureDefinition(A,$))w.enqueued+=1;else w.skipped+=1;return w}async ensureDefinition(A,Q){if(!this.matchesPolicy(A,Q))return!1;if(this.hasTargetField(A,Q.targetEntityField))return!1;if(!this.deps.context.attachments.hasProvider(A.entityType,Q.attachmentType))return!1;let B=this.resolveJobType(Q);if(!B)return!1;let w=this.getPredictedMediaId(A,Q),$=this.getDeduplicationKey(A,Q);return await this.deps.context.jobs.enqueue({type:B,data:{sourceEntityType:A.entityType,sourceEntityId:A.id,attachmentType:Q.attachmentType,imageId:w,dedupKey:$,targetEntityType:A.entityType,targetEntityId:A.id,...this.getTargetImageFieldData(Q.targetEntityField)},options:{source:"content-pipeline",metadata:{operationType:"content_operations"},deduplication:"skip",deduplicationKey:$}}),this.deps.context.logger.debug("Queued publish asset generation",{entityType:A.entityType,entityId:A.id,attachmentType:Q.attachmentType,jobType:B}),!0}matchesPolicy(A,Q){let{requiredWhen:B}=Q;if(!B)return!0;if(B.status&&A.metadata.status!==B.status)return!1;if(B.visibility&&A.visibility!==B.visibility)return!1;return!0}hasTargetField(A,Q){if(!Q)return!1;if(typeof Q==="string")return ShA(A.metadata[Q]);if(Q.location==="metadata")return ShA(A.metadata[Q.field]);let{frontmatter:B}=jB(A.content);return ShA(B[Q.field])}resolveJobType(A){if(A.jobType)return A.jobType;if(A.mediaEntityType==="image")return"image:image-render-source";return}getPredictedMediaId(A,Q){let B=Q.attachmentType==="og-image"?"og":Q.attachmentType;return X1(`${B}-${A.entityType}-${A.id}`)}getDeduplicationKey(A,Q){return`publish-asset:${Q.attachmentType}:${A.entityType}:${A.id}`}getTargetImageFieldData(A){let Q=typeof A==="string"?A:A?.field;if(Q==="coverImageId"||Q==="ogImageId")return{targetImageField:Q};return{}}}function ShA(A){return typeof A==="string"?A.length>0:A!==void 0}aA();WA();var COQ=H.object({id:H.string().min(1)});async function Hz1(A,Q){let{bodyContent:B,coverImageId:w,documents:$,sourceEntityType:f,sourceEntityId:I}=OOQ(Q.content),D=w?await POQ(A,w):void 0,U;if($&&$.length>0){let J=await kOQ(A,$);if(J.length>0)U=J}U??=await bOQ(A,f,I);let Y={bodyContent:B};if(D)Y.imageData=D;if(U&&U.length>0)Y.documentData=U;return Y}function OOQ(A){try{let Q=R2(A,H.record(H.unknown())),B=Q.metadata.coverImageId,w=typeof B==="string"?B:void 0,$=ROQ(Q.metadata.documents),f=Wz1(Q.metadata.sourceEntityType),I=Wz1(Q.metadata.sourceEntityId);return{bodyContent:Q.content,...w&&{coverImageId:w},...$.length>0&&{documents:$},...f&&{sourceEntityType:f},...I&&{sourceEntityId:I}}}catch{return{bodyContent:A}}}function ROQ(A){if(!Array.isArray(A))return[];return A.flatMap((Q)=>{let B=COQ.safeParse(Q);return B.success?[B.data]:[]})}function Wz1(A){return typeof A==="string"&&A.length>0?A:void 0}async function bOQ(A,Q,B){if(!Q||!B)return;let w=await A.attachments.resolve({sourceEntityType:Q,sourceEntityId:B,attachmentType:"carousel"});return w?[w]:void 0}async function POQ(A,Q){let B=await A.entityService.getEntity({entityType:"image",id:Q});if(!B?.content)return;let w=Gz1(B.content);if(!w?.mimeType.startsWith("image/"))return;return{data:w.data,mimeType:w.mimeType}}async function kOQ(A,Q){return(await Promise.all(Q.map((w)=>jOQ(A,w)))).filter((w)=>w!==void 0)}async function jOQ(A,Q){let B=await A.entityService.getEntity({entityType:"document",id:Q.id});if(!B?.content)return;let w=Gz1(B.content);if(w?.mimeType!=="application/pdf")return;return{type:"document",data:w.data,mimeType:"application/pdf",filename:_OQ(B,Q.id)}}function Gz1(A){let Q=A.match(/^data:([^;]+);base64,(.+)$/);if(!Q?.[1]||!Q[2])return;return{mimeType:Q[1],data:Buffer.from(Q[2],"base64")}}function _OQ(A,Q){let B=A.metadata.filename;return typeof B==="string"&&B.length>0?B:`${Q}.pdf`}WA();var vOQ=/^---\r?\n[\s\S]*?\r?\n---(?:\r?\n|$)/;async function ghA(A,Q,B,w={}){let $=w.publishedAt??new Date().toISOString(),f=w.publishTimestampField??"publishedAt",I={...Q.metadata,status:"published",[f]:$,platformId:B.id,...TOQ(B.id,w.publishResultIdField)},D={...Q,content:Kz1(Q.content,$,B.id,w.publishResultIdField,f),metadata:I};return await A.entityService.updateEntity({entity:D}),D}function Kz1(A,Q,B,w,$="publishedAt"){if(!vOQ.test(A))return A;let f=Y4(Y4(A,"status","published"),$,Q);if(!B||!w)return f;return Y4(f,w,B)}function TOQ(A,Q){if(!Q||Q==="platformId")return{};return{[Q]:A}}class xv{deps;constructor(A){this.deps=A}async resolveCandidate(A){let{entityType:Q,id:B,slug:w}=A;if(!B&&!w)return{error:"Either 'id' or 'slug' must be provided"};let $=await this.findPublishableEntity(Q,B,w);if(!$)return{error:`Entity not found: ${Q}:${B??w}`};if($.visibility!=="public")return{error:`Cannot publish ${Q}:${$.id} to a public provider because visibility is ${$.visibility}`};if($.metadata.status==="published")return{error:"Entity is already published"};if(!this.deps.providerRegistry.has(Q))return{error:`No publish provider registered for ${Q}. Check that the required credentials are configured.`};return{entity:$}}async publish(A){let Q=await this.resolveCandidate(A);if("error"in Q)return Q;let{entity:B}=Q,{entityType:w}=A,$=this.deps.providerRegistry.get(w),{bodyContent:f,imageData:I,documentData:D}=await Hz1(this.deps.context,B),U=await $.publish(f,B.metadata,I,D),Y=this.deps.providerRegistry.getPublishResultIdField(w),J=this.deps.providerRegistry.getPublishTimestampField(w),X=await ghA(this.deps.context,B,U,{...Y?{publishResultIdField:Y}:{},...J?{publishTimestampField:J}:{}});return await this.runPublishAssetPreflight(X),{entity:X,result:U}}async runPublishAssetPreflight(A){if(!this.deps.publishAssetPreflight)return;try{await this.deps.publishAssetPreflight.ensureForEntity(A)}catch(Q){this.deps.context.logger.warn("Publish asset preflight failed",{entityType:A.entityType,entityId:A.id,error:Q instanceof Error?Q.message:String(Q)})}}async findPublishableEntity(A,Q,B){if(Q)return this.deps.context.entityService.getEntity({entityType:A,id:Q});if(!B)return null;return(await this.deps.context.entityService.listEntities({entityType:A,options:{filter:{metadata:{slug:B}},limit:1}}))[0]??null}}aA();WA();var hhA=H.object({action:H.enum(["list","add","remove","reorder"]).describe("Queue action to perform"),entityType:H.string().optional().describe("Entity type (required for add/remove/reorder, optional for list)"),entityId:H.string().optional().describe("Entity ID (required for add/remove/reorder)"),position:H.number().optional().describe("New position for reorder action (1-based)")}),mhA=H.object({position:H.number(),entityType:H.string(),entityId:H.string(),queuedAt:H.string()}),yOQ=H.object({success:H.literal(!0),message:H.string().optional(),data:H.object({queue:H.array(mhA).optional(),entityType:H.string().optional(),entityId:H.string().optional(),position:H.number().optional()}).optional()}),xOQ=H.object({success:H.literal(!1),error:H.string(),code:H.string().optional()}),uhA=H.union([yOQ,xOQ]);function T$A(A,Q,B){return{...oQ(Q,"queue","Manage the publish queue for all entity types (list, add, remove, reorder)",hhA,async($,f)=>{let{action:I,entityType:D,entityId:U,position:Y}=$;switch(I){case"list":return SOQ(B,D);case"add":return gOQ(A,B,D,U,f);case"remove":return hOQ(A,B,D,U,f);case"reorder":return mOQ(A,B,D,U,Y,f);default:return{success:!1,error:`Unknown action: ${I}`}}}),outputSchema:uhA}}async function SOQ(A,Q){let B=[];if(Q)B=await A.list(Q);else{let $=A.getRegisteredTypes();for(let f of $){let I=await A.list(f);B.push(...I)}B.sort((f,I)=>new Date(f.queuedAt).getTime()-new Date(I.queuedAt).getTime())}if(B.length===0)return{success:!0,data:{queue:[]},message:"No items in queue"};return{success:!0,data:{queue:B.map(($,f)=>({position:f+1,entityType:$.entityType,entityId:$.entityId,queuedAt:$.queuedAt}))},message:`${B.length} items in queue`}}async function gOQ(A,Q,B,w,$){let f=chA("add",B,w);if(!f.success)return f.error;A.permissions.assertEntityActionAllowed(f.entityType,"publish",$??{});let I=await Q.add(f.entityType,f.entityId,{...$,authorization:"user"});return{success:!0,data:{entityType:f.entityType,entityId:f.entityId,position:I.position},message:`Added to queue at position ${I.position}`}}async function hOQ(A,Q,B,w,$){let f=chA("remove",B,w);if(!f.success)return f.error;return A.permissions.assertEntityActionAllowed(f.entityType,"update",$??{}),await Q.remove(f.entityType,f.entityId),{success:!0,data:{entityType:f.entityType,entityId:f.entityId},message:"Removed from queue"}}async function mOQ(A,Q,B,w,$,f){let I=chA("reorder",B,w);if(!I.success)return I.error;let D=uOQ($);if(!D.success)return D.error;return A.permissions.assertEntityActionAllowed(I.entityType,"update",f??{}),await Q.reorder(I.entityType,I.entityId,D.position),{success:!0,data:{entityType:I.entityType,entityId:I.entityId,position:D.position},message:`Moved to position ${D.position}`}}function chA(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 uOQ(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}}WA();var y$A=H.object({entityType:H.string().describe("Entity type to publish (e.g., social-post, post, deck)"),id:H.string().optional().describe("Entity ID to publish"),slug:H.string().optional().describe("Entity slug to publish"),confirmed:H.boolean().optional(),confirmationToken:H.string().optional(),contentHash:H.string().optional()}),cOQ=H.object({success:H.literal(!0),message:H.string().optional(),data:H.object({entityType:H.string().optional(),entityId:H.string().optional(),platformId:H.string().optional(),url:H.string().optional()}).optional()}),lOQ=H.object({success:H.literal(!1),error:H.string(),code:H.string().optional()}),pOQ=H.object({success:H.literal(!1).optional(),error:H.string().optional(),needsConfirmation:H.literal(!0),toolName:H.string(),summary:H.string(),preview:H.string().optional(),args:H.unknown()}),lhA=H.union([cOQ,lOQ,pOQ]),iOQ=900000,rOQ=1000;class Zz1{tokens=new Map;add(A){if(this.prune(),this.tokens.size>=rOQ){let Q=this.tokens.keys().next().value;if(Q!==void 0)this.tokens.delete(Q)}this.tokens.set(A,Date.now()+iOQ)}has(A){let Q=this.tokens.get(A);if(Q===void 0)return!1;if(Q<=Date.now())return this.tokens.delete(A),!1;return!0}delete(A){this.tokens.delete(A)}prune(){let A=Date.now();for(let[Q,B]of this.tokens)if(B<=A)this.tokens.delete(Q)}}function x$A(A,Q,B,w){let $=w??new xv({context:A,providerRegistry:B}),f=new Zz1,I=`${Q}_publish`;return{name:I,description:"Publish an entity directly to its platform. Call this when the user asks to publish; the tool will request confirmation itself. Works with any registered entity type (social-post, post, deck, etc.)",inputSchema:y$A.shape,outputSchema:lhA,visibility:"anchor",handler:async(D,U)=>{let Y=y$A.safeParse(D);if(!Y.success)return{success:!1,error:`Invalid input: ${Y.error.errors.map((V)=>`${V.path.join(".")}: ${V.message}`).join(", ")}`};let J=Y.data,{entityType:X,id:G,slug:Z}=J;try{A.permissions.assertEntityActionAllowed(X,"publish",U)}catch(V){return{success:!1,error:V instanceof Error?V.message:String(V)}}let N=await $.resolveCandidate({entityType:X,id:G,slug:Z});if("error"in N)return{success:!1,error:N.error};let{entity:L}=N;if(J.confirmed){let V=J.confirmationToken;if(!V||!f.has(V))return Fz1(I,J,L,f);if(f.delete(V),J.contentHash&&J.contentHash!==L.contentHash)return{success:!1,error:`Cannot publish ${X}:${L.id} because it changed after confirmation. Review it and try again.`};let M;try{M=await $.publish({entityType:X,id:L.id})}catch(S){return{success:!1,error:S instanceof Error?S.message:String(S)}}if("error"in M)return{success:!1,error:M.error};let{entity:O,result:E}=M;return{success:!0,data:{entityType:X,entityId:O.id,platformId:E.id,url:E.url},message:`Published ${X}:${O.id}`}}return Fz1(I,J,L,f)}}}function Fz1(A,Q,B,w){let $=crypto.randomUUID();w.add($);let f=dOQ(B);return{needsConfirmation:!0,toolName:A,summary:`Publish "${f}"?`,preview:`This will publish ${B.entityType}:${B.id} to its registered public publish provider.`,args:{...Q,id:B.id,slug:void 0,confirmed:!0,confirmationToken:$,contentHash:B.contentHash}}}function dOQ(A){let Q=A.metadata.title;if(typeof Q==="string"&&Q.length>0)return Q;let B=A.metadata.subject;if(typeof B==="string"&&B.length>0)return B;let w=A.metadata.slug;if(typeof w==="string"&&w.length>0)return w;return A.id}aA();WA();var phA=H.object({entityType:H.string().min(1).describe("Entity type to reconcile"),status:H.string().min(1).optional().describe("Optional metadata status filter, e.g. published"),assetType:H.string().min(1).optional().describe("Optional attachment type filter, e.g. og-image")}),ihA=H.object({success:H.literal(!0),data:H.object({entityType:H.string(),assetType:H.string().optional(),checkedEntities:H.number(),checkedAssets:H.number(),enqueued:H.number(),skipped:H.number()}),message:H.string().optional()});function S$A(A,Q,B,w){return{...oQ(Q,"ensure-assets","Reconcile configured publish assets for existing entities, queueing missing generated assets such as OG images.",phA,async(f,I)=>{if(A.permissions.assertEntityActionAllowed(f.entityType,"publish",I),B.list(f.entityType).filter((G)=>G.autoGenerate===!0).filter((G)=>!f.assetType||G.attachmentType===f.assetType).length===0)return{success:!0,data:{entityType:f.entityType,...f.assetType&&{assetType:f.assetType},checkedEntities:0,checkedAssets:0,enqueued:0,skipped:0},message:`No publish assets configured for ${f.entityType}`};let U=await A.entityService.listEntities({entityType:f.entityType,options:{...f.status&&{filter:{metadata:{status:f.status}}}}}),Y=0,J=0,X=0;for(let G of U){let Z=await w.ensureForEntity(G,{...f.assetType&&{attachmentType:f.assetType}});Y+=Z.checked,J+=Z.enqueued,X+=Z.skipped}return{success:!0,data:{entityType:f.entityType,...f.assetType&&{assetType:f.assetType},checkedEntities:U.length,checkedAssets:Y,enqueued:J,skipped:X},message:`Queued ${J} publish asset job(s)`}}),outputSchema:ihA}}aA();WA();function Nz1(A,Q){nOQ(A,Q),oOQ(A,Q),sOQ(A,Q),aOQ(A,Q)}function nOQ(A,Q){A.messaging.subscribe(c4.REGISTER,async(B)=>tOQ(Q,B.payload)),A.messaging.subscribe(c4.QUEUE,async(B)=>BRQ(A,Q,B.payload)),A.messaging.subscribe(c4.DIRECT,async(B)=>wRQ(A,Q,B.payload)),A.messaging.subscribe(c4.REMOVE,async(B)=>$RQ(Q,B.payload)),A.messaging.subscribe(c4.REORDER,async(B)=>fRQ(Q,B.payload)),A.messaging.subscribe(c4.LIST,async(B)=>IRQ(A,Q,B.payload)),A.messaging.subscribe(c4.REPORT_SUCCESS,async(B)=>DRQ(Q,B.payload)),A.messaging.subscribe(c4.REPORT_FAILURE,async(B)=>URQ(Q,B.payload)),Q.logger.debug("Subscribed to publish messages")}function oOQ(A,Q){A.messaging.subscribe(oz.REPORT_SUCCESS,async(B)=>YRQ(Q,B.payload)),A.messaging.subscribe(oz.REPORT_FAILURE,async(B)=>JRQ(Q,B.payload)),Q.logger.debug("Subscribed to generation messages")}function sOQ(A,Q){A.messaging.subscribe(e31.REGISTER,async(B)=>eOQ(Q,B.payload)),Q.logger.debug("Subscribed to publish asset messages")}function aOQ(A,Q){let B=async(w)=>ARQ(A,Q,w.payload);A.messaging.subscribe("entity:created",B),A.messaging.subscribe("entity:updated",B),Q.logger.debug("Subscribed to entity change messages for publish assets")}async function tOQ(A,Q){let{entityType:B,provider:w,config:$}=Q;try{let f=$?Az1.safeParse($):void 0;if(f&&!f.success)return A.logger.warn("Invalid publish provider config",{entityType:B,error:f.error.message}),{success:!1};if(w)A.providerRegistry.register(B,w,f?.data),A.logger.info(`Registered provider for entity type: ${B}`,{providerName:w.name,executionMode:A.providerRegistry.getExecutionMode(B)});return{success:!0}}catch(f){let I=T0(f);return A.logger.error(`Failed to register provider: ${I}`),{success:!1}}}async function eOQ(A,Q){let B=_$A.safeParse(Q);if(!B.success)return A.logger.warn("Invalid publish asset registration",{error:B.error.message}),{success:!1};return A.publishAssetRegistry.register(B.data),A.logger.info("Registered publish asset",{entityType:B.data.entityType,attachmentType:B.data.attachmentType,mediaEntityType:B.data.mediaEntityType}),{success:!0}}async function ARQ(A,Q,B){try{if(Q.publishAssetRegistry.list(B.entityType).length===0)return{success:!0};let w=B.entity??await A.entityService.getEntity({entityType:B.entityType,id:B.entityId});if(!QRQ(w))return{success:!0};return await Q.publishAssetPreflight.ensureForEntity(w),{success:!0}}catch(w){return Q.logger.warn("Failed to run publish asset preflight for entity event",{entityType:B.entityType,entityId:B.entityId,error:T0(w)}),{success:!1}}}function QRQ(A){if(!A)return!1;let Q=t31.safeParse(A.metadata);return Q.success&&Q.data.status==="published"}async function BRQ(A,Q,B){let{entityType:w,entityId:$}=B;try{let f=B.authContext??ri;A.permissions.assertEntityActionAllowed(w,"publish",f);let I=await Q.queueManager.add(w,$,f);return await A.messaging.send({type:c4.QUEUED,payload:{entityType:w,entityId:$,position:I.position}}),Q.logger.debug(`Entity queued: ${$}`,{entityType:w,position:I.position}),{success:!0}}catch(f){let I=T0(f);return Q.logger.error(`Failed to queue entity: ${I}`),{success:!1}}}async function wRQ(A,Q,B){let{entityType:w,entityId:$}=B,f=B.authContext??ri;try{if(A.permissions.assertEntityActionAllowed(w,"publish",f),!Q.providerRegistry.has(w))return Q.scheduler.failPublish(w,$,`No publish provider registered for ${w}`),{success:!1};let I=await Q.publishExecutor.publish({entityType:w,id:$});if("error"in I)return Q.scheduler.failPublish(w,$,I.error),{success:!1};return Q.scheduler.completePublish(w,$,I.result),Q.logger.debug(`Direct publish completed: ${$}`,{entityType:w}),{success:!0}}catch(I){let D=T0(I);return Q.logger.error(`Failed direct publish request: ${D}`),{success:!1}}}async function $RQ(A,Q){let{entityType:B,entityId:w}=Q;try{return await A.queueManager.remove(B,w),A.logger.debug(`Entity removed from queue: ${w}`,{entityType:B}),{success:!0}}catch($){let f=T0($);return A.logger.error(`Failed to remove entity: ${f}`),{success:!1}}}async function fRQ(A,Q){let{entityType:B,entityId:w,position:$}=Q;try{return await A.queueManager.reorder(B,w,$),A.logger.debug(`Entity reordered: ${w}`,{entityType:B,newPosition:$}),{success:!0}}catch(f){let I=T0(f);return A.logger.error(`Failed to reorder entity: ${I}`),{success:!1}}}async function IRQ(A,Q,B){let{entityType:w}=B;try{let $=await Q.queueManager.list(w);return await A.messaging.send({type:c4.LIST_RESPONSE,payload:{entityType:w,queue:$.map((f)=>({entityId:f.entityId,position:f.position,queuedAt:f.queuedAt}))}}),{success:!0}}catch($){let f=T0($);return Q.logger.error(`Failed to list queue: ${f}`),{success:!1}}}async function DRQ(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 URQ(A,Q){let{entityType:B,entityId:w,error:$}=Q;A.scheduler.failPublish(B,w,$);let f=A.retryTracker.getRetryInfo(w);return A.logger.info(`Publish reported failure: ${w}`,{entityType:B,error:$,retryCount:f?.retryCount}),{success:!0}}async function YRQ(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 JRQ(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}}WA();async function zz1(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:T0($)}),{shouldGenerate:!1,reason:`Condition check failed: ${T0($)}`}}}function qz1(A){let{context:Q,config:B,queueManager:w,providerRegistry:$,retryTracker:f,publishExecutor:I,logger:D}=A,U=XRQ(Q);return UX.createFresh({queueManager:w,providerRegistry:$,retryTracker:f,logger:D,backend:new j$A,...B.entitySchedules&&{entitySchedules:B.entitySchedules},...B.generationSchedules&&{generationSchedules:B.generationSchedules},...B.generationConditions&&{generationConditions:B.generationConditions},messageBus:U,publishExecutor:I,onCheckGenerationConditions:(Y,J)=>zz1(Q.entityService,D,Y,J)})}function XRQ(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 Lz1(A,Q,B){let w=A.getEntityTypes();for(let f of w){let I=await A.listEntities({entityType:f,options:{filter:{metadata:{status:"queued"}}}});for(let D of I)await Q.add(D.entityType,D.id)}let $=0;for(let f of w){let I=await Q.list(f);$+=I.length}if($>0)B.info(`Rebuilt queue with ${$} queued entities`)}var WRQ=["draft","queued","published","failed"];async function Vz1(A,Q){await A.messaging.send({type:"dashboard:register-widget",payload:{id:"publication-pipeline",pluginId:Q,title:"Publication Pipeline",section:"secondary",priority:100,rendererName:"PipelineWidget",visibility:"anchor",dataProvider:()=>HRQ(A)}})}async function HRQ(A){let Q=A.entityService.getEntityTypes(),B=[],w={draft:0,queued:0,published:0,failed:0};for(let $ of Q){let f=await A.entityService.listEntities({entityType:$});for(let I of f){let D=GRQ(I.metadata.status);if(!D)continue;w[D]++,B.push({id:I.id,title:KRQ(I.id,I.metadata.title),type:$,status:D})}}return{summary:w,items:B}}function GRQ(A){return WRQ.find((Q)=>Q===A)}function KRQ(A,Q){return typeof Q==="string"?Q:A}var Ez1={name:"@brains/content-pipeline",private:!0,version:"0.2.0-alpha.120",description:"Content pipeline plugin for managing entity publishing queues, scheduling, and generation",type:"module",main:"src/index.ts",types:"src/index.ts",scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*",croner:"^9.1.0"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14",typescript:"^5.3.3"},exports:{".":{types:"./src/index.ts",default:"./src/index.ts"}},files:["src"]};class rhA extends YB{pluginContext;queueManager;providerRegistry;retryTracker;publishExecutor;publishAssetRegistry;publishAssetPreflight;scheduler;constructor(A){super("content-pipeline",Ez1,A??{},Qz1)}async onRegister(A){this.pluginContext=A,this.queueManager=vH.createFresh(),this.providerRegistry=TH.createFresh(),this.retryTracker=yH.createFresh(),this.publishAssetRegistry=xH.createFresh(),this.publishAssetPreflight=new v$A({context:A,registry:this.publishAssetRegistry}),this.publishExecutor=new xv({context:A,providerRegistry:this.providerRegistry,publishAssetPreflight:this.publishAssetPreflight}),this.scheduler=qz1({context:A,config:this.config,queueManager:this.queueManager,providerRegistry:this.providerRegistry,retryTracker:this.retryTracker,publishExecutor:this.publishExecutor,logger:this.logger}),Nz1(A,{queueManager:this.queueManager,providerRegistry:this.providerRegistry,retryTracker:this.retryTracker,publishExecutor:this.publishExecutor,publishAssetRegistry:this.publishAssetRegistry,publishAssetPreflight:this.publishAssetPreflight,scheduler:this.scheduler,logger:this.logger})}async onReady(A){await Lz1(A.entityService,this.queueManager,this.logger),await Vz1(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[T$A(this.pluginContext,this.id,this.queueManager),x$A(this.pluginContext,this.id,this.providerRegistry,this.publishExecutor),S$A(this.pluginContext,this.id,this.publishAssetRegistry,this.publishAssetPreflight)]}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). This tool has its own confirmation flow; call it without `confirmed` when the user asks to publish instead of asking for plain-text confirmation.\n- Use `content-pipeline_ensure-assets` to reconcile missing publish assets such as generated OG images for already-published content.\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}getPublishAssetRegistry(){return this.publishAssetRegistry}getScheduler(){return this.scheduler}async onShutdown(){await this.scheduler.stop(),vH.resetInstance(),TH.resetInstance(),yH.resetInstance(),xH.resetInstance()}}function dhA(A){return new rhA(A)}aA();WA();var Mz1=H.object({accountId:H.string().describe("Cloudflare account ID"),apiToken:H.string().describe("Cloudflare API token with Analytics:Read permission"),siteTag:H.string().describe("Cloudflare Web Analytics site tag")}),nhA=H.object({cloudflare:Mz1.optional()});aA();WA();var ZRQ=H.object({date:H.string().describe("Single date in YYYY-MM-DD format").optional(),days:H.number().min(1).max(365).describe("Number of days back from yesterday (e.g., 7 for last week)").optional(),startDate:H.string().describe("Start date in YYYY-MM-DD format (use with endDate)").optional(),endDate:H.string().describe("End date in YYYY-MM-DD format (use with startDate)").optional(),limit:H.number().min(1).max(100).default(20).describe("Maximum items for breakdowns (pages, referrers, countries)")});function NRQ(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 Cz1(A,Q,B){let w=[];if(!B)return w;return w.push(oQ(A,"query",`Query website analytics from Cloudflare.
|
|
6523
6523
|
|
|
6524
6524
|
Date range options (use only one):
|
|
6525
6525
|
- No params: yesterday only
|
|
@@ -6657,7 +6657,7 @@ Returns pageviews, visitors, top pages, referrers, devices, and countries.`,ZRQ,
|
|
|
6657
6657
|
}
|
|
6658
6658
|
}
|
|
6659
6659
|
}
|
|
6660
|
-
`,variables:B})});if(!w.ok){let I=await w.text();throw Error(`Cloudflare API error: ${w.status} - ${I}`)}let $=await w.json();if($.errors&&$.errors.length>0)throw Error(`Cloudflare GraphQL error: ${$.errors.map((I)=>I.message).join(", ")}`);return($.data.viewer.accounts[0]?.rumPageloadEventsAdaptiveGroups??[]).map((I)=>({country:I.dimensions.countryName,visits:I.sum.visits}))}}WA();var shA=7,zRQ=10;function Rz1(A){return async()=>{if(!A)return{unavailable:!0,reason:"Cloudflare analytics not configured"};let Q=oO(),B=tn(shA),w=AN(B),$=AN(Q);try{let[f,I]=await Promise.all([A.getWebsiteStats({startDate:w,endDate:$}),A.getTopPages({startDate:w,endDate:$,limit:zRQ})]);return{days:shA,startDate:w,endDate:$,pageviews:f.pageviews,visitors:f.visitors,topPages:I}}catch(f){return{error:f instanceof Error?f.message:"Failed to fetch analytics",days:shA}}}}var bz1={name:"@brains/analytics",private:!0,version:"0.2.0-alpha.
|
|
6660
|
+
`,variables:B})});if(!w.ok){let I=await w.text();throw Error(`Cloudflare API error: ${w.status} - ${I}`)}let $=await w.json();if($.errors&&$.errors.length>0)throw Error(`Cloudflare GraphQL error: ${$.errors.map((I)=>I.message).join(", ")}`);return($.data.viewer.accounts[0]?.rumPageloadEventsAdaptiveGroups??[]).map((I)=>({country:I.dimensions.countryName,visits:I.sum.visits}))}}WA();var shA=7,zRQ=10;function Rz1(A){return async()=>{if(!A)return{unavailable:!0,reason:"Cloudflare analytics not configured"};let Q=oO(),B=tn(shA),w=AN(B),$=AN(Q);try{let[f,I]=await Promise.all([A.getWebsiteStats({startDate:w,endDate:$}),A.getTopPages({startDate:w,endDate:$,limit:zRQ})]);return{days:shA,startDate:w,endDate:$,pageviews:f.pageviews,visitors:f.visitors,topPages:I}}catch(f){return{error:f instanceof Error?f.message:"Failed to fetch analytics",days:shA}}}}var bz1={name:"@brains/analytics",private:!0,version:"0.2.0-alpha.120",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 Pz1 extends YB{cloudflareClient;constructor(A={}){super("analytics",bz1,A,nhA)}async onRegister(A){this.cloudflareClient=this.config.cloudflare?new ohA(this.config.cloudflare):void 0,A.insights.register("traffic-overview",Rz1(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:Oz1(Q)}})}async getTools(){return Cz1(this.id,this.getContext(),this.cloudflareClient)}}function LRQ(A={}){return new Pz1(A)}var g$A=LRQ;import{randomBytes as RRQ}from"crypto";aA();WA();Y8();var VRQ=new Set(["description","excerpt","summary","tagline","story"]);function ERQ(A){if(A.endsWith("s"))return A;return zI(A)}function ahA(A,Q=!1,B){let w=A._def.typeName;if(w==="ZodOptional"||w==="ZodNullable")return ahA(A._def.innerType,!0,B);if(w==="ZodDefault")return ahA(A._def.innerType,Q,A._def.defaultValue());return{inner:A,isOptional:Q,defaultValue:B}}function thA(A,Q){let{inner:B,isOptional:w,defaultValue:$}=ahA(Q),f=B._def.typeName,I={name:A,label:lX(A),widget:"string",...w&&{required:!1},...$!==void 0&&{default:$}};switch(f){case"ZodString":{if((B._def.checks??[]).some((U)=>U.kind==="datetime"))return{...I,widget:"datetime"};if(VRQ.has(A))return{...I,widget:"text"};return{...I,widget:"string"}}case"ZodNumber":return{...I,widget:"number"};case"ZodBoolean":return{...I,widget:"boolean"};case"ZodEnum":{let D=B._def.values;return{...I,widget:"select",options:D}}case"ZodArray":{let D=B._def.type,U=thA("item",D);if(U.widget==="object"&&U.fields)return{...I,widget:"list",fields:U.fields};return{...I,widget:"list",field:{name:A,label:lX(A),widget:U.widget}}}case"ZodObject":{let D=B.shape,U=Object.entries(D).map(([Y,J])=>thA(Y,J));return{...I,widget:"object",fields:U}}default:return{...I,widget:"string"}}}function kz1(A,Q){let B=Object.entries(A.shape).map(([w,$])=>thA(w,$));if(Q)B.push({name:"body",label:"Body",widget:"markdown"});return B}function jz1(A){let Q=[],B=[];for(let w of A.entityTypes){let $=A.getFrontmatterSchema(w);if(!$)continue;let f=A.getAdapter(w),I=f?.hasBody!==!1,D=A.entityDisplay?.[w],U=w===eo?"Note":lX(w),Y=D?.label??U,J=D?.pluralName??ERQ(Y);if(f?.isSingleton){B.push({name:w,label:Y,file:`${w}/${w}.md`,fields:kz1($,I)});continue}if(w===eo){Q.push({name:w,label:J,folder:".",create:!0,extension:"md",format:"raw",fields:[{name:"body",label:"Body",widget:"markdown"}]});continue}Q.push({name:w,label:J,folder:w,create:!0,extension:"md",format:"frontmatter",fields:kz1($,I)})}if(B.length>0)Q.push({name:"settings",label:"Settings",files:B});return{backend:{name:"github",repo:A.repo,branch:A.branch,...A.baseUrl&&{base_url:A.baseUrl},...A.authEndpoint&&{auth_endpoint:A.authEndpoint}},media_folder:"image",public_folder:"/images",collections:Q}}var MRQ=new RegExp("[<>&\\u2028\\u2029]","g");function Sv(A){return JSON.stringify(A).replace(MRQ,(Q)=>`\\u${Q.charCodeAt(0).toString(16).padStart(4,"0")}`)}var _z1="https://unpkg.com/@sveltia/cms@0.165.1/dist/sveltia-cms.js";function h$A(A){let Q=`<script src="${_z1}"></script>`;return`<!doctype html>
|
|
6661
6661
|
<html>
|
|
6662
6662
|
<head>
|
|
6663
6663
|
<meta charset="utf-8" />
|
|
@@ -6696,7 +6696,7 @@ Returns pageviews, visitors, top pages, referrers, devices, and countries.`,ZRQ,
|
|
|
6696
6696
|
showError(error instanceof Error ? error.message : String(error));
|
|
6697
6697
|
}
|
|
6698
6698
|
})();
|
|
6699
|
-
`}WA();var vz1={name:"@brains/cms",private:!0,version:"0.2.0-alpha.
|
|
6699
|
+
`}WA();var vz1={name:"@brains/cms",private:!0,version:"0.2.0-alpha.120",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/auth-service":"workspace:*","@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 AmA="brains_cms_oauth_state",bRQ=600,PRQ="auth",kRQ=H.object({label:H.string().optional(),pluralName:H.string().optional()}).passthrough(),jRQ=H.object({clientId:H.string().optional(),clientSecret:H.string().optional(),scope:H.string().optional()}),_RQ=H.object({contentRepoToken:H.string().optional()}),vRQ=H.object({entityDisplay:H.record(kRQ).optional(),routePath:H.string().default("/cms"),githubOAuth:jRQ.optional(),passkeyLogin:_RQ.optional()}).refine((A)=>{let Q=Boolean(ZC(A.githubOAuth?.clientId)&&ZC(A.githubOAuth?.clientSecret)),B=Boolean(ZC(A.passkeyLogin?.contentRepoToken));return!(Q&&B)},{message:"CMS login supports a single method per brain: configure githubOAuth or passkeyLogin, not both."});function TRQ(A){return`${A.endsWith("/")?A:`${A}/`}config.yml`}function ZC(A){if(!A)return;let Q=A.trim();return Q.length>0?Q:void 0}function yRQ(A){let Q=ZC(A.githubOAuth?.clientId),B=ZC(A.githubOAuth?.clientSecret),w=ZC(A.passkeyLogin?.contentRepoToken);return{...Q&&B?{githubOAuth:{clientId:Q,clientSecret:B,scope:ZC(A.githubOAuth?.scope)??"repo"}}:{},...w?{passkeyLogin:{contentRepoToken:w}}:{}}}function xRQ(A){return Boolean(A.githubOAuth??A.passkeyLogin)}function SRQ(A,Q,B){let w=A.entityDisplay??B?.entityDisplay;return{...w?{entityDisplay:w}:{},...xRQ(Q)?{authEndpoint:PRQ}:{}}}async function gRQ(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 hRQ(A,Q={}){let{repo:B,branch:w}=await gRQ(A);return jz1({repo:B,branch:w,...Q.baseUrl&&{baseUrl:Q.baseUrl},...Q.authEndpoint&&{authEndpoint:Q.authEndpoint},entityTypes:A.entityService.getEntityTypes(),getFrontmatterSchema:($)=>A.entities.getEffectiveFrontmatterSchema($),getAdapter:($)=>A.entities.getAdapter($),...Q.entityDisplay&&{entityDisplay:Q.entityDisplay}})}async function xz1(A,Q={}){return cX(await hRQ(A,Q))}class QmA extends YB{constructor(A={}){super("cms",vz1,A,vRQ)}async onRegister(A){await super.onRegister(A),A.endpoints.register({label:"CMS",url:this.config.routePath,priority:40,visibility:"anchor"}),A.interactions.register({id:"cms",label:"CMS",description:"Edit and manage content through the browser CMS.",href:this.config.routePath,kind:"admin",priority:40,visibility:"anchor"})}getWebRoutes(){let A=TRQ(this.config.routePath),Q=yRQ(this.config),B=[];if(Q.githubOAuth||Q.passkeyLogin)B.push({path:"/auth",method:"GET",public:!0,handler:async(w)=>this.handleAuth(w,Q)});if(Q.githubOAuth){let w=Q.githubOAuth;B.push({path:"/auth/callback",method:"GET",public:!0,handler:async($)=>this.handleGitHubCallback($,w)})}if(Q.passkeyLogin){let w=Q.passkeyLogin;B.push({path:"/auth/cms-token",method:"POST",public:!0,handler:async($)=>this.handleCmsToken($,w)})}return[{path:this.config.routePath,method:"GET",public:!0,handler:async(w)=>{if(Q.passkeyLogin){if(!await yz1(w))return new Response(null,{status:302,headers:{Location:`/login?return_to=${encodeURIComponent(this.config.routePath)}`,"Cache-Control":"no-store"}});return si(h$A({cmsConfigPath:A,authTokenEndpoint:"/auth/cms-token"}))}return si(h$A({cmsConfigPath:A}))}},{path:A,method:"GET",public:!0,handler:async(w)=>{try{let $=SRQ(this.config,Q,this.getContext()),f=await xz1(this.getContext(),{...$,...$.authEndpoint?{baseUrl:oi(this.getContext(),w)}:{}});return new Response(f,{headers:{"Content-Type":"application/yaml; charset=utf-8"}})}catch($){return new Response($ instanceof Error?$.message:"CMS unavailable",{status:503,headers:{"Content-Type":"text/plain; charset=utf-8"}})}}},...B]}async handleAuth(A,Q){if(Q.githubOAuth)return this.redirectToGitHub(A,Q.githubOAuth);if(Q.passkeyLogin){let B=await yz1(A)?rRQ:iRQ;return si(B(oi(this.getContext(),A)))}return pRQ("CMS login is not enabled",404)}redirectToGitHub(A,Q){let B=RRQ(32).toString("base64url"),w=`${oi(this.getContext(),A)}/auth/callback`,$=new URL("https://github.com/login/oauth/authorize");return $.searchParams.set("client_id",Q.clientId),$.searchParams.set("redirect_uri",w),$.searchParams.set("scope",Q.scope),$.searchParams.set("state",B),new Response(null,{status:302,headers:{Location:$.toString(),"Set-Cookie":cRQ(B,A),"Cache-Control":"no-store"}})}async handleGitHubCallback(A,Q){let B=new URL(A.url),w=B.searchParams.get("error");if(w){let Y=B.searchParams.get("error_description")??w;return m$A(`GitHub OAuth failed: ${Y}`)}let $=B.searchParams.get("state"),f=lRQ(A.headers.get("cookie"),AmA);if(!$||!f||$!==f)return m$A("GitHub OAuth state did not match");let I=B.searchParams.get("code");if(!I)return m$A("GitHub OAuth callback did not include a code");let D=`${oi(this.getContext(),A)}/auth/callback`,U=await mRQ(Q,I,D);if(!U.success)return m$A(U.error);return si(dRQ(U.token,oi(this.getContext(),A)),200,{"Set-Cookie":gz1()})}async handleCmsToken(A,Q){if(!await RU()?.getOperatorSession(A))return Tz1({error:"Operator session required"},401);return Tz1({token:Q.contentRepoToken,provider:"github"},200,{"Cache-Control":"no-store"})}}function NC(A){return new QmA(A)}async function mRQ(A,Q,B){let w=new URLSearchParams({client_id:A.clientId,client_secret:A.clientSecret,code:Q,redirect_uri:B}),$=await fetch("https://github.com/login/oauth/access_token",{method:"POST",headers:{Accept:"application/json","Content-Type":"application/x-www-form-urlencoded"},body:w}),f;try{f=await $.json()}catch{return{success:!1,error:"GitHub token response was not JSON"}}if(!$.ok)return{success:!1,error:uRQ(f)??"GitHub token exchange failed"};if(ehA(f)&&typeof f.error==="string")return{success:!1,error:typeof f.error_description==="string"?f.error_description:f.error};let I=ehA(f)?f.access_token:void 0;if(typeof I!=="string"||I.length===0)return{success:!1,error:"GitHub token response omitted token"};return{success:!0,token:I}}function uRQ(A){if(!ehA(A))return;if(typeof A.error_description==="string")return A.error_description;return typeof A.error==="string"?A.error:void 0}function ehA(A){return Boolean(A&&typeof A==="object"&&!Array.isArray(A))}function oi(A,Q){let B=new URL(Q.url).origin;if(Sz1(B))return B;return A.siteUrl??B}function Sz1(A){let{hostname:Q}=new URL(A);return Q==="localhost"||Q==="127.0.0.1"||Q==="::1"||Q==="[::1]"}function cRQ(A,Q){let B=Sz1(new URL(Q.url).origin)?"":"; Secure";return`${AmA}=${A}; Path=/auth; HttpOnly; SameSite=Lax; Max-Age=${bRQ}${B}`}function gz1(){return`${AmA}=; Path=/auth; HttpOnly; SameSite=Lax; Max-Age=0`}function lRQ(A,Q){if(!A)return;for(let B of A.split(";")){let[w,...$]=B.trim().split("=");if(w===Q)return $.join("=")}return}function si(A,Q=200,B={}){return new Response(A,{status:Q,headers:{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store",...B}})}function pRQ(A,Q=200){return new Response(A,{status:Q,headers:{"Content-Type":"text/plain; charset=utf-8","Cache-Control":"no-store"}})}function Tz1(A,Q=200,B={}){return new Response(JSON.stringify(A),{status:Q,headers:{"Content-Type":"application/json; charset=utf-8","Cache-Control":"no-store",...B}})}function m$A(A){return si(`<!doctype html><html><body><h1>CMS login failed</h1><p>${sRQ(A)}</p></body></html>`,400,{"Set-Cookie":gz1()})}async function yz1(A){return Boolean(await RU()?.getOperatorSession(A))}function iRQ(A){return`<!doctype html>
|
|
6700
6700
|
<html lang="en">
|
|
6701
6701
|
<head>
|
|
6702
6702
|
<meta charset="utf-8" />
|
|
@@ -8101,7 +8101,7 @@ ${mz1}`;import{jsxDEV as YX,Fragment as lz1}from"preact/jsx-dev-runtime";functio
|
|
|
8101
8101
|
}
|
|
8102
8102
|
});
|
|
8103
8103
|
})();`;function jbQ({input:A}){let Q=A.appInfo.entities,B=A.appInfo.entityCounts,w=bbQ(A.widgets),$=Boolean(A.character.role)||Boolean(A.character.purpose)||A.character.values.length>0,f=A.appInfo.interactions,I=`layout${$?" has-identity":""}`,D=A.operatorAccess&&!A.operatorAccess.isOperator&&A.operatorAccess.hiddenWidgetCount>0,U=new Date;return HB("html",{lang:"en","data-theme":"dark",children:[HB("head",{children:[HB("meta",{charSet:"utf-8"},void 0,!1,void 0,this),HB("meta",{name:"viewport",content:"width=device-width, initial-scale=1.0"},void 0,!1,void 0,this),HB("title",{children:A.title},void 0,!1,void 0,this),HB("link",{rel:"preconnect",href:"https://fonts.googleapis.com"},void 0,!1,void 0,this),HB("link",{rel:"preconnect",href:"https://fonts.gstatic.com",crossOrigin:"anonymous"},void 0,!1,void 0,this),HB("link",{href:RbQ,rel:"stylesheet"},void 0,!1,void 0,this),A.themeCSS!==void 0&&HB("style",{"data-dashboard-theme":!0,dangerouslySetInnerHTML:{__html:A.themeCSS}},void 0,!1,void 0,this),HB("style",{"data-dashboard-styles":!0,dangerouslySetInnerHTML:{__html:cz1}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),HB("body",{children:[HB("main",{class:"console","data-component":"dashboard:dashboard",children:[HB(pz1,{title:A.title,tagline:A.profile.description,operatorAccess:A.operatorAccess},void 0,!1,void 0,this),HB("section",{class:I,children:[$&&HB("div",{class:"identity-column",children:[HB(rz1,{character:A.character},void 0,!1,void 0,this),HB(fmA,{interactions:f,baseUrl:A.baseUrl},void 0,!1,void 0,this),D&&A.operatorAccess&&HB(ez1,{hiddenWidgetCount:A.operatorAccess.hiddenWidgetCount,loginUrl:A.operatorAccess.loginUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this),HB("div",{class:"main-column",children:[HB(iz1,{total:Q,entityCounts:B},void 0,!1,void 0,this),!$&&D&&A.operatorAccess&&HB(ez1,{hiddenWidgetCount:A.operatorAccess.hiddenWidgetCount,loginUrl:A.operatorAccess.loginUrl},void 0,!1,void 0,this),w.primary.map((Y)=>HB(p$A,{widget:Y},`${Y.widget.pluginId}:${Y.widget.id}`,!1,void 0,this)),w.secondary.map((Y)=>HB(p$A,{widget:Y},`${Y.widget.pluginId}:${Y.widget.id}`,!1,void 0,this))]},void 0,!0,void 0,this),HB("div",{class:"sidebar-column",children:[!$&&HB(fmA,{interactions:f,baseUrl:A.baseUrl},void 0,!1,void 0,this),w.sidebar.map((Y)=>HB(p$A,{widget:Y},`${Y.widget.pluginId}:${Y.widget.id}`,!1,void 0,this)),HB(dz1,{endpoints:A.appInfo.endpoints,baseUrl:A.baseUrl},void 0,!1,void 0,this),HB(az1,{appInfo:A.appInfo,now:U},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),HB(tz1,{title:A.title,appInfo:A.appInfo,baseUrl:A.baseUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this),HB("script",{dangerouslySetInnerHTML:{__html:PbQ}},void 0,!1,void 0,this),HB("script",{dangerouslySetInnerHTML:{__html:kbQ}},void 0,!1,void 0,this),A.widgetScripts.map((Y,J)=>HB("script",{dangerouslySetInnerHTML:{__html:Y}},`widget-script:${J}`,!1,void 0,this))]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}function Aq1(A){return`<!doctype html>
|
|
8104
|
-
${ObQ(HB(jbQ,{input:A},void 0,!1,void 0,this))}`}function Qq1(A,Q){let B={},w=new Set;for(let[$,f]of Object.entries(A)){let I=Q?.get(f.widget.pluginId,f.widget.id);if(B[$]={...f,...I?.component?{component:I.component}:{}},I?.clientScript)w.add(I.clientScript)}return{widgets:B,widgetScripts:Array.from(w)}}var Bq1={name:"@brains/dashboard",private:!0,version:"0.2.0-alpha.
|
|
8104
|
+
${ObQ(HB(jbQ,{input:A},void 0,!1,void 0,this))}`}function Qq1(A,Q){let B={},w=new Set;for(let[$,f]of Object.entries(A)){let I=Q?.get(f.widget.pluginId,f.widget.id);if(B[$]={...f,...I?.component?{component:I.component}:{}},I?.clientScript)w.add(I.clientScript)}return{widgets:B,widgetScripts:Array.from(w)}}var Bq1={name:"@brains/dashboard",private:!0,version:"0.2.0-alpha.120",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 vbQ=H.object({version:H.string().default("1.0.0"),routePath:H.string().default("/dashboard"),themeCSS:H.string().optional()}),TbQ=H.object({id:H.string(),pluginId:H.string(),title:H.string(),description:H.string().optional(),priority:H.number().default(50),section:H.enum(["primary","secondary","sidebar"]).default("primary"),rendererName:H.string(),visibility:J4.default("public"),component:H.custom().optional(),clientScript:H.string().optional(),dataProvider:H.function().returns(H.promise(H.unknown()))}).superRefine((A,Q)=>{if(!$mA(A.rendererName)&&!A.component)Q.addIssue({code:H.ZodIssueCode.custom,message:"Custom dashboard widgets must register a Preact component.",path:["component"]})}),ybQ=H.object({pluginId:H.string(),widgetId:H.string().optional()});function xbQ(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 DmA extends YB{widgetRegistry=null;datasource=null;siteUrl;ctx;constructor(A){super("dashboard",Bq1,A??{},vbQ)}async onRegister(A){this.siteUrl=A.siteUrl,this.ctx=A,this.widgetRegistry=new c$A(this.logger),this.datasource=new l$A(this.widgetRegistry,this.logger),A.entities.registerDataSource(this.datasource),A.endpoints.register({label:"Dashboard",url:this.config.routePath,priority:30,visibility:"public"}),A.interactions.register({id:"dashboard",label:"Dashboard",description:"Inspect runtime status, endpoints, and dashboard widgets.",href:this.config.routePath,kind:"admin",priority:30,visibility:"public"}),A.messaging.subscribe("dashboard:register-widget",async(Q)=>{try{let B=TbQ.parse(Q.payload),w=xbQ(B);return this.widgetRegistry?.register(w),this.logger.debug("Widget registered via messaging",{widgetId:B.id,pluginId:B.pluginId,rendererName:B.rendererName,builtIn:u$A.includes(B.rendererName)}),{success:!0}}catch(B){return this.logger.error("Failed to register widget",{error:T0(B),payload:Q.payload}),{success:!1,error:"Widget registration failed"}}}),A.messaging.subscribe("dashboard:unregister-widget",async(Q)=>{let B=ybQ.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 RU()?.getOperatorSession(A),w=Boolean(B),$=w?"anchor":"public",f=this.widgetRegistry?.list({permissionLevel:"anchor"})??[],I=f.filter((S)=>O9.hasPermission($,S.visibility)),D=f.length-I.length,[U,Y]=await Promise.all([this.datasource.getDashboardData({permissionLevel:$,widgets:I}),Q.appInfo()]),J=Q.identity.get(),X=Q.identity.getProfile(),G=this.siteUrl??(()=>{try{return new URL(A.url).origin}catch{return}})(),Z={...Y,endpoints:Y.endpoints.filter((S)=>O9.hasPermission($,S.visibility)),interactions:Y.interactions.filter((S)=>O9.hasPermission($,S.visibility))},N=X.name||Y.model||"Brain Dashboard",L=new URL(A.url),V=`${L.pathname}${L.search}`,M=encodeURIComponent(V),O=Qq1(U.widgets,this.widgetRegistry),E={title:N,baseUrl:G,widgets:O.widgets,widgetScripts:O.widgetScripts,character:J,profile:X,appInfo:Z,...this.config.themeCSS!==void 0&&{themeCSS:this.config.themeCSS},operatorAccess:{isOperator:w,hiddenWidgetCount:D,loginUrl:`/login?return_to=${M}`,logoutUrl:`/logout?return_to=${M}`}};return new Response(Aq1(E),{headers:{"Content-Type":"text/html; charset=utf-8"}})}}]}async getTools(){return[]}getWidgetRegistry(){return this.widgetRegistry}}function az(A){return new DmA(A)}aA();WA();var SbQ=H.object({id:H.string(),pluginId:H.string(),title:H.string(),description:H.string().optional(),priority:H.number(),section:H.enum(["primary","secondary","sidebar"]),rendererName:H.string(),visibility:J4,component:H.custom().optional()}),gbQ=H.object({widget:SbQ,data:H.unknown()}),hbQ=H.object({widgets:H.record(gbQ)});WA();aA();WA();import{h as ebQ}from"preact";WA();wU();aA();var gv=H.enum(["generating","draft","queued","published","failed"]),ti=H.object({subject:H.string(),status:gv,entityIds:H.array(H.string()).optional(),scheduledFor:H.string().datetime().optional(),sentAt:H.string().datetime().optional(),buttondownId:H.string().optional(),sourceEntityType:H.string().optional()}),wq1=ti.pick({subject:!0,status:!0,entityIds:!0,scheduledFor:!0,sentAt:!0,buttondownId:!0,sourceEntityType:!0}).extend({error:H.string().optional()}),ei=A2.extend({entityType:H.literal("newsletter"),metadata:wq1});aA();class $q1 extends q2{constructor(){super({entityType:"newsletter",schema:ei,frontmatterSchema:ti})}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}}buildStub(A){let Q={subject:A.title,status:"generating"};return{content:this.buildMarkdown("",Q),metadata:Q}}}var fq1=new $q1;aA();aA();WA();var mbQ=QW.extend({status:H.enum(["generating","draft","queued","published","failed"]).optional()}),ubQ=BW.extend({query:mbQ.optional()});function Iq1(A){try{let{content:Q}=R2(A.content,ti);return Q}catch{return A.content}}class UmA extends m5{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=ubQ.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}transformEntity(A){let Q=Iq1(A),B={id:A.id,subject:A.metadata.subject,status:A.metadata.status,excerpt:H7(Q,150),created:A.created,url:`/newsletters/${A.id}`};if(A.metadata.sentAt)B.sentAt=A.metadata.sentAt;return B}buildListResult(A,Q,B){return{newsletters:A,totalCount:Q?.totalItems??A.length,pagination:Q}}async fetch(A,Q,B){let{query:w}=this.parseQuery(A),$=B.entityService;if(w.id)return this.fetchSingleNewsletter(w.id,Q,$);let f=w.status,I=f?{filter:{metadata:{status:f}}}:void 0,{items:D,pagination:U}=await this.fetchList(w,$,I);return Q.parse(this.buildListResult(D,U,w))}async fetchSingleNewsletter(A,Q,B){let w=await B.getEntity({entityType:this.config.entityType,id:A});if(!w)throw Error(`Newsletter not found: ${A}`);let $=await this.resolveNavigation(w,B),f=[];if(w.metadata.entityIds?.length){let U=w.metadata.sourceEntityType??"post";f=(await Promise.all(w.metadata.entityIds.map(async(J)=>{let X=await B.getEntity({entityType:U,id:J});if(X){let G=X.metadata;return{id:J,title:G.title??J,url:`/${U}s/${G.slug??J}`}}return null}))).filter((J)=>J!==null)}let I=Iq1(w),D={id:w.id,subject:w.metadata.subject,status:w.metadata.status,content:I,created:w.created,updated:w.updated,sentAt:w.metadata.sentAt,scheduledFor:w.metadata.scheduledFor,newsletter:w,prevNewsletter:$.prev?{id:$.prev.id,subject:$.prev.subject,url:$.prev.url}:null,nextNewsletter:$.next?{id:$.next.id,subject:$.next.subject,url:$.next.url}:null,sourceEntities:f.length>0?f:void 0};return Q.parse(D)}}aA();WA();var cbQ=H.object({prompt:H.string().optional().describe("AI generation prompt"),sourceEntityIds:H.array(H.string()).optional().describe("Entity IDs to include in newsletter (e.g., blog posts)"),sourceEntityType:H.enum(["post"]).optional().describe("Type of source entities"),content:H.string().optional().describe("Direct content (skip AI)"),subject:H.string().optional().describe("Newsletter subject (AI-generated if not provided)"),addToQueue:H.boolean().optional().describe("Create as queued (true) or draft (false)")});class YmA extends z7{constructor(A,Q){super(A,Q,{schema:cbQ,jobTypeName:"newsletter:generation",entityType:"newsletter"})}async generate(A,Q){let B=A.addToQueue??!1,{prompt:w,sourceEntityIds:$,sourceEntityType:f}=A,{content:I,subject:D}=A;if(I){if(!D)this.failEarly("Subject is required when providing content directly");await this.reportProgress(Q,{progress:50,message:"Using provided content"})}else if($&&$.length>0){let G=f??"post";await this.reportProgress(Q,{progress:10,message:`Fetching ${$.length} source entities`});let N=(await Promise.all($.map((E)=>this.context.entityService.getEntity({entityType:G,id:E})))).filter((E)=>E!=null);if(N.length===0)this.failEarly(`No source entities found for IDs: ${$.join(", ")}`);await this.reportProgress(Q,{progress:30,message:`Generating newsletter from ${N.length} posts`});let V=`Create an engaging newsletter that highlights these blog posts:
|
|
8105
8105
|
|
|
8106
8106
|
${N.map((E)=>`## ${E.metadata.title}
|
|
8107
8107
|
|
|
@@ -8170,14 +8170,14 @@ Newsletter-specific guidelines:
|
|
|
8170
8170
|
- "Reply and let me know..."
|
|
8171
8171
|
- "Until next time..."
|
|
8172
8172
|
|
|
8173
|
-
The goal is to build a relationship with readers through valuable, authentic content.`});WA();aA();import{jsxDEV as l4,Fragment as dbQ}from"preact/jsx-dev-runtime";var pbQ=H.object({id:H.string(),subject:H.string(),status:gv,excerpt:H.string(),created:H.string(),sentAt:H.string().optional(),url:H.string()}),ibQ=H.object({newsletters:H.array(pbQ),totalCount:H.number(),pagination:Z7.nullable()}),rbQ=({newsletters:A,totalCount:Q,pageTitle:B,pagination:w,baseUrl:$="/newsletters"})=>{let f=B??"Newsletters",I=`Browse all ${Q} ${Q===1?"newsletter":"newsletters"}`;return l4(dbQ,{children:[l4(KQ,{title:f,description:I},void 0,!1,void 0,this),l4("div",{className:"newsletter-list bg-theme",children:l4("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[l4("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:f},void 0,!1,void 0,this),A.length===0?l4("p",{className:"text-theme-muted italic",children:"No newsletters yet."},void 0,!1,void 0,this):l4("div",{className:"space-y-4",children:A.map((D)=>l4(PB,{href:D.url,children:[l4(Y9,{className:"text-lg",children:D.subject},void 0,!1,void 0,this),l4(c9,{children:l4("div",{className:"flex items-center gap-3",children:[l4(gf,{status:D.status},void 0,!1,void 0,this),l4("span",{className:"text-sm text-theme-muted",children:i6(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&&l4("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&&l4(VF,{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)},Uq1=P1({name:"newsletter-list",description:"Newsletter list page template",schema:ibQ,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:rbQ}});WA();aA();import{jsxDEV as q8,Fragment as abQ}from"preact/jsx-dev-runtime";var nbQ=H.object({id:H.string(),title:H.string(),url:H.string()}),Yq1=H.object({id:H.string(),subject:H.string(),url:H.string()}),obQ=H.object({id:H.string(),subject:H.string(),status:gv,content:H.string(),created:H.string(),updated:H.string(),sentAt:H.string().optional(),scheduledFor:H.string().optional(),sourceEntities:H.array(nbQ).optional(),prevNewsletter:Yq1.nullable().optional(),nextNewsletter:Yq1.nullable().optional()}),sbQ=({subject:A,status:Q,content:B,created:w,sentAt:$,scheduledFor:f,sourceEntities:I,prevNewsletter:D,nextNewsletter:U})=>{let Y=[{label:"Home",href:"/"},{label:"Newsletters",href:"/newsletters"},{label:A}],J=$??w,X=$?"Sent":"Created";return q8(abQ,{children:[q8(KQ,{title:A,description:`Newsletter: ${A}`},void 0,!1,void 0,this),q8("section",{className:"newsletter-detail-section",children:q8("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:q8("div",{className:"max-w-3xl mx-auto",children:[q8(YH,{items:Y},void 0,!1,void 0,this),q8("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),q8("div",{className:"flex flex-wrap items-center gap-3 mb-8 text-sm text-theme-muted",children:[q8(gf,{status:Q},void 0,!1,void 0,this),q8("span",{children:[X,": ",i6(J,{style:"long"})]},void 0,!0,void 0,this),f&&Q==="queued"&&q8("span",{children:["Scheduled for: ",i6(f,{style:"long"})]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),I&&I.length>0&&q8(PB,{variant:"compact",className:"mb-8",children:[q8("h3",{className:"text-sm font-medium text-heading mb-2",children:"Related Content"},void 0,!1,void 0,this),q8("ul",{className:"space-y-1",children:I.map((G)=>q8("li",{children:q8("a",{href:G.url,className:"text-sm text-brand hover:text-brand-dark transition-colors",children:G.title},void 0,!1,void 0,this)},G.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),q8(V$,{markdown:B},void 0,!1,void 0,this),(D??U)&&q8("nav",{className:"mt-12 pt-8 border-t border-theme",children:q8("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[D?q8(PB,{href:D.url,variant:"compact",children:[q8("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Newer"},void 0,!1,void 0,this),q8("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):q8("div",{},void 0,!1,void 0,this),U&&q8(PB,{href:U.url,variant:"compact",className:"md:text-right",children:[q8("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Older"},void 0,!1,void 0,this),q8("span",{className:"block mt-1 font-medium text-heading group-hover:text-brand transition-colors truncate",children:U.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)},Jq1=P1({name:"newsletter-detail",description:"Individual newsletter detail template",schema:obQ,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:sbQ}});var Xq1={name:"@brains/newsletter-entity",private:!0,version:"0.2.0-alpha.
|
|
8173
|
+
The goal is to build a relationship with readers through valuable, authentic content.`});WA();aA();import{jsxDEV as l4,Fragment as dbQ}from"preact/jsx-dev-runtime";var pbQ=H.object({id:H.string(),subject:H.string(),status:gv,excerpt:H.string(),created:H.string(),sentAt:H.string().optional(),url:H.string()}),ibQ=H.object({newsletters:H.array(pbQ),totalCount:H.number(),pagination:Z7.nullable()}),rbQ=({newsletters:A,totalCount:Q,pageTitle:B,pagination:w,baseUrl:$="/newsletters"})=>{let f=B??"Newsletters",I=`Browse all ${Q} ${Q===1?"newsletter":"newsletters"}`;return l4(dbQ,{children:[l4(KQ,{title:f,description:I},void 0,!1,void 0,this),l4("div",{className:"newsletter-list bg-theme",children:l4("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[l4("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:f},void 0,!1,void 0,this),A.length===0?l4("p",{className:"text-theme-muted italic",children:"No newsletters yet."},void 0,!1,void 0,this):l4("div",{className:"space-y-4",children:A.map((D)=>l4(PB,{href:D.url,children:[l4(Y9,{className:"text-lg",children:D.subject},void 0,!1,void 0,this),l4(c9,{children:l4("div",{className:"flex items-center gap-3",children:[l4(gf,{status:D.status},void 0,!1,void 0,this),l4("span",{className:"text-sm text-theme-muted",children:i6(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&&l4("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&&l4(VF,{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)},Uq1=P1({name:"newsletter-list",description:"Newsletter list page template",schema:ibQ,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:rbQ}});WA();aA();import{jsxDEV as q8,Fragment as abQ}from"preact/jsx-dev-runtime";var nbQ=H.object({id:H.string(),title:H.string(),url:H.string()}),Yq1=H.object({id:H.string(),subject:H.string(),url:H.string()}),obQ=H.object({id:H.string(),subject:H.string(),status:gv,content:H.string(),created:H.string(),updated:H.string(),sentAt:H.string().optional(),scheduledFor:H.string().optional(),sourceEntities:H.array(nbQ).optional(),prevNewsletter:Yq1.nullable().optional(),nextNewsletter:Yq1.nullable().optional()}),sbQ=({subject:A,status:Q,content:B,created:w,sentAt:$,scheduledFor:f,sourceEntities:I,prevNewsletter:D,nextNewsletter:U})=>{let Y=[{label:"Home",href:"/"},{label:"Newsletters",href:"/newsletters"},{label:A}],J=$??w,X=$?"Sent":"Created";return q8(abQ,{children:[q8(KQ,{title:A,description:`Newsletter: ${A}`},void 0,!1,void 0,this),q8("section",{className:"newsletter-detail-section",children:q8("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:q8("div",{className:"max-w-3xl mx-auto",children:[q8(YH,{items:Y},void 0,!1,void 0,this),q8("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),q8("div",{className:"flex flex-wrap items-center gap-3 mb-8 text-sm text-theme-muted",children:[q8(gf,{status:Q},void 0,!1,void 0,this),q8("span",{children:[X,": ",i6(J,{style:"long"})]},void 0,!0,void 0,this),f&&Q==="queued"&&q8("span",{children:["Scheduled for: ",i6(f,{style:"long"})]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),I&&I.length>0&&q8(PB,{variant:"compact",className:"mb-8",children:[q8("h3",{className:"text-sm font-medium text-heading mb-2",children:"Related Content"},void 0,!1,void 0,this),q8("ul",{className:"space-y-1",children:I.map((G)=>q8("li",{children:q8("a",{href:G.url,className:"text-sm text-brand hover:text-brand-dark transition-colors",children:G.title},void 0,!1,void 0,this)},G.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),q8(V$,{markdown:B},void 0,!1,void 0,this),(D??U)&&q8("nav",{className:"mt-12 pt-8 border-t border-theme",children:q8("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[D?q8(PB,{href:D.url,variant:"compact",children:[q8("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Newer"},void 0,!1,void 0,this),q8("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):q8("div",{},void 0,!1,void 0,this),U&&q8(PB,{href:U.url,variant:"compact",className:"md:text-right",children:[q8("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Older"},void 0,!1,void 0,this),q8("span",{className:"block mt-1 font-medium text-heading group-hover:text-brand transition-colors truncate",children:U.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)},Jq1=P1({name:"newsletter-detail",description:"Individual newsletter detail template",schema:obQ,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:sbQ}});var Xq1={name:"@brains/newsletter-entity",private:!0,version:"0.2.0-alpha.120",description:"Newsletter entity type with AI generation and publish pipeline",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint src test --ext .ts,.tsx","lint:fix":"eslint src test --ext .ts,.tsx --fix"},dependencies:{"@brains/contracts":"workspace:*","@brains/entity-service":"workspace:*","@brains/plugins":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var APQ=H.object({});class JmA extends jQ{entityType="newsletter";schema=ei;adapter=fq1;constructor(A={}){super("newsletter",Xq1,A,APQ)}getEntityTypeConfig(){return{publish:{publishStatuses:["queued","published","failed"]}}}createGenerationHandler(A){return new YmA(this.logger,A)}getTemplates(){return{generation:Dq1,"newsletter-list":Uq1,"newsletter-detail":Jq1}}getDataSources(){return[new UmA(this.logger.child("NewsletterDataSource"))]}async onRegister(A){this.deferPublishRegistration(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:()=>ebQ(gTA,{variant:"inline"})}});return{success:!0}}),this.logger.debug("Newsletter plugin registered")}deferPublishRegistration(A){let Q={name:"internal",publish:async(B,w)=>{let $=typeof w.subject==="string"?w.subject:"",f=await A.messaging.send({type:"buttondown:send",payload:{entityId:"",subject:$,content:B}});return{id:!("noop"in f)&&f.data?.emailId?f.data.emailId:"internal"}}};A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"publish:register",payload:{entityType:"newsletter",provider:Q,config:{publishResultIdField:"buttondownId",publishTimestampField:"sentAt"}}}),{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:T0(B)}}),{success:!0}}})}registerEvalHandlers(A){let Q=H.object({prompt:H.string().optional(),content:H.string().optional()});A.eval.registerHandler("generation",async(B)=>{let w=Q.parse(B),$=w.content?`Create an engaging newsletter based on this content:
|
|
8174
8174
|
|
|
8175
|
-
${w.content}`:w.prompt??"Write an engaging newsletter";return A.ai.generate({prompt:$,templateName:"newsletter:generation"})})}}function XmA(A={}){return new JmA(A)}aA();WA();class hv{config;logger;constructor(A,Q){this.config=A;this.logger=Q}async request(A,Q={}){let B=`https://api.buttondown.email/v1${A}`;this.logger.debug("Buttondown API request",{endpoint:A,method:Q.method??"GET"});let w=await fetch(B,{...Q,headers:{Authorization:`Token ${this.config.apiKey}`,"Content-Type":"application/json",...Q.headers}});if(!w.ok){let $=await w.json().catch(()=>({})),f=$.detail??$.message??`HTTP ${w.status}`;throw this.logger.error("Buttondown API error",{endpoint:A,status:w.status,error:f}),Error(`Buttondown API error: ${f}`)}return w.json()}async createSubscriber(A){let Q={email_address:A.email,type:this.config.doubleOptIn?"unactivated":"regular"};if(A.name)Q.metadata={name:A.name};if(A.tags&&A.tags.length>0)Q.tags=A.tags;this.logger.info("Creating subscriber",{email:A.email});try{return await this.request("/subscribers",{method:"POST",body:JSON.stringify(Q)})}catch(B){if(B instanceof Error&&B.message.includes("already subscribed")){let w=B.message.match(/id=([a-f0-9-]+)/);return this.logger.info("Subscriber already exists",{email:A.email}),{id:w?.[1]??"existing",email:A.email,subscriber_type:"already_subscribed"}}throw B}}async unsubscribe(A){this.logger.info("Unsubscribing",{email:A}),await this.request(`/subscribers/${encodeURIComponent(A)}`,{method:"DELETE"})}async listSubscribers(A){let Q=new URLSearchParams;if(A?.type)Q.set("type",A.type);if(A?.limit)Q.set("page_size",String(A.limit));let B=Q.toString(),w=B?`/subscribers?${B}`:"/subscribers";return this.request(w)}async createEmail(A){let Q={subject:A.subject,body:A.body,status:A.status??"draft"};if(A.publish_date)Q.publish_date=A.publish_date;return this.logger.info("Creating email",{subject:A.subject,status:A.status??"draft"}),this.request("/emails",{method:"POST",body:JSON.stringify(Q)})}async getEmail(A){return this.request(`/emails/${A}`)}async validateCredentials(){try{return await this.request("/subscribers?page_size=1"),!0}catch{return!1}}}aA();WA();var QPQ=H.object({email:H.string().email().describe("Email address to subscribe"),name:H.string().optional().describe("Subscriber name (optional)"),tags:H.array(H.string()).optional().describe("Tags to apply to subscriber (optional)")}),BPQ=H.object({email:H.string().email().describe("Email address to unsubscribe")}),wPQ=H.object({type:H.enum(["unactivated","regular","unsubscribed"]).optional().describe("Filter by subscriber status"),limit:H.number().optional().describe("Maximum number of results")});function Wq1(A,Q,B){let w=new hv(Q,B);return[oQ(A,"subscribe","Subscribe an email address to the newsletter. Uses double opt-in by default.",QPQ,async($)=>{try{let f=await w.createSubscriber({email:$.email,...$.name&&{name:$.name},...$.tags&&{tags:$.tags}}),I=f.subscriber_type==="already_subscribed";return U8({subscriberId:f.id,email:f.email,status:f.subscriber_type,message:I?"already_subscribed":"subscribed"},I?`${$.email} is already subscribed`:`Subscribed ${$.email} successfully`)}catch(f){return X$(T0(f))}}),oQ(A,"unsubscribe","Unsubscribe an email address from the newsletter.",BPQ,async($)=>{try{return await w.unsubscribe($.email),U8({email:$.email},`Unsubscribed ${$.email} successfully`)}catch(f){return X$(T0(f))}}),oQ(A,"list_subscribers","List newsletter subscribers with optional filtering by status.",wPQ,async($)=>{try{let f=await w.listSubscribers({...$.type&&{type:$.type},...$.limit&&{limit:$.limit}});return U8({subscribers:f.results.map((I)=>({id:I.id,email:I.email,status:I.subscriber_type})),count:f.count},`Found ${f.count} subscribers`)}catch(f){return X$(T0(f))}})]}WA();async function Hq1(A,Q,B,w){if(A.entityType!=="post")return{success:!0,skipped:!0,reason:"Only post entity types trigger auto-send"};let $=await B.getEntity({entityType:"post",id:A.entityId});if(!$)return{success:!1,error:`Post ${A.entityId} not found`};w.info("Auto-sending newsletter for published post",{postId:$.id,title:$.metadata.title});try{let f=await Q.createEmail({subject:$.metadata.title,body:$.content,status:"about_to_send"});return w.info("Newsletter sent for post",{postId:$.id,emailId:f.id}),{success:!0,emailId:f.id}}catch(f){let I=T0(f);return w.error("Failed to send newsletter for post",{postId:$.id,error:I}),{success:!1,error:I}}}var Gq1={name:"@brains/buttondown",private:!0,version:"0.2.0-alpha.
|
|
8175
|
+
${w.content}`:w.prompt??"Write an engaging newsletter";return A.ai.generate({prompt:$,templateName:"newsletter:generation"})})}}function XmA(A={}){return new JmA(A)}aA();WA();class hv{config;logger;constructor(A,Q){this.config=A;this.logger=Q}async request(A,Q={}){let B=`https://api.buttondown.email/v1${A}`;this.logger.debug("Buttondown API request",{endpoint:A,method:Q.method??"GET"});let w=await fetch(B,{...Q,headers:{Authorization:`Token ${this.config.apiKey}`,"Content-Type":"application/json",...Q.headers}});if(!w.ok){let $=await w.json().catch(()=>({})),f=$.detail??$.message??`HTTP ${w.status}`;throw this.logger.error("Buttondown API error",{endpoint:A,status:w.status,error:f}),Error(`Buttondown API error: ${f}`)}return w.json()}async createSubscriber(A){let Q={email_address:A.email,type:this.config.doubleOptIn?"unactivated":"regular"};if(A.name)Q.metadata={name:A.name};if(A.tags&&A.tags.length>0)Q.tags=A.tags;this.logger.info("Creating subscriber",{email:A.email});try{return await this.request("/subscribers",{method:"POST",body:JSON.stringify(Q)})}catch(B){if(B instanceof Error&&B.message.includes("already subscribed")){let w=B.message.match(/id=([a-f0-9-]+)/);return this.logger.info("Subscriber already exists",{email:A.email}),{id:w?.[1]??"existing",email:A.email,subscriber_type:"already_subscribed"}}throw B}}async unsubscribe(A){this.logger.info("Unsubscribing",{email:A}),await this.request(`/subscribers/${encodeURIComponent(A)}`,{method:"DELETE"})}async listSubscribers(A){let Q=new URLSearchParams;if(A?.type)Q.set("type",A.type);if(A?.limit)Q.set("page_size",String(A.limit));let B=Q.toString(),w=B?`/subscribers?${B}`:"/subscribers";return this.request(w)}async createEmail(A){let Q={subject:A.subject,body:A.body,status:A.status??"draft"};if(A.publish_date)Q.publish_date=A.publish_date;return this.logger.info("Creating email",{subject:A.subject,status:A.status??"draft"}),this.request("/emails",{method:"POST",body:JSON.stringify(Q)})}async getEmail(A){return this.request(`/emails/${A}`)}async validateCredentials(){try{return await this.request("/subscribers?page_size=1"),!0}catch{return!1}}}aA();WA();var QPQ=H.object({email:H.string().email().describe("Email address to subscribe"),name:H.string().optional().describe("Subscriber name (optional)"),tags:H.array(H.string()).optional().describe("Tags to apply to subscriber (optional)")}),BPQ=H.object({email:H.string().email().describe("Email address to unsubscribe")}),wPQ=H.object({type:H.enum(["unactivated","regular","unsubscribed"]).optional().describe("Filter by subscriber status"),limit:H.number().optional().describe("Maximum number of results")});function Wq1(A,Q,B){let w=new hv(Q,B);return[oQ(A,"subscribe","Subscribe an email address to the newsletter. Uses double opt-in by default.",QPQ,async($)=>{try{let f=await w.createSubscriber({email:$.email,...$.name&&{name:$.name},...$.tags&&{tags:$.tags}}),I=f.subscriber_type==="already_subscribed";return U8({subscriberId:f.id,email:f.email,status:f.subscriber_type,message:I?"already_subscribed":"subscribed"},I?`${$.email} is already subscribed`:`Subscribed ${$.email} successfully`)}catch(f){return X$(T0(f))}}),oQ(A,"unsubscribe","Unsubscribe an email address from the newsletter.",BPQ,async($)=>{try{return await w.unsubscribe($.email),U8({email:$.email},`Unsubscribed ${$.email} successfully`)}catch(f){return X$(T0(f))}}),oQ(A,"list_subscribers","List newsletter subscribers with optional filtering by status.",wPQ,async($)=>{try{let f=await w.listSubscribers({...$.type&&{type:$.type},...$.limit&&{limit:$.limit}});return U8({subscribers:f.results.map((I)=>({id:I.id,email:I.email,status:I.subscriber_type})),count:f.count},`Found ${f.count} subscribers`)}catch(f){return X$(T0(f))}})]}WA();async function Hq1(A,Q,B,w){if(A.entityType!=="post")return{success:!0,skipped:!0,reason:"Only post entity types trigger auto-send"};let $=await B.getEntity({entityType:"post",id:A.entityId});if(!$)return{success:!1,error:`Post ${A.entityId} not found`};w.info("Auto-sending newsletter for published post",{postId:$.id,title:$.metadata.title});try{let f=await Q.createEmail({subject:$.metadata.title,body:$.content,status:"about_to_send"});return w.info("Newsletter sent for post",{postId:$.id,emailId:f.id}),{success:!0,emailId:f.id}}catch(f){let I=T0(f);return w.error("Failed to send newsletter for post",{postId:$.id,error:I}),{success:!1,error:I}}}var Gq1={name:"@brains/buttondown",private:!0,version:"0.2.0-alpha.120",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 fPQ=H.object({apiKey:H.string().optional().describe("Buttondown API key"),doubleOptIn:H.boolean().default(!0).describe("Require email confirmation for new subscribers"),autoSendOnPublish:H.boolean().default(!1).describe("Automatically send newsletter when a blog post is published")});class WmA extends YB{constructor(A={}){super("buttondown",Gq1,A,fPQ)}async onRegister(A){if(A.messaging.subscribe("buttondown:is-configured",async()=>{return{success:!!this.config.apiKey}}),this.config.apiKey){let Q=new hv({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:T0(w)}),{success:!1}}}),this.config.autoSendOnPublish)A.messaging.subscribe("publish:completed",async(B)=>{return await Hq1(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 Wq1(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 HmA(A={}){return new WmA(A)}var IPQ=H.object({apiKey:H.string().optional().describe("Buttondown API key"),doubleOptIn:H.boolean().optional().describe("Require email confirmation for new subscribers"),autoSendOnPublish:H.boolean().optional().describe("Automatically send newsletter when a blog post is published")});function Kq1(A={}){let Q=IPQ.parse(A);return[XmA({}),HmA({...Q.apiKey!==void 0&&{apiKey:Q.apiKey},...Q.doubleOptIn!==void 0&&{doubleOptIn:Q.doubleOptIn},...Q.autoSendOnPublish!==void 0&&{autoSendOnPublish:Q.autoSendOnPublish}})]}aA();WA();import{existsSync as NPQ,mkdirSync as zPQ,writeFileSync as qPQ}from"fs";import{join as dF}from"path";WA();var GmA=H.object({baseFolder:H.string().default("_obsidian")});WA();function DPQ(A){let Q=A,B=!0,w=void 0,$=!1,f=!0;while(f){if(f=!1,Q instanceof H.ZodOptional)B=!1,Q=Q._def.innerType,f=!0;if(Q instanceof H.ZodDefault)B=!1,$=!0,w=Q._def.defaultValue(),Q=Q._def.innerType,f=!0;if(Q instanceof H.ZodNullable)B=!1,Q=Q._def.innerType,f=!0}let I={inner:Q,required:B};if($)I.defaultValue=w;return I}function UPQ(A){if(A instanceof H.ZodEnum)return{type:"enum",enumValues:A._def.values};if(A instanceof H.ZodLiteral)return{type:"string",defaultValue:A._def.value};if(A instanceof H.ZodString)return{type:"string"};if(A instanceof H.ZodNumber)return{type:"number"};if(A instanceof H.ZodBoolean)return{type:"boolean"};if(A instanceof H.ZodArray)return{type:"array"};if(A instanceof H.ZodDate)return{type:"date"};if(A instanceof H.ZodPipeline){if(A._def.out instanceof H.ZodDate)return{type:"date"}}return{type:"unknown"}}function Fq1(A){let Q=A.shape,B=[];for(let[w,$]of Object.entries(Q)){let{inner:f,required:I,defaultValue:D}=DPQ($),U=UPQ(f),Y={name:w,type:U.type,required:I},J=D!==void 0?D:U.defaultValue;if(J!==void 0)Y.defaultValue=J;if(U.enumValues)Y.enumValues=U.enumValues;B.push(Y)}return B}function YPQ(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 Zq1(A,Q,B=""){let w=["---"];for(let $ of Q){let f=YPQ($,A);if(f==="")w.push(`${$.name}:`);else w.push(`${$.name}: ${f}`)}if(w.push("---"),w.push(""),B)w.push(B);else w.push("<!-- Write your content here -->"),w.push("");return w.join(`
|
|
8176
8176
|
`)}WA();var JPQ={string:"Input",number:"Number",boolean:"Boolean",date:"Date",enum:"Select",array:"Multi",unknown:"Input"};function XPQ(A){let Q={name:A.name,id:A.name,type:JPQ[A.type]};if(A.type==="enum"&&A.enumValues){let B={};A.enumValues.forEach((w,$)=>{B[String($)]=w}),Q.options=B}return Q}function Nq1(A,Q){let B={filesPaths:A,fields:Q.map(XPQ)};return`---
|
|
8177
8177
|
${cX(B)}---
|
|
8178
|
-
`}WA();var WPQ=new Set(["entityType"]),HPQ={base:"Notes"},GPQ=new Set(["base"]);function KPQ(A){let Q=["file.name"];for(let B of A)if(!WPQ.has(B.name))Q.push(B.name);return Q}function FPQ(A){return A.some((Q)=>Q.name==="status"&&Q.type==="enum")}function zq1(A,Q){let B=HPQ[A]??sn(A),w=FPQ(Q),$=KPQ(Q),f=[{type:"table",name:`All ${B}`,order:$}];if(w)f.push({type:"table",name:"By Status",groupBy:{property:"status",direction:"ASC"},order:$});let D={filters:{and:[GPQ.has(A)?'file.folder == "/"':`file.inFolder("${A}")`]},views:f};return{filename:`${B}.base`,content:cX(D),hasStatus:w}}function qq1(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 cX(B)}function Lq1(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 cX(B)}var Vq1={name:"@brains/obsidian-vault",private:!0,version:"0.2.0-alpha.119",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 LPQ={mkdir:zPQ,writeFile:qPQ,existsFile:NPQ},VPQ=H.object({entityTypes:H.array(H.string()).optional().describe("Entity types to generate templates for (default: all)")});class KmA extends YB{deps;constructor(A={},Q={}){super("obsidian-vault",Vq1,A,GmA);this.deps={...LPQ,...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[oQ(this.id,"sync-templates","Generate Obsidian templates, Metadata Menu fileClass definitions, and Bases views for all registered entity types.",VPQ,async(Q)=>{return this.sync(A,Q.entityTypes)})]}async sync(A,Q){try{let B=A.entityService.getEntityTypes(),w=Q?B.filter((V)=>Q.includes(V)):B,$=dF(A.dataDir,this.config.baseFolder),f=dF($,"templates"),I=dF($,"fileClasses"),D=dF($,"bases");this.deps.mkdir(f,{recursive:!0}),this.deps.mkdir(I,{recursive:!0}),this.deps.mkdir(D,{recursive:!0});let U=[],Y=[],J=[],X=[],G=[],Z=[];for(let V of w){let M=A.entities.getEffectiveFrontmatterSchema(V);if(!M){this.logger.debug(`Skipping ${V}: no frontmatter schema`),Y.push(V);continue}let O=Fq1(M),E=A.entities.getAdapter(V),S=E?.isSingleton===!0,y=Nq1(V,O);if(this.deps.writeFile(dF(I,`${V}.md`),y),J.push(V),S){G.push(V),this.logger.debug(`Generated fileClass (singleton): ${V}`);continue}let T=E?.getBodyTemplate()??"",_=Zq1(V,O,T);this.deps.writeFile(dF(f,`${V}.md`),_),U.push(V);let x=zq1(V,O),g=dF(D,x.filename);if(!this.deps.existsFile(g))this.deps.writeFile(g,x.content),X.push(V),this.logger.debug(`Generated base: ${x.filename}`);if(x.hasStatus)Z.push({entityType:V,fields:O});this.logger.debug(`Generated template + fileClass: ${V}`)}let N=qq1(G);if(N){let V=dF(D,"Settings.base");if(!this.deps.existsFile(V))this.deps.writeFile(V,N),X.push("Settings"),this.logger.debug("Generated Settings.base")}let L=Lq1(Z);if(L){let V=dF(D,"Pipeline.base");if(!this.deps.existsFile(V))this.deps.writeFile(V,L),X.push("Pipeline"),this.logger.debug("Generated Pipeline.base")}return this.logger.info(`Synced ${U.length} templates, ${J.length} fileClasses, ${X.length} bases (${Y.length} skipped)`),U8({generated:U,skipped:Y,fileClasses:J,bases:X})}catch(B){return this.logger.error("Failed to sync",{error:B}),X$(B instanceof Error?B.message:"Unknown error")}}}function FmA(A,Q){return new KmA(A,Q)}aA();WA();aA();var ZmA=H.enum(["new","planned","in-progress","done","declined"]),NmA=H.enum(["low","medium","high","critical"]),Ar=H.object({title:H.string(),status:ZmA,priority:NmA.default("medium"),requested:H.number().int().default(1),declinedReason:H.string().optional()}),Eq1=H.object({title:H.string(),status:ZmA,priority:NmA,requested:H.number().int(),slug:H.string()}),Qr=A2.extend({entityType:H.literal("wish"),metadata:Eq1}),zmA=H.object({});aA();WA();class Br extends q2{constructor(){super({entityType:"wish",schema:Qr,frontmatterSchema:Ar})}createWishContent(A,Q){return this.buildMarkdown(Q,A)}parseWishContent(A){let Q=this.parseFrontMatter(A,Ar);return{frontmatter:Ar.parse(Q),description:this.extractBody(A).trim()}}fromMarkdown(A){let{frontmatter:Q}=this.parseWishContent(A),B=X1(Q.title);return{content:A,entityType:"wish",metadata:{title:Q.title,status:Q.status,priority:Q.priority,requested:Q.requested,slug:B}}}}var qmA=new Br;WA();WA();async function Mq1(A,Q){let B=`${Q.title}: ${Q.description}`,$=(await A.search({query:B,options:{types:["wish"],limit:1}}))[0];if($&&$.score>=A.similarityThreshold)return $.entity;let f=X1(Q.title);return A.getEntity({entityType:"wish",id:f})}class i$A{logger;context;adapter=new Br;constructor(A,Q){this.logger=A;this.context=Q}async process(A,Q,B){let w=A.title??A.prompt??"Untitled wish",$=A.content??A.prompt??"",f=await Mq1({search:(Y)=>this.context.entityService.search(Y),getEntity:(Y)=>this.context.entityService.getEntity(Y),similarityThreshold:0.85},{title:w,description:$});if(f){let{frontmatter:Y,description:J}=this.adapter.parseWishContent(f.content),X=Y.requested+1,G=this.adapter.createWishContent({...Y,requested:X},J);return await this.context.entityService.updateEntity({entity:{...f,content:G,metadata:{...f.metadata,requested:X}}}),this.logger.info("Incremented wish request count",{id:f.id,requested:X}),{success:!0,entityId:f.id,existed:!0,requested:X}}let I=X1(w),D=A.options?.priority??"medium",U=this.adapter.createWishContent({title:w,status:"new",priority:D,requested:1},$);return await this.context.entityService.createEntity({entity:{id:I,entityType:"wish",content:U,metadata:{title:w,status:"new",priority:D,requested:1,slug:I}}}),this.logger.info("Created new wish",{id:I,title:w}),{success:!0,entityId:I,existed:!1,requested:1}}}var Cq1={critical:0,high:1,medium:2,low:3};function Oq1(A){A.sort((Q,B)=>{let w=B.metadata.requested-Q.metadata.requested;if(w!==0)return w;return Cq1[Q.metadata.priority]-Cq1[B.metadata.priority]})}var Rq1={name:"@brains/wishlist",private:!0,version:"0.2.0-alpha.119",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 bq1 extends jQ{entityType=qmA.entityType;schema=Qr;adapter=qmA;constructor(A={}){super("wishlist",Rq1,A,zmA)}async interceptCreate(A,Q,B){let w=await new i$A(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 Oq1(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 i$A(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 MPQ(A={}){return new bq1(A)}var r$A=MPQ;aA();WA();aA();var wr=H.object({title:H.string(),target:H.string()}),Pq1=H.object({title:H.string(),target:H.string(),slug:H.string().optional()}),$r=A2.extend({entityType:H.literal("prompt"),metadata:Pq1});aA();WA();class LmA extends q2{constructor(){super({entityType:"prompt",schema:$r,frontmatterSchema:wr})}toMarkdown(A){let Q=this.extractBody(A.content),B=this.parseFrontMatter(A.content,wr);return this.buildMarkdown(Q,B)}fromMarkdown(A){let Q=this.parseFrontMatter(A,wr),B=X1(Q.target.replace(/:/g,"-"));return{content:A,entityType:"prompt",metadata:{title:Q.title,target:Q.target,slug:B}}}}var d$A=new LmA;var kq1={name:"@brains/prompt",private:!0,version:"0.2.0-alpha.119",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 VmA extends jQ{entityType=d$A.entityType;schema=$r;adapter=d$A;constructor(){super("prompt",kq1,{},void 0)}getEntityTypeConfig(){return{embeddable:!1}}}function zC(){return new VmA}aA();WA();class n$A{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(OPQ),total:$.total,totalPages:$.total_pages,page:Q.page}}async triggerDownload(A){try{await this.fetchFn(A,{headers:{Authorization:`Client-ID ${this.apiKey}`}})}catch{}}}function OPQ(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}}WA();var jq1={query:H.string().describe("Search terms for stock photos"),perPage:H.number().min(1).max(30).default(10).describe("Results per page (1-30)"),page:H.number().min(1).default(1).describe("Page number")},_q1={photoId:H.string().describe("Photo ID from search results"),downloadLocation:H.string().url().describe("Download tracking URL (required by provider ToS)"),photographerName:H.string().describe("Photographer name for attribution"),photographerUrl:H.string().url().describe("Photographer profile URL for attribution"),sourceUrl:H.string().url().describe("Photo page URL on provider"),imageUrl:H.string().url().describe("Image URL to download"),title:H.string().optional().describe("Image entity title"),alt:H.string().optional().describe("Alt text for the image"),targetEntityType:H.string().optional().describe("Entity type to set cover image on"),targetEntityId:H.string().optional().describe("Entity ID to set cover image on")};function vq1(A,Q){return[RPQ(A,Q),bPQ(A,Q)]}function RPQ(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:jq1,handler:async(B)=>{let w=H.object(jq1).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 bPQ(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:_q1,handler:async(B)=>{let w=H.object(_q1).safeParse(B);if(!w.success)return{success:!1,error:`Invalid input: ${w.error.message}`};let{photoId:$,downloadLocation:f,photographerName:I,photographerUrl:D,sourceUrl:U,imageUrl:Y,title:J,alt:X,targetEntityType:G,targetEntityId:Z}=w.data,N={photographerName:I,photographerUrl:D,sourceUrl:U},L=await Q.entityService.listEntities({entityType:"image",options:{limit:1,filter:{metadata:{sourceUrl:Y}}}});if(L[0]){let O={imageEntityId:L[0].id,alreadyExisted:!0,attribution:N};if(G&&Z)await PPQ(Q.entityService,G,Z,L[0].id),O.coverSet=!0;return{success:!0,data:O}}let V=await Q.jobs.enqueue({type:"select-photo",data:{photoId:$,downloadLocation:f,photographerName:I,photographerUrl:D,sourceUrl:U,imageUrl:Y,...J!==void 0?{title:J}:{},...X!==void 0?{alt:X}:{},...G!==void 0?{targetEntityType:G}:{},...Z!==void 0?{targetEntityId:Z}:{}}}),M={imageEntityId:$,alreadyExisted:!1,attribution:N,jobId:V,status:"generating"};if(G&&Z)M.coverSet=!0;return{success:!0,data:M}}}}async function PPQ(A,Q,B,w){let $=await A.getEntity({entityType:Q,id:B});if(!$)return;await A.updateEntity({entity:{...$,metadata:{...$.metadata,coverImageId:w}}})}aA();WA();E7();var kPQ=H.object({photoId:H.string(),downloadLocation:H.string().url(),photographerName:H.string(),photographerUrl:H.string().url(),sourceUrl:H.string().url(),imageUrl:H.string().url(),title:H.string().optional(),alt:H.string().optional(),targetEntityType:H.string().optional(),targetEntityId:H.string().optional()});class EmA extends ZB{deps;constructor(A,Q){super(A,{schema:kPQ,jobTypeName:"select-photo"});this.deps=Q}async process(A,Q,B){await this.reportProgress(B,{progress:10,message:"Tracking stock photo download"}),await this.deps.provider.triggerDownload(A.downloadLocation),await this.reportProgress(B,{progress:35,message:"Downloading stock photo"});let w=await this.deps.fetchImage(A.imageUrl),$=A.title??`Stock photo ${A.photoId}`,f=HU.createImageEntity({dataUrl:w,title:$,alt:A.alt??$});await this.reportProgress(B,{progress:75,message:"Saving stock photo"});let{entityId:I}=await this.deps.entityService.createEntity({entity:{id:A.photoId,...f,metadata:{...f.metadata,sourceUrl:A.imageUrl}}}),D={imageEntityId:I,alreadyExisted:!1};if(A.targetEntityType&&A.targetEntityId)await jPQ(this.deps.entityService,A.targetEntityType,A.targetEntityId,I),D.coverSet=!0;return await this.reportProgress(B,{progress:100,message:"Stock photo selected"}),D}summarizeDataForLog(A){return{photoId:A.photoId,hasTarget:A.targetEntityType!==void 0}}}async function jPQ(A,Q,B,w){let $=await A.getEntity({entityType:Q,id:B});if(!$)return;await A.updateEntity({entity:{...$,metadata:{...$.metadata,coverImageId:w}}})}E7();var Tq1={name:"@brains/stock-photo",private:!0,version:"0.2.0-alpha.119",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 vPQ=H.object({provider:H.enum(["unsplash"]).default("unsplash"),apiKey:H.string().optional().describe("Stock photo provider API key")});class MmA extends YB{deps;cachedTools=null;constructor(A={},Q={}){super("stock-photo",Tq1,A,vPQ);this.deps=Q}async getTools(){if(!this.config.apiKey)return[];if(this.cachedTools)return this.cachedTools;let A=this.getContext(),Q=this.createProvider();return this.cachedTools=vq1(this.id,{provider:Q,entityService:A.entityService,fetchImage:this.deps.fetchImage??WU,jobs:A.jobs}),this.cachedTools}async registerJobHandlers(){if(!this.config.apiKey)return;let A=this.getContext();A.jobs.registerHandler("select-photo",new EmA(this.logger.child("SelectPhotoJobHandler"),{provider:this.createProvider(),entityService:A.entityService,fetchImage:this.deps.fetchImage??WU}))}createProvider(){return new n$A(this.config.apiKey??"",this.deps.fetch??globalThis.fetch)}}function CmA(A={},Q={}){return new MmA(A,Q)}aA();WA();aA();aA();WA();var yq1=H.enum(["ai","foundation","work"]),xq1=H.object({suffix:yq1,title:H.string(),body:H.string(),linkLabel:H.string(),linkHref:H.string()}),fr=H.object({eyebrow:H.string(),headline:H.string(),cards:H.array(xq1).min(1)}),o$A=H.object({title:H.string(),slug:H.string(),status:H.enum(["draft","published"])}),Ir=A2.extend({entityType:H.literal("ecosystem-section"),metadata:o$A});class Sq1 extends q2{constructor(){super({entityType:"ecosystem-section",schema:Ir,frontmatterSchema:o$A})}fromMarkdown(A){return{content:A,entityType:"ecosystem-section",metadata:this.parseFrontmatter(A)}}}var OmA=new Sq1;WA();function TPQ(A){return A.replace(/^---\n[\s\S]*?\n---\n?/,"")}function RmA(A,Q){return new RegExp(`(?:^|\\n)## ${Q}\\s*\\n([\\s\\S]*?)(?=\\n## |$)`).exec(A)?.[1]?.trim()??""}function Dr(A,Q){return new RegExp(`(?:^|\\n)#### ${Q}\\s*\\n([\\s\\S]*?)(?=\\n#### |\\n### |$)`).exec(A)?.[1]?.trim()??""}function s$A(A){let Q=TPQ(A),w=RmA(Q,"Cards").split(/^### Card \d+\s*$/m).map(($)=>$.trim()).filter(Boolean);return fr.parse({eyebrow:RmA(Q,"Eyebrow"),headline:RmA(Q,"Headline"),cards:w.map(($)=>({suffix:Dr($,"Suffix"),title:Dr($,"Title"),body:Dr($,"Body"),linkLabel:Dr($,"Link Label"),linkHref:Dr($,"Link Href")}))})}function gq1(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(`
|
|
8178
|
+
`}WA();var WPQ=new Set(["entityType"]),HPQ={base:"Notes"},GPQ=new Set(["base"]);function KPQ(A){let Q=["file.name"];for(let B of A)if(!WPQ.has(B.name))Q.push(B.name);return Q}function FPQ(A){return A.some((Q)=>Q.name==="status"&&Q.type==="enum")}function zq1(A,Q){let B=HPQ[A]??sn(A),w=FPQ(Q),$=KPQ(Q),f=[{type:"table",name:`All ${B}`,order:$}];if(w)f.push({type:"table",name:"By Status",groupBy:{property:"status",direction:"ASC"},order:$});let D={filters:{and:[GPQ.has(A)?'file.folder == "/"':`file.inFolder("${A}")`]},views:f};return{filename:`${B}.base`,content:cX(D),hasStatus:w}}function qq1(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 cX(B)}function Lq1(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 cX(B)}var Vq1={name:"@brains/obsidian-vault",private:!0,version:"0.2.0-alpha.120",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 LPQ={mkdir:zPQ,writeFile:qPQ,existsFile:NPQ},VPQ=H.object({entityTypes:H.array(H.string()).optional().describe("Entity types to generate templates for (default: all)")});class KmA extends YB{deps;constructor(A={},Q={}){super("obsidian-vault",Vq1,A,GmA);this.deps={...LPQ,...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[oQ(this.id,"sync-templates","Generate Obsidian templates, Metadata Menu fileClass definitions, and Bases views for all registered entity types.",VPQ,async(Q)=>{return this.sync(A,Q.entityTypes)})]}async sync(A,Q){try{let B=A.entityService.getEntityTypes(),w=Q?B.filter((V)=>Q.includes(V)):B,$=dF(A.dataDir,this.config.baseFolder),f=dF($,"templates"),I=dF($,"fileClasses"),D=dF($,"bases");this.deps.mkdir(f,{recursive:!0}),this.deps.mkdir(I,{recursive:!0}),this.deps.mkdir(D,{recursive:!0});let U=[],Y=[],J=[],X=[],G=[],Z=[];for(let V of w){let M=A.entities.getEffectiveFrontmatterSchema(V);if(!M){this.logger.debug(`Skipping ${V}: no frontmatter schema`),Y.push(V);continue}let O=Fq1(M),E=A.entities.getAdapter(V),S=E?.isSingleton===!0,y=Nq1(V,O);if(this.deps.writeFile(dF(I,`${V}.md`),y),J.push(V),S){G.push(V),this.logger.debug(`Generated fileClass (singleton): ${V}`);continue}let T=E?.getBodyTemplate()??"",_=Zq1(V,O,T);this.deps.writeFile(dF(f,`${V}.md`),_),U.push(V);let x=zq1(V,O),g=dF(D,x.filename);if(!this.deps.existsFile(g))this.deps.writeFile(g,x.content),X.push(V),this.logger.debug(`Generated base: ${x.filename}`);if(x.hasStatus)Z.push({entityType:V,fields:O});this.logger.debug(`Generated template + fileClass: ${V}`)}let N=qq1(G);if(N){let V=dF(D,"Settings.base");if(!this.deps.existsFile(V))this.deps.writeFile(V,N),X.push("Settings"),this.logger.debug("Generated Settings.base")}let L=Lq1(Z);if(L){let V=dF(D,"Pipeline.base");if(!this.deps.existsFile(V))this.deps.writeFile(V,L),X.push("Pipeline"),this.logger.debug("Generated Pipeline.base")}return this.logger.info(`Synced ${U.length} templates, ${J.length} fileClasses, ${X.length} bases (${Y.length} skipped)`),U8({generated:U,skipped:Y,fileClasses:J,bases:X})}catch(B){return this.logger.error("Failed to sync",{error:B}),X$(B instanceof Error?B.message:"Unknown error")}}}function FmA(A,Q){return new KmA(A,Q)}aA();WA();aA();var ZmA=H.enum(["new","planned","in-progress","done","declined"]),NmA=H.enum(["low","medium","high","critical"]),Ar=H.object({title:H.string(),status:ZmA,priority:NmA.default("medium"),requested:H.number().int().default(1),declinedReason:H.string().optional()}),Eq1=H.object({title:H.string(),status:ZmA,priority:NmA,requested:H.number().int(),slug:H.string()}),Qr=A2.extend({entityType:H.literal("wish"),metadata:Eq1}),zmA=H.object({});aA();WA();class Br extends q2{constructor(){super({entityType:"wish",schema:Qr,frontmatterSchema:Ar})}createWishContent(A,Q){return this.buildMarkdown(Q,A)}parseWishContent(A){let Q=this.parseFrontMatter(A,Ar);return{frontmatter:Ar.parse(Q),description:this.extractBody(A).trim()}}fromMarkdown(A){let{frontmatter:Q}=this.parseWishContent(A),B=X1(Q.title);return{content:A,entityType:"wish",metadata:{title:Q.title,status:Q.status,priority:Q.priority,requested:Q.requested,slug:B}}}}var qmA=new Br;WA();WA();async function Mq1(A,Q){let B=`${Q.title}: ${Q.description}`,$=(await A.search({query:B,options:{types:["wish"],limit:1}}))[0];if($&&$.score>=A.similarityThreshold)return $.entity;let f=X1(Q.title);return A.getEntity({entityType:"wish",id:f})}class i$A{logger;context;adapter=new Br;constructor(A,Q){this.logger=A;this.context=Q}async process(A,Q,B){let w=A.title??A.prompt??"Untitled wish",$=A.content??A.prompt??"",f=await Mq1({search:(Y)=>this.context.entityService.search(Y),getEntity:(Y)=>this.context.entityService.getEntity(Y),similarityThreshold:0.85},{title:w,description:$});if(f){let{frontmatter:Y,description:J}=this.adapter.parseWishContent(f.content),X=Y.requested+1,G=this.adapter.createWishContent({...Y,requested:X},J);return await this.context.entityService.updateEntity({entity:{...f,content:G,metadata:{...f.metadata,requested:X}}}),this.logger.info("Incremented wish request count",{id:f.id,requested:X}),{success:!0,entityId:f.id,existed:!0,requested:X}}let I=X1(w),D=A.options?.priority??"medium",U=this.adapter.createWishContent({title:w,status:"new",priority:D,requested:1},$);return await this.context.entityService.createEntity({entity:{id:I,entityType:"wish",content:U,metadata:{title:w,status:"new",priority:D,requested:1,slug:I}}}),this.logger.info("Created new wish",{id:I,title:w}),{success:!0,entityId:I,existed:!1,requested:1}}}var Cq1={critical:0,high:1,medium:2,low:3};function Oq1(A){A.sort((Q,B)=>{let w=B.metadata.requested-Q.metadata.requested;if(w!==0)return w;return Cq1[Q.metadata.priority]-Cq1[B.metadata.priority]})}var Rq1={name:"@brains/wishlist",private:!0,version:"0.2.0-alpha.120",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 bq1 extends jQ{entityType=qmA.entityType;schema=Qr;adapter=qmA;constructor(A={}){super("wishlist",Rq1,A,zmA)}async interceptCreate(A,Q,B){let w=await new i$A(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 Oq1(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 i$A(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 MPQ(A={}){return new bq1(A)}var r$A=MPQ;aA();WA();aA();var wr=H.object({title:H.string(),target:H.string()}),Pq1=H.object({title:H.string(),target:H.string(),slug:H.string().optional()}),$r=A2.extend({entityType:H.literal("prompt"),metadata:Pq1});aA();WA();class LmA extends q2{constructor(){super({entityType:"prompt",schema:$r,frontmatterSchema:wr})}toMarkdown(A){let Q=this.extractBody(A.content),B=this.parseFrontMatter(A.content,wr);return this.buildMarkdown(Q,B)}fromMarkdown(A){let Q=this.parseFrontMatter(A,wr),B=X1(Q.target.replace(/:/g,"-"));return{content:A,entityType:"prompt",metadata:{title:Q.title,target:Q.target,slug:B}}}}var d$A=new LmA;var kq1={name:"@brains/prompt",private:!0,version:"0.2.0-alpha.120",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 VmA extends jQ{entityType=d$A.entityType;schema=$r;adapter=d$A;constructor(){super("prompt",kq1,{},void 0)}getEntityTypeConfig(){return{embeddable:!1}}}function zC(){return new VmA}aA();WA();class n$A{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(OPQ),total:$.total,totalPages:$.total_pages,page:Q.page}}async triggerDownload(A){try{await this.fetchFn(A,{headers:{Authorization:`Client-ID ${this.apiKey}`}})}catch{}}}function OPQ(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}}WA();var jq1={query:H.string().describe("Search terms for stock photos"),perPage:H.number().min(1).max(30).default(10).describe("Results per page (1-30)"),page:H.number().min(1).default(1).describe("Page number")},_q1={photoId:H.string().describe("Photo ID from search results"),downloadLocation:H.string().url().describe("Download tracking URL (required by provider ToS)"),photographerName:H.string().describe("Photographer name for attribution"),photographerUrl:H.string().url().describe("Photographer profile URL for attribution"),sourceUrl:H.string().url().describe("Photo page URL on provider"),imageUrl:H.string().url().describe("Image URL to download"),title:H.string().optional().describe("Image entity title"),alt:H.string().optional().describe("Alt text for the image"),targetEntityType:H.string().optional().describe("Entity type to set cover image on"),targetEntityId:H.string().optional().describe("Entity ID to set cover image on")};function vq1(A,Q){return[RPQ(A,Q),bPQ(A,Q)]}function RPQ(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:jq1,handler:async(B)=>{let w=H.object(jq1).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 bPQ(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:_q1,handler:async(B)=>{let w=H.object(_q1).safeParse(B);if(!w.success)return{success:!1,error:`Invalid input: ${w.error.message}`};let{photoId:$,downloadLocation:f,photographerName:I,photographerUrl:D,sourceUrl:U,imageUrl:Y,title:J,alt:X,targetEntityType:G,targetEntityId:Z}=w.data,N={photographerName:I,photographerUrl:D,sourceUrl:U},L=await Q.entityService.listEntities({entityType:"image",options:{limit:1,filter:{metadata:{sourceUrl:Y}}}});if(L[0]){let O={imageEntityId:L[0].id,alreadyExisted:!0,attribution:N};if(G&&Z)await PPQ(Q.entityService,G,Z,L[0].id),O.coverSet=!0;return{success:!0,data:O}}let V=await Q.jobs.enqueue({type:"select-photo",data:{photoId:$,downloadLocation:f,photographerName:I,photographerUrl:D,sourceUrl:U,imageUrl:Y,...J!==void 0?{title:J}:{},...X!==void 0?{alt:X}:{},...G!==void 0?{targetEntityType:G}:{},...Z!==void 0?{targetEntityId:Z}:{}}}),M={imageEntityId:$,alreadyExisted:!1,attribution:N,jobId:V,status:"generating"};if(G&&Z)M.coverSet=!0;return{success:!0,data:M}}}}async function PPQ(A,Q,B,w){let $=await A.getEntity({entityType:Q,id:B});if(!$)return;await A.updateEntity({entity:{...$,metadata:{...$.metadata,coverImageId:w}}})}aA();WA();E7();var kPQ=H.object({photoId:H.string(),downloadLocation:H.string().url(),photographerName:H.string(),photographerUrl:H.string().url(),sourceUrl:H.string().url(),imageUrl:H.string().url(),title:H.string().optional(),alt:H.string().optional(),targetEntityType:H.string().optional(),targetEntityId:H.string().optional()});class EmA extends ZB{deps;constructor(A,Q){super(A,{schema:kPQ,jobTypeName:"select-photo"});this.deps=Q}async process(A,Q,B){await this.reportProgress(B,{progress:10,message:"Tracking stock photo download"}),await this.deps.provider.triggerDownload(A.downloadLocation),await this.reportProgress(B,{progress:35,message:"Downloading stock photo"});let w=await this.deps.fetchImage(A.imageUrl),$=A.title??`Stock photo ${A.photoId}`,f=HU.createImageEntity({dataUrl:w,title:$,alt:A.alt??$});await this.reportProgress(B,{progress:75,message:"Saving stock photo"});let{entityId:I}=await this.deps.entityService.createEntity({entity:{id:A.photoId,...f,metadata:{...f.metadata,sourceUrl:A.imageUrl}}}),D={imageEntityId:I,alreadyExisted:!1};if(A.targetEntityType&&A.targetEntityId)await jPQ(this.deps.entityService,A.targetEntityType,A.targetEntityId,I),D.coverSet=!0;return await this.reportProgress(B,{progress:100,message:"Stock photo selected"}),D}summarizeDataForLog(A){return{photoId:A.photoId,hasTarget:A.targetEntityType!==void 0}}}async function jPQ(A,Q,B,w){let $=await A.getEntity({entityType:Q,id:B});if(!$)return;await A.updateEntity({entity:{...$,metadata:{...$.metadata,coverImageId:w}}})}E7();var Tq1={name:"@brains/stock-photo",private:!0,version:"0.2.0-alpha.120",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 vPQ=H.object({provider:H.enum(["unsplash"]).default("unsplash"),apiKey:H.string().optional().describe("Stock photo provider API key")});class MmA extends YB{deps;cachedTools=null;constructor(A={},Q={}){super("stock-photo",Tq1,A,vPQ);this.deps=Q}async getTools(){if(!this.config.apiKey)return[];if(this.cachedTools)return this.cachedTools;let A=this.getContext(),Q=this.createProvider();return this.cachedTools=vq1(this.id,{provider:Q,entityService:A.entityService,fetchImage:this.deps.fetchImage??WU,jobs:A.jobs}),this.cachedTools}async registerJobHandlers(){if(!this.config.apiKey)return;let A=this.getContext();A.jobs.registerHandler("select-photo",new EmA(this.logger.child("SelectPhotoJobHandler"),{provider:this.createProvider(),entityService:A.entityService,fetchImage:this.deps.fetchImage??WU}))}createProvider(){return new n$A(this.config.apiKey??"",this.deps.fetch??globalThis.fetch)}}function CmA(A={},Q={}){return new MmA(A,Q)}aA();WA();aA();aA();WA();var yq1=H.enum(["ai","foundation","work"]),xq1=H.object({suffix:yq1,title:H.string(),body:H.string(),linkLabel:H.string(),linkHref:H.string()}),fr=H.object({eyebrow:H.string(),headline:H.string(),cards:H.array(xq1).min(1)}),o$A=H.object({title:H.string(),slug:H.string(),status:H.enum(["draft","published"])}),Ir=A2.extend({entityType:H.literal("ecosystem-section"),metadata:o$A});class Sq1 extends q2{constructor(){super({entityType:"ecosystem-section",schema:Ir,frontmatterSchema:o$A})}fromMarkdown(A){return{content:A,entityType:"ecosystem-section",metadata:this.parseFrontmatter(A)}}}var OmA=new Sq1;WA();function TPQ(A){return A.replace(/^---\n[\s\S]*?\n---\n?/,"")}function RmA(A,Q){return new RegExp(`(?:^|\\n)## ${Q}\\s*\\n([\\s\\S]*?)(?=\\n## |$)`).exec(A)?.[1]?.trim()??""}function Dr(A,Q){return new RegExp(`(?:^|\\n)#### ${Q}\\s*\\n([\\s\\S]*?)(?=\\n#### |\\n### |$)`).exec(A)?.[1]?.trim()??""}function s$A(A){let Q=TPQ(A),w=RmA(Q,"Cards").split(/^### Card \d+\s*$/m).map(($)=>$.trim()).filter(Boolean);return fr.parse({eyebrow:RmA(Q,"Eyebrow"),headline:RmA(Q,"Headline"),cards:w.map(($)=>({suffix:Dr($,"Suffix"),title:Dr($,"Title"),body:Dr($,"Body"),linkLabel:Dr($,"Link Label"),linkHref:Dr($,"Link Href")}))})}function gq1(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(`
|
|
8179
8179
|
`)}var yPQ=H.object({query:H.object({id:H.string().optional()}).optional()}).passthrough();class a$A{id="rizom-ecosystem:entities";name="Rizom Ecosystem";description="Fetches an ecosystem-section entity for rendering";async fetch(A,Q,B){let $=yPQ.parse(A??{}).query?.id??"rizom-ecosystem",f=await B.entityService.getEntity({entityType:"ecosystem-section",id:$});if(!f)throw Error(`Ecosystem section not found: ${$}`);return Q.parse(s$A(f.content))}}aA();var xPQ=EwA({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 SH(...A){return xPQ(W_(A))}import{jsxDEV as Y58}from"preact/jsx-dev-runtime";import{jsxDEV as H58}from"preact/jsx-dev-runtime";import{jsxDEV as Z58}from"preact/jsx-dev-runtime";import{jsxDEV as gPQ}from"preact/jsx-dev-runtime";var bmA="px-6 md:px-10 xl:px-20",SPQ=`${bmA} relative z-[1]`,PmA=({id:A,className:Q,children:B})=>gPQ("section",{id:A,className:SH(SPQ,Q),children:B},void 0,!1,void 0,this);import{jsxDEV as t$A}from"preact/jsx-dev-runtime";var hPQ=new Map([["work","text-accent"],["foundation","text-secondary"],["ai","text-accent-bright"]]),Ur=({name:A="rizom",brandSuffix:Q,className:B,dotClassName:w,suffixClassName:$})=>{let f=hPQ.get(Q);return t$A("span",{className:SH("inline-flex items-baseline gap-0 font-display font-medium tracking-[-0.015em] [font-variation-settings:'opsz'_24]",B),children:[t$A("span",{className:"text-theme",children:A},void 0,!1,void 0,this),t$A("span",{className:SH(f??"text-accent",w),children:"."},void 0,!1,void 0,this),t$A("span",{className:SH("italic font-normal text-theme-muted",$),children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as P58}from"preact/jsx-dev-runtime";import{jsxDEV as v58}from"preact/jsx-dev-runtime";import{jsxDEV as S58,Fragment as x58}from"preact/jsx-dev-runtime";import{jsxDEV as m58}from"preact/jsx-dev-runtime";import{Fragment as kmA}from"preact";import{jsxDEV as Yr}from"preact/jsx-dev-runtime";var mPQ=/(\*[^*]+\*)/;function jmA(A,Q){let B=A.split(`
|
|
8180
|
-
`);return Yr(kmA,{children:B.map((w,$)=>Yr(kmA,{children:[$>0&&Yr("br",{},void 0,!1,void 0,this),w.split(mPQ).map((f,I)=>{if(f.length>=3&&f.startsWith("*")&&f.endsWith("*"))return Yr("span",{className:Q,children:f.slice(1,-1)},I,!1,void 0,this);return Yr(kmA,{children:f},I,!1,void 0,this)})]},$,!0,void 0,this))},void 0,!1,void 0,this)}import{jsxDEV as rf,Fragment as aPQ}from"preact/jsx-dev-runtime";var uPQ="italic text-accent font-normal",cPQ="You are here",lPQ={work:"text-accent",foundation:"text-secondary",ai:"text-accent-bright"},pPQ={work:"border-t-accent/60",foundation:"border-t-secondary/60",ai:"border-t-accent-bright/60"},iPQ={work:"hover:border-t-accent",foundation:"hover:border-t-secondary",ai:"hover:border-t-accent-bright"},rPQ="font-label text-[10.5px] uppercase tracking-[0.26em] mt-1",dPQ="font-body text-[15px] leading-[1.6] text-theme-muted mt-2",nPQ="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",oPQ="font-label text-[10.5px] uppercase tracking-[0.22em] text-accent self-start mt-[18px] pb-1",sPQ=({card:A})=>{let Q=A.linkLabel===cPQ,B=A.linkHref.trim().length===0,w=rf(aPQ,{children:[rf(Ur,{brandSuffix:A.suffix,className:"text-[clamp(28px,3vw,40px)] [font-variation-settings:'opsz'_96]"},void 0,!1,void 0,this),rf("span",{className:`${rPQ} ${lPQ[A.suffix]}`,children:A.title},void 0,!1,void 0,this),rf("p",{className:dPQ,children:A.body},void 0,!1,void 0,this),Q?rf("span",{className:oPQ,children:A.linkLabel},void 0,!1,void 0,this):rf("span",{className:nPQ,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?pPQ[A.suffix]:"border-white/10"}`;return Q||B?rf("div",{className:$,children:w},void 0,!1,void 0,this):rf("a",{href:A.linkHref,className:`${$} text-inherit no-underline transition-colors ${iPQ[A.suffix]}`,children:w},void 0,!1,void 0,this)},_mA=({eyebrow:A,headline:Q,cards:B})=>rf(PmA,{id:"ecosystem",className:"pt-[112px] pb-[144px] border-t border-white/5",children:[rf("div",{className:"mx-auto mb-[88px] max-w-[1180px] text-center",children:[rf("span",{className:"font-label text-[11px] font-semibold uppercase tracking-[0.24em] text-accent",children:A},void 0,!1,void 0,this),rf("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:jmA(Q,uPQ)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),rf("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)=>rf(sPQ,{card:w},w.suffix,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this);var tPQ=[{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 hq1(A){return{eyebrow:"The Ecosystem",headline:"One practice. *Three faces.*",cards:tPQ.map((Q)=>Q.suffix===A?{...Q,linkLabel:"You are here",linkHref:""}:Q)}}var ePQ=hq1();var vmA=P1({name:"ecosystem",description:"Rizom ecosystem sibling-site section",schema:fr,formatter:{parse:s$A,format:gq1},dataSourceId:"rizom-ecosystem:entities",requiredPermission:"public",layout:{component:_mA}});var mq1={name:"@brains/rizom-ecosystem",private:!0,version:"0.2.0-alpha.
|
|
8180
|
+
`);return Yr(kmA,{children:B.map((w,$)=>Yr(kmA,{children:[$>0&&Yr("br",{},void 0,!1,void 0,this),w.split(mPQ).map((f,I)=>{if(f.length>=3&&f.startsWith("*")&&f.endsWith("*"))return Yr("span",{className:Q,children:f.slice(1,-1)},I,!1,void 0,this);return Yr(kmA,{children:f},I,!1,void 0,this)})]},$,!0,void 0,this))},void 0,!1,void 0,this)}import{jsxDEV as rf,Fragment as aPQ}from"preact/jsx-dev-runtime";var uPQ="italic text-accent font-normal",cPQ="You are here",lPQ={work:"text-accent",foundation:"text-secondary",ai:"text-accent-bright"},pPQ={work:"border-t-accent/60",foundation:"border-t-secondary/60",ai:"border-t-accent-bright/60"},iPQ={work:"hover:border-t-accent",foundation:"hover:border-t-secondary",ai:"hover:border-t-accent-bright"},rPQ="font-label text-[10.5px] uppercase tracking-[0.26em] mt-1",dPQ="font-body text-[15px] leading-[1.6] text-theme-muted mt-2",nPQ="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",oPQ="font-label text-[10.5px] uppercase tracking-[0.22em] text-accent self-start mt-[18px] pb-1",sPQ=({card:A})=>{let Q=A.linkLabel===cPQ,B=A.linkHref.trim().length===0,w=rf(aPQ,{children:[rf(Ur,{brandSuffix:A.suffix,className:"text-[clamp(28px,3vw,40px)] [font-variation-settings:'opsz'_96]"},void 0,!1,void 0,this),rf("span",{className:`${rPQ} ${lPQ[A.suffix]}`,children:A.title},void 0,!1,void 0,this),rf("p",{className:dPQ,children:A.body},void 0,!1,void 0,this),Q?rf("span",{className:oPQ,children:A.linkLabel},void 0,!1,void 0,this):rf("span",{className:nPQ,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?pPQ[A.suffix]:"border-white/10"}`;return Q||B?rf("div",{className:$,children:w},void 0,!1,void 0,this):rf("a",{href:A.linkHref,className:`${$} text-inherit no-underline transition-colors ${iPQ[A.suffix]}`,children:w},void 0,!1,void 0,this)},_mA=({eyebrow:A,headline:Q,cards:B})=>rf(PmA,{id:"ecosystem",className:"pt-[112px] pb-[144px] border-t border-white/5",children:[rf("div",{className:"mx-auto mb-[88px] max-w-[1180px] text-center",children:[rf("span",{className:"font-label text-[11px] font-semibold uppercase tracking-[0.24em] text-accent",children:A},void 0,!1,void 0,this),rf("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:jmA(Q,uPQ)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),rf("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)=>rf(sPQ,{card:w},w.suffix,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this);var tPQ=[{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 hq1(A){return{eyebrow:"The Ecosystem",headline:"One practice. *Three faces.*",cards:tPQ.map((Q)=>Q.suffix===A?{...Q,linkLabel:"You are here",linkHref:""}:Q)}}var ePQ=hq1();var vmA=P1({name:"ecosystem",description:"Rizom ecosystem sibling-site section",schema:fr,formatter:{parse:s$A,format:gq1},dataSourceId:"rizom-ecosystem:entities",requiredPermission:"public",layout:{component:_mA}});var mq1={name:"@brains/rizom-ecosystem",private:!0,version:"0.2.0-alpha.120",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 TmA extends jQ{entityType="ecosystem-section";schema=Ir;adapter=OmA;constructor(A={}){super("rizom-ecosystem",mq1,A,H.object({}).default({}))}getTemplates(){return{ecosystem:vmA}}getDataSources(){return[new a$A]}}function qC(A={}){return new TmA(A)}WA();aA();aA();WA();o$();WA();aA();var a9="agent",uq1="agent-discovery",cq1="agent:generation",lq1="agent-network",pq1="AgentNetworkWidget",Jr="agent-discovery:entities",ymA="agent-list",xmA="agent-detail",o6="skill",iq1="skill",e$A="skill-derivation",rq1="skill:project",dq1="skill-derivation",nq1="skill:skill-derivation",oq1="skills";var mv=H.object({name:H.string(),description:H.string(),tags:H.array(H.string())}),aU=H.enum(["discovered","approved"]).describe("Discovered for review or approved for calling"),JX=lY.pick({name:!0,kind:!0,organization:!0}).extend({brainName:H.string().describe("Name of the brain instance"),url:H.string().url().describe("Brain endpoint URL"),did:H.string().optional().describe("Decentralized identifier (public)"),repoDid:H.string().optional().describe("ATProto repo DID"),brainDid:H.string().optional().describe("ATProto brain DID"),anchorDid:H.string().optional().describe("ATProto anchor DID"),cardUri:H.string().optional().describe("ATProto brain card URI"),cardCid:H.string().optional().describe("ATProto brain card CID"),a2aEndpoint:H.string().url().optional().describe("A2A endpoint URL"),status:aU,discoveredAt:H.string().datetime().describe("When this agent was first discovered")}),sq1=JX.pick({name:!0,url:!0,status:!0}).extend({discoveredAt:H.string().datetime().optional(),slug:H.string(),repoDid:H.string().optional(),brainDid:H.string().optional(),anchorDid:H.string().optional(),cardUri:H.string().optional(),cardCid:H.string().optional(),a2aEndpoint:H.string().url().optional()}),uv=A2.extend({entityType:H.literal(a9),metadata:sq1}),Xr=uv.extend({frontmatter:JX,about:H.string(),skills:H.array(mv),notes:H.string()}),cv=Xr.extend({url:H.string().optional(),typeLabel:H.string().optional()}),QkQ=Xr.extend({url:H.string(),typeLabel:H.string()});WA();var BkQ=H.array(mv);function aq1(A){let Q=BkQ.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(`
|
|
8181
8181
|
`)}function tq1(A){if(!A.trim())return[];let Q=[];for(let B of A.split(`
|
|
8182
8182
|
`)){let w=B.match(/^- (.+?): (.+?)(?:\s+\[(.+?)\])?$/);if(!w)continue;let $=w[1]??"",f=w[2]??"",I=w[3],D=I?I.split(",").map((U)=>U.trim()).filter(Boolean):[];Q.push({name:$,description:f,tags:D})}return Q}var wkQ=H.object({about:H.string(),skills:H.array(mv),notes:H.string()}),eq1=new lB(wkQ,{title:"Agent",mappings:[{key:"about",label:"About",type:"string"},{key:"skills",label:"Skills",type:"custom",formatter:aq1,parser:tq1},{key:"notes",label:"Notes",type:"string"}]});class df extends q2{constructor(){super({entityType:a9,schema:uv,frontmatterSchema:JX})}fromMarkdown(A){let Q=this.parseFrontMatter(A,JX),B=tZ(Q.url);return{content:A,entityType:a9,metadata:{name:Q.name,url:Q.url,status:Q.status,discoveredAt:Q.discoveredAt,slug:B,...Q.repoDid&&{repoDid:Q.repoDid},...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},...Q.cardUri&&{cardUri:Q.cardUri},...Q.cardCid&&{cardCid:Q.cardCid},...Q.a2aEndpoint&&{a2aEndpoint:Q.a2aEndpoint}}}}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},...A.repoDid&&{repoDid:A.repoDid},...A.brainDid&&{brainDid:A.brainDid},...A.anchorDid&&{anchorDid:A.anchorDid},...A.cardUri&&{cardUri:A.cardUri},...A.cardCid&&{cardCid:A.cardCid},...A.a2aEndpoint&&{a2aEndpoint:A.a2aEndpoint},status:aU.parse(A.status),discoveredAt:A.discoveredAt},B=eq1.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=eq1.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,JX),body:this.parseAgentContent(A.content)}}}aA();var $kQ=new df,fkQ=QW.extend({status:aU.optional()}),IkQ=BW.extend({query:fkQ.optional()});function DkQ(A){let Q=R2(A.content,JX),B=$kQ.parseAgentContent(A.content);return Xr.parse({...A,frontmatter:Q.metadata,about:B.about,skills:B.skills,notes:B.notes})}class A9A extends m5{id=Jr;name="Agent Directory DataSource";description="Fetches and transforms agent entities for rendering";config={entityType:a9,defaultSort:[{field:"discoveredAt",direction:"desc"}],defaultLimit:50,lookupField:"slug",enableNavigation:!0};constructor(A){super(A)}transformEntity(A){return DkQ(A)}buildDetailResult(A,Q){return{agent:A,prevAgent:Q?.prev??null,nextAgent:Q?.next??null}}parseQuery(A){let Q=IkQ.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}buildListResult(A,Q,B){let w=aU.safeParse(B.status);return{agents:A,pagination:Q,baseUrl:B.baseUrl,selectedStatus:w.success?w.data:"all"}}async fetch(A,Q,B){let{query:w}=this.parseQuery(A);if(w.id)return super.fetch(A,Q,B);let{items:$,pagination:f}=await this.fetchList(w,B.entityService,w.status?{filter:{metadata:{status:w.status}}}:void 0);return Q.parse(this.buildListResult($,f,w))}}aA();WA();H6();aA();async function AL1(A,Q){let w=`${(A.startsWith("http")?A:`https://${A}`).replace(/\/$/,"")}/.well-known/agent-card.json`;try{let $=await Q(w);if(!$.ok)return null;let f=await $.json();return xx(f)}catch{return null}}function Q9A(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""}WA();var UkQ=new df;function QL1(A){return A.trim().toLowerCase().replace(/[_\s]+/g,"-")}function tz(A){let Q=new Set,B=[];for(let w of A){let $=QL1(w);if(!$||Q.has($))continue;Q.add($),B.push($)}return B}function YkQ(A,Q){if(Q.count!==A.count)return Q.count-A.count;return A.tag.localeCompare(Q.tag)}async function BL1(A,Q={}){let B=Q.minCount??1,w=Q.topN??12,$=Q.visibilityScope??"public",f=new Map,[I,D]=await Promise.all([A.entityService.listEntities({entityType:o6,options:{filter:{visibilityScope:$}}}),A.entityService.listEntities({entityType:a9,options:{filter:{visibilityScope:$}}})]),U=(Y)=>{for(let J of tz(Y))f.set(J,(f.get(J)??0)+1)};for(let Y of I)U(Y.metadata.tags);for(let Y of D){let J=UkQ.parseAgentContent(Y.content);U(J.skills.flatMap((X)=>X.tags))}return Array.from(f.entries()).map(([Y,J])=>({tag:Y,count:J})).filter((Y)=>Y.count>=B).sort(YkQ).slice(0,w)}function wL1(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(`
|
|
8183
8183
|
`)}var JkQ=new df;function $L1(A,Q={}){let B=A.anchor?.name??A.brainName,w=A.anchor?.kind??"professional",$=[];if(A.anchor?.description)$.push(A.anchor.description);if(A.description)$.push(A.description);let f=Q.status??"discovered",I=new Date().toISOString();return{content:JkQ.createAgentContent({name:B,kind:w,...A.anchor?.organization&&{organization:A.anchor.organization},brainName:A.brainName,url:A.url,status:f,discoveredAt:I,about:$.join(`
|
|
@@ -8278,7 +8278,7 @@ ${cX(B)}---
|
|
|
8278
8278
|
setTagFilter("all");
|
|
8279
8279
|
});
|
|
8280
8280
|
})();`;import{jsxDEV as nQ}from"preact/jsx-dev-runtime";function zkQ({item:A}){return nQ("li",{class:"list-item",children:[nQ("div",{class:"list-main",children:[nQ("span",{class:"list-name",children:A.name},void 0,!1,void 0,this),nQ("span",{class:"list-desc",children:A.description},void 0,!1,void 0,this),A.tags.length>0&&nQ("div",{class:"list-tags",children:A.tags.map((Q)=>nQ("span",{class:"tag",children:Q},`${A.id}:${Q}`,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),nQ("div",{class:"list-meta",children:A.status==="discovered"&&nQ("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 qkQ({item:A}){return nQ("li",{class:"list-item agent-network-skill-row","data-agent-network-skill-row":!0,"data-agent-network-tags":JSON.stringify(A.tags),children:[nQ("div",{class:"list-main",children:nQ("span",{class:"list-name",children:A.name},void 0,!1,void 0,this)},void 0,!1,void 0,this),nQ("div",{class:"list-meta",children:nQ("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 LkQ({kind:A,items:Q,active:B}){return nQ("div",{class:`agent-network-panel${B?" is-active":""}`,"data-agent-network-panel":A,children:Q.length>0?nQ("ul",{class:"list agent-network-list",children:Q.map((w)=>nQ(zkQ,{item:w},w.id,!1,void 0,this))},void 0,!1,void 0,this):nQ("p",{class:"agent-network-empty",children:"Nothing to show yet."},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function VkQ({skills:A,count:Q,filters:B}){return nQ("div",{class:"agent-network-panel","data-agent-network-panel":"skills",children:[nQ("div",{class:"agent-network-filter-row",role:"tablist","aria-label":"Filter skills by tag",children:[nQ("button",{class:"agent-network-filter is-active",type:"button","data-agent-network-tag-filter":"all","aria-pressed":"true",children:[nQ("span",{class:"count",children:Q},void 0,!1,void 0,this),nQ("span",{class:"label",children:"all"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),B.map((w)=>nQ("button",{class:`agent-network-filter${w.variant==="gap"?" is-gap":""}`,type:"button","data-agent-network-tag-filter":w.tag,"aria-pressed":"false",children:[nQ("span",{class:"count",children:w.count},void 0,!1,void 0,this),nQ("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?nQ("ul",{class:"list agent-network-list agent-network-skills-list",children:A.map((w)=>nQ(qkQ,{item:w},w.id,!1,void 0,this))},void 0,!1,void 0,this):nQ("p",{class:"agent-network-empty",children:"Nothing to show yet."},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function hmA({data:A}){let Q=JL1.safeParse(A);if(!Q.success)return nQ("p",{class:"muted",children:"Nothing to show yet."},void 0,!1,void 0,this);let B=Q.data;return nQ("div",{"data-agent-network-widget":!0,"data-agent-network-view":"agents",children:[nQ("div",{class:"agent-network-view-tabs",role:"tablist","aria-label":"Browse the agent network",children:[nQ("button",{class:"agent-network-view-tab is-active",type:"button","data-agent-network-view-tab":"agents","aria-pressed":"true",children:["Agents",nQ("span",{class:"agent-network-view-count",children:B.counts.agents},void 0,!1,void 0,this)]},void 0,!0,void 0,this),nQ("button",{class:"agent-network-view-tab",type:"button","data-agent-network-view-tab":"skills","aria-pressed":"false",children:["Skills",nQ("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),nQ("div",{class:"agent-network-kind-tabs",role:"tablist","aria-label":"Filter agents by kind",children:gmA.map((w)=>{let $=w==="all";return nQ("button",{class:`agent-network-kind-tab${$?" is-active":""}`,type:"button","data-agent-network-kind-tab":w,"aria-pressed":$?"true":"false",children:[nQ("span",{class:"agent-network-kind-count",children:B.agents[w].length},void 0,!1,void 0,this),nQ("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),gmA.map((w)=>nQ(LkQ,{kind:w,items:B.agents[w],active:w==="all"},w,!1,void 0,this)),nQ(VkQ,{skills:B.skills,count:B.counts.skills,filters:B.skillFilters},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function WL1(A,Q){A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"dashboard:register-widget",payload:{id:lq1,pluginId:Q,title:"Agent Network",section:"secondary",priority:15,rendererName:pq1,component:hmA,clientScript:w9A,dataProvider:async()=>XL1(A)}}),{success:!0}})}WA();var HL1=new df;function EkQ(A){return A.skills.map((Q)=>({name:Q.name,description:Q.description,tags:Q.tags??[]}))}function MkQ(A){return new URL(A).hostname}function CkQ(A){return[`ATProto card: ${A.uri}`,`ATProto card CID: ${A.cid}`,`ATProto repo DID: ${A.repoDid}`].join(`
|
|
8281
|
-
`)}function OkQ(A){let Q=A.record.brain.did,B=A.record.anchor.did;return{agentId:A.agent.id,name:A.agent.metadata.name,url:A.agent.metadata.url,status:A.agent.metadata.status,repoDid:A.repoDid,...Q&&{brainDid:Q},...B&&{anchorDid:B},cardUri:A.uri,cardCid:A.cid}}async function RkQ(A,Q,B){await A.messaging.send({type:Q,payload:B,broadcast:!0})}async function bkQ(A,Q,B=new Date().toISOString()){let{record:w}=Q,$=MkQ(w.siteUrl),f=await A.entityService.getEntity({entityType:"agent",id:$}),I=f?HL1.parseEntity(f):void 0,D=w.brain.did,U=w.anchor.did,Y=EkQ(w),J=f?.metadata.status??"discovered",X=f?.metadata.url??w.siteUrl,G=f?.metadata.slug??tZ(X),Z=f?.metadata.name??w.anchor.name,N=I?.frontmatter.kind??w.anchor.kind,L=f?.metadata.discoveredAt??B,V=w.brain.purpose||I?.body.about||"",M=Y.length>0?Y:I?.body.skills??[],O={...f?.metadata??{},name:Z,url:X,status:J,discoveredAt:L,slug:G,repoDid:Q.repoDid,...D&&{brainDid:D},...U&&{anchorDid:U},cardUri:Q.uri,cardCid:Q.cid},E=HL1.createAgentContent({name:Z,kind:N,...I?.frontmatter.organization&&{organization:I.frontmatter.organization},brainName:w.brain.name,url:X,...D&&{did:D,brainDid:D},...U&&{anchorDid:U},repoDid:Q.repoDid,cardUri:Q.uri,cardCid:Q.cid,...I?.frontmatter.a2aEndpoint&&{a2aEndpoint:I.frontmatter.a2aEndpoint},status:J,discoveredAt:L,about:V,skills:M,notes:CkQ({repoDid:Q.repoDid,uri:Q.uri,cid:Q.cid})});if(f){let y={...f,content:E,metadata:O,updated:B};return await A.entityService.updateEntity({entity:y}),{agent:y,created:!1}}let S={id:$,entityType:"agent",content:E,metadata:O,contentHash:"",visibility:"public",created:B,updated:B};return await A.entityService.createEntity({entity:S}),{agent:S,created:!0}}function GL1(A){A.messaging.subscribe($5A,async(Q)=>{let B=qK1.parse(Q.payload),w=await bkQ(A,B),$=OkQ({agent:w.agent,repoDid:B.repoDid,uri:B.uri,cid:B.cid,record:B.record});return await RkQ(A,w.created?NK1:zK1,$),{success:!0,data:$}})}function KL1(){return'## Agent directory\n\nThese rules govern the local `agent` directory and agent-contact requests. They override the general wishlist rule and the general "always attempt tool calls" rule.\n\n### Directory CRUD\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 let the standard confirmation flow ask the user to confirm. Never pass `confirmed: true` on the initial 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\n### Contact requests (ask / talk to / what does X say)\n- Treat phrases like `what does <agent> have to say`, `what would <agent> say/think`, and asking a saved agent for its own skills/capabilities as contact requests. For an exact saved local agent id such as `yeehaa.io`, use `a2a_call` rather than answering from local saved agent metadata, unless the user explicitly asks for directory/profile details.\n- If the user uses a display/contact name like `Brain` rather than an exact saved id, first inspect saved agents with `system_list({ entityType: "agent" })`. If multiple saved agents could match, ask which one and do not call any tool. Never choose the first match.\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\n### Save-first for unsaved agents\n- Calling and saving agents are separate actions. If the user asks to `call`, `talk to`, `ask`, message, contact, or reach out to an unsaved agent domain/URL, do **not** call `system_create` or `a2a_call` on that first request. Tell the user the agent is not yet in the local agent **directory** and ask them to **add/save it first**. The reply must include both the word **directory** (to be clear about what\'s missing) and the phrase **add/save it first**.\n- This applies equally to full URLs (`https://unknown-agent.io/a2a`) and bare domains/ids (`unknown-agent.io`). A URL-based or unsaved-domain agent contact request is a save-first directory case, not a wishlist case.\n- When refusing, cite the agent domain/URL **by name** in your reply (e.g. "you\'ll need to add/save `unknown-agent.io` first") \u2014 do not say "that agent" without naming it. This anchors the domain for any affirmative follow-up.\n- The save-first refusal turn must have **no tool calls**. Do not create a wish, note, reminder, task, or backlog item to remember the blocked contact request. Specifically: never call `system_create` with `entityType: "wish"` for an agent-contact request, and never create any other fallback entity for a missing, archived/removed, or ambiguous agent unless the user explicitly asks you to add/save/unarchive it.\n\n### Affirmative follow-up after save-first refusal\n- If a recent user message named exactly one unsaved agent domain/URL and you told them to add/save it first, 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({ entityType: "agent", url: "that-domain" })`. The trigger is the user\'s prior reference to the domain, not whether your refusal echoed it back.\n- Do **not** repeat the save-first instruction after such an affirmative follow-up; just call `system_create`.\n\n### Examples\n- User: "Ask https://unknown-agent.io about X" \u2192 do **not** call `a2a_call` and do **not** call `system_create` for a wish. Tell them to add/save `unknown-agent.io` first.\n- User: "Can you message this agent URL for me: https://unknown-agent.io/a2a?" \u2192 do **not** create a wish. Tell them the agent must be saved first.\n- User: "Ask Brain about X" with both `yeehaa.io` and `brain-labs.io` saved as "Brain" \u2192 ask the user to choose between those two saved ids and do not call `a2a_call`.'}aA();Ew();WA();import{jsxDEV as FL1}from"preact/jsx-dev-runtime";function $9A(A){try{return new URL(A).hostname}catch{return A}}var f9A=({name:A,className:Q=""})=>{let B=A.charAt(0).toUpperCase(),w=0;for(let f=0;f<A.length;f++)w=A.charCodeAt(f)+((w<<5)-w);let $=Math.abs(w)%360;return FL1("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)},I9A=({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 FL1("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 L2,Fragment as jkQ}from"preact/jsx-dev-runtime";var PkQ=({skills:A})=>{if(A.length===0)return null;return L2("div",{className:"flex gap-1.5 flex-wrap mt-2",children:A.map((Q)=>L2("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 kkQ(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric"})}function ZL1(A,Q,B){let w=new URLSearchParams({status:Q});if(B>1)w.set("page",String(B));return`${A}?${w.toString()}`}var mmA=({agent:A})=>{let{frontmatter:Q,about:B,skills:w,url:$}=A,f=Q.status==="approved";return L2("a",{href:$,className:`flex items-start gap-5 p-6 rounded-xl border border-theme bg-theme-subtle hover:shadow-lg transition-shadow ${f?"":"opacity-70"}`,children:[L2(f9A,{name:Q.name,className:"w-12 h-12 text-lg"},void 0,!1,void 0,this),L2("div",{className:"flex-1 min-w-0",children:[L2("div",{className:"flex items-center gap-2 mb-1 flex-wrap",children:[L2("span",{className:"text-lg font-semibold text-heading",children:Q.name},void 0,!1,void 0,this),L2(I9A,{kind:Q.kind,size:"sm"},void 0,!1,void 0,this),Q.organization&&L2("span",{className:"text-xs text-theme-muted",children:["\xB7 ",Q.organization]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),L2("div",{className:"text-sm text-theme-muted mb-1",children:Q.brainName},void 0,!1,void 0,this),B&&L2("p",{className:"text-sm text-theme-muted line-clamp-2 mb-0",children:B},void 0,!1,void 0,this),f&&L2(PkQ,{skills:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this),L2("div",{className:"flex flex-col items-end gap-1 flex-shrink-0 text-right",children:[L2("span",{className:"text-xs text-theme-muted",children:$9A(Q.url)},void 0,!1,void 0,this),L2("span",{className:"text-[11px] text-theme-muted opacity-60",children:f?`Discovered ${kkQ(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)},NL1=({agents:A,pageTitle:Q,pagination:B,baseUrl:w="/agents",selectedStatus:$})=>{let f=Q??"Agent Directory",I=B?.totalItems??A.length,D=A.filter((G)=>G.frontmatter.status==="approved"),U=A.filter((G)=>G.frontmatter.status==="discovered"),Y=D.length,J=U.length,X=`Your network of ${I} ${I===1?"brain":"brains"} and their anchors`;return L2(jkQ,{children:[L2(KQ,{title:f,description:X},void 0,!1,void 0,this),L2("div",{className:"agent-list bg-theme",children:L2("div",{className:"container mx-auto px-6 md:px-12 max-w-5xl py-16 md:py-24",children:[L2("div",{className:"mb-8 pb-6 border-b border-theme",children:[L2("h1",{className:"text-4xl font-bold text-heading mb-2",children:f},void 0,!1,void 0,this),L2("p",{className:"text-theme-muted mb-4",children:X},void 0,!1,void 0,this),L2("div",{className:"flex flex-wrap gap-2 text-sm mb-4",children:[L2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-heading",children:[I," total"]},void 0,!0,void 0,this),L2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-status-success",children:[Y," approved"]},void 0,!0,void 0,this),L2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-theme-muted",children:[J," discovered"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),L2("div",{className:"flex flex-wrap gap-2 text-sm",children:[L2("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),L2("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),L2("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&&L2("section",{className:"mb-10",children:[L2("div",{className:"flex items-center justify-between mb-4",children:[L2("h2",{className:"text-lg font-semibold text-heading",children:"Approved brains"},void 0,!1,void 0,this),L2("span",{className:"text-sm text-theme-muted",children:D.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),L2("div",{className:"flex flex-col gap-4",children:D.map((G)=>L2(mmA,{agent:G},G.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$==="all"&&U.length>0&&L2("section",{children:[L2("div",{className:"flex items-center justify-between mb-4",children:[L2("div",{children:[L2("h2",{className:"text-lg font-semibold text-heading",children:"Discovered brains"},void 0,!1,void 0,this),L2("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),L2("span",{className:"text-sm text-theme-muted",children:U.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),L2("div",{className:"flex flex-col gap-4",children:U.map((G)=>L2(mmA,{agent:G},G.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$!=="all"&&A.length>0&&L2("section",{children:[L2("div",{className:"flex items-center justify-between mb-4",children:[L2("h2",{className:"text-lg font-semibold text-heading",children:$==="approved"?"Approved brains":"Discovered brains"},void 0,!1,void 0,this),L2("span",{className:"text-sm text-theme-muted",children:A.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),L2("div",{className:"flex flex-col gap-4",children:A.map((G)=>L2(mmA,{agent:G},G.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.length===0&&L2("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"&&L2("div",{className:"mt-12",children:L2(VF,{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"&&L2("nav",{"aria-label":"Pagination",className:"flex items-center justify-center gap-3 mt-12",children:[B.hasPrevPage?L2("a",{href:ZL1(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):L2("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),L2("span",{className:"text-sm text-theme-muted",children:["Page ",B.currentPage," of ",B.totalPages]},void 0,!0,void 0,this),B.hasNextPage?L2("a",{href:ZL1(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):L2("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 X2,Fragment as ykQ}from"preact/jsx-dev-runtime";function _kQ(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"})}var Wr=({children:A})=>X2("h2",{className:"text-sm font-semibold text-theme-muted uppercase tracking-wide mb-3",children:A},void 0,!1,void 0,this),vkQ=({skill:A})=>X2("div",{className:"flex items-start gap-3 px-4 py-3 bg-theme-subtle rounded-lg",children:[X2("div",{className:"flex-1",children:[X2("div",{className:"text-sm font-semibold text-heading",children:A.name},void 0,!1,void 0,this),X2("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&&X2("div",{className:"flex gap-1 flex-shrink-0",children:A.tags.map((Q)=>X2("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),TkQ=({label:A,value:Q,valueClassName:B})=>X2("div",{className:"flex justify-between text-[13px]",children:[X2("span",{className:"text-theme-muted",children:A},void 0,!1,void 0,this),X2("span",{className:B??"text-heading",children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this),zL1=({agent:A,prevAgent:Q,nextAgent:B})=>{let{frontmatter:w,about:$,skills:f,notes:I}=A,D=$9A(w.url),U=w.status==="approved";return X2(ykQ,{children:[X2(KQ,{title:w.name,description:$||`Agent profile for ${w.name}`},void 0,!1,void 0,this),X2("article",{className:"agent-detail",children:X2("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:[X2("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),X2("div",{className:"flex items-start gap-6 mb-8",children:[X2(f9A,{name:w.name,className:"w-[72px] h-[72px] text-3xl"},void 0,!1,void 0,this),X2("div",{children:[X2("div",{className:"flex items-center gap-3 mb-1",children:[X2("h1",{className:"text-3xl md:text-4xl font-bold text-heading",children:w.name},void 0,!1,void 0,this),X2(I9A,{kind:w.kind},void 0,!1,void 0,this)]},void 0,!0,void 0,this),X2("div",{className:"text-base text-theme-muted mb-2",children:w.brainName},void 0,!1,void 0,this),X2("div",{className:"flex items-center gap-3 text-theme-muted",children:[w.organization&&X2("span",{className:"text-[15px]",children:w.organization},void 0,!1,void 0,this),w.organization&&X2("span",{className:"text-theme-muted opacity-40",children:"\xB7"},void 0,!1,void 0,this),X2("span",{className:"text-sm",children:["Discovered ",_kQ(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),X2("div",{className:"border-b border-theme mb-8"},void 0,!1,void 0,this),!U&&X2("div",{className:"mb-8 rounded-xl border border-theme bg-theme-subtle px-5 py-4",children:[X2("div",{className:"text-sm font-semibold text-heading mb-1",children:"Saved for review"},void 0,!1,void 0,this),X2("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),X2("div",{className:"flex flex-col md:flex-row gap-12",children:[X2("div",{className:"flex-[2] min-w-0",children:[$&&X2("section",{className:"mb-8",children:[X2(Wr,{children:"About"},void 0,!1,void 0,this),X2("p",{className:"text-[15px] text-theme leading-relaxed",children:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this),f.length>0&&X2("section",{className:"mb-8",children:[X2(Wr,{children:"Skills"},void 0,!1,void 0,this),X2("div",{className:"flex flex-col gap-2.5",children:f.map((Y)=>X2(vkQ,{skill:Y},Y.name,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),I&&X2("section",{className:"mb-8",children:[X2(Wr,{children:"Notes"},void 0,!1,void 0,this),X2("p",{className:"text-[15px] text-theme leading-relaxed",children:I},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),X2("aside",{className:"flex-1 md:pl-8 md:border-l border-theme-muted/20",children:[X2("section",{className:"mb-8",children:[X2(Wr,{children:"Brain"},void 0,!1,void 0,this),X2("div",{className:"p-4 bg-theme-subtle rounded-xl",children:[X2("div",{className:"text-[15px] font-semibold text-heading mb-1",children:w.brainName},void 0,!1,void 0,this),w.did&&X2("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),X2("section",{className:"mb-8",children:[X2(Wr,{children:"Connection"},void 0,!1,void 0,this),X2("div",{className:"flex flex-col gap-3",children:[X2("div",{children:[X2("div",{className:"text-[13px] text-theme-muted mb-0.5",children:"Endpoint"},void 0,!1,void 0,this),X2("div",{className:"text-xs text-heading font-mono",children:w.url},void 0,!1,void 0,this)]},void 0,!0,void 0,this),X2(TkQ,{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),X2("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)&&X2("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:[X2("div",{className:"min-h-[1px]",children:Q&&X2("a",{href:Q.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[X2("span",{children:"\u2190 Previous"},void 0,!1,void 0,this),X2("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),X2("div",{className:"min-h-[1px] md:text-right",children:B&&X2("a",{href:B.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[X2("span",{children:"Next \u2192"},void 0,!1,void 0,this),X2("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 xkQ=H.object({agents:H.array(cv),pageTitle:H.string().optional(),pagination:Z7.nullable(),baseUrl:H.string().optional(),selectedStatus:H.union([H.literal("all"),aU])});function qL1(){return{[ymA]:P1({name:ymA,description:"Agent directory list page template",schema:xkQ,dataSourceId:Jr,requiredPermission:"public",layout:{component:NL1}}),[xmA]:P1({name:xmA,description:"Individual agent profile template",schema:H.object({agent:cv,prevAgent:cv.nullable(),nextAgent:cv.nullable()}),dataSourceId:Jr,requiredPermission:"public",layout:{component:zL1}})}}var D9A={name:"@brains/agent-discovery",private:!0,version:"0.2.0-alpha.119",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/atproto-contracts":"workspace:*","@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/dashboard":"workspace:*","@brains/plugins":"workspace:*","@brains/templates":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var gkQ=new df;class umA extends jQ{entityType=a9;schema=uv;adapter=gkQ;constructor(){super(uq1,D9A)}interceptCreate(A,Q,B){return fL1(A,Q,B,this.id)}createGenerationHandler(A){return new SmA(this.logger.child("AgentGenerationJobHandler"),A)}getTemplates(){return qL1()}getDataSources(){return[new A9A(this.logger.child("AgentDataSource"))]}async onRegister(A){GL1(A),WL1(A,this.id)}async getInstructions(){return KL1()}}function cmA(){return new umA}aA();WA();aA();var lv=RI,LL1=RI,Hr=A2.extend({entityType:H.literal(o6),metadata:LL1});aA();class pv extends q2{constructor(){super({entityType:o6,schema:Hr,frontmatterSchema:lv})}fromMarkdown(A){let Q=this.parseFrontMatter(A,lv);return{content:A,entityType:o6,metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}aA();WA();var hkQ=H.object({skills:H.array(lv).max(8)}),VL1=P1({name:"skill:skill-derivation",description:"Derive skills from topic titles and brain capabilities",dataSourceId:"shell:ai-content",schema:hkQ,useKnowledgeContext:!0,basePrompt:`You are analyzing a brain's content to identify its high-level capabilities.
|
|
8281
|
+
`)}function OkQ(A){let Q=A.record.brain.did,B=A.record.anchor.did;return{agentId:A.agent.id,name:A.agent.metadata.name,url:A.agent.metadata.url,status:A.agent.metadata.status,repoDid:A.repoDid,...Q&&{brainDid:Q},...B&&{anchorDid:B},cardUri:A.uri,cardCid:A.cid}}async function RkQ(A,Q,B){await A.messaging.send({type:Q,payload:B,broadcast:!0})}async function bkQ(A,Q,B=new Date().toISOString()){let{record:w}=Q,$=MkQ(w.siteUrl),f=await A.entityService.getEntity({entityType:"agent",id:$}),I=f?HL1.parseEntity(f):void 0,D=w.brain.did,U=w.anchor.did,Y=EkQ(w),J=f?.metadata.status??"discovered",X=f?.metadata.url??w.siteUrl,G=f?.metadata.slug??tZ(X),Z=f?.metadata.name??w.anchor.name,N=I?.frontmatter.kind??w.anchor.kind,L=f?.metadata.discoveredAt??B,V=w.brain.purpose||I?.body.about||"",M=Y.length>0?Y:I?.body.skills??[],O={...f?.metadata??{},name:Z,url:X,status:J,discoveredAt:L,slug:G,repoDid:Q.repoDid,...D&&{brainDid:D},...U&&{anchorDid:U},cardUri:Q.uri,cardCid:Q.cid},E=HL1.createAgentContent({name:Z,kind:N,...I?.frontmatter.organization&&{organization:I.frontmatter.organization},brainName:w.brain.name,url:X,...D&&{did:D,brainDid:D},...U&&{anchorDid:U},repoDid:Q.repoDid,cardUri:Q.uri,cardCid:Q.cid,...I?.frontmatter.a2aEndpoint&&{a2aEndpoint:I.frontmatter.a2aEndpoint},status:J,discoveredAt:L,about:V,skills:M,notes:CkQ({repoDid:Q.repoDid,uri:Q.uri,cid:Q.cid})});if(f){let y={...f,content:E,metadata:O,updated:B};return await A.entityService.updateEntity({entity:y}),{agent:y,created:!1}}let S={id:$,entityType:"agent",content:E,metadata:O,contentHash:"",visibility:"public",created:B,updated:B};return await A.entityService.createEntity({entity:S}),{agent:S,created:!0}}function GL1(A){A.messaging.subscribe($5A,async(Q)=>{let B=qK1.parse(Q.payload),w=await bkQ(A,B),$=OkQ({agent:w.agent,repoDid:B.repoDid,uri:B.uri,cid:B.cid,record:B.record});return await RkQ(A,w.created?NK1:zK1,$),{success:!0,data:$}})}function KL1(){return'## Agent directory\n\nThese rules govern the local `agent` directory and agent-contact requests. They override the general wishlist rule and the general "always attempt tool calls" rule.\n\n### Directory CRUD\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 let the standard confirmation flow ask the user to confirm. Never pass `confirmed: true` on the initial 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\n### Contact requests (ask / talk to / what does X say)\n- Treat phrases like `what does <agent> have to say`, `what would <agent> say/think`, and asking a saved agent for its own skills/capabilities as contact requests. For an exact saved local agent id such as `yeehaa.io`, use `a2a_call` rather than answering from local saved agent metadata, unless the user explicitly asks for directory/profile details.\n- If the user uses a display/contact name like `Brain` rather than an exact saved id, first inspect saved agents with `system_list({ entityType: "agent" })`. If multiple saved agents could match, ask which one and do not call any tool. Never choose the first match.\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\n### Save-first for unsaved agents\n- Calling and saving agents are separate actions. If the user asks to `call`, `talk to`, `ask`, message, contact, or reach out to an unsaved agent domain/URL, do **not** call `system_create` or `a2a_call` on that first request. Tell the user the agent is not yet in the local agent **directory** and ask them to **add/save it first**. The reply must include both the word **directory** (to be clear about what\'s missing) and the phrase **add/save it first**.\n- This applies equally to full URLs (`https://unknown-agent.io/a2a`) and bare domains/ids (`unknown-agent.io`). A URL-based or unsaved-domain agent contact request is a save-first directory case, not a wishlist case.\n- When refusing, cite the agent domain/URL **by name** in your reply (e.g. "you\'ll need to add/save `unknown-agent.io` first") \u2014 do not say "that agent" without naming it. This anchors the domain for any affirmative follow-up.\n- The save-first refusal turn must have **no tool calls**. Do not create a wish, note, reminder, task, or backlog item to remember the blocked contact request. Specifically: never call `system_create` with `entityType: "wish"` for an agent-contact request, and never create any other fallback entity for a missing, archived/removed, or ambiguous agent unless the user explicitly asks you to add/save/unarchive it.\n\n### Affirmative follow-up after save-first refusal\n- If a recent user message named exactly one unsaved agent domain/URL and you told them to add/save it first, 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({ entityType: "agent", url: "that-domain" })`. The trigger is the user\'s prior reference to the domain, not whether your refusal echoed it back.\n- Do **not** repeat the save-first instruction after such an affirmative follow-up; just call `system_create`.\n\n### Examples\n- User: "Ask https://unknown-agent.io about X" \u2192 do **not** call `a2a_call` and do **not** call `system_create` for a wish. Tell them to add/save `unknown-agent.io` first.\n- User: "Can you message this agent URL for me: https://unknown-agent.io/a2a?" \u2192 do **not** create a wish. Tell them the agent must be saved first.\n- User: "Ask Brain about X" with both `yeehaa.io` and `brain-labs.io` saved as "Brain" \u2192 ask the user to choose between those two saved ids and do not call `a2a_call`.'}aA();Ew();WA();import{jsxDEV as FL1}from"preact/jsx-dev-runtime";function $9A(A){try{return new URL(A).hostname}catch{return A}}var f9A=({name:A,className:Q=""})=>{let B=A.charAt(0).toUpperCase(),w=0;for(let f=0;f<A.length;f++)w=A.charCodeAt(f)+((w<<5)-w);let $=Math.abs(w)%360;return FL1("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)},I9A=({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 FL1("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 L2,Fragment as jkQ}from"preact/jsx-dev-runtime";var PkQ=({skills:A})=>{if(A.length===0)return null;return L2("div",{className:"flex gap-1.5 flex-wrap mt-2",children:A.map((Q)=>L2("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 kkQ(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric"})}function ZL1(A,Q,B){let w=new URLSearchParams({status:Q});if(B>1)w.set("page",String(B));return`${A}?${w.toString()}`}var mmA=({agent:A})=>{let{frontmatter:Q,about:B,skills:w,url:$}=A,f=Q.status==="approved";return L2("a",{href:$,className:`flex items-start gap-5 p-6 rounded-xl border border-theme bg-theme-subtle hover:shadow-lg transition-shadow ${f?"":"opacity-70"}`,children:[L2(f9A,{name:Q.name,className:"w-12 h-12 text-lg"},void 0,!1,void 0,this),L2("div",{className:"flex-1 min-w-0",children:[L2("div",{className:"flex items-center gap-2 mb-1 flex-wrap",children:[L2("span",{className:"text-lg font-semibold text-heading",children:Q.name},void 0,!1,void 0,this),L2(I9A,{kind:Q.kind,size:"sm"},void 0,!1,void 0,this),Q.organization&&L2("span",{className:"text-xs text-theme-muted",children:["\xB7 ",Q.organization]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),L2("div",{className:"text-sm text-theme-muted mb-1",children:Q.brainName},void 0,!1,void 0,this),B&&L2("p",{className:"text-sm text-theme-muted line-clamp-2 mb-0",children:B},void 0,!1,void 0,this),f&&L2(PkQ,{skills:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this),L2("div",{className:"flex flex-col items-end gap-1 flex-shrink-0 text-right",children:[L2("span",{className:"text-xs text-theme-muted",children:$9A(Q.url)},void 0,!1,void 0,this),L2("span",{className:"text-[11px] text-theme-muted opacity-60",children:f?`Discovered ${kkQ(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)},NL1=({agents:A,pageTitle:Q,pagination:B,baseUrl:w="/agents",selectedStatus:$})=>{let f=Q??"Agent Directory",I=B?.totalItems??A.length,D=A.filter((G)=>G.frontmatter.status==="approved"),U=A.filter((G)=>G.frontmatter.status==="discovered"),Y=D.length,J=U.length,X=`Your network of ${I} ${I===1?"brain":"brains"} and their anchors`;return L2(jkQ,{children:[L2(KQ,{title:f,description:X},void 0,!1,void 0,this),L2("div",{className:"agent-list bg-theme",children:L2("div",{className:"container mx-auto px-6 md:px-12 max-w-5xl py-16 md:py-24",children:[L2("div",{className:"mb-8 pb-6 border-b border-theme",children:[L2("h1",{className:"text-4xl font-bold text-heading mb-2",children:f},void 0,!1,void 0,this),L2("p",{className:"text-theme-muted mb-4",children:X},void 0,!1,void 0,this),L2("div",{className:"flex flex-wrap gap-2 text-sm mb-4",children:[L2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-heading",children:[I," total"]},void 0,!0,void 0,this),L2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-status-success",children:[Y," approved"]},void 0,!0,void 0,this),L2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-theme-muted",children:[J," discovered"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),L2("div",{className:"flex flex-wrap gap-2 text-sm",children:[L2("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),L2("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),L2("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&&L2("section",{className:"mb-10",children:[L2("div",{className:"flex items-center justify-between mb-4",children:[L2("h2",{className:"text-lg font-semibold text-heading",children:"Approved brains"},void 0,!1,void 0,this),L2("span",{className:"text-sm text-theme-muted",children:D.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),L2("div",{className:"flex flex-col gap-4",children:D.map((G)=>L2(mmA,{agent:G},G.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$==="all"&&U.length>0&&L2("section",{children:[L2("div",{className:"flex items-center justify-between mb-4",children:[L2("div",{children:[L2("h2",{className:"text-lg font-semibold text-heading",children:"Discovered brains"},void 0,!1,void 0,this),L2("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),L2("span",{className:"text-sm text-theme-muted",children:U.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),L2("div",{className:"flex flex-col gap-4",children:U.map((G)=>L2(mmA,{agent:G},G.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$!=="all"&&A.length>0&&L2("section",{children:[L2("div",{className:"flex items-center justify-between mb-4",children:[L2("h2",{className:"text-lg font-semibold text-heading",children:$==="approved"?"Approved brains":"Discovered brains"},void 0,!1,void 0,this),L2("span",{className:"text-sm text-theme-muted",children:A.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),L2("div",{className:"flex flex-col gap-4",children:A.map((G)=>L2(mmA,{agent:G},G.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.length===0&&L2("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"&&L2("div",{className:"mt-12",children:L2(VF,{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"&&L2("nav",{"aria-label":"Pagination",className:"flex items-center justify-center gap-3 mt-12",children:[B.hasPrevPage?L2("a",{href:ZL1(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):L2("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),L2("span",{className:"text-sm text-theme-muted",children:["Page ",B.currentPage," of ",B.totalPages]},void 0,!0,void 0,this),B.hasNextPage?L2("a",{href:ZL1(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):L2("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 X2,Fragment as ykQ}from"preact/jsx-dev-runtime";function _kQ(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"})}var Wr=({children:A})=>X2("h2",{className:"text-sm font-semibold text-theme-muted uppercase tracking-wide mb-3",children:A},void 0,!1,void 0,this),vkQ=({skill:A})=>X2("div",{className:"flex items-start gap-3 px-4 py-3 bg-theme-subtle rounded-lg",children:[X2("div",{className:"flex-1",children:[X2("div",{className:"text-sm font-semibold text-heading",children:A.name},void 0,!1,void 0,this),X2("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&&X2("div",{className:"flex gap-1 flex-shrink-0",children:A.tags.map((Q)=>X2("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),TkQ=({label:A,value:Q,valueClassName:B})=>X2("div",{className:"flex justify-between text-[13px]",children:[X2("span",{className:"text-theme-muted",children:A},void 0,!1,void 0,this),X2("span",{className:B??"text-heading",children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this),zL1=({agent:A,prevAgent:Q,nextAgent:B})=>{let{frontmatter:w,about:$,skills:f,notes:I}=A,D=$9A(w.url),U=w.status==="approved";return X2(ykQ,{children:[X2(KQ,{title:w.name,description:$||`Agent profile for ${w.name}`},void 0,!1,void 0,this),X2("article",{className:"agent-detail",children:X2("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:[X2("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),X2("div",{className:"flex items-start gap-6 mb-8",children:[X2(f9A,{name:w.name,className:"w-[72px] h-[72px] text-3xl"},void 0,!1,void 0,this),X2("div",{children:[X2("div",{className:"flex items-center gap-3 mb-1",children:[X2("h1",{className:"text-3xl md:text-4xl font-bold text-heading",children:w.name},void 0,!1,void 0,this),X2(I9A,{kind:w.kind},void 0,!1,void 0,this)]},void 0,!0,void 0,this),X2("div",{className:"text-base text-theme-muted mb-2",children:w.brainName},void 0,!1,void 0,this),X2("div",{className:"flex items-center gap-3 text-theme-muted",children:[w.organization&&X2("span",{className:"text-[15px]",children:w.organization},void 0,!1,void 0,this),w.organization&&X2("span",{className:"text-theme-muted opacity-40",children:"\xB7"},void 0,!1,void 0,this),X2("span",{className:"text-sm",children:["Discovered ",_kQ(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),X2("div",{className:"border-b border-theme mb-8"},void 0,!1,void 0,this),!U&&X2("div",{className:"mb-8 rounded-xl border border-theme bg-theme-subtle px-5 py-4",children:[X2("div",{className:"text-sm font-semibold text-heading mb-1",children:"Saved for review"},void 0,!1,void 0,this),X2("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),X2("div",{className:"flex flex-col md:flex-row gap-12",children:[X2("div",{className:"flex-[2] min-w-0",children:[$&&X2("section",{className:"mb-8",children:[X2(Wr,{children:"About"},void 0,!1,void 0,this),X2("p",{className:"text-[15px] text-theme leading-relaxed",children:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this),f.length>0&&X2("section",{className:"mb-8",children:[X2(Wr,{children:"Skills"},void 0,!1,void 0,this),X2("div",{className:"flex flex-col gap-2.5",children:f.map((Y)=>X2(vkQ,{skill:Y},Y.name,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),I&&X2("section",{className:"mb-8",children:[X2(Wr,{children:"Notes"},void 0,!1,void 0,this),X2("p",{className:"text-[15px] text-theme leading-relaxed",children:I},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),X2("aside",{className:"flex-1 md:pl-8 md:border-l border-theme-muted/20",children:[X2("section",{className:"mb-8",children:[X2(Wr,{children:"Brain"},void 0,!1,void 0,this),X2("div",{className:"p-4 bg-theme-subtle rounded-xl",children:[X2("div",{className:"text-[15px] font-semibold text-heading mb-1",children:w.brainName},void 0,!1,void 0,this),w.did&&X2("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),X2("section",{className:"mb-8",children:[X2(Wr,{children:"Connection"},void 0,!1,void 0,this),X2("div",{className:"flex flex-col gap-3",children:[X2("div",{children:[X2("div",{className:"text-[13px] text-theme-muted mb-0.5",children:"Endpoint"},void 0,!1,void 0,this),X2("div",{className:"text-xs text-heading font-mono",children:w.url},void 0,!1,void 0,this)]},void 0,!0,void 0,this),X2(TkQ,{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),X2("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)&&X2("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:[X2("div",{className:"min-h-[1px]",children:Q&&X2("a",{href:Q.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[X2("span",{children:"\u2190 Previous"},void 0,!1,void 0,this),X2("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),X2("div",{className:"min-h-[1px] md:text-right",children:B&&X2("a",{href:B.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[X2("span",{children:"Next \u2192"},void 0,!1,void 0,this),X2("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 xkQ=H.object({agents:H.array(cv),pageTitle:H.string().optional(),pagination:Z7.nullable(),baseUrl:H.string().optional(),selectedStatus:H.union([H.literal("all"),aU])});function qL1(){return{[ymA]:P1({name:ymA,description:"Agent directory list page template",schema:xkQ,dataSourceId:Jr,requiredPermission:"public",layout:{component:NL1}}),[xmA]:P1({name:xmA,description:"Individual agent profile template",schema:H.object({agent:cv,prevAgent:cv.nullable(),nextAgent:cv.nullable()}),dataSourceId:Jr,requiredPermission:"public",layout:{component:zL1}})}}var D9A={name:"@brains/agent-discovery",private:!0,version:"0.2.0-alpha.120",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/atproto-contracts":"workspace:*","@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/dashboard":"workspace:*","@brains/plugins":"workspace:*","@brains/templates":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var gkQ=new df;class umA extends jQ{entityType=a9;schema=uv;adapter=gkQ;constructor(){super(uq1,D9A)}interceptCreate(A,Q,B){return fL1(A,Q,B,this.id)}createGenerationHandler(A){return new SmA(this.logger.child("AgentGenerationJobHandler"),A)}getTemplates(){return qL1()}getDataSources(){return[new A9A(this.logger.child("AgentDataSource"))]}async onRegister(A){GL1(A),WL1(A,this.id)}async getInstructions(){return KL1()}}function cmA(){return new umA}aA();WA();aA();var lv=RI,LL1=RI,Hr=A2.extend({entityType:H.literal(o6),metadata:LL1});aA();class pv extends q2{constructor(){super({entityType:o6,schema:Hr,frontmatterSchema:lv})}fromMarkdown(A){let Q=this.parseFrontMatter(A,lv);return{content:A,entityType:o6,metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}aA();WA();var hkQ=H.object({skills:H.array(lv).max(8)}),VL1=P1({name:"skill:skill-derivation",description:"Derive skills from topic titles and brain capabilities",dataSourceId:"shell:ai-content",schema:hkQ,useKnowledgeContext:!0,basePrompt:`You are analyzing a brain's content to identify its high-level capabilities.
|
|
8282
8282
|
|
|
8283
8283
|
Given knowledge domains, CONSOLIDATE related topics into broader skills.
|
|
8284
8284
|
There should be FEWER skills than topics \u2014 combine related domains.
|
|
@@ -8428,9 +8428,9 @@ Context:
|
|
|
8428
8428
|
${JSON.stringify(w,null,2)}
|
|
8429
8429
|
|
|
8430
8430
|
Draft SWOT:
|
|
8431
|
-
${JSON.stringify(B,null,2)}`}function K9A(A){return A.map((Q)=>Q.detail===null?{title:Q.title}:{title:Q.title,detail:Q.detail})}function DjQ(A,Q){let B=["strengths","weaknesses","opportunities","threats"];for(let w of B){let $=new Set(A[w].map((f)=>f.theme.trim().toLowerCase()));for(let f of Q[w]){let I=f.sourceTheme.trim().toLowerCase();if(!$.has(I))throw Error(`SWOT refinement invented theme "${f.sourceTheme}" in ${w}`)}}}class F9A{logger;context;adapter=new nF;constructor(A,Q){this.logger=A;this.context=Q}validateAndParse(A){let Q=imA.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 smA(this.context),$;if(w.summary.brainSkillCount+w.summary.approvedAgentCount+w.summary.discoveredAgentCount===0)$={strengths:[],weaknesses:[],opportunities:[],threats:[]};else{await B.report({progress:0.6,message:"Synthesizing SWOT analysis"});let{object:Y}=await this.context.ai.generateObject(await $jQ(this.context,w),rmA),J=rmA.parse(Y);await B.report({progress:0.75,message:"Refining SWOT language"});let X=await this.context.ai.generateObject(await IjQ(this.context,w,J),W9A);$=W9A.parse(X.object),DjQ(J,$)}let I=new Date().toISOString(),D=this.adapter.createSwotContent({strengths:K9A($.strengths),weaknesses:K9A($.weaknesses),opportunities:K9A($.opportunities),threats:K9A($.threats),derivedAt:I});await B.report({progress:0.9,message:"Saving SWOT entity"});let U=await this.context.entityService.getEntity({entityType:"swot",id:"swot"});if(U)await this.context.entityService.updateEntity({entity:{...U,content:D,metadata:{derivedAt:I}}});else await this.context.entityService.createEntity({entity:{id:"swot",entityType:"swot",content:D,metadata:{derivedAt:I}}});return this.logger.info("SWOT derivation complete",{derivedAt:I,brainSkillCount:w.summary.brainSkillCount,approvedAgentCount:w.summary.approvedAgentCount,discoveredAgentCount:w.summary.discoveredAgentCount}),{entityId:"swot"}}}WA();import{jsxDEV as c7}from"preact/jsx-dev-runtime";var Z9A=H.object({title:H.string(),detail:H.string().optional()}),UjQ=H.discriminatedUnion("status",[H.object({status:H.literal("generating")}),H.object({status:H.literal("ready"),strengths:H.array(Z9A).default([]),weaknesses:H.array(Z9A).default([]),opportunities:H.array(Z9A).default([]),threats:H.array(Z9A).default([]),derivedAt:H.string()})]);function YjQ({items:A}){if(A.length===0)return c7("p",{class:"swot-empty",children:"\u2014"},void 0,!1,void 0,this);return c7("ul",{class:"swot-list",children:A.map((Q)=>c7("li",{class:"swot-item",children:[c7("b",{children:Q.title},void 0,!1,void 0,this),Q.detail?c7("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 N9A({title:A,tone:Q,items:B}){return c7("section",{class:`swot-cell is-${Q}`,children:[c7("div",{class:"swot-head",children:A},void 0,!1,void 0,this),c7(YjQ,{items:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function emA({data:A}){let Q=UjQ.safeParse(A);if(!Q.success||Q.data.status==="generating")return c7("div",{"data-swot-widget":!0,children:c7("p",{class:"muted",children:"generating assessment\u2026"},void 0,!1,void 0,this)},void 0,!1,void 0,this);let B=Q.data;return c7("div",{"data-swot-widget":!0,children:c7("div",{class:"swot",role:"grid","aria-label":"SWOT analysis of agent network",children:[c7(N9A,{title:"Strengths",tone:"s",items:B.strengths},void 0,!1,void 0,this),c7(N9A,{title:"Weaknesses",tone:"w",items:B.weaknesses},void 0,!1,void 0,this),c7(N9A,{title:"Opportunities",tone:"o",items:B.opportunities},void 0,!1,void 0,this),c7(N9A,{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)}WA();var AuA={name:"@brains/assessment",private:!0,version:"0.2.0-alpha.
|
|
8431
|
+
${JSON.stringify(B,null,2)}`}function K9A(A){return A.map((Q)=>Q.detail===null?{title:Q.title}:{title:Q.title,detail:Q.detail})}function DjQ(A,Q){let B=["strengths","weaknesses","opportunities","threats"];for(let w of B){let $=new Set(A[w].map((f)=>f.theme.trim().toLowerCase()));for(let f of Q[w]){let I=f.sourceTheme.trim().toLowerCase();if(!$.has(I))throw Error(`SWOT refinement invented theme "${f.sourceTheme}" in ${w}`)}}}class F9A{logger;context;adapter=new nF;constructor(A,Q){this.logger=A;this.context=Q}validateAndParse(A){let Q=imA.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 smA(this.context),$;if(w.summary.brainSkillCount+w.summary.approvedAgentCount+w.summary.discoveredAgentCount===0)$={strengths:[],weaknesses:[],opportunities:[],threats:[]};else{await B.report({progress:0.6,message:"Synthesizing SWOT analysis"});let{object:Y}=await this.context.ai.generateObject(await $jQ(this.context,w),rmA),J=rmA.parse(Y);await B.report({progress:0.75,message:"Refining SWOT language"});let X=await this.context.ai.generateObject(await IjQ(this.context,w,J),W9A);$=W9A.parse(X.object),DjQ(J,$)}let I=new Date().toISOString(),D=this.adapter.createSwotContent({strengths:K9A($.strengths),weaknesses:K9A($.weaknesses),opportunities:K9A($.opportunities),threats:K9A($.threats),derivedAt:I});await B.report({progress:0.9,message:"Saving SWOT entity"});let U=await this.context.entityService.getEntity({entityType:"swot",id:"swot"});if(U)await this.context.entityService.updateEntity({entity:{...U,content:D,metadata:{derivedAt:I}}});else await this.context.entityService.createEntity({entity:{id:"swot",entityType:"swot",content:D,metadata:{derivedAt:I}}});return this.logger.info("SWOT derivation complete",{derivedAt:I,brainSkillCount:w.summary.brainSkillCount,approvedAgentCount:w.summary.approvedAgentCount,discoveredAgentCount:w.summary.discoveredAgentCount}),{entityId:"swot"}}}WA();import{jsxDEV as c7}from"preact/jsx-dev-runtime";var Z9A=H.object({title:H.string(),detail:H.string().optional()}),UjQ=H.discriminatedUnion("status",[H.object({status:H.literal("generating")}),H.object({status:H.literal("ready"),strengths:H.array(Z9A).default([]),weaknesses:H.array(Z9A).default([]),opportunities:H.array(Z9A).default([]),threats:H.array(Z9A).default([]),derivedAt:H.string()})]);function YjQ({items:A}){if(A.length===0)return c7("p",{class:"swot-empty",children:"\u2014"},void 0,!1,void 0,this);return c7("ul",{class:"swot-list",children:A.map((Q)=>c7("li",{class:"swot-item",children:[c7("b",{children:Q.title},void 0,!1,void 0,this),Q.detail?c7("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 N9A({title:A,tone:Q,items:B}){return c7("section",{class:`swot-cell is-${Q}`,children:[c7("div",{class:"swot-head",children:A},void 0,!1,void 0,this),c7(YjQ,{items:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function emA({data:A}){let Q=UjQ.safeParse(A);if(!Q.success||Q.data.status==="generating")return c7("div",{"data-swot-widget":!0,children:c7("p",{class:"muted",children:"generating assessment\u2026"},void 0,!1,void 0,this)},void 0,!1,void 0,this);let B=Q.data;return c7("div",{"data-swot-widget":!0,children:c7("div",{class:"swot",role:"grid","aria-label":"SWOT analysis of agent network",children:[c7(N9A,{title:"Strengths",tone:"s",items:B.strengths},void 0,!1,void 0,this),c7(N9A,{title:"Weaknesses",tone:"w",items:B.weaknesses},void 0,!1,void 0,this),c7(N9A,{title:"Opportunities",tone:"o",items:B.opportunities},void 0,!1,void 0,this),c7(N9A,{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)}WA();var AuA={name:"@brains/assessment",private:!0,version:"0.2.0-alpha.120",description:"Assessment outputs and capability-profile analysis",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts,.tsx","lint:fix":"eslint . --ext .ts,.tsx --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/dashboard":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var QuA=new nF;class BuA extends jQ{entityType="swot";schema=iv;adapter=QuA;initialSyncComplete=!1;constructor(){super("swot",AuA)}async onRegister(A){let Q=new F9A(this.logger.child("SwotDerivationHandler"),A);A.jobs.registerHandler("derive",Q),A.eval.registerHandler("deriveSwot",async()=>{let f=M9.from(async()=>{});if(!f)throw Error("Expected progress reporter to be created");await Q.process({reason:"eval"},"eval-swot-derive",f);let I=await A.entityService.getEntity({entityType:"swot",id:"swot"});if(!I)throw Error("Expected SWOT entity to be created during eval");return QuA.parseSwotContent(I.content).frontmatter});let B=async(f)=>{try{return await A.jobs.enqueue({type:"derive",data:{reason:f},options:{source:this.id,priority:10,deduplication:"coalesce",deduplicationKey:"swot",metadata:{operationType:"data_processing",operationTarget:`swot:${f}`}}})}catch(I){return this.logger.error("Failed to queue SWOT derivation",{error:I,reason:f}),null}},w=async(f)=>{if(!await A.entityService.getEntity({entityType:"swot",id:"swot"}))await B(f)};A.messaging.subscribe("sync:initial:completed",async()=>{return this.initialSyncComplete=!0,await w("initial-missing-entity"),{success:!0}}),A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"dashboard:register-widget",payload:{id:"swot",pluginId:this.id,title:"SWOT",section:"secondary",priority:14,rendererName:"SwotWidget",component:emA,dataProvider:async()=>{let f=await A.entityService.getEntity({entityType:"swot",id:"swot"});if(!f)return{status:"generating"};let{frontmatter:I}=QuA.parseSwotContent(f.content);return{status:"ready",...I}}}}),{success:!0}});let $=async(f)=>{let{entityType:I}=f.payload;if(!this.initialSyncComplete)return{success:!0};if(I!=="agent"&&I!=="skill")return{success:!0};return await B("entity-change"),{success:!0}};A.messaging.subscribe("entity:created",$),A.messaging.subscribe("entity:updated",$),A.messaging.subscribe("entity:deleted",$)}}function wuA(){return new BuA}aA();o$();WA();var If8=new nF,xL1=H.object({name:H.string(),description:H.string(),tags:H.array(H.string())}),$uA=H.enum(["discovered","approved"]),XjQ=H.object({name:H.string(),kind:H.enum(["professional","team","collective"]),organization:H.string().optional(),brainName:H.string(),url:H.string().url(),did:H.string().optional(),status:$uA,discoveredAt:H.string().datetime()}),WjQ=A2.extend({entityType:H.literal("agent"),metadata:H.object({name:H.string(),url:H.string().url(),status:$uA,slug:H.string()})}),HjQ=A2.extend({entityType:H.literal("skill"),metadata:RI}),GjQ=H.object({about:H.string(),skills:H.array(xL1),notes:H.string()});function KjQ(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(`
|
|
8432
8432
|
`)}function FjQ(A){if(!A.trim())return[];return A.split(`
|
|
8433
|
-
`).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 ZjQ=new lB(GjQ,{title:"Agent",mappings:[{key:"about",label:"About",type:"string"},{key:"skills",label:"Skills",type:"custom",formatter:KjQ,parser:FjQ},{key:"notes",label:"Notes",type:"string"}]});class SL1 extends q2{constructor(){super({entityType:"agent",schema:WjQ,frontmatterSchema:XjQ})}fromMarkdown(A){return{content:A,entityType:"agent"}}createAgentContent(A){let Q=ZjQ.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 gL1 extends q2{constructor(){super({entityType:"skill",schema:HjQ,frontmatterSchema:RI})}fromMarkdown(A){let Q=this.parseFrontMatter(A,RI);return{content:A,entityType:"skill",metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}var Df8=new SL1,Uf8=new gL1,Yf8=H.object({skills:H.array(RI),agents:H.array(H.object({id:H.string().optional(),name:H.string(),kind:H.enum(["professional","team","collective"]),organization:H.string().optional(),brainName:H.string(),url:H.string().url(),did:H.string().optional(),status:$uA,discoveredAt:H.string().datetime().optional(),about:H.string(),skills:H.array(xL1),notes:H.string().default("")}))});var NjQ=H.object({}).strict();function z9A(A={}){return NjQ.parse(A),[wuA()]}aA();WA();WA();var fuA=H.object({enabled:H.boolean().default(!0),pdsEndpoint:H.string().url().default("https://bsky.social").describe("AT Protocol PDS service endpoint"),identifier:H.string().optional().describe("PDS login identifier, usually a handle or account DID"),repoDid:H.string().optional().describe("DID of the PDS repo that owns records"),appPassword:H.string().optional().describe("App password for prototype authentication; supply via ${ENV_VAR} interpolation, never a committed literal"),anchorDid:H.string().optional().describe("Optional human/operator DID referenced from records; defaults to did:web:<site-host>:anchor when omitted"),brainDid:H.string().optional().describe("Optional public brain DID referenced from records; defaults to did:web:<site-host> when omitted")});function zjQ(A){return A.replace(/\/+$/,"")}var qjQ=(A,Q)=>fetch(A,Q);async function Kr(A){let Q=await A.json();if(!A.ok){let B=typeof Q==="object"&&Q!==null&&"message"in Q&&typeof Q.message==="string"?Q.message:`AT Protocol request failed with ${A.status}`;throw Error(B)}return Q}class Fr{pdsEndpoint;identifier;appPassword;fetchFn;session;constructor(A){this.pdsEndpoint=zjQ(A.pdsEndpoint),this.identifier=A.identifier,this.appPassword=A.appPassword,this.fetchFn=A.fetch??qjQ}async createSession(){let A=await this.fetchFn(`${this.pdsEndpoint}/xrpc/com.atproto.server.createSession`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({identifier:this.identifier,password:this.appPassword})}),Q=await Kr(A);return this.session=Q,Q}async createRecord(A){let Q=await this.getSession(),B=await this.fetchFn(`${this.pdsEndpoint}/xrpc/com.atproto.repo.createRecord`,{method:"POST",headers:{Authorization:`Bearer ${Q.accessJwt}`,"Content-Type":"application/json"},body:JSON.stringify({repo:A.repo,collection:A.collection,record:A.record,...A.rkey&&{rkey:A.rkey},...A.validate!==void 0&&{validate:A.validate}})});return Kr(B)}async putRecord(A){let Q=await this.getSession(),B=await this.fetchFn(`${this.pdsEndpoint}/xrpc/com.atproto.repo.putRecord`,{method:"POST",headers:{Authorization:`Bearer ${Q.accessJwt}`,"Content-Type":"application/json"},body:JSON.stringify({repo:A.repo,collection:A.collection,record:A.record,rkey:A.rkey,...A.validate!==void 0&&{validate:A.validate},...A.swapRecord!==void 0&&{swapRecord:A.swapRecord}})});return Kr(B)}async getRecord(A){let Q=new URLSearchParams({repo:A.repo,collection:A.collection,rkey:A.rkey}),B=await this.fetchFn(`${this.pdsEndpoint}/xrpc/com.atproto.repo.getRecord?${Q.toString()}`,{method:"GET"});return Kr(B)}async uploadBlob(A){let Q=await this.getSession(),B=await this.fetchFn(`${this.pdsEndpoint}/xrpc/com.atproto.repo.uploadBlob`,{method:"POST",headers:{Authorization:`Bearer ${Q.accessJwt}`,"Content-Type":A.mimeType},body:new Blob([new Uint8Array(A.data)],{type:A.mimeType})});return Kr(B)}async getSession(){return this.session??=await this.createSession(),this.session}}function VC(A){return A?.startsWith("did:web:")??!1}function q9A(A){if(!VC(A))return;let Q=A.slice(8);if(!Q)return;let[B]=Q.split(":");if(!B)return;try{return decodeURIComponent(B)}catch{return B}}function mL1(A){if(!VC(A))return;let Q=A.slice(8);if(!Q)return;let[,...B]=Q.split(":");if(B.length===0)return"/.well-known/did.json";return`/${B.map(($)=>{try{return decodeURIComponent($)}catch{return $}}).join("/")}/did.json`}function uL1(A){return A.replace(/\/+$/,"")}function Zr(A){return`did:web:${encodeURIComponent(A)}`}function L9A(A){return`${Zr(A)}:anchor`}function IuA(A){return{"@context":["https://www.w3.org/ns/did/v1"],id:A}}function cL1(A,Q){let B=A.identifier?.startsWith("did:")?void 0:A.identifier?[`at://${A.identifier}`]:void 0;return{...IuA(Q),...B&&{alsoKnownAs:B},service:[{id:"#atproto_pds",type:"AtprotoPersonalDataServer",serviceEndpoint:uL1(A.pdsEndpoint)}]}}function lL1(A){if(!VC(A.brainDid))return null;return cL1(A,A.brainDid)}function hL1(A,Q){if(!A||!Q)return;let B=q9A(A),w=mL1(A);if(!B||!w)return;return{path:w,hostname:B,document:Q}}function V9A(A){let Q=[],B=hL1(A.brainDid,lL1(A));if(B)Q.push(B);if(VC(A.anchorDid)&&A.anchorDid!==A.brainDid){let w=hL1(A.anchorDid,IuA(A.anchorDid));if(w)Q.push(w)}return Q}function DuA(A,Q){let B=[];if(!A.brainDid){let w=Zr(Q);B.push({path:"/.well-known/did.json",hostname:Q,document:cL1(A,w)})}if(!A.anchorDid){let w=L9A(Q);B.push({path:"/anchor/did.json",hostname:Q,document:IuA(w)})}return B}function LjQ(A,Q){if(!A)return;try{return new URL(A,Q).toString()}catch{return}}function VjQ(A){let Q=A.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,200);return Q.length>0?Q:"skill"}function pL1(A,Q){let B=A[Q];return typeof B==="string"&&B.length>0?B:void 0}function iL1(A,Q){let B=A[Q];if(!Array.isArray(B))return;let w=B.filter(($)=>typeof $==="string"&&$.length>0);return w.length>0?w:void 0}function EjQ(A){let Q=A.metadata,B=pL1(Q,"name"),w=pL1(Q,"description");if(!B||!w)return;let $=iL1(Q,"tags"),f=iL1(Q,"examples");return{id:VjQ(B),name:B,description:w,...$&&{tags:$},...f&&{examples:f}}}async function MjQ(A){if(!A.entityService.hasEntityType("skill"))return[];return(await A.entityService.listEntities({entityType:"skill",options:{filter:{visibilityScope:"public"}}})).map((B)=>EjQ(B)).filter((B)=>B!==void 0).slice(0,100)}async function UuA(A,Q,B=new Date){let w=A.identity.get(),$=A.identity.getProfile(),f=await A.identity.getAppInfo(),I=LjQ(A.siteUrl??$.website,void 0);if(!I)throw Error("AT Protocol brain card publishing requires siteUrl");let D=new URL(I).hostname,U=Q.brainDid??Zr(D),Y=Q.anchorDid??L9A(D);if(VC(U)){if(q9A(U)!==D)throw Error("AT Protocol brain card did:web host must match siteUrl host")}let J=await MjQ(A);return{$type:"ai.rizom.brain.card",siteUrl:I,brain:{did:U,name:w.name,role:w.role,purpose:w.purpose,values:w.values},anchor:{did:Y,name:$.name,kind:$.kind},skills:J,model:f.model,version:f.version,createdAt:B.toISOString(),updatedAt:B.toISOString()}}WA();var rL1={dryRun:H.boolean().default(!1).describe("Build and return the card record without writing to the PDS")},CjQ={},dL1={entityType:H.string().describe("Local entity type with a registered AT Protocol projection"),entityId:H.string().optional().describe("Local entity ID to publish"),slug:H.string().optional().describe("Local entity slug to publish"),dryRun:H.boolean().default(!1).describe("Build and return the record without writing to the PDS"),topics:H.array(H.string()).optional().describe("Optional topic labels to include in the AT Protocol record")},nL1={repos:H.array(H.string().min(1)).min(1).max(50).describe("Candidate AT Protocol repo DIDs or handles to inspect")},oL1={entityId:H.string().optional().describe("Local blog post entity ID to publish"),slug:H.string().optional().describe("Local blog post slug to publish"),dryRun:H.boolean().default(!1).describe("Build and return the post record without writing to the PDS"),topics:H.array(H.string()).optional().describe("Optional topic labels to include in the AT Protocol record")};function sL1(A,Q,B){return[OjQ(A,Q),RjQ(A,Q,B),bjQ(A,Q,B),kjQ(A,Q,B),PjQ(A,Q,B)]}function OjQ(A,Q){return{name:`${A}_validate_credentials`,description:"Validate AT Protocol PDS credentials without publishing records.",inputSchema:CjQ,handler:async()=>{return{success:!0,data:{valid:await Q.validatePdsCredentials()}}}}}function RjQ(A,Q,B){return{name:`${A}_publish_card`,description:"Publish this brain's AT Protocol discovery card to the configured PDS, or dry-run the record payload.",inputSchema:rL1,handler:async(w)=>{let $=H.object(rL1).safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};try{return{success:!0,data:await Q.publishBrainCard(B,{dryRun:$.data.dryRun})}}catch(f){return{success:!1,error:f instanceof Error?f.message:"Publish failed"}}}}}function bjQ(A,Q,B){return{name:`${A}_publish_entity`,description:"Publish any public local entity with a registered AT Protocol projection, or dry-run the record payload.",inputSchema:dL1,handler:async(w)=>{let $=H.object(dL1).safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};try{if(!$.data.entityId&&!$.data.slug)return{success:!1,error:"Invalid input: entityId or slug is required"};return{success:!0,data:await Q.publishEntity(B,{entityType:$.data.entityType,...$.data.entityId&&{entityId:$.data.entityId},...$.data.slug&&{slug:$.data.slug},dryRun:$.data.dryRun,...$.data.topics&&{topics:$.data.topics}})}}catch(f){return{success:!1,error:f instanceof Error?f.message:"Publish failed"}}}}}function PjQ(A,Q,B){return{name:`${A}_discover_brain_cards`,description:"Read public ai.rizom.brain.card/self records from candidate AT Protocol repo DIDs or handles and emit internal discovery events.",inputSchema:nL1,handler:async(w)=>{let $=H.object(nL1).safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};try{return{success:!0,data:await Q.discoverBrainCards(B,{repos:$.data.repos})}}catch(f){return{success:!1,error:f instanceof Error?f.message:"Discovery failed"}}}}}function kjQ(A,Q,B){return{name:`${A}_publish_post`,description:"Publish a local blog post entity as an ai.rizom.brain.post AT Protocol record, or dry-run the record payload.",inputSchema:oL1,handler:async(w)=>{let $=H.object(oL1).safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};try{if(!$.data.entityId&&!$.data.slug)return{success:!1,error:"Invalid input: entityId or slug is required"};return{success:!0,data:await Q.publishPost(B,{...$.data.entityId&&{entityId:$.data.entityId},...$.data.slug&&{slug:$.data.slug},dryRun:$.data.dryRun,...$.data.topics&&{topics:$.data.topics}})}}catch(f){return{success:!1,error:f instanceof Error?f.message:"Publish failed"}}}}}var aL1={name:"@brains/atproto",private:!0,version:"0.2.0-alpha.119",description:"AT Protocol integration for identity, publishing, discovery, and feeds",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/atproto-contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var tL1=Gw["ai.rizom.brain.card"],_jQ="ai.rizom.brain.card",vjQ="self",eL1=50;class YuA extends YB{deps;projectionRegistry;constructor(A={},Q={}){super("atproto",aL1,A,fuA);this.deps=Q,this.projectionRegistry=Q.projectionRegistry??d6.getInstance()}getWebRoutes(){if(!this.config.enabled)return[];let A=V9A(this.config),Q=[...!this.config.brainDid?["/.well-known/did.json"]:[],...!this.config.anchorDid?["/anchor/did.json"]:[]];return[...new Set([...A.map((w)=>w.path),...Q])].map((w)=>({path:w,method:"GET",public:!0,handler:($)=>{let f=new URL($.url).hostname,I=[...V9A(this.config),...DuA(this.config,f)].filter((U)=>U.path===w),D=I.find((U)=>U.hostname===f)??I[0];if(!D)return new Response("Not found",{status:404});return new Response(JSON.stringify(D.document),{headers:{"Content-Type":"application/did+json"}})}}))}async publishBrainCard(A,Q={}){let B=await UuA(A,this.config);Tz(tL1,B);let w=this.config.repoDid;if(Q.dryRun)return{record:B,dryRun:!0,...w&&{repo:w}};let $=this.resolveAppPassword();if(!this.config.identifier||!$)throw Error("AT Protocol publishing requires identifier and app password configuration");let f=this.createPdsClient($),I=await f.createSession(),D=w??I.did;if(!f.putRecord)throw Error("AT Protocol PDS client does not support record upserts");let U=await f.putRecord({repo:D,collection:"ai.rizom.brain.card",rkey:"self",validate:!1,record:B});return{record:B,repo:D,uri:U.uri,cid:U.cid,dryRun:!1}}async publishEntity(A,Q){let B=this.projectionRegistry.get(Q.entityType);if(!B)throw Error(`No AT Protocol projection registered for ${Q.entityType}`);return this.publishProjectedEntity(A,Q,B)}async publishPost(A,Q){let B=this.projectionRegistry.get("post");if(!B)throw Error("No AT Protocol projection registered for post");return this.publishProjectedEntity(A,{entityType:"post",...Q},B)}async discoverBrainCards(A,Q){let B=[...new Set(Q.repos.map((f)=>f.trim()))].filter((f)=>f.length>0);if(B.length===0)throw Error("AT Protocol discovery requires at least one repo DID or handle");if(B.length>eL1)throw Error(`AT Protocol discovery accepts at most ${eL1} repos per batch`);let w=new Set,$=[];for(let f of B)try{let I=await this.resolveRepoPdsEndpoint(f),D=this.createPublicPdsClient(I.pdsEndpoint);if(!D.getRecord)throw Error("AT Protocol PDS client does not support record reads");let U=await D.getRecord({repo:I.repoDid,collection:_jQ,rkey:vjQ});Tz(tL1,U.value);let Y=yjQ(U.uri)??I.repoDid,J=`${Y}:${U.uri}:${U.cid}`;if(w.has(J)){$.push({repo:f,status:"skipped",repoDid:Y,uri:U.uri,cid:U.cid,error:"Duplicate brain card in discovery batch"});continue}w.add(J),await A.messaging.send({type:$5A,payload:{repoDid:Y,uri:U.uri,cid:U.cid,record:U.value},broadcast:!0}),$.push({repo:f,status:"discovered",repoDid:Y,uri:U.uri,cid:U.cid})}catch(I){$.push({repo:f,status:"skipped",error:T0(I)})}return{discovered:$.filter((f)=>f.status==="discovered").length,skipped:$.filter((f)=>f.status==="skipped").length,results:$}}async validatePdsCredentials(){let A=this.resolveAppPassword();if(!this.config.identifier||!A)return!1;try{return await this.createPdsClient(A).createSession(),!0}catch(Q){return this.logger.warn("AT Protocol PDS authentication failed",{error:T0(Q)}),!1}}async getTools(){if(!this.config.enabled)return[];return sL1(this.id,this,this.getContext())}async getInstructions(){if(!this.config.enabled)return;return"## AT Protocol publishing\n- Use `atproto_validate_credentials` to check PDS credentials before publishing.\n- Use `atproto_publish_card` to publish or dry-run this brain's public discovery card.\n- Use `atproto_publish_entity` to publish any public entity with a registered AT Protocol projection.\n- Use `atproto_publish_post` for the blog-post convenience path by `entityId` or `slug`.\n- Use `atproto_discover_brain_cards` to read public `ai.rizom.brain.card/self` records from candidate repo DIDs or handles and emit internal discovery events.\n- Prefer `dryRun: true` first when publishing new AT Protocol records.\n- Only public posts and public cover images can be published."}async publishProjectedEntity(A,Q,B){let w=await this.findPublishEntity(A,Q),$=Q.entityId??Q.slug;if(!$)throw Error(`${Q.entityType} publish requires entityId or slug`);if(!w)throw Error(`${Q.entityType} not found: ${$}`);if(w.visibility!=="public")throw Error(`Cannot publish non-public ${Q.entityType}: ${$}`);let f=this.config.repoDid;if(Q.dryRun){let G=await B.buildRecord({entity:w,context:A,config:this.config,...Q.topics&&{topics:Q.topics},dryRun:!0});return Tz(B.lexicon,G),{record:G,dryRun:!0,...f&&{repo:f}}}let I=this.resolveAppPassword();if(!this.config.identifier||!I)throw Error("AT Protocol publishing requires identifier and app password configuration");let D=this.createPdsClient(I),U=await D.createSession(),Y=f??U.did,J=await B.buildRecord({entity:w,context:A,config:this.config,client:D,...Q.topics&&{topics:Q.topics}});if(Tz(B.lexicon,J),!D.putRecord)throw Error("AT Protocol PDS client does not support record upserts");let X=await D.putRecord({repo:Y,collection:B.collection,rkey:TjQ(w.id),...B.validate!==void 0&&{validate:B.validate},record:J});return await B.onPublished?.({entity:w,context:A,record:J,uri:X.uri,cid:X.cid}),{record:J,repo:Y,uri:X.uri,cid:X.cid,dryRun:!1}}async findPublishEntity(A,Q){if(Q.entityId)return A.entityService.getEntity({entityType:Q.entityType,id:Q.entityId});if(Q.slug)return(await A.entityService.listEntities({entityType:Q.entityType,options:{filter:{metadata:{slug:Q.slug}}}}))[0]??null;return null}createPublicPdsClient(A){if(this.deps.createPdsClient)return this.deps.createPdsClient({pdsEndpoint:A,identifier:this.config.identifier??"",appPassword:this.config.appPassword??""});return new Fr({pdsEndpoint:A,identifier:this.config.identifier??"",appPassword:this.config.appPassword??""})}async resolveRepoPdsEndpoint(A){let Q=A.startsWith("did:")?A:await this.resolveHandleToDid(A);if(!Q)throw Error(`Could not resolve AT Protocol repo: ${A}`);let B=await this.resolveDidToPdsEndpoint(Q);if(!B)throw Error(`Could not resolve AT Protocol PDS for repo: ${Q}`);return{repoDid:Q,pdsEndpoint:B}}async resolveHandleToDid(A){let Q=new URL("/xrpc/com.atproto.identity.resolveHandle",this.config.pdsEndpoint);Q.searchParams.set("handle",A);let B=await this.fetch(Q.toString());if(!B.ok)return;let w=await B.json();if(typeof w!=="object"||w===null||!("did"in w))return;return typeof w.did==="string"?w.did:void 0}async resolveDidToPdsEndpoint(A){let Q=A.startsWith("did:plc:")?await this.fetchJson(`https://plc.directory/${encodeURIComponent(A)}`):A.startsWith("did:web:")?await this.fetchJson(xjQ(A)):void 0;if(typeof Q!=="object"||Q===null)return;let B=Q.service;if(!Array.isArray(B))return;let w=B.find(($)=>{return typeof $==="object"&&$!==null&&($.id==="#atproto_pds"||$.type==="AtprotoPersonalDataServer")});return typeof w?.serviceEndpoint==="string"?w.serviceEndpoint:void 0}async fetchJson(A){let Q=await this.fetch(A);if(!Q.ok)return;return Q.json()}fetch(A){return(this.deps.fetch??fetch)(A)}createPdsClient(A){if(this.deps.createPdsClient)return this.deps.createPdsClient({pdsEndpoint:this.config.pdsEndpoint,identifier:this.config.identifier??"",appPassword:A});return new Fr({pdsEndpoint:this.config.pdsEndpoint,identifier:this.config.identifier??"",appPassword:A})}resolveAppPassword(){return this.config.appPassword}}function TjQ(A){let Q=A.replace(/[^A-Za-z0-9._~:-]/g,"_").slice(0,512);return Q.length>0?Q:"self"}function yjQ(A){return/^at:\/\/([^/]+)/.exec(A)?.[1]}function xjQ(A){let Q=A.slice(8).split(":").map(decodeURIComponent),[B,...w]=Q;if(!B)throw Error(`Invalid did:web value: ${A}`);if(w.length===0)return`https://${B}/.well-known/did.json`;return`https://${B}/${w.join("/")}/did.json`}function E9A(A,Q){return new YuA(A,Q)}aA();WA();Ew();f5();WA();aA();var M9A=Xs.extend({expertise:H.array(H.string()).optional().describe("Skills, domains, areas of focus"),currentFocus:H.string().optional().describe("What you're currently working on"),availability:H.string().optional().describe("What you're open to (consulting, speaking, etc.)")}),ez=lY.extend(M9A.shape);aA();nG();WA();var SjQ=new wW;class C9A{postsListUrl;decksListUrl;id="professional:homepage-list";name="Homepage List DataSource";description="Fetches profile, blog posts, and presentation decks for homepage";constructor(A,Q){this.postsListUrl=A;this.decksListUrl=Q}async fetch(A,Q,B){let w=B.entityService,[$,f,I,D]=await Promise.all([gR(w),w.listEntities({entityType:"post",options:{limit:20}}),w.listEntities({entityType:"deck",options:{limit:20}}),tp(w)]),U=SjQ.parseProfileBody($,ez),Y=f.sort(cy).slice(0,3).map(Qi),J=I.sort(cy).slice(0,3).map(Di);if(!D.cta)throw Error("CTA not configured in site-info");let X={profile:U,posts:Y,decks:J,postsListUrl:this.postsListUrl,decksListUrl:this.decksListUrl,cta:D.cta,sections:D.sections??{}};return Q.parse(X)}}aA();nG();var gjQ=new wW;class O9A{id="professional:about";name="About Page DataSource";description="Fetches full profile data for the about page";async fetch(A,Q,B){let w=await gR(B.entityService),f={profile:gjQ.parseProfileBody(w,ez)};return Q.parse(f)}}import{jsxDEV as w8,Fragment as ujQ}from"preact/jsx-dev-runtime";var hjQ="grid md:grid-cols-[14rem_1px_1fr] gap-y-2 gap-x-0 md:gap-16 items-start",mjQ="border-t md:border-t-0 md:border-l border-rule-strong md:self-stretch",JuA=({number:A,title:Q,blurb:B,children:w})=>w8("section",{className:"py-20 border-b border-rule px-6 md:px-12",children:w8("div",{className:"max-w-6xl mx-auto",children:w8("div",{className:hjQ,children:[w8(vTA,{title:Q,number:A,blurb:B},void 0,!1,void 0,this),w8("div",{className:mjQ,"aria-hidden":"true"},void 0,!1,void 0,this),w8("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),XuA=({profile:A,posts:Q,decks:B,postsListUrl:w,decksListUrl:$,cta:f,sections:I})=>{let D=A.tagline||A.description,U=Q.map((Z)=>({id:Z.id,url:Z.url,title:Z.metadata.title,date:Z.metadata.publishedAt||Z.created,description:Z.frontmatter.excerpt,series:Z.frontmatter.seriesName&&Z.frontmatter.seriesIndex?{name:Z.frontmatter.seriesName,index:Z.frontmatter.seriesIndex}:void 0})),Y=B.map((Z)=>({id:Z.id,url:Z.url,title:Z.frontmatter.title||Z.id,date:Z.frontmatter.publishedAt??Z.created,description:Z.frontmatter.description})),J=A.name||"Home",X=A.intro||A.description||D||"Professional site",G=Boolean(A.description)||A.expertise!==void 0&&A.expertise.length>0;return w8(ujQ,{children:[w8(KQ,{title:J,description:X,ogType:"website"},void 0,!1,void 0,this),w8("div",{className:"homepage-list bg-theme",children:[w8("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:w8("div",{className:"relative z-10 max-w-6xl mx-auto w-full",children:[A.name&&w8("div",{className:"flex items-center gap-[0.6rem] mb-6 font-mono text-[0.7rem] font-medium uppercase tracking-[0.22em] text-accent",children:[w8("span",{className:"w-[18px] h-px bg-accent","aria-hidden":"true"},void 0,!1,void 0,this),w8("span",{children:A.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),D&&w8("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:N8A(D,"italic font-normal text-accent [font-variation-settings:'opsz'_144,'SOFT'_80]")},void 0,!1,void 0,this),A.intro&&w8("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:N8A(A.intro,"italic text-accent")},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),w8(JuA,{number:"01",title:"Essays",blurb:I.essays?.blurb,children:w8(Z8A,{items:U,viewAllUrl:w,viewAllLabel:"View all essays"},void 0,!1,void 0,this)},void 0,!1,void 0,this),Y.length>0&&w8(JuA,{number:"02",title:"Presentations",blurb:I.presentations?.blurb,children:w8(Z8A,{items:Y,viewAllUrl:$,viewAllLabel:"View all presentations"},void 0,!1,void 0,this)},void 0,!1,void 0,this),G&&w8(JuA,{number:"03",title:"About",blurb:I.about?.blurb,children:w8("div",{className:"flex flex-col gap-8",children:[A.description&&w8("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&&w8(TTA,{subjects:A.expertise},void 0,!1,void 0,this),w8("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",w8("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),w8(NTA,{cta:f,variant:"editorial",socialLinks:A.socialLinks},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as Fw,Fragment as cjQ}from"preact/jsx-dev-runtime";var WuA=({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 Fw(cjQ,{children:[Fw(KQ,{title:Q,description:B,ogType:"profile"},void 0,!1,void 0,this),Fw("div",{className:"about-page bg-theme",children:[Fw("header",{className:"hero-bg-pattern relative w-full py-16 md:py-24 px-6 md:px-12 bg-theme overflow-hidden",children:Fw("div",{className:"relative z-10 max-w-4xl mx-auto",children:[Fw("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&&Fw("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),Fw("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-12 md:py-16",children:[A.story&&Fw("section",{className:"content-section-reveal mb-20 md:mb-28",children:Fw(V$,{markdown:A.story},void 0,!1,void 0,this)},void 0,!1,void 0,this),w&&Fw("div",{className:"content-section-reveal grid md:grid-cols-2 gap-x-16 gap-y-12",children:[A.expertise&&A.expertise.length>0&&Fw("section",{children:[Fw("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Expertise"},void 0,!1,void 0,this),Fw("ul",{className:"flex flex-wrap gap-3",children:A.expertise.map(($,f)=>Fw("li",{className:Ap({variant:"accent",size:"lg"}),children:$},f,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.currentFocus&&Fw("section",{children:[Fw("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Current Focus"},void 0,!1,void 0,this),Fw("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&&Fw("section",{children:[Fw("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Availability"},void 0,!1,void 0,this),Fw("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)&&Fw("section",{children:[Fw("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Contact"},void 0,!1,void 0,this),Fw("div",{className:"space-y-4",children:[A.email&&Fw("p",{className:"text-lg",children:Fw("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&&Fw("p",{className:"text-lg",children:Fw("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&&Fw("div",{className:"flex flex-wrap gap-4 mt-4",children:A.socialLinks.map(($,f)=>Fw(L$,{href:$.url,external:!0,variant:"secondary",size:"md",children:$.label||$.platform},f,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as l7,Fragment as AV1}from"preact/jsx-dev-runtime";var HuA=()=>{return l7(AV1,{children:[l7(KQ,{title:"Thanks for subscribing!",description:"You've successfully subscribed to the newsletter."},void 0,!1,void 0,this),l7("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:l7("div",{className:"text-center max-w-md",children:[l7("div",{className:"text-6xl mb-6",children:"\uD83C\uDF89"},void 0,!1,void 0,this),l7("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Thanks for subscribing!"},void 0,!1,void 0,this),l7("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),l7(L$,{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)},GuA=()=>{return l7(AV1,{children:[l7(KQ,{title:"Subscription failed",description:"There was a problem with your subscription."},void 0,!1,void 0,this),l7("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:l7("div",{className:"text-center max-w-md",children:[l7("div",{className:"text-6xl mb-6",children:"\uD83D\uDE22"},void 0,!1,void 0,this),l7("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Something went wrong"},void 0,!1,void 0,this),l7("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),l7(L$,{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)};WA();var QV1=H.object({label:H.string().describe("Display label for entity type (e.g., 'Essay')"),pluralName:H.string().optional().describe("URL path segment (defaults to label.toLowerCase() + 's')")}),BV1=H.object({entityDisplay:H.object({post:QV1,deck:QV1}).describe("Display metadata for post and deck entity types (required for homepage)")});var wV1={name:"@brains/site-professional",private:!0,version:"0.2.0-alpha.119",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 KuA extends YB{dependencies=["blog","decks"];constructor(A){super("professional-site",wV1,A,BV1)}async onRegister(A){A.entities.extendFrontmatterSchema("anchor-profile",M9A);let Q=this.config.entityDisplay.post,B=this.config.entityDisplay.deck,w=`/${Q.pluralName??Q.label.toLowerCase()+"s"}`,$=`/${B.pluralName??B.label.toLowerCase()+"s"}`,f=new C9A(w,$);A.entities.registerDataSource(f);let I=new O9A;A.entities.registerDataSource(I);let D=H.object({profile:ez,posts:H.array(SF),decks:H.array(wC),postsListUrl:H.string(),decksListUrl:H.string(),cta:ASA,sections:H.record(H.string(),No)}),U=H.object({profile:ez}),Y=H.object({});A.templates.register({"homepage-list":P1({name:"homepage-list",description:"Professional homepage with essays and presentations",schema:D,dataSourceId:"professional:homepage-list",requiredPermission:"public",layout:{component:XuA}}),about:P1({name:"about",description:"About page with full profile information",schema:U,dataSourceId:"professional:about",requiredPermission:"public",layout:{component:WuA}}),"subscribe-thanks":P1({name:"subscribe-thanks",description:"Newsletter subscription success page",schema:Y,requiredPermission:"public",layout:{component:HuA}}),"subscribe-error":P1({name:"subscribe-error",description:"Newsletter subscription error page",schema:Y,requiredPermission:"public",layout:{component:GuA}})}),this.logger.info("Professional site plugin registered successfully")}async getTools(){return[]}async getResources(){return[]}}function $V1(A){return new KuA(A??{})}var fV1=[{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 R9A}from"preact/jsx-dev-runtime";function IV1({sections:A,siteInfo:Q,slots:B,wordmark:w}){return R9A("div",{className:"flex flex-col min-h-screen bg-theme overflow-x-clip",children:[R9A(VTA,{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),R9A("main",{className:"flex-grow flex flex-col bg-theme",children:A},void 0,!1,void 0,this),R9A(qTA,{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 pjQ={layouts:{default:IV1},routes:fV1,plugin:$V1,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"}}}},Nr=pjQ;var DV1=`/*
|
|
8433
|
+
`).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 ZjQ=new lB(GjQ,{title:"Agent",mappings:[{key:"about",label:"About",type:"string"},{key:"skills",label:"Skills",type:"custom",formatter:KjQ,parser:FjQ},{key:"notes",label:"Notes",type:"string"}]});class SL1 extends q2{constructor(){super({entityType:"agent",schema:WjQ,frontmatterSchema:XjQ})}fromMarkdown(A){return{content:A,entityType:"agent"}}createAgentContent(A){let Q=ZjQ.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 gL1 extends q2{constructor(){super({entityType:"skill",schema:HjQ,frontmatterSchema:RI})}fromMarkdown(A){let Q=this.parseFrontMatter(A,RI);return{content:A,entityType:"skill",metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}var Df8=new SL1,Uf8=new gL1,Yf8=H.object({skills:H.array(RI),agents:H.array(H.object({id:H.string().optional(),name:H.string(),kind:H.enum(["professional","team","collective"]),organization:H.string().optional(),brainName:H.string(),url:H.string().url(),did:H.string().optional(),status:$uA,discoveredAt:H.string().datetime().optional(),about:H.string(),skills:H.array(xL1),notes:H.string().default("")}))});var NjQ=H.object({}).strict();function z9A(A={}){return NjQ.parse(A),[wuA()]}aA();WA();WA();var fuA=H.object({enabled:H.boolean().default(!0),pdsEndpoint:H.string().url().default("https://bsky.social").describe("AT Protocol PDS service endpoint"),identifier:H.string().optional().describe("PDS login identifier, usually a handle or account DID"),repoDid:H.string().optional().describe("DID of the PDS repo that owns records"),appPassword:H.string().optional().describe("App password for prototype authentication; supply via ${ENV_VAR} interpolation, never a committed literal"),anchorDid:H.string().optional().describe("Optional human/operator DID referenced from records; defaults to did:web:<site-host>:anchor when omitted"),brainDid:H.string().optional().describe("Optional public brain DID referenced from records; defaults to did:web:<site-host> when omitted")});function zjQ(A){return A.replace(/\/+$/,"")}var qjQ=(A,Q)=>fetch(A,Q);async function Kr(A){let Q=await A.json();if(!A.ok){let B=typeof Q==="object"&&Q!==null&&"message"in Q&&typeof Q.message==="string"?Q.message:`AT Protocol request failed with ${A.status}`;throw Error(B)}return Q}class Fr{pdsEndpoint;identifier;appPassword;fetchFn;session;constructor(A){this.pdsEndpoint=zjQ(A.pdsEndpoint),this.identifier=A.identifier,this.appPassword=A.appPassword,this.fetchFn=A.fetch??qjQ}async createSession(){let A=await this.fetchFn(`${this.pdsEndpoint}/xrpc/com.atproto.server.createSession`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({identifier:this.identifier,password:this.appPassword})}),Q=await Kr(A);return this.session=Q,Q}async createRecord(A){let Q=await this.getSession(),B=await this.fetchFn(`${this.pdsEndpoint}/xrpc/com.atproto.repo.createRecord`,{method:"POST",headers:{Authorization:`Bearer ${Q.accessJwt}`,"Content-Type":"application/json"},body:JSON.stringify({repo:A.repo,collection:A.collection,record:A.record,...A.rkey&&{rkey:A.rkey},...A.validate!==void 0&&{validate:A.validate}})});return Kr(B)}async putRecord(A){let Q=await this.getSession(),B=await this.fetchFn(`${this.pdsEndpoint}/xrpc/com.atproto.repo.putRecord`,{method:"POST",headers:{Authorization:`Bearer ${Q.accessJwt}`,"Content-Type":"application/json"},body:JSON.stringify({repo:A.repo,collection:A.collection,record:A.record,rkey:A.rkey,...A.validate!==void 0&&{validate:A.validate},...A.swapRecord!==void 0&&{swapRecord:A.swapRecord}})});return Kr(B)}async getRecord(A){let Q=new URLSearchParams({repo:A.repo,collection:A.collection,rkey:A.rkey}),B=await this.fetchFn(`${this.pdsEndpoint}/xrpc/com.atproto.repo.getRecord?${Q.toString()}`,{method:"GET"});return Kr(B)}async uploadBlob(A){let Q=await this.getSession(),B=await this.fetchFn(`${this.pdsEndpoint}/xrpc/com.atproto.repo.uploadBlob`,{method:"POST",headers:{Authorization:`Bearer ${Q.accessJwt}`,"Content-Type":A.mimeType},body:new Blob([new Uint8Array(A.data)],{type:A.mimeType})});return Kr(B)}async getSession(){return this.session??=await this.createSession(),this.session}}function VC(A){return A?.startsWith("did:web:")??!1}function q9A(A){if(!VC(A))return;let Q=A.slice(8);if(!Q)return;let[B]=Q.split(":");if(!B)return;try{return decodeURIComponent(B)}catch{return B}}function mL1(A){if(!VC(A))return;let Q=A.slice(8);if(!Q)return;let[,...B]=Q.split(":");if(B.length===0)return"/.well-known/did.json";return`/${B.map(($)=>{try{return decodeURIComponent($)}catch{return $}}).join("/")}/did.json`}function uL1(A){return A.replace(/\/+$/,"")}function Zr(A){return`did:web:${encodeURIComponent(A)}`}function L9A(A){return`${Zr(A)}:anchor`}function IuA(A){return{"@context":["https://www.w3.org/ns/did/v1"],id:A}}function cL1(A,Q){let B=A.identifier?.startsWith("did:")?void 0:A.identifier?[`at://${A.identifier}`]:void 0;return{...IuA(Q),...B&&{alsoKnownAs:B},service:[{id:"#atproto_pds",type:"AtprotoPersonalDataServer",serviceEndpoint:uL1(A.pdsEndpoint)}]}}function lL1(A){if(!VC(A.brainDid))return null;return cL1(A,A.brainDid)}function hL1(A,Q){if(!A||!Q)return;let B=q9A(A),w=mL1(A);if(!B||!w)return;return{path:w,hostname:B,document:Q}}function V9A(A){let Q=[],B=hL1(A.brainDid,lL1(A));if(B)Q.push(B);if(VC(A.anchorDid)&&A.anchorDid!==A.brainDid){let w=hL1(A.anchorDid,IuA(A.anchorDid));if(w)Q.push(w)}return Q}function DuA(A,Q){let B=[];if(!A.brainDid){let w=Zr(Q);B.push({path:"/.well-known/did.json",hostname:Q,document:cL1(A,w)})}if(!A.anchorDid){let w=L9A(Q);B.push({path:"/anchor/did.json",hostname:Q,document:IuA(w)})}return B}function LjQ(A,Q){if(!A)return;try{return new URL(A,Q).toString()}catch{return}}function VjQ(A){let Q=A.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,200);return Q.length>0?Q:"skill"}function pL1(A,Q){let B=A[Q];return typeof B==="string"&&B.length>0?B:void 0}function iL1(A,Q){let B=A[Q];if(!Array.isArray(B))return;let w=B.filter(($)=>typeof $==="string"&&$.length>0);return w.length>0?w:void 0}function EjQ(A){let Q=A.metadata,B=pL1(Q,"name"),w=pL1(Q,"description");if(!B||!w)return;let $=iL1(Q,"tags"),f=iL1(Q,"examples");return{id:VjQ(B),name:B,description:w,...$&&{tags:$},...f&&{examples:f}}}async function MjQ(A){if(!A.entityService.hasEntityType("skill"))return[];return(await A.entityService.listEntities({entityType:"skill",options:{filter:{visibilityScope:"public"}}})).map((B)=>EjQ(B)).filter((B)=>B!==void 0).slice(0,100)}async function UuA(A,Q,B=new Date){let w=A.identity.get(),$=A.identity.getProfile(),f=await A.identity.getAppInfo(),I=LjQ(A.siteUrl??$.website,void 0);if(!I)throw Error("AT Protocol brain card publishing requires siteUrl");let D=new URL(I).hostname,U=Q.brainDid??Zr(D),Y=Q.anchorDid??L9A(D);if(VC(U)){if(q9A(U)!==D)throw Error("AT Protocol brain card did:web host must match siteUrl host")}let J=await MjQ(A);return{$type:"ai.rizom.brain.card",siteUrl:I,brain:{did:U,name:w.name,role:w.role,purpose:w.purpose,values:w.values},anchor:{did:Y,name:$.name,kind:$.kind},skills:J,model:f.model,version:f.version,createdAt:B.toISOString(),updatedAt:B.toISOString()}}WA();var rL1={dryRun:H.boolean().default(!1).describe("Build and return the card record without writing to the PDS")},CjQ={},dL1={entityType:H.string().describe("Local entity type with a registered AT Protocol projection"),entityId:H.string().optional().describe("Local entity ID to publish"),slug:H.string().optional().describe("Local entity slug to publish"),dryRun:H.boolean().default(!1).describe("Build and return the record without writing to the PDS"),topics:H.array(H.string()).optional().describe("Optional topic labels to include in the AT Protocol record")},nL1={repos:H.array(H.string().min(1)).min(1).max(50).describe("Candidate AT Protocol repo DIDs or handles to inspect")},oL1={entityId:H.string().optional().describe("Local blog post entity ID to publish"),slug:H.string().optional().describe("Local blog post slug to publish"),dryRun:H.boolean().default(!1).describe("Build and return the post record without writing to the PDS"),topics:H.array(H.string()).optional().describe("Optional topic labels to include in the AT Protocol record")};function sL1(A,Q,B){return[OjQ(A,Q),RjQ(A,Q,B),bjQ(A,Q,B),kjQ(A,Q,B),PjQ(A,Q,B)]}function OjQ(A,Q){return{name:`${A}_validate_credentials`,description:"Validate AT Protocol PDS credentials without publishing records.",inputSchema:CjQ,handler:async()=>{return{success:!0,data:{valid:await Q.validatePdsCredentials()}}}}}function RjQ(A,Q,B){return{name:`${A}_publish_card`,description:"Publish this brain's AT Protocol discovery card to the configured PDS, or dry-run the record payload.",inputSchema:rL1,handler:async(w)=>{let $=H.object(rL1).safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};try{return{success:!0,data:await Q.publishBrainCard(B,{dryRun:$.data.dryRun})}}catch(f){return{success:!1,error:f instanceof Error?f.message:"Publish failed"}}}}}function bjQ(A,Q,B){return{name:`${A}_publish_entity`,description:"Publish any public local entity with a registered AT Protocol projection, or dry-run the record payload.",inputSchema:dL1,handler:async(w)=>{let $=H.object(dL1).safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};try{if(!$.data.entityId&&!$.data.slug)return{success:!1,error:"Invalid input: entityId or slug is required"};return{success:!0,data:await Q.publishEntity(B,{entityType:$.data.entityType,...$.data.entityId&&{entityId:$.data.entityId},...$.data.slug&&{slug:$.data.slug},dryRun:$.data.dryRun,...$.data.topics&&{topics:$.data.topics}})}}catch(f){return{success:!1,error:f instanceof Error?f.message:"Publish failed"}}}}}function PjQ(A,Q,B){return{name:`${A}_discover_brain_cards`,description:"Read public ai.rizom.brain.card/self records from candidate AT Protocol repo DIDs or handles and emit internal discovery events.",inputSchema:nL1,handler:async(w)=>{let $=H.object(nL1).safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};try{return{success:!0,data:await Q.discoverBrainCards(B,{repos:$.data.repos})}}catch(f){return{success:!1,error:f instanceof Error?f.message:"Discovery failed"}}}}}function kjQ(A,Q,B){return{name:`${A}_publish_post`,description:"Publish a local blog post entity as an ai.rizom.brain.post AT Protocol record, or dry-run the record payload.",inputSchema:oL1,handler:async(w)=>{let $=H.object(oL1).safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};try{if(!$.data.entityId&&!$.data.slug)return{success:!1,error:"Invalid input: entityId or slug is required"};return{success:!0,data:await Q.publishPost(B,{...$.data.entityId&&{entityId:$.data.entityId},...$.data.slug&&{slug:$.data.slug},dryRun:$.data.dryRun,...$.data.topics&&{topics:$.data.topics}})}}catch(f){return{success:!1,error:f instanceof Error?f.message:"Publish failed"}}}}}var aL1={name:"@brains/atproto",private:!0,version:"0.2.0-alpha.120",description:"AT Protocol integration for identity, publishing, discovery, and feeds",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/atproto-contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var tL1=Gw["ai.rizom.brain.card"],_jQ="ai.rizom.brain.card",vjQ="self",eL1=50;class YuA extends YB{deps;projectionRegistry;constructor(A={},Q={}){super("atproto",aL1,A,fuA);this.deps=Q,this.projectionRegistry=Q.projectionRegistry??d6.getInstance()}getWebRoutes(){if(!this.config.enabled)return[];let A=V9A(this.config),Q=[...!this.config.brainDid?["/.well-known/did.json"]:[],...!this.config.anchorDid?["/anchor/did.json"]:[]];return[...new Set([...A.map((w)=>w.path),...Q])].map((w)=>({path:w,method:"GET",public:!0,handler:($)=>{let f=new URL($.url).hostname,I=[...V9A(this.config),...DuA(this.config,f)].filter((U)=>U.path===w),D=I.find((U)=>U.hostname===f)??I[0];if(!D)return new Response("Not found",{status:404});return new Response(JSON.stringify(D.document),{headers:{"Content-Type":"application/did+json"}})}}))}async publishBrainCard(A,Q={}){let B=await UuA(A,this.config);Tz(tL1,B);let w=this.config.repoDid;if(Q.dryRun)return{record:B,dryRun:!0,...w&&{repo:w}};let $=this.resolveAppPassword();if(!this.config.identifier||!$)throw Error("AT Protocol publishing requires identifier and app password configuration");let f=this.createPdsClient($),I=await f.createSession(),D=w??I.did;if(!f.putRecord)throw Error("AT Protocol PDS client does not support record upserts");let U=await f.putRecord({repo:D,collection:"ai.rizom.brain.card",rkey:"self",validate:!1,record:B});return{record:B,repo:D,uri:U.uri,cid:U.cid,dryRun:!1}}async publishEntity(A,Q){let B=this.projectionRegistry.get(Q.entityType);if(!B)throw Error(`No AT Protocol projection registered for ${Q.entityType}`);return this.publishProjectedEntity(A,Q,B)}async publishPost(A,Q){let B=this.projectionRegistry.get("post");if(!B)throw Error("No AT Protocol projection registered for post");return this.publishProjectedEntity(A,{entityType:"post",...Q},B)}async discoverBrainCards(A,Q){let B=[...new Set(Q.repos.map((f)=>f.trim()))].filter((f)=>f.length>0);if(B.length===0)throw Error("AT Protocol discovery requires at least one repo DID or handle");if(B.length>eL1)throw Error(`AT Protocol discovery accepts at most ${eL1} repos per batch`);let w=new Set,$=[];for(let f of B)try{let I=await this.resolveRepoPdsEndpoint(f),D=this.createPublicPdsClient(I.pdsEndpoint);if(!D.getRecord)throw Error("AT Protocol PDS client does not support record reads");let U=await D.getRecord({repo:I.repoDid,collection:_jQ,rkey:vjQ});Tz(tL1,U.value);let Y=yjQ(U.uri)??I.repoDid,J=`${Y}:${U.uri}:${U.cid}`;if(w.has(J)){$.push({repo:f,status:"skipped",repoDid:Y,uri:U.uri,cid:U.cid,error:"Duplicate brain card in discovery batch"});continue}w.add(J),await A.messaging.send({type:$5A,payload:{repoDid:Y,uri:U.uri,cid:U.cid,record:U.value},broadcast:!0}),$.push({repo:f,status:"discovered",repoDid:Y,uri:U.uri,cid:U.cid})}catch(I){$.push({repo:f,status:"skipped",error:T0(I)})}return{discovered:$.filter((f)=>f.status==="discovered").length,skipped:$.filter((f)=>f.status==="skipped").length,results:$}}async validatePdsCredentials(){let A=this.resolveAppPassword();if(!this.config.identifier||!A)return!1;try{return await this.createPdsClient(A).createSession(),!0}catch(Q){return this.logger.warn("AT Protocol PDS authentication failed",{error:T0(Q)}),!1}}async getTools(){if(!this.config.enabled)return[];return sL1(this.id,this,this.getContext())}async getInstructions(){if(!this.config.enabled)return;return"## AT Protocol publishing\n- Use `atproto_validate_credentials` to check PDS credentials before publishing.\n- Use `atproto_publish_card` to publish or dry-run this brain's public discovery card.\n- Use `atproto_publish_entity` to publish any public entity with a registered AT Protocol projection.\n- Use `atproto_publish_post` for the blog-post convenience path by `entityId` or `slug`.\n- Use `atproto_discover_brain_cards` to read public `ai.rizom.brain.card/self` records from candidate repo DIDs or handles and emit internal discovery events.\n- Prefer `dryRun: true` first when publishing new AT Protocol records.\n- Only public posts and public cover images can be published."}async publishProjectedEntity(A,Q,B){let w=await this.findPublishEntity(A,Q),$=Q.entityId??Q.slug;if(!$)throw Error(`${Q.entityType} publish requires entityId or slug`);if(!w)throw Error(`${Q.entityType} not found: ${$}`);if(w.visibility!=="public")throw Error(`Cannot publish non-public ${Q.entityType}: ${$}`);let f=this.config.repoDid;if(Q.dryRun){let G=await B.buildRecord({entity:w,context:A,config:this.config,...Q.topics&&{topics:Q.topics},dryRun:!0});return Tz(B.lexicon,G),{record:G,dryRun:!0,...f&&{repo:f}}}let I=this.resolveAppPassword();if(!this.config.identifier||!I)throw Error("AT Protocol publishing requires identifier and app password configuration");let D=this.createPdsClient(I),U=await D.createSession(),Y=f??U.did,J=await B.buildRecord({entity:w,context:A,config:this.config,client:D,...Q.topics&&{topics:Q.topics}});if(Tz(B.lexicon,J),!D.putRecord)throw Error("AT Protocol PDS client does not support record upserts");let X=await D.putRecord({repo:Y,collection:B.collection,rkey:TjQ(w.id),...B.validate!==void 0&&{validate:B.validate},record:J});return await B.onPublished?.({entity:w,context:A,record:J,uri:X.uri,cid:X.cid}),{record:J,repo:Y,uri:X.uri,cid:X.cid,dryRun:!1}}async findPublishEntity(A,Q){if(Q.entityId)return A.entityService.getEntity({entityType:Q.entityType,id:Q.entityId});if(Q.slug)return(await A.entityService.listEntities({entityType:Q.entityType,options:{filter:{metadata:{slug:Q.slug}}}}))[0]??null;return null}createPublicPdsClient(A){if(this.deps.createPdsClient)return this.deps.createPdsClient({pdsEndpoint:A,identifier:this.config.identifier??"",appPassword:this.config.appPassword??""});return new Fr({pdsEndpoint:A,identifier:this.config.identifier??"",appPassword:this.config.appPassword??""})}async resolveRepoPdsEndpoint(A){let Q=A.startsWith("did:")?A:await this.resolveHandleToDid(A);if(!Q)throw Error(`Could not resolve AT Protocol repo: ${A}`);let B=await this.resolveDidToPdsEndpoint(Q);if(!B)throw Error(`Could not resolve AT Protocol PDS for repo: ${Q}`);return{repoDid:Q,pdsEndpoint:B}}async resolveHandleToDid(A){let Q=new URL("/xrpc/com.atproto.identity.resolveHandle",this.config.pdsEndpoint);Q.searchParams.set("handle",A);let B=await this.fetch(Q.toString());if(!B.ok)return;let w=await B.json();if(typeof w!=="object"||w===null||!("did"in w))return;return typeof w.did==="string"?w.did:void 0}async resolveDidToPdsEndpoint(A){let Q=A.startsWith("did:plc:")?await this.fetchJson(`https://plc.directory/${encodeURIComponent(A)}`):A.startsWith("did:web:")?await this.fetchJson(xjQ(A)):void 0;if(typeof Q!=="object"||Q===null)return;let B=Q.service;if(!Array.isArray(B))return;let w=B.find(($)=>{return typeof $==="object"&&$!==null&&($.id==="#atproto_pds"||$.type==="AtprotoPersonalDataServer")});return typeof w?.serviceEndpoint==="string"?w.serviceEndpoint:void 0}async fetchJson(A){let Q=await this.fetch(A);if(!Q.ok)return;return Q.json()}fetch(A){return(this.deps.fetch??fetch)(A)}createPdsClient(A){if(this.deps.createPdsClient)return this.deps.createPdsClient({pdsEndpoint:this.config.pdsEndpoint,identifier:this.config.identifier??"",appPassword:A});return new Fr({pdsEndpoint:this.config.pdsEndpoint,identifier:this.config.identifier??"",appPassword:A})}resolveAppPassword(){return this.config.appPassword}}function TjQ(A){let Q=A.replace(/[^A-Za-z0-9._~:-]/g,"_").slice(0,512);return Q.length>0?Q:"self"}function yjQ(A){return/^at:\/\/([^/]+)/.exec(A)?.[1]}function xjQ(A){let Q=A.slice(8).split(":").map(decodeURIComponent),[B,...w]=Q;if(!B)throw Error(`Invalid did:web value: ${A}`);if(w.length===0)return`https://${B}/.well-known/did.json`;return`https://${B}/${w.join("/")}/did.json`}function E9A(A,Q){return new YuA(A,Q)}aA();WA();Ew();f5();WA();aA();var M9A=Xs.extend({expertise:H.array(H.string()).optional().describe("Skills, domains, areas of focus"),currentFocus:H.string().optional().describe("What you're currently working on"),availability:H.string().optional().describe("What you're open to (consulting, speaking, etc.)")}),ez=lY.extend(M9A.shape);aA();nG();WA();var SjQ=new wW;class C9A{postsListUrl;decksListUrl;id="professional:homepage-list";name="Homepage List DataSource";description="Fetches profile, blog posts, and presentation decks for homepage";constructor(A,Q){this.postsListUrl=A;this.decksListUrl=Q}async fetch(A,Q,B){let w=B.entityService,[$,f,I,D]=await Promise.all([gR(w),w.listEntities({entityType:"post",options:{limit:20}}),w.listEntities({entityType:"deck",options:{limit:20}}),tp(w)]),U=SjQ.parseProfileBody($,ez),Y=f.sort(cy).slice(0,3).map(Qi),J=I.sort(cy).slice(0,3).map(Di);if(!D.cta)throw Error("CTA not configured in site-info");let X={profile:U,posts:Y,decks:J,postsListUrl:this.postsListUrl,decksListUrl:this.decksListUrl,cta:D.cta,sections:D.sections??{}};return Q.parse(X)}}aA();nG();var gjQ=new wW;class O9A{id="professional:about";name="About Page DataSource";description="Fetches full profile data for the about page";async fetch(A,Q,B){let w=await gR(B.entityService),f={profile:gjQ.parseProfileBody(w,ez)};return Q.parse(f)}}import{jsxDEV as w8,Fragment as ujQ}from"preact/jsx-dev-runtime";var hjQ="grid md:grid-cols-[14rem_1px_1fr] gap-y-2 gap-x-0 md:gap-16 items-start",mjQ="border-t md:border-t-0 md:border-l border-rule-strong md:self-stretch",JuA=({number:A,title:Q,blurb:B,children:w})=>w8("section",{className:"py-20 border-b border-rule px-6 md:px-12",children:w8("div",{className:"max-w-6xl mx-auto",children:w8("div",{className:hjQ,children:[w8(vTA,{title:Q,number:A,blurb:B},void 0,!1,void 0,this),w8("div",{className:mjQ,"aria-hidden":"true"},void 0,!1,void 0,this),w8("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),XuA=({profile:A,posts:Q,decks:B,postsListUrl:w,decksListUrl:$,cta:f,sections:I})=>{let D=A.tagline||A.description,U=Q.map((Z)=>({id:Z.id,url:Z.url,title:Z.metadata.title,date:Z.metadata.publishedAt||Z.created,description:Z.frontmatter.excerpt,series:Z.frontmatter.seriesName&&Z.frontmatter.seriesIndex?{name:Z.frontmatter.seriesName,index:Z.frontmatter.seriesIndex}:void 0})),Y=B.map((Z)=>({id:Z.id,url:Z.url,title:Z.frontmatter.title||Z.id,date:Z.frontmatter.publishedAt??Z.created,description:Z.frontmatter.description})),J=A.name||"Home",X=A.intro||A.description||D||"Professional site",G=Boolean(A.description)||A.expertise!==void 0&&A.expertise.length>0;return w8(ujQ,{children:[w8(KQ,{title:J,description:X,ogType:"website"},void 0,!1,void 0,this),w8("div",{className:"homepage-list bg-theme",children:[w8("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:w8("div",{className:"relative z-10 max-w-6xl mx-auto w-full",children:[A.name&&w8("div",{className:"flex items-center gap-[0.6rem] mb-6 font-mono text-[0.7rem] font-medium uppercase tracking-[0.22em] text-accent",children:[w8("span",{className:"w-[18px] h-px bg-accent","aria-hidden":"true"},void 0,!1,void 0,this),w8("span",{children:A.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),D&&w8("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:N8A(D,"italic font-normal text-accent [font-variation-settings:'opsz'_144,'SOFT'_80]")},void 0,!1,void 0,this),A.intro&&w8("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:N8A(A.intro,"italic text-accent")},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),w8(JuA,{number:"01",title:"Essays",blurb:I.essays?.blurb,children:w8(Z8A,{items:U,viewAllUrl:w,viewAllLabel:"View all essays"},void 0,!1,void 0,this)},void 0,!1,void 0,this),Y.length>0&&w8(JuA,{number:"02",title:"Presentations",blurb:I.presentations?.blurb,children:w8(Z8A,{items:Y,viewAllUrl:$,viewAllLabel:"View all presentations"},void 0,!1,void 0,this)},void 0,!1,void 0,this),G&&w8(JuA,{number:"03",title:"About",blurb:I.about?.blurb,children:w8("div",{className:"flex flex-col gap-8",children:[A.description&&w8("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&&w8(TTA,{subjects:A.expertise},void 0,!1,void 0,this),w8("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",w8("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),w8(NTA,{cta:f,variant:"editorial",socialLinks:A.socialLinks},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as Fw,Fragment as cjQ}from"preact/jsx-dev-runtime";var WuA=({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 Fw(cjQ,{children:[Fw(KQ,{title:Q,description:B,ogType:"profile"},void 0,!1,void 0,this),Fw("div",{className:"about-page bg-theme",children:[Fw("header",{className:"hero-bg-pattern relative w-full py-16 md:py-24 px-6 md:px-12 bg-theme overflow-hidden",children:Fw("div",{className:"relative z-10 max-w-4xl mx-auto",children:[Fw("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&&Fw("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),Fw("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-12 md:py-16",children:[A.story&&Fw("section",{className:"content-section-reveal mb-20 md:mb-28",children:Fw(V$,{markdown:A.story},void 0,!1,void 0,this)},void 0,!1,void 0,this),w&&Fw("div",{className:"content-section-reveal grid md:grid-cols-2 gap-x-16 gap-y-12",children:[A.expertise&&A.expertise.length>0&&Fw("section",{children:[Fw("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Expertise"},void 0,!1,void 0,this),Fw("ul",{className:"flex flex-wrap gap-3",children:A.expertise.map(($,f)=>Fw("li",{className:Ap({variant:"accent",size:"lg"}),children:$},f,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.currentFocus&&Fw("section",{children:[Fw("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Current Focus"},void 0,!1,void 0,this),Fw("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&&Fw("section",{children:[Fw("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Availability"},void 0,!1,void 0,this),Fw("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)&&Fw("section",{children:[Fw("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Contact"},void 0,!1,void 0,this),Fw("div",{className:"space-y-4",children:[A.email&&Fw("p",{className:"text-lg",children:Fw("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&&Fw("p",{className:"text-lg",children:Fw("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&&Fw("div",{className:"flex flex-wrap gap-4 mt-4",children:A.socialLinks.map(($,f)=>Fw(L$,{href:$.url,external:!0,variant:"secondary",size:"md",children:$.label||$.platform},f,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as l7,Fragment as AV1}from"preact/jsx-dev-runtime";var HuA=()=>{return l7(AV1,{children:[l7(KQ,{title:"Thanks for subscribing!",description:"You've successfully subscribed to the newsletter."},void 0,!1,void 0,this),l7("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:l7("div",{className:"text-center max-w-md",children:[l7("div",{className:"text-6xl mb-6",children:"\uD83C\uDF89"},void 0,!1,void 0,this),l7("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Thanks for subscribing!"},void 0,!1,void 0,this),l7("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),l7(L$,{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)},GuA=()=>{return l7(AV1,{children:[l7(KQ,{title:"Subscription failed",description:"There was a problem with your subscription."},void 0,!1,void 0,this),l7("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:l7("div",{className:"text-center max-w-md",children:[l7("div",{className:"text-6xl mb-6",children:"\uD83D\uDE22"},void 0,!1,void 0,this),l7("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Something went wrong"},void 0,!1,void 0,this),l7("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),l7(L$,{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)};WA();var QV1=H.object({label:H.string().describe("Display label for entity type (e.g., 'Essay')"),pluralName:H.string().optional().describe("URL path segment (defaults to label.toLowerCase() + 's')")}),BV1=H.object({entityDisplay:H.object({post:QV1,deck:QV1}).describe("Display metadata for post and deck entity types (required for homepage)")});var wV1={name:"@brains/site-professional",private:!0,version:"0.2.0-alpha.120",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 KuA extends YB{dependencies=["blog","decks"];constructor(A){super("professional-site",wV1,A,BV1)}async onRegister(A){A.entities.extendFrontmatterSchema("anchor-profile",M9A);let Q=this.config.entityDisplay.post,B=this.config.entityDisplay.deck,w=`/${Q.pluralName??Q.label.toLowerCase()+"s"}`,$=`/${B.pluralName??B.label.toLowerCase()+"s"}`,f=new C9A(w,$);A.entities.registerDataSource(f);let I=new O9A;A.entities.registerDataSource(I);let D=H.object({profile:ez,posts:H.array(SF),decks:H.array(wC),postsListUrl:H.string(),decksListUrl:H.string(),cta:ASA,sections:H.record(H.string(),No)}),U=H.object({profile:ez}),Y=H.object({});A.templates.register({"homepage-list":P1({name:"homepage-list",description:"Professional homepage with essays and presentations",schema:D,dataSourceId:"professional:homepage-list",requiredPermission:"public",layout:{component:XuA}}),about:P1({name:"about",description:"About page with full profile information",schema:U,dataSourceId:"professional:about",requiredPermission:"public",layout:{component:WuA}}),"subscribe-thanks":P1({name:"subscribe-thanks",description:"Newsletter subscription success page",schema:Y,requiredPermission:"public",layout:{component:HuA}}),"subscribe-error":P1({name:"subscribe-error",description:"Newsletter subscription error page",schema:Y,requiredPermission:"public",layout:{component:GuA}})}),this.logger.info("Professional site plugin registered successfully")}async getTools(){return[]}async getResources(){return[]}}function $V1(A){return new KuA(A??{})}var fV1=[{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 R9A}from"preact/jsx-dev-runtime";function IV1({sections:A,siteInfo:Q,slots:B,wordmark:w}){return R9A("div",{className:"flex flex-col min-h-screen bg-theme overflow-x-clip",children:[R9A(VTA,{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),R9A("main",{className:"flex-grow flex flex-col bg-theme",children:A},void 0,!1,void 0,this),R9A(qTA,{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 pjQ={layouts:{default:IV1},routes:fV1,plugin:$V1,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"}}}},Nr=pjQ;var DV1=`/*
|
|
8434
8434
|
* Default theme \u2014 simplified editorial base inspired by the Rizom family.
|
|
8435
8435
|
*
|
|
8436
8436
|
* This theme is intentionally less branded than @brains/theme-rizom. It
|
|
@@ -8818,8 +8818,8 @@ ${JSON.stringify(B,null,2)}`}function K9A(A){return A.map((Q)=>Q.detail===null?{
|
|
|
8818
8818
|
|
|
8819
8819
|
.btn-primary:disabled { opacity: 0.5; }
|
|
8820
8820
|
}
|
|
8821
|
-
`;var dv=DV1;import{join as djQ}from"path";var UV1={name:"@brains/rover",version:"0.2.0-alpha.
|
|
8822
|
-
`,{headers:{"Content-Type":"application/json"}})}class ZuA extends YB{constructor(A={}){super("atproto-registry",WV1,A,GV1)}getWebRoutes(){if(!this.config.enabled)return[];return[{path:`${FuA}/index.json`,method:"GET",public:!0,handler:()=>HV1(this.getIndex())},...tM().map((A)=>({path:`${FuA}/${A.id}.json`,method:"GET",public:!0,handler:()=>HV1(A)}))]}getIndex(){return{lexicons:fSA().map((A)=>({...A,path:`${FuA}/${A.id}.json`}))}}getLexicon(A){return $SA(A)}async getTools(){return[this.createListLexiconsTool(),this.createValidateLexiconTool(),this.createCheckContractsTool()]}createListLexiconsTool(){return{name:`${this.id}_list_lexicons`,description:"List canonical Rizom AT Protocol lexicons.",inputSchema:{},handler:async()=>({success:!0,data:this.getIndex()})}}createValidateLexiconTool(){return{name:`${this.id}_validate_lexicon`,description:"Validate a record payload against a canonical Rizom AT Protocol lexicon.",inputSchema:{nsid:H.string().describe("Canonical lexicon NSID"),record:H.record(H.unknown()).describe("Record payload to validate")},handler:async(A)=>{let Q=H.object({nsid:H.string(),record:H.record(H.unknown())}).safeParse(A);if(!Q.success)return{success:!1,error:`Invalid input: ${Q.error.message}`};let B=this.getLexicon(Q.data.nsid);if(!B)return{success:!1,error:`Unknown AT Protocol lexicon: ${Q.data.nsid}`};try{return Tz(B,Q.data.record),{success:!0,data:{valid:!0}}}catch(w){return{success:!0,data:{valid:!1,error:w instanceof Error?w.message:"Invalid record"}}}}}}createCheckContractsTool(){return{name:`${this.id}_check_contracts`,description:"Check that canonical Rizom AT Protocol lexicon contracts are available.",inputSchema:{},handler:async()=>({success:!0,data:{lexiconCount:tM().length,nsids:tM().map((A)=>A.id),metadata:fSA()}})}}}function NuA(A={}){return new ZuA(A)}aA();WA();WA();aA();var b9A=H.object({routeId:H.string(),sectionId:H.string()}),zr=A2.extend({entityType:H.literal("site-content"),template:H.string().optional(),content:H.string(),metadata:b9A});aA();class KV1 extends q2{constructor(){super({entityType:"site-content",schema:zr,frontmatterSchema:b9A})}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 zuA=new KV1;WA();var P9A=H.object({routeId:H.string().optional().describe("Optional: specific route filter"),sectionId:H.string().optional().describe("Optional: specific section filter"),dryRun:H.boolean().optional().default(!1).describe("Optional: preview changes without executing"),force:H.boolean().optional().default(!1).describe("Force regeneration even if content exists")}),DU8=H.object({jobs:H.array(H.object({jobId:H.string(),routeId:H.string(),sectionId:H.string()})),totalSections:H.number(),queuedSections:H.number(),skippedSections:H.number().optional(),batchId:H.string().optional()});class quA{context;constructor(A){this.context=A}createJobOptions(A,Q){if(!A)return;return{source:A.operationType??Q,rootJobId:A.rootJobId??`${Q}-${Date.now()}`,metadata:{operationType:A.operationType??"content_operations",progressToken:A.progressToken,pluginId:A.pluginId??"site-content"}}}async fetchRoutes(){let A=await this.context.messaging.send({type:"site-builder:routes:list",payload:{}});if("noop"in A)throw Error("No handler for site-builder:routes:list \u2014 is site-builder plugin loaded?");if(!A.success||!A.data)throw Error("Failed to fetch routes from site-builder");return A.data}async generate(A,Q,B){let w=this.context.logger.child("SiteContentOperations"),$=await this.fetchRoutes(),f=$;if(A.routeId){if(f=$.filter((J)=>J.id===A.routeId),f.length===0)throw Error(`Route not found: ${A.routeId}`)}let I=[];for(let J of f)for(let X of J.sections){if(A.sectionId&&X.id!==A.sectionId)continue;if(X.content){w.debug("Section has static content, skipping",{routeId:J.id,sectionId:X.id});continue}if(X.template){let G=this.context.templates.getCapabilities(X.template);if(!G){w.warn("Template not found, skipping section",{routeId:J.id,sectionId:X.id,templateName:X.template});continue}if(!G.canGenerate){w.debug("Template doesn't support generation, skipping",{routeId:J.id,sectionId:X.id,templateName:X.template,capabilities:G});continue}}else{w.debug("Section has no template, skipping",{routeId:J.id,sectionId:X.id});continue}if(!A.force&&!A.dryRun){let G=`${J.id}:${X.id}`;if(await this.context.entityService.getEntity({entityType:"site-content",id:G})){w.debug("Content already exists, skipping",{routeId:J.id,sectionId:X.id});continue}}I.push({route:J,section:X})}let D=I.length;if(A.dryRun)return{jobs:[],totalSections:D,queuedSections:D,batchId:`dry-run-${Date.now()}`};let U=[],Y=[];for(let{route:J,section:X}of I){let G=`${J.id}:${X.id}`,Z=X.template,N={routeId:J.id,sectionId:X.id,entityId:G,entityType:"site-content",templateName:Z,context:{prompt:typeof X.content==="string"?X.content:void 0,data:{routeId:J.id,sectionId:X.id,routeTitle:J.title??Q?.title??"",routeDescription:J.description??Q?.description??"",sectionContent:X.content},conversationId:"system"},siteConfig:Q};Y.push({type:"shell:content-generation",data:N})}if(Y.length>0){let J=this.createJobOptions(B,"site:content-generation"),X=await this.context.jobs.enqueueBatch(Y,J);for(let G=0;G<I.length;G++){let Z=I[G];if(Z)U.push({jobId:`${X}-${G}`,routeId:Z.route.id,sectionId:Z.section.id})}return{jobs:U,totalSections:D,queuedSections:U.length,batchId:X}}return{jobs:[],totalSections:D,queuedSections:0,batchId:`empty-${Date.now()}`}}}class LuA{siteConfig;operations;constructor(A,Q){this.siteConfig=Q;this.operations=new quA(A)}async generateContent(A,Q){let B=P9A.parse(A);return this.operations.generate(B,this.siteConfig,Q)}}o$();WA();function qr(A,Q){return Q?A.optional():A}function EuA(A){switch(A.type){case"string":return qr(H.string(),A.optional);case"number":return qr(H.number(),A.optional);case"enum":{let Q=[...A.options];return qr(H.enum(Q),A.optional)}case"object":{let Q={};for(let[B,w]of Object.entries(A.fields))Q[B]=EuA(w);return qr(H.object(Q),A.optional)}case"array":{let Q=H.array(ajQ(A));if(A.minItems!==void 0)Q=Q.min(A.minItems);if(A.length!==void 0)Q=Q.length(A.length);return qr(Q,A.optional)}}}function ajQ(A){let{items:Q}=A;switch(Q.type){case"string":return H.string();case"number":return H.number();case"enum":{let B=[...Q.options];return H.enum(B)}case"object":{let B={};for(let[w,$]of Object.entries(Q.fields))B[w]=EuA($);return H.object(B)}}}function VuA(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])=>VuA(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,$])=>VuA(w,$)),B}}}}function tjQ(A,Q){let B={};for(let[f,I]of Object.entries(Q.fields))B[f]=EuA(I);let w=H.object(B),$=new lB(w,{title:Q.title,mappings:Object.entries(Q.fields).map(([f,I])=>VuA(f,I))});return{name:A,description:Q.description,schema:w,formatter:$,requiredPermission:Q.requiredPermission??"public",layout:{component:Q.layout,...Q.fullscreen!==void 0?{fullscreen:Q.fullscreen}:{}},...Q.runtimeScripts?{runtimeScripts:Q.runtimeScripts}:{}}}function MuA(A){return Object.fromEntries(Object.entries(A.sections).map(([Q,B])=>[Q,tjQ(Q,B)]))}WA();var FV1=H.object({namespace:H.string(),sections:H.record(H.any())}),ZV1=H.object({definitions:H.union([FV1,H.array(FV1)]).optional()});aA();function NV1(A,Q){return[oQ(Q,"generate","Generate content for all routes, a specific route, or a specific section",P9A,async(B,w)=>{let $=A();if(!$)return{success:!1,error:"Site content service not initialized"};if(B.sectionId&&!B.routeId)return{success:!1,error:"sectionId requires routeId to be specified"};let f={rootJobId:`generate-${Date.now()}`,progressToken:w.progressToken,pluginId:Q,operationType:"content_operations",interfaceType:w.interfaceType,channelId:w.channelId},I=await $.generateContent(B,f);return{success:!0,message:`Generated ${I.queuedSections} of ${I.totalSections} sections. ${I.queuedSections>0?"Jobs are running in the background.":"No new content to generate."}`,data:{batchId:I.batchId,jobsQueued:I.queuedSections,totalSections:I.totalSections,jobs:I.jobs}}})]}var zV1={name:"@brains/site-content",private:!0,version:"0.2.0-alpha.119",description:"Site content entity and generation orchestration",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/plugins":"workspace:*","@brains/site-info":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class CuA extends YB{siteContentService;constructor(A={}){super("site-content",zV1,A,ZV1)}async onRegister(A){A.entities.register("site-content",zr,zuA);for(let Q of iX(this.config.definitions))A.templates.register(MuA(Q),Q.namespace);this.siteContentService=new LuA(A)}async getTools(){return NV1(()=>this.siteContentService,this.id)}}function Lr(A={}){return new CuA(A)}aA();WA();Ew();WA();aA();var qV1=H.enum(["available","early access","coming soon","planned"]),LV1=H.object({title:H.string(),description:H.string()}),CD=H.object({name:H.string(),availability:qV1,order:H.number(),ogImageId:H.string().optional()}),k9A=H.object({tagline:H.string(),promise:H.string(),role:H.string(),purpose:H.string(),audience:H.string(),values:H.array(H.string()).min(1),features:H.array(LV1).min(1).max(6),story:H.string()}),A_Q=CD.pick({name:!0,availability:!0,order:!0}).extend({slug:H.string()}),nv=A2.extend({entityType:H.literal("product"),metadata:A_Q}),j9A=nv.extend({frontmatter:CD,body:k9A,labels:H.record(H.string(),H.string()),ogImageUrl:H.string().optional()}),_9A=j9A.extend({url:H.string().optional(),typeLabel:H.string().optional(),listUrl:H.string().optional(),listLabel:H.string().optional(),ogImageUrl:H.string().optional()});aA();WA();o$();class ov extends lB{constructor(){super(k9A,{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 OuA extends q2{constructor(){super({entityType:"product",schema:nv,frontmatterSchema:CD,bodyFormatter:new ov})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,CD);return this.buildMarkdown(Q,B)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,CD),B=X1(Q.name);return{content:A,entityType:"product",metadata:{name:Q.name,slug:B,availability:Q.availability,order:Q.order}}}}var v9A=new OuA;WA();aA();var VV1=H.object({title:H.string(),description:H.string()}),EV1=H.object({title:H.string(),description:H.string()}),Q_Q=H.object({title:H.string(),description:H.string()}),MV1=H.object({heading:H.string(),buttonText:H.string(),link:H.string()}),oF=H.object({headline:H.string(),tagline:H.string()}),B_Q=H.object({title:H.string(),description:H.string()}),T9A=H.object({vision:H.string(),pillars:H.array(VV1).min(1).max(6),approach:H.array(B_Q).min(1).max(6),productsIntro:H.string(),technologies:H.array(Q_Q).min(1).max(6),benefits:H.array(EV1).min(1).max(6),cta:MV1}),CV1=oF.pick({headline:!0}).extend({slug:H.string()}),sv=A2.extend({entityType:H.literal("products-overview"),metadata:CV1}),Vr=sv.extend({frontmatter:oF,body:T9A,labels:H.record(H.string(),H.string())});aA();WA();o$();class av extends lB{constructor(){super(T9A,{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 RuA extends q2{constructor(){super({entityType:"products-overview",schema:sv,frontmatterSchema:oF,bodyFormatter:new av})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,oF);return this.buildMarkdown(Q,B)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,oF),B=X1(Q.headline);return{content:A,entityType:"products-overview",metadata:{headline:Q.headline,slug:B}}}}var buA=new RuA;aA();WA();var w_Q=H.object({entityType:H.string(),query:H.object({id:H.string().optional()}).optional()});function OV1(A,Q){let B=R2(A.content,CD),w=Q.parse(B.content),$=Q.getLabels();return j9A.parse({...A,frontmatter:B.metadata,body:w,labels:$})}function RV1(A,Q){let B=R2(A.content,oF),w=Q.parse(B.content),$=Q.getLabels();return Vr.parse({...A,frontmatter:B.metadata,body:w,labels:$})}class y9A{logger;id="products:entities";name="Products Entity DataSource";description="Fetches products and overview for the products page";overviewFormatter=new av;productFormatter=new ov;constructor(A){this.logger=A;this.logger.debug("ProductsDataSource initialized")}async fetch(A,Q,B){let w=w_Q.parse(A),$=B.entityService;if(w.entityType==="products-overview"){let Y=(await $.listEntities({entityType:"products-overview",options:{limit:1}}))[0];if(!Y)throw Error("Products overview entity not found");let J=RV1(Y,this.overviewFormatter);return Q.parse(J)}if(w.query?.id){let Y=(await $.listEntities({entityType:"product",options:{filter:{metadata:{slug:w.query.id}},limit:1}}))[0];if(!Y)throw Error(`Product not found: ${w.query.id}`);return Q.parse({product:OV1(Y,this.productFormatter)})}let[f,I]=await Promise.all([$.listEntities({entityType:"products-overview",options:{limit:1}}),$.listEntities({entityType:"product",options:{sortFields:[{field:"order",direction:"asc"}]}})]),D=f[0];if(!D)throw Error("Products overview entity not found");return Q.parse({overview:RV1(D,this.overviewFormatter),products:I.map((U)=>OV1(U,this.productFormatter))})}}import{jsxDEV as A1,Fragment as I_Q}from"preact/jsx-dev-runtime";var bV1=({overview:A,products:Q})=>{let{frontmatter:B,body:w,labels:$}=A;return A1(I_Q,{children:[A1(KQ,{title:B.headline,description:B.tagline},void 0,!1,void 0,this),A1("header",{className:"relative w-full min-h-[80vh] flex items-end px-6 md:px-12 bg-brand-dark overflow-hidden",children:[A1("style",{children:`
|
|
8821
|
+
`;var dv=DV1;import{join as djQ}from"path";var UV1={name:"@brains/rover",version:"0.2.0-alpha.120",type:"module",private:!0,main:"./src/index.ts",files:["src","brain.eval.yaml","env.schema.template"],scripts:{"build:web-chat":"turbo run build --filter=@brains/web-chat","start:core":"bun run build:web-chat && cd test-apps/core && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start","start:default":"bun run build:web-chat && cd test-apps/default && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start","start:full":"bun run build:web-chat && 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/atproto":"workspace:*","@brains/auth-service":"workspace:*","@brains/blog":"workspace:*","@brains/cms":"workspace:*","@brains/content-pipeline":"workspace:*","@brains/dashboard":"workspace:*","@brains/decks":"workspace:*","@brains/directory-sync":"workspace:*","@brains/discord":"workspace:*","@brains/document-plugin":"workspace:*","@brains/email-resend":"workspace:*","@brains/image-plugin":"workspace:*","@brains/link":"workspace:*","@brains/mcp":"workspace:*","@brains/newsletter":"workspace:*","@brains/note":"workspace:*","@brains/notifications":"workspace:*","@brains/obsidian-vault":"workspace:*","@brains/portfolio":"workspace:*","@brains/prompt":"workspace:*","@brains/rizom-ecosystem":"workspace:*","@brains/series":"workspace:*","@brains/site-builder-plugin":"workspace:*","@brains/site-default":"workspace:*","@brains/site-info":"workspace:*","@brains/social-media":"workspace:*","@brains/stock-photo":"workspace:*","@brains/theme-default":"workspace:*","@brains/topics":"workspace:*","@brains/web-chat":"workspace:*","@brains/webserver":"workspace:*","@brains/wishlist":"workspace:*"},devDependencies:{"@brains/ai-evaluation":"workspace:*","@brains/typescript-config":"workspace:*",typescript:"^5.3.3"}};var YV1=["prompt","note","link","wishlist","topics","directory-sync","atproto","agents","assessment","auth-service","notifications","email-resend","cms","dashboard-root","mcp","webserver","web-chat","discord","a2a"],JV1=[...YV1.filter((A)=>A!=="dashboard-root"),"image","dashboard","blog","series","decks","analytics","obsidian-vault","site-info","site-builder"],njQ=[...JV1,"portfolio","topics","content-pipeline","document","social-media","newsletter","stock-photo"],ojQ=["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.","Draft blog posts are only post entities with status draft. If the user asks whether draft blog posts exist, call only system_list for entityType post with status draft; do not also list social-post, newsletter, deck, or other draft entity types."],XV1=hN({name:"rover",version:UV1.version,model:"gpt-5.4-mini",site:Nr,theme:dv,presets:{core:YV1,default:JV1,full:njQ},evalDisable:["discord","webserver","web-chat","mcp","analytics","dashboard","dashboard-root","email-resend"],agentInstructions:ojQ,capabilities:[["prompt",zC,void 0],["image",Xh,void 0],["cms",NC,(A)=>({...A.CMS_CONTENT_REPO_PAT?{passkeyLogin:{contentRepoToken:A.CMS_CONTENT_REPO_PAT}}:{}})],["auth-service",Qu,void 0],["notifications",l0A,void 0],["email-resend",VwA,void 0],["dashboard",az,void 0],["dashboard-root",az,{routePath:"/"}],["blog",LSA,{}],["series",RSA,void 0],["decks",Ui,void 0],["document",_gA,void 0],["note",YC,{}],["link",WC,{}],["portfolio",IhA,{}],["topics",V$A,{includeEntityTypes:["post","deck","project","link","anchor-profile"]}],["content-pipeline",dhA,{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",ii,{autoGenerateOnBlogPublish:!0}],["newsletter",Kq1,{doubleOptIn:!0}],["obsidian-vault",FmA,{autoSync:!0}],["wishlist",r$A,{}],["stock-photo",CmA,{}],["agents",Y9A,void 0],["assessment",z9A,void 0],["atproto",E9A,(A)=>({...A.ATPROTO_APP_PASSWORD?{appPassword:A.ATPROTO_APP_PASSWORD}:{}})],["directory-sync",WM,{seedContent:!0,seedContentPath:djQ(import.meta.dir,"..","seed-content"),initialSync:!0}],["analytics",g$A,{}],["rizom-ecosystem",qC,void 0],["site-info",aM,void 0],["site-builder",sM,{cms:{}}]],interfaces:[["mcp",q3,()=>({})],["discord",Qz,()=>({})],["webserver",Bz,()=>({})],["web-chat",sj,()=>({})],["a2a",aj,()=>({})]],permissions:{rules:[{pattern:"cli:*",level:"anchor"},{pattern:"mcp:stdio",level:"anchor"},{pattern:"mcp:http",level:"public"},{pattern:"discord:*",level:"public"},{pattern:"web-chat:*",level:"anchor"}],entityActions:{"*":{create:"anchor",update:"anchor",delete:"anchor",extract:"anchor"}}},deployment:{cdn:{enabled:!0,provider:"bunny"},dns:{enabled:!0,provider:"bunny"}}});cN();aA();WA();var WV1={name:"@brains/atproto-registry",private:!0,version:"0.2.0-alpha.120",description:"Canonical Rizom AT Protocol lexicon registry",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/atproto-contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var GV1=H.object({enabled:H.boolean().default(!0)}),FuA="/atproto/lexicons";function HV1(A){return new Response(`${JSON.stringify(A,null,2)}
|
|
8822
|
+
`,{headers:{"Content-Type":"application/json"}})}class ZuA extends YB{constructor(A={}){super("atproto-registry",WV1,A,GV1)}getWebRoutes(){if(!this.config.enabled)return[];return[{path:`${FuA}/index.json`,method:"GET",public:!0,handler:()=>HV1(this.getIndex())},...tM().map((A)=>({path:`${FuA}/${A.id}.json`,method:"GET",public:!0,handler:()=>HV1(A)}))]}getIndex(){return{lexicons:fSA().map((A)=>({...A,path:`${FuA}/${A.id}.json`}))}}getLexicon(A){return $SA(A)}async getTools(){return[this.createListLexiconsTool(),this.createValidateLexiconTool(),this.createCheckContractsTool()]}createListLexiconsTool(){return{name:`${this.id}_list_lexicons`,description:"List canonical Rizom AT Protocol lexicons.",inputSchema:{},handler:async()=>({success:!0,data:this.getIndex()})}}createValidateLexiconTool(){return{name:`${this.id}_validate_lexicon`,description:"Validate a record payload against a canonical Rizom AT Protocol lexicon.",inputSchema:{nsid:H.string().describe("Canonical lexicon NSID"),record:H.record(H.unknown()).describe("Record payload to validate")},handler:async(A)=>{let Q=H.object({nsid:H.string(),record:H.record(H.unknown())}).safeParse(A);if(!Q.success)return{success:!1,error:`Invalid input: ${Q.error.message}`};let B=this.getLexicon(Q.data.nsid);if(!B)return{success:!1,error:`Unknown AT Protocol lexicon: ${Q.data.nsid}`};try{return Tz(B,Q.data.record),{success:!0,data:{valid:!0}}}catch(w){return{success:!0,data:{valid:!1,error:w instanceof Error?w.message:"Invalid record"}}}}}}createCheckContractsTool(){return{name:`${this.id}_check_contracts`,description:"Check that canonical Rizom AT Protocol lexicon contracts are available.",inputSchema:{},handler:async()=>({success:!0,data:{lexiconCount:tM().length,nsids:tM().map((A)=>A.id),metadata:fSA()}})}}}function NuA(A={}){return new ZuA(A)}aA();WA();WA();aA();var b9A=H.object({routeId:H.string(),sectionId:H.string()}),zr=A2.extend({entityType:H.literal("site-content"),template:H.string().optional(),content:H.string(),metadata:b9A});aA();class KV1 extends q2{constructor(){super({entityType:"site-content",schema:zr,frontmatterSchema:b9A})}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 zuA=new KV1;WA();var P9A=H.object({routeId:H.string().optional().describe("Optional: specific route filter"),sectionId:H.string().optional().describe("Optional: specific section filter"),dryRun:H.boolean().optional().default(!1).describe("Optional: preview changes without executing"),force:H.boolean().optional().default(!1).describe("Force regeneration even if content exists")}),DU8=H.object({jobs:H.array(H.object({jobId:H.string(),routeId:H.string(),sectionId:H.string()})),totalSections:H.number(),queuedSections:H.number(),skippedSections:H.number().optional(),batchId:H.string().optional()});class quA{context;constructor(A){this.context=A}createJobOptions(A,Q){if(!A)return;return{source:A.operationType??Q,rootJobId:A.rootJobId??`${Q}-${Date.now()}`,metadata:{operationType:A.operationType??"content_operations",progressToken:A.progressToken,pluginId:A.pluginId??"site-content"}}}async fetchRoutes(){let A=await this.context.messaging.send({type:"site-builder:routes:list",payload:{}});if("noop"in A)throw Error("No handler for site-builder:routes:list \u2014 is site-builder plugin loaded?");if(!A.success||!A.data)throw Error("Failed to fetch routes from site-builder");return A.data}async generate(A,Q,B){let w=this.context.logger.child("SiteContentOperations"),$=await this.fetchRoutes(),f=$;if(A.routeId){if(f=$.filter((J)=>J.id===A.routeId),f.length===0)throw Error(`Route not found: ${A.routeId}`)}let I=[];for(let J of f)for(let X of J.sections){if(A.sectionId&&X.id!==A.sectionId)continue;if(X.content){w.debug("Section has static content, skipping",{routeId:J.id,sectionId:X.id});continue}if(X.template){let G=this.context.templates.getCapabilities(X.template);if(!G){w.warn("Template not found, skipping section",{routeId:J.id,sectionId:X.id,templateName:X.template});continue}if(!G.canGenerate){w.debug("Template doesn't support generation, skipping",{routeId:J.id,sectionId:X.id,templateName:X.template,capabilities:G});continue}}else{w.debug("Section has no template, skipping",{routeId:J.id,sectionId:X.id});continue}if(!A.force&&!A.dryRun){let G=`${J.id}:${X.id}`;if(await this.context.entityService.getEntity({entityType:"site-content",id:G})){w.debug("Content already exists, skipping",{routeId:J.id,sectionId:X.id});continue}}I.push({route:J,section:X})}let D=I.length;if(A.dryRun)return{jobs:[],totalSections:D,queuedSections:D,batchId:`dry-run-${Date.now()}`};let U=[],Y=[];for(let{route:J,section:X}of I){let G=`${J.id}:${X.id}`,Z=X.template,N={routeId:J.id,sectionId:X.id,entityId:G,entityType:"site-content",templateName:Z,context:{prompt:typeof X.content==="string"?X.content:void 0,data:{routeId:J.id,sectionId:X.id,routeTitle:J.title??Q?.title??"",routeDescription:J.description??Q?.description??"",sectionContent:X.content},conversationId:"system"},siteConfig:Q};Y.push({type:"shell:content-generation",data:N})}if(Y.length>0){let J=this.createJobOptions(B,"site:content-generation"),X=await this.context.jobs.enqueueBatch(Y,J);for(let G=0;G<I.length;G++){let Z=I[G];if(Z)U.push({jobId:`${X}-${G}`,routeId:Z.route.id,sectionId:Z.section.id})}return{jobs:U,totalSections:D,queuedSections:U.length,batchId:X}}return{jobs:[],totalSections:D,queuedSections:0,batchId:`empty-${Date.now()}`}}}class LuA{siteConfig;operations;constructor(A,Q){this.siteConfig=Q;this.operations=new quA(A)}async generateContent(A,Q){let B=P9A.parse(A);return this.operations.generate(B,this.siteConfig,Q)}}o$();WA();function qr(A,Q){return Q?A.optional():A}function EuA(A){switch(A.type){case"string":return qr(H.string(),A.optional);case"number":return qr(H.number(),A.optional);case"enum":{let Q=[...A.options];return qr(H.enum(Q),A.optional)}case"object":{let Q={};for(let[B,w]of Object.entries(A.fields))Q[B]=EuA(w);return qr(H.object(Q),A.optional)}case"array":{let Q=H.array(ajQ(A));if(A.minItems!==void 0)Q=Q.min(A.minItems);if(A.length!==void 0)Q=Q.length(A.length);return qr(Q,A.optional)}}}function ajQ(A){let{items:Q}=A;switch(Q.type){case"string":return H.string();case"number":return H.number();case"enum":{let B=[...Q.options];return H.enum(B)}case"object":{let B={};for(let[w,$]of Object.entries(Q.fields))B[w]=EuA($);return H.object(B)}}}function VuA(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])=>VuA(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,$])=>VuA(w,$)),B}}}}function tjQ(A,Q){let B={};for(let[f,I]of Object.entries(Q.fields))B[f]=EuA(I);let w=H.object(B),$=new lB(w,{title:Q.title,mappings:Object.entries(Q.fields).map(([f,I])=>VuA(f,I))});return{name:A,description:Q.description,schema:w,formatter:$,requiredPermission:Q.requiredPermission??"public",layout:{component:Q.layout,...Q.fullscreen!==void 0?{fullscreen:Q.fullscreen}:{}},...Q.runtimeScripts?{runtimeScripts:Q.runtimeScripts}:{}}}function MuA(A){return Object.fromEntries(Object.entries(A.sections).map(([Q,B])=>[Q,tjQ(Q,B)]))}WA();var FV1=H.object({namespace:H.string(),sections:H.record(H.any())}),ZV1=H.object({definitions:H.union([FV1,H.array(FV1)]).optional()});aA();function NV1(A,Q){return[oQ(Q,"generate","Generate content for all routes, a specific route, or a specific section",P9A,async(B,w)=>{let $=A();if(!$)return{success:!1,error:"Site content service not initialized"};if(B.sectionId&&!B.routeId)return{success:!1,error:"sectionId requires routeId to be specified"};let f={rootJobId:`generate-${Date.now()}`,progressToken:w.progressToken,pluginId:Q,operationType:"content_operations",interfaceType:w.interfaceType,channelId:w.channelId},I=await $.generateContent(B,f);return{success:!0,message:`Generated ${I.queuedSections} of ${I.totalSections} sections. ${I.queuedSections>0?"Jobs are running in the background.":"No new content to generate."}`,data:{batchId:I.batchId,jobsQueued:I.queuedSections,totalSections:I.totalSections,jobs:I.jobs}}})]}var zV1={name:"@brains/site-content",private:!0,version:"0.2.0-alpha.120",description:"Site content entity and generation orchestration",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/plugins":"workspace:*","@brains/site-info":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class CuA extends YB{siteContentService;constructor(A={}){super("site-content",zV1,A,ZV1)}async onRegister(A){A.entities.register("site-content",zr,zuA);for(let Q of iX(this.config.definitions))A.templates.register(MuA(Q),Q.namespace);this.siteContentService=new LuA(A)}async getTools(){return NV1(()=>this.siteContentService,this.id)}}function Lr(A={}){return new CuA(A)}aA();WA();Ew();WA();aA();var qV1=H.enum(["available","early access","coming soon","planned"]),LV1=H.object({title:H.string(),description:H.string()}),CD=H.object({name:H.string(),availability:qV1,order:H.number(),ogImageId:H.string().optional()}),k9A=H.object({tagline:H.string(),promise:H.string(),role:H.string(),purpose:H.string(),audience:H.string(),values:H.array(H.string()).min(1),features:H.array(LV1).min(1).max(6),story:H.string()}),A_Q=CD.pick({name:!0,availability:!0,order:!0}).extend({slug:H.string()}),nv=A2.extend({entityType:H.literal("product"),metadata:A_Q}),j9A=nv.extend({frontmatter:CD,body:k9A,labels:H.record(H.string(),H.string()),ogImageUrl:H.string().optional()}),_9A=j9A.extend({url:H.string().optional(),typeLabel:H.string().optional(),listUrl:H.string().optional(),listLabel:H.string().optional(),ogImageUrl:H.string().optional()});aA();WA();o$();class ov extends lB{constructor(){super(k9A,{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 OuA extends q2{constructor(){super({entityType:"product",schema:nv,frontmatterSchema:CD,bodyFormatter:new ov})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,CD);return this.buildMarkdown(Q,B)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,CD),B=X1(Q.name);return{content:A,entityType:"product",metadata:{name:Q.name,slug:B,availability:Q.availability,order:Q.order}}}}var v9A=new OuA;WA();aA();var VV1=H.object({title:H.string(),description:H.string()}),EV1=H.object({title:H.string(),description:H.string()}),Q_Q=H.object({title:H.string(),description:H.string()}),MV1=H.object({heading:H.string(),buttonText:H.string(),link:H.string()}),oF=H.object({headline:H.string(),tagline:H.string()}),B_Q=H.object({title:H.string(),description:H.string()}),T9A=H.object({vision:H.string(),pillars:H.array(VV1).min(1).max(6),approach:H.array(B_Q).min(1).max(6),productsIntro:H.string(),technologies:H.array(Q_Q).min(1).max(6),benefits:H.array(EV1).min(1).max(6),cta:MV1}),CV1=oF.pick({headline:!0}).extend({slug:H.string()}),sv=A2.extend({entityType:H.literal("products-overview"),metadata:CV1}),Vr=sv.extend({frontmatter:oF,body:T9A,labels:H.record(H.string(),H.string())});aA();WA();o$();class av extends lB{constructor(){super(T9A,{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 RuA extends q2{constructor(){super({entityType:"products-overview",schema:sv,frontmatterSchema:oF,bodyFormatter:new av})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,oF);return this.buildMarkdown(Q,B)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,oF),B=X1(Q.headline);return{content:A,entityType:"products-overview",metadata:{headline:Q.headline,slug:B}}}}var buA=new RuA;aA();WA();var w_Q=H.object({entityType:H.string(),query:H.object({id:H.string().optional()}).optional()});function OV1(A,Q){let B=R2(A.content,CD),w=Q.parse(B.content),$=Q.getLabels();return j9A.parse({...A,frontmatter:B.metadata,body:w,labels:$})}function RV1(A,Q){let B=R2(A.content,oF),w=Q.parse(B.content),$=Q.getLabels();return Vr.parse({...A,frontmatter:B.metadata,body:w,labels:$})}class y9A{logger;id="products:entities";name="Products Entity DataSource";description="Fetches products and overview for the products page";overviewFormatter=new av;productFormatter=new ov;constructor(A){this.logger=A;this.logger.debug("ProductsDataSource initialized")}async fetch(A,Q,B){let w=w_Q.parse(A),$=B.entityService;if(w.entityType==="products-overview"){let Y=(await $.listEntities({entityType:"products-overview",options:{limit:1}}))[0];if(!Y)throw Error("Products overview entity not found");let J=RV1(Y,this.overviewFormatter);return Q.parse(J)}if(w.query?.id){let Y=(await $.listEntities({entityType:"product",options:{filter:{metadata:{slug:w.query.id}},limit:1}}))[0];if(!Y)throw Error(`Product not found: ${w.query.id}`);return Q.parse({product:OV1(Y,this.productFormatter)})}let[f,I]=await Promise.all([$.listEntities({entityType:"products-overview",options:{limit:1}}),$.listEntities({entityType:"product",options:{sortFields:[{field:"order",direction:"asc"}]}})]),D=f[0];if(!D)throw Error("Products overview entity not found");return Q.parse({overview:RV1(D,this.overviewFormatter),products:I.map((U)=>OV1(U,this.productFormatter))})}}import{jsxDEV as A1,Fragment as I_Q}from"preact/jsx-dev-runtime";var bV1=({overview:A,products:Q})=>{let{frontmatter:B,body:w,labels:$}=A;return A1(I_Q,{children:[A1(KQ,{title:B.headline,description:B.tagline},void 0,!1,void 0,this),A1("header",{className:"relative w-full min-h-[80vh] flex items-end px-6 md:px-12 bg-brand-dark overflow-hidden",children:[A1("style",{children:`
|
|
8823
8823
|
@keyframes wave-drift {
|
|
8824
8824
|
from { transform: translateX(0); }
|
|
8825
8825
|
to { transform: translateX(-50%); }
|
|
@@ -9014,7 +9014,7 @@ ${JSON.stringify(B,null,2)}`}function K9A(A){return A.map((Q)=>Q.detail===null?{
|
|
|
9014
9014
|
font: 10px/1.45 var(--font-mono, "JetBrains Mono", ui-monospace, monospace);
|
|
9015
9015
|
}
|
|
9016
9016
|
`}},void 0,!1,void 0,this),OD("section",{className:"product-shell",children:[OD("header",{className:"product-hero",children:[Q.brandLabel&&OD("p",{className:"printable-kicker",children:Q.brandLabel},void 0,!1,void 0,this),OD("h1",{className:"printable-title",children:Q.name},void 0,!1,void 0,this),Q.availability&&OD("div",{className:"printable-meta",children:OD("span",{children:Q.availability},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),OD("div",{className:"product-body-wrap",children:[OD("aside",{className:"product-rail","aria-hidden":"true",children:OD("p",{className:"product-rail-label",children:"Product brief / capabilities"},void 0,!1,void 0,this)},void 0,!1,void 0,this),OD(V$,{markdown:Q.body,className:"printable-body"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.brandLabel&&OD("footer",{className:"printable-footer",children:Q.brandLabel},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}var G_Q=26214400,K_Q=60000;class kuA{context;renderPdf;constructor(A,Q={}){this.context=A;this.renderPdf=Q.renderPdf??$X}async resolve(A){if(A.sourceEntityType!=="product"||A.attachmentType!==x9A)return;let Q=await this.context.entityService.getEntity({entityType:"product",id:A.sourceEntityId});if(!Q)return;let B=F_Q(Q,{brandLabel:this.resolveBrandLabel()}),w=await J_Q(H_Q(W_Q(),"brain-product-printable-"));try{let $=await ZD({outputDir:w,mediaPath:`/_media/printable/product/${Q.id}`,template:jV1,format:"pdf",content:B,siteConfig:{title:B.name,themeMode:"light"},themeCSS:this.context.themeCSS}),f=await ND({rootDir:w});try{return{type:"document",data:await this.renderPdf(f.urlFor($.urlPath),{maxBytes:G_Q,timeoutMs:K_Q,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${Z_Q(Q)}-printable.pdf`}}finally{await f.close()}}finally{await X_Q(w,{recursive:!0,force:!0})}}resolveBrandLabel(){let A=this.context.domain?.trim();if(A&&A.length>0)return A;let Q=this.context.identity.getProfile().name.trim();return Q.length>0?Q:void 0}}function F_Q(A,Q={}){let{frontmatter:B,content:w}=jB(A.content),$=CD.parse(B);return{name:$.name,body:w,availability:$.availability,...Q.brandLabel?{brandLabel:Q.brandLabel}:{}}}function Z_Q(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.name)}WA();WA();import{jsxDEV as q_Q}from"preact/jsx-dev-runtime";var S9A="og-image",N_Q="products:og-image",_V1=H.object({name:H.string().min(1),tagline:H.string().optional(),availability:H.string().optional(),brandLabel:H.string().optional()}),vV1={name:N_Q,pluginId:"products",schema:_V1,renderers:{image:z_Q}};function z_Q(A){let Q=_V1.parse(A);return q_Q(zF,{cover:!0,brandLabel:Q.brandLabel??Q.name,eyebrow:"Product",title:Q.name,subtitle:Q.tagline,tag:Q.availability},void 0,!1,void 0,this)}class juA{context;deps;constructor(A,Q={}){this.context=A;this.deps=Q}async resolve(A){if(A.sourceEntityType!=="product"||A.attachmentType!==S9A)return;let Q=await this.context.entityService.getEntity({entityType:"product",id:A.sourceEntityId});if(!Q)return;let{frontmatter:B,content:w}=jB(Q.content),$=CD.parse(B),f=L_Q(w,"Tagline"),I=this.resolveBrandLabel(),D={name:$.name,availability:$.availability,...f?{tagline:f}:{},...I?{brandLabel:I}:{}};return{type:"image",data:await AC({mediaPath:`/_media/og/product/${Q.id}`,template:vV1,content:D,title:D.name,themeMode:"light",themeCSS:this.context.themeCSS,tmpPrefix:"brain-product-og-image-",...this.deps.screenshotPng&&{screenshotPng:this.deps.screenshotPng}}),mimeType:"image/png",filename:`${V_Q(Q)}-og.png`}}resolveBrandLabel(){let A=this.context.domain?.trim();if(A&&A.length>0)return A;let Q=this.context.identity.getProfile().name.trim();return Q.length>0?Q:void 0}}function L_Q(A,Q){let B=A.split(/\r?\n/),w=B.findIndex((I)=>I.trim().toLowerCase()===`## ${Q.toLowerCase()}`);if(w===-1)return;let $=[];for(let I of B.slice(w+1)){if(I.trim().startsWith("## "))break;$.push(I)}let f=$.join(`
|
|
9017
|
-
`).trim();return f.length>0?f:void 0}function V_Q(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.name)}var TV1={name:"@brains/products",private:!0,version:"0.2.0-alpha.
|
|
9017
|
+
`).trim();return f.length>0?f:void 0}function V_Q(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.name)}var TV1={name:"@brains/products",private:!0,version:"0.2.0-alpha.120",description:"Product entity management and overview page for marketing showcase",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/media-page-composer":"workspace:*","@brains/media-renderer":"workspace:*","@brains/plugins":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var M_Q=H.object({overview:Vr,products:H.array(_9A)}),C_Q=H.object({product:_9A});class _uA extends jQ{entityType=v9A.entityType;schema=nv;adapter=v9A;unregisterPrintableAttachmentProvider;unregisterOgImageAttachmentProvider;constructor(A={}){super("products",TV1,A,PuA)}getTemplates(){return{"product-list":P1({name:"product-list",description:"Products page \u2014 overview + brain model cards",schema:M_Q,dataSourceId:"products:entities",requiredPermission:"public",layout:{component:bV1}}),"product-detail":P1({name:"product-detail",description:"Individual product detail page",schema:C_Q,dataSourceId:"products:entities",requiredPermission:"public",layout:{component:PV1}})}}getDataSources(){return[new y9A(this.logger.child("ProductsDataSource"))]}async onRegister(A){this.unregisterPrintableAttachmentProvider=A.attachments.register("product",x9A,new kuA(A)),this.unregisterOgImageAttachmentProvider=A.attachments.register("product",S9A,new juA(A)),A.entities.register("products-overview",sv,buA)}async onShutdown(){this.unregisterPrintableAttachmentProvider?.(),this.unregisterPrintableAttachmentProvider=void 0,this.unregisterOgImageAttachmentProvider?.(),this.unregisterOgImageAttachmentProvider=void 0}}function vuA(A={}){return new _uA(A)}import{join as e_Q}from"path";import{jsxDEV as g9A,Fragment as O_Q}from"preact/jsx-dev-runtime";var tv=({children:A})=>g9A(O_Q,{children:[g9A("div",{id:"bgCanvasWrap",className:"rizom-frame-canvas-wrap fixed top-0 left-0 w-full h-full pointer-events-none",children:g9A("canvas",{id:"heroCanvas",className:"w-full h-full block"},void 0,!1,void 0,this)},void 0,!1,void 0,this),g9A("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 zJ8}from"preact/jsx-dev-runtime";import{jsxDEV as b_Q}from"preact/jsx-dev-runtime";var h9A="px-6 md:px-10 xl:px-20",R_Q=`${h9A} relative z-[1]`,Aq=({id:A,className:Q,children:B})=>b_Q("section",{id:A,className:B2(R_Q,Q),children:B},void 0,!1,void 0,this);import{jsxDEV as RJ8}from"preact/jsx-dev-runtime";import{jsxDEV as kJ8}from"preact/jsx-dev-runtime";import{jsxDEV as v_Q}from"preact/jsx-dev-runtime";var P_Q="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)]",k_Q={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)]"},j_Q={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)]"},__Q="w-full md:w-auto",EC=({href:A,variant:Q="primary",size:B="md",block:w=!1,className:$,children:f})=>v_Q("a",{href:A,className:B2("rizom-btn",`rizom-btn-${Q}`,`rizom-btn-${B}`,w&&"rizom-btn-block",P_Q,k_Q[Q],j_Q[B],w&&__Q,$),children:f},void 0,!1,void 0,this);import{jsxDEV as SJ8}from"preact/jsx-dev-runtime";import{jsxDEV as uJ8}from"preact/jsx-dev-runtime";import{Fragment as pJ8}from"preact";import{jsxDEV as rJ8}from"preact/jsx-dev-runtime";import{jsxDEV as yV1}from"preact/jsx-dev-runtime";var m9A=({sections:A})=>yV1(tv,{children:yV1("main",{children:A},void 0,!1,void 0,this)},void 0,!1,void 0,this);aA();WA();var xV1=`/*
|
|
9018
9018
|
* Shared globals + helpers used by tree / constellation / roots canvas
|
|
9019
9019
|
* scripts. Loaded as a shared static asset by the Rizom runtime package
|
|
9020
9020
|
* so the variant canvases
|
|
@@ -11504,7 +11504,7 @@ facts, owners, or tasks. Return only the required structured JSON.`});WA();var X
|
|
|
11504
11504
|
`);return this.truncateContent(w||Q||DT(A))}truncateContent(A){if(A.length<=zE1)return A;let Q=A.slice(0,zE1-1),B=Q.search(/\s\S*$/);return`${(B>0?Q.slice(0,B):Q).trimEnd()}\u2026`}isSummaryEntity(A){return A.entityType===s6}isDecisionEntity(A){return A.entityType===RD}getEntitySpaceId(A){let Q=A.metadata;if("spaceId"in Q&&typeof Q.spaceId==="string")return Q.spaceId;return XX(Q)}}var xvQ=5,SvQ=3;function luA(A){A.messaging.subscribe(ey,async(Q)=>{let B=DDA.parse(Q.payload);return{success:!0,data:await e9A(A,B)}})}async function e9A(A,Q){let B=d$(Q.userPermissionLevel);if(!Q.channelId)return qE1(A,Q,{visibilityScope:B,reason:"no-channel-context",items:[]}),{items:[]};let w=new UT(A),$=await w.retrieve({query:Q.message,conversationId:Q.conversationId,interfaceType:Q.interfaceType,channelId:Q.channelId,limit:xvQ,visibilityScope:B}),f=$.results.length===0?await w.retrieve({conversationId:Q.conversationId,interfaceType:Q.interfaceType,channelId:Q.channelId,limit:SvQ,visibilityScope:B}):void 0,I=$.results.length>0,D=I?$.results:f?.results??[];return qE1(A,Q,{visibilityScope:B,spaceId:$.spaceId??f?.spaceId,reason:D.length>0?"memory-injected":"no-same-space-memory",items:D.map((U)=>gvQ(U,I))}),{items:D.map(hvQ)}}function qE1(A,Q,B){A.logger.info("Conversation memory agent context audit",{conversationId:Q.conversationId,interfaceType:Q.interfaceType,channelId:Q.channelId,channelName:Q.channelName,userPermissionLevel:Q.userPermissionLevel,visibilityScope:B.visibilityScope,spaceId:B.spaceId,reason:B.reason,itemCount:B.items.length,items:B.items})}function gvQ(A,Q){return{id:A.id,entityType:A.entityType,conversationId:A.conversationId,spaceId:A.spaceId,visibility:A.visibility,score:A.score,updated:A.updated,eligibilityReason:Q?"same-space-query-match":"recent-same-space-memory"}}function hvQ(A){let Q=A.channelName??A.channelId;return{id:A.id,source:"conversation-memory",title:`${A.entityType} from ${Q}`,content:A.content,provenance:{entityType:A.entityType,entityId:A.id,conversationId:A.conversationId,spaceId:A.spaceId,interfaceType:A.interfaceType,channelId:A.channelId,channelName:A.channelName,updated:A.updated,score:A.score,messageCount:A.messageCount,entryCount:A.entryCount,status:A.status}}}aA();H6();WA();wU();var iuA=H.object({role:SG,content:H.string(),timestamp:H.string().datetime().optional(),actor:PL.optional(),source:kL.optional()}),mvQ=H.object({conversationId:H.string().default("eval-conversation"),messages:H.array(iuA)}),uvQ=H.object({conversationId:H.string()}),cvQ=H.object({conversationId:H.string().default("eval-conversation"),interfaceType:H.string().default("eval"),channelId:H.string().default("eval-channel"),channelName:H.string().optional(),projectionDecision:H.enum(["update","append"]).default("update"),existingSummary:H.string().optional(),existingMessageCount:H.number().int().min(0).default(0),messages:H.array(iuA)}),A7A=H.object({actorId:H.string(),canonicalId:H.string().optional(),displayName:H.string().optional()}),lvQ=A7A.extend({roles:H.array(H.enum(["user","assistant","system"])).default(["user"]),sourceActorIds:H.array(H.string()).optional()}),pvQ=H.object({actorId:H.string().optional(),canonicalId:H.string().optional(),displayName:H.string()}),EE1=H.object({id:H.string(),entityType:H.enum(["summary","decision","action-item"]),content:H.string(),excerpt:H.string().optional(),score:H.number().optional(),conversationId:H.string(),interfaceType:H.string(),channelId:H.string(),channelName:H.string().optional(),updated:H.string().datetime().optional(),visibility:R9,status:H.string().optional(),participants:H.array(lvQ).optional(),decidedBy:H.array(A7A).optional(),mentionedBy:H.array(A7A).optional(),assignedTo:H.array(pvQ).optional(),requestedBy:H.array(A7A).optional()}),ivQ=H.object({query:H.string().optional(),conversationId:H.string().optional(),interfaceType:H.string().optional(),channelId:H.string().optional(),limit:H.number().int().min(1).optional(),includeOtherSpaces:H.boolean().optional(),actorId:H.string().optional(),canonicalId:H.string().optional(),visibilityScope:R9.optional(),memory:H.array(EE1).optional()}),rvQ=H.object({conversationId:H.string().default("eval-conversation"),message:H.string(),interfaceType:H.string().default("eval"),channelId:H.string().optional(),channelName:H.string().optional(),userPermissionLevel:H.enum(["anchor","trusted","public"]).default("trusted"),memory:H.array(EE1).optional()}),dvQ=H.object({conversationId:H.string().default("eval-conversation"),existingSummary:H.string().optional(),existingMessageCount:H.number().int().min(0).default(0),messages:H.array(iuA)});function ME1(A){let{context:Q,logger:B,config:w}=A;Q.eval.registerHandler("summarizeMessages",async($)=>{let f=mvQ.parse($),I=puA(f.messages,f.conversationId),U=await new $T(Q,B,w).extract(I);return U.entries.map((Y)=>{let J=U.decisions.filter((G)=>G.timeRange.start>=Y.timeRange.start).filter((G)=>G.timeRange.end<=Y.timeRange.end).map((G)=>G.text),X=U.actionItems.filter((G)=>G.timeRange.start>=Y.timeRange.start).filter((G)=>G.timeRange.end<=Y.timeRange.end).map((G)=>G.text);return{...Y,decisions:J,actionItems:X,keyPointsText:Y.keyPoints.join(`
|
|
11505
11505
|
`),decisionsText:J.join(`
|
|
11506
11506
|
`),actionItemsText:X.join(`
|
|
11507
|
-
`)}})}),Q.eval.registerHandler("decideProjection",async($)=>{let f=dvQ.parse($),I=puA(f.messages,f.conversationId),D=f.existingSummary?LE1({conversationId:f.conversationId,content:f.existingSummary,messageCount:f.existingMessageCount,projectionVersion:w.projectionVersion,visibility:w.memoryVisibility}):null;return new Bq(Q,B,w).decideProjection(I,D)}),Q.eval.registerHandler("retrieveMemory",async($)=>{let f=ivQ.parse($),I=f.memory?VE1(Q,f.memory):Q;return new UT(I).retrieve(f)}),Q.eval.registerHandler("buildAgentContext",async($)=>{let f=rvQ.parse($),I=f.memory?VE1(Q,f.memory):Q;return e9A(I,f)}),Q.eval.registerHandler("projectMessages",async($)=>{let f=cvQ.parse($),I=puA(f.messages,f.conversationId),D=nvQ({conversationId:f.conversationId,interfaceType:f.interfaceType,channelId:f.channelId,channelName:f.channelName,messages:I}),U=f.existingSummary?LE1({conversationId:f.conversationId,content:f.existingSummary,messageCount:f.existingMessageCount,projectionVersion:w.projectionVersion,visibility:w.memoryVisibility}):null,Y=[],J=[],X=ovQ({context:Q,conversation:D,messages:I,existing:U,upserted:Y,deleted:J,projectionDecision:f.projectionDecision});return{result:await new Bq(X,B,w).projectConversation(f.conversationId),summaries:Y.filter((N)=>N.entityType==="summary"),decisions:Y.filter((N)=>N.entityType==="decision"),actionItems:Y.filter((N)=>N.entityType==="action-item"),deleted:J}}),Q.eval.registerHandler("projectConversation",async($)=>{let f=uvQ.parse($);return new Bq(Q,B,w).projectConversation(f.conversationId)})}function LE1(A){return{id:A.conversationId,entityType:"summary",content:A.content,contentHash:"eval-existing-summary",visibility:A.visibility,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 puA(A,Q){return A.map((B,w)=>{let $=B.timestamp??new Date(Date.UTC(2026,0,1,0,w)).toISOString();return{id:`eval-message-${w+1}`,conversationId:Q,role:B.role,content:B.content,timestamp:$,metadata:{...B.actor?{actor:B.actor}:{},...B.source?{source:B.source}:{}}}})}function nvQ(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 ovQ(A){let Q=XX(A.conversation);return{...A.context,spaces:[Q],conversations:{...A.context.conversations,get:async()=>A.conversation,getMessages:async()=>A.messages},ai:{...A.context.ai,generateObject:async()=>({object:{decision:A.projectionDecision,rationale:"Forced by eval input"}})},entityService:{...A.context.entityService,getEntity:async({entityType:B})=>B==="summary"?A.existing:null,listEntities:async()=>[],deleteEntity:async(B)=>{return A.deleted.push(B),!0},upsertEntity:async({entity:B})=>{return A.upserted.push(B),{entityId:B.id,jobId:"eval-upsert",created:!0,skipped:!1}}}}}function VE1(A,Q){let B=Q.map(svQ),w=B.map(($,f)=>({entity:$,score:Q[f]?.score??1,excerpt:Q[f]?.excerpt??DT($)}));return{...A,entityService:{...A.entityService,search:async()=>w,listEntities:async({entityType:$})=>B.filter((f)=>f.entityType===$)}}}function svQ(A){if(A.entityType==="summary")return avQ(A);if(A.entityType==="decision")return tvQ(A);return evQ(A)}function ruA(A){let Q=A.updated??"2026-01-01T00:00:00.000Z";return{id:A.id,content:A.content,contentHash:gB(A.content),visibility:A.visibility,created:Q,updated:Q}}function avQ(A){return{...ruA(A),entityType:"summary",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,messageCount:3,entryCount:1,sourceHash:`source-${A.id}`,projectionVersion:1,...A.participants?{participants:A.participants}:{}}}}function tvQ(A){return{...ruA(A),entityType:"decision",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,spaceId:XX(A),timeRange:{start:"2026-01-01T00:00:00.000Z",end:"2026-01-01T00:01:00.000Z"},sourceSummaryId:A.conversationId,sourceMessageCount:2,projectionVersion:1,status:A.status==="superseded"?"superseded":"active",...A.decidedBy?{decidedBy:A.decidedBy}:{},...A.mentionedBy?{mentionedBy:A.mentionedBy}:{}}}}function evQ(A){let Q=A.status==="done"||A.status==="dropped"?A.status:"open";return{...ruA(A),entityType:"action-item",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,spaceId:XX(A),timeRange:{start:"2026-01-01T00:00:00.000Z",end:"2026-01-01T00:01:00.000Z"},sourceSummaryId:A.conversationId,sourceMessageCount:2,projectionVersion:1,status:Q,...A.assignedTo?{assignedTo:A.assignedTo}:{},...A.requestedBy?{requestedBy:A.requestedBy}:{}}}}var CE1={name:"@brains/conversation-memory",private:!0,version:"0.2.0-alpha.119",description:"Plugin for deriving durable conversation memory",type:"module",main:"./src/index.ts",exports:{".":"./src/index.ts"},scripts:{test:"bun test",typecheck:"tsc --noEmit",lint:"eslint src test --ext .ts,.tsx",eval:"cd evals && bun run brain-eval","lint:fix":"eslint src test --ext .ts,.tsx --fix"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/conversation-service":"workspace:*","@brains/dashboard":"workspace:*","@brains/plugins":"workspace:*","@brains/templates":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/node":"^20.0.0",eslint:"^8.56.0",typescript:"^5.3.3"}};var QTQ=new eU,BTQ=new QT,wTQ=new BT,$TQ=H.object({conversationId:H.string()});class duA extends jQ{entityType=s6;schema=Mr;adapter=QTQ;constructor(A={}){super(c9A,CE1,A,SuA)}getConfig(){return this.config}getTemplates(){return{"summary-list":aV1,"summary-detail":tV1,"ai-response":eV1}}getDataSources(){return[new cuA(this.logger.child("SummaryDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableProjection)return[];return[{id:"conversation-memory-projection",targetType:s6,job:{type:pV1,handler:new n9A(A,this.logger,this.config)},initialSync:{shouldEnqueue:async()=>A.spaces.length>0&&!await OL(A,s6,{outputVisibility:this.config.memoryVisibility}),jobData:{mode:"rebuild-all",reason:"initial-sync"},jobOptions:{source:xuA,deduplication:"coalesce",deduplicationKey:"conversation-memory:rebuild-all:initial-sync",metadata:{operationType:"data_processing",operationTarget:"conversation-memory:rebuild-all",pluginId:c9A}}},sourceChange:{sourceKind:_x,sourceTypes:[_x],shouldEnqueue:(Q)=>this.shouldEnqueueConversationProjection(A,Q),events:[_R],jobData:(Q)=>{let{conversationId:B}=this.parseConversationMessagePayload(Q);return{mode:"conversation",conversationId:B,reason:"message-added"}},jobOptions:(Q)=>{let{conversationId:B}=this.parseConversationMessagePayload(Q);return{priority:5,delayMs:this.config.projectionDelayMs,source:xuA,deduplication:"skip",deduplicationKey:`conversation-memory:${B}`,metadata:{operationType:"data_processing",operationTarget:`conversation-memory:${B}`,pluginId:c9A}}}}}]}parseConversationMessagePayload(A){return $TQ.parse(A)}async shouldEnqueueConversationProjection(A,Q){let{conversationId:B}=this.parseConversationMessagePayload(Q),w=await A.conversations.get(B);if(!w)return!1;return OC({conversation:w,spaces:A.spaces}).eligible}async onRegister(A){A.entities.register(RD,Cr,BTQ),A.entities.register(tU,Or,wTQ),BE1({context:A,pluginId:this.id}),$E1({context:A,pluginId:this.id}),GE1({context:A,pluginId:this.id}),ZE1({context:A,pluginId:this.id,config:this.config}),luA(A),ME1({context:A,logger:this.logger,config:this.config})}}function nuA(A){return new duA(A)}aA();WA();aA();var sF=H.object({title:H.string(),section:H.string(),order:H.number().int(),sourcePath:H.string(),description:H.string().optional(),slug:H.string().optional()}),OE1=sF.pick({title:!0,section:!0,order:!0,description:!0}).extend({slug:H.string()}),YT=A2.extend({entityType:H.literal("doc"),metadata:OE1}),aF=YT.extend({frontmatter:sF,body:H.string()});aA();WA();class ouA extends q2{constructor(){super({entityType:"doc",schema:YT,frontmatterSchema:sF})}toMarkdown(A){let Q=this.extractBody(A.content),B=this.parseFrontMatter(A.content,sF);return this.buildMarkdown(Q,B)}fromMarkdown(A){let Q=this.parseFrontMatter(A,sF),B=Q.slug??X1(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 Q7A=new ouA;aA();function RE1(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 bE1(A){let Q=R2(A.content,sF);return aF.parse({...A,frontmatter:Q.metadata,body:Q.content})}class B7A extends m5{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 bE1(A)}async fetch(A,Q,B){let w=this.parseQuery(A);if(!w.query.id){let J=await this.fetchList({...w.query,limit:1000,page:void 0,pageSize:void 0},B.entityService);return Q.parse(this.buildListResult(J.items,null,w.query))}let[$,f]=await Promise.all([this.fetchDetail(w.query.id,B.entityService),this.fetchList({limit:1000},B.entityService)]),I=RE1(f.items),D=I.findIndex((J)=>J.id===$.item.id),U=D>0?I[D-1]:null,Y=D>=0&&D<I.length-1?I[D+1]:null;return Q.parse({doc:$.item,docs:I,prevDoc:U,nextDoc:Y})}buildDetailResult(A,Q){return{doc:A,docs:[A],prevDoc:Q?.prev??null,nextDoc:Q?.next??null}}buildListResult(A,Q,B){return{docs:RE1(A),pagination:Q,baseUrl:B.baseUrl}}}aA();Ew();WA();import{jsxDEV as w$}from"preact/jsx-dev-runtime";var fTQ=["I","II","III","IV","V","VI","VII","VIII","IX","X"];function Pr(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 w7A(A){let Q=new Map;for(let B of Pr(A)){let w=B.metadata.section;Q.set(w,[...Q.get(w)??[],B])}return[...Q.entries()].map(([B,w])=>({section:B,docs:w}))}function JT(A){return`/docs/${A.metadata.slug}`}function $7A(A){return`section-${A+1}`}function XT(A){return fTQ[A]??String(A+1)}var jE1="text-[var(--docs-text)] font-bold",_E1="text-[var(--docs-accent)] font-bold",vE1="text-[var(--docs-text-muted)]",ITQ="docs-font-label text-xs uppercase tracking-[0.18em] text-[var(--docs-accent)]",DTQ="docs-font-display text-[var(--docs-heading)]",PE1="inline-flex items-center justify-center rounded-lg border px-[18px] py-2.5 text-sm font-semibold transition-colors duration-150",kE1="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",suA="docs-font-label text-[13px] text-[var(--docs-text-light)] transition-colors duration-150 hover:text-[var(--docs-text)]",gH={wrap:"mx-auto max-w-6xl px-6 pt-20 md:px-12 md:pt-24",label:ITQ,display:DTQ,button:`${PE1} border-[var(--docs-text)] text-[var(--docs-text)] hover:border-[var(--docs-accent)] hover:text-[var(--docs-accent)]`,primaryButton:`${PE1} border-[var(--docs-accent)] bg-[var(--docs-accent)] text-white hover:bg-transparent hover:text-[var(--docs-accent)]`},TE1=()=>w$("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:[w$("a",{href:"/docs",className:"docs-font-body text-xl font-bold","aria-label":"Brains docs",children:[w$("span",{className:jE1,children:"brains"},void 0,!1,void 0,this),w$("span",{className:_E1,children:"."},void 0,!1,void 0,this),w$("span",{className:vE1,children:"docs"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),w$("div",{className:"docs-header__nav flex items-center gap-4 md:gap-8",children:[w$("a",{className:kE1,href:"/docs/roadmap",children:"Roadmap"},void 0,!1,void 0,this),w$("a",{className:kE1,href:"https://github.com/rizom-ai/brains",children:"GitHub"},void 0,!1,void 0,this),w$("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),yE1=()=>w$("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:[w$("a",{href:"https://rizom.ai",className:"docs-font-body text-[15px] font-bold",children:[w$("span",{className:jE1,children:"rizom"},void 0,!1,void 0,this),w$("span",{className:_E1,children:"."},void 0,!1,void 0,this),w$("span",{className:vE1,children:"ai"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),w$("div",{className:"flex flex-wrap items-center justify-center gap-6 md:justify-end",children:[w$("a",{className:suA,href:"/docs/roadmap",children:"Roadmap"},void 0,!1,void 0,this),w$("a",{className:suA,href:"https://github.com/rizom-ai/brains",children:"GitHub"},void 0,!1,void 0,this),w$("a",{className:suA,href:"https://rizom.ai",children:"Rizom"},void 0,!1,void 0,this),w$("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),UTQ=`
|
|
11507
|
+
`)}})}),Q.eval.registerHandler("decideProjection",async($)=>{let f=dvQ.parse($),I=puA(f.messages,f.conversationId),D=f.existingSummary?LE1({conversationId:f.conversationId,content:f.existingSummary,messageCount:f.existingMessageCount,projectionVersion:w.projectionVersion,visibility:w.memoryVisibility}):null;return new Bq(Q,B,w).decideProjection(I,D)}),Q.eval.registerHandler("retrieveMemory",async($)=>{let f=ivQ.parse($),I=f.memory?VE1(Q,f.memory):Q;return new UT(I).retrieve(f)}),Q.eval.registerHandler("buildAgentContext",async($)=>{let f=rvQ.parse($),I=f.memory?VE1(Q,f.memory):Q;return e9A(I,f)}),Q.eval.registerHandler("projectMessages",async($)=>{let f=cvQ.parse($),I=puA(f.messages,f.conversationId),D=nvQ({conversationId:f.conversationId,interfaceType:f.interfaceType,channelId:f.channelId,channelName:f.channelName,messages:I}),U=f.existingSummary?LE1({conversationId:f.conversationId,content:f.existingSummary,messageCount:f.existingMessageCount,projectionVersion:w.projectionVersion,visibility:w.memoryVisibility}):null,Y=[],J=[],X=ovQ({context:Q,conversation:D,messages:I,existing:U,upserted:Y,deleted:J,projectionDecision:f.projectionDecision});return{result:await new Bq(X,B,w).projectConversation(f.conversationId),summaries:Y.filter((N)=>N.entityType==="summary"),decisions:Y.filter((N)=>N.entityType==="decision"),actionItems:Y.filter((N)=>N.entityType==="action-item"),deleted:J}}),Q.eval.registerHandler("projectConversation",async($)=>{let f=uvQ.parse($);return new Bq(Q,B,w).projectConversation(f.conversationId)})}function LE1(A){return{id:A.conversationId,entityType:"summary",content:A.content,contentHash:"eval-existing-summary",visibility:A.visibility,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 puA(A,Q){return A.map((B,w)=>{let $=B.timestamp??new Date(Date.UTC(2026,0,1,0,w)).toISOString();return{id:`eval-message-${w+1}`,conversationId:Q,role:B.role,content:B.content,timestamp:$,metadata:{...B.actor?{actor:B.actor}:{},...B.source?{source:B.source}:{}}}})}function nvQ(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 ovQ(A){let Q=XX(A.conversation);return{...A.context,spaces:[Q],conversations:{...A.context.conversations,get:async()=>A.conversation,getMessages:async()=>A.messages},ai:{...A.context.ai,generateObject:async()=>({object:{decision:A.projectionDecision,rationale:"Forced by eval input"}})},entityService:{...A.context.entityService,getEntity:async({entityType:B})=>B==="summary"?A.existing:null,listEntities:async()=>[],deleteEntity:async(B)=>{return A.deleted.push(B),!0},upsertEntity:async({entity:B})=>{return A.upserted.push(B),{entityId:B.id,jobId:"eval-upsert",created:!0,skipped:!1}}}}}function VE1(A,Q){let B=Q.map(svQ),w=B.map(($,f)=>({entity:$,score:Q[f]?.score??1,excerpt:Q[f]?.excerpt??DT($)}));return{...A,entityService:{...A.entityService,search:async()=>w,listEntities:async({entityType:$})=>B.filter((f)=>f.entityType===$)}}}function svQ(A){if(A.entityType==="summary")return avQ(A);if(A.entityType==="decision")return tvQ(A);return evQ(A)}function ruA(A){let Q=A.updated??"2026-01-01T00:00:00.000Z";return{id:A.id,content:A.content,contentHash:gB(A.content),visibility:A.visibility,created:Q,updated:Q}}function avQ(A){return{...ruA(A),entityType:"summary",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,messageCount:3,entryCount:1,sourceHash:`source-${A.id}`,projectionVersion:1,...A.participants?{participants:A.participants}:{}}}}function tvQ(A){return{...ruA(A),entityType:"decision",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,spaceId:XX(A),timeRange:{start:"2026-01-01T00:00:00.000Z",end:"2026-01-01T00:01:00.000Z"},sourceSummaryId:A.conversationId,sourceMessageCount:2,projectionVersion:1,status:A.status==="superseded"?"superseded":"active",...A.decidedBy?{decidedBy:A.decidedBy}:{},...A.mentionedBy?{mentionedBy:A.mentionedBy}:{}}}}function evQ(A){let Q=A.status==="done"||A.status==="dropped"?A.status:"open";return{...ruA(A),entityType:"action-item",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,spaceId:XX(A),timeRange:{start:"2026-01-01T00:00:00.000Z",end:"2026-01-01T00:01:00.000Z"},sourceSummaryId:A.conversationId,sourceMessageCount:2,projectionVersion:1,status:Q,...A.assignedTo?{assignedTo:A.assignedTo}:{},...A.requestedBy?{requestedBy:A.requestedBy}:{}}}}var CE1={name:"@brains/conversation-memory",private:!0,version:"0.2.0-alpha.120",description:"Plugin for deriving durable conversation memory",type:"module",main:"./src/index.ts",exports:{".":"./src/index.ts"},scripts:{test:"bun test",typecheck:"tsc --noEmit",lint:"eslint src test --ext .ts,.tsx",eval:"cd evals && bun run brain-eval","lint:fix":"eslint src test --ext .ts,.tsx --fix"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/conversation-service":"workspace:*","@brains/dashboard":"workspace:*","@brains/plugins":"workspace:*","@brains/templates":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/node":"^20.0.0",eslint:"^8.56.0",typescript:"^5.3.3"}};var QTQ=new eU,BTQ=new QT,wTQ=new BT,$TQ=H.object({conversationId:H.string()});class duA extends jQ{entityType=s6;schema=Mr;adapter=QTQ;constructor(A={}){super(c9A,CE1,A,SuA)}getConfig(){return this.config}getTemplates(){return{"summary-list":aV1,"summary-detail":tV1,"ai-response":eV1}}getDataSources(){return[new cuA(this.logger.child("SummaryDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableProjection)return[];return[{id:"conversation-memory-projection",targetType:s6,job:{type:pV1,handler:new n9A(A,this.logger,this.config)},initialSync:{shouldEnqueue:async()=>A.spaces.length>0&&!await OL(A,s6,{outputVisibility:this.config.memoryVisibility}),jobData:{mode:"rebuild-all",reason:"initial-sync"},jobOptions:{source:xuA,deduplication:"coalesce",deduplicationKey:"conversation-memory:rebuild-all:initial-sync",metadata:{operationType:"data_processing",operationTarget:"conversation-memory:rebuild-all",pluginId:c9A}}},sourceChange:{sourceKind:_x,sourceTypes:[_x],shouldEnqueue:(Q)=>this.shouldEnqueueConversationProjection(A,Q),events:[_R],jobData:(Q)=>{let{conversationId:B}=this.parseConversationMessagePayload(Q);return{mode:"conversation",conversationId:B,reason:"message-added"}},jobOptions:(Q)=>{let{conversationId:B}=this.parseConversationMessagePayload(Q);return{priority:5,delayMs:this.config.projectionDelayMs,source:xuA,deduplication:"skip",deduplicationKey:`conversation-memory:${B}`,metadata:{operationType:"data_processing",operationTarget:`conversation-memory:${B}`,pluginId:c9A}}}}}]}parseConversationMessagePayload(A){return $TQ.parse(A)}async shouldEnqueueConversationProjection(A,Q){let{conversationId:B}=this.parseConversationMessagePayload(Q),w=await A.conversations.get(B);if(!w)return!1;return OC({conversation:w,spaces:A.spaces}).eligible}async onRegister(A){A.entities.register(RD,Cr,BTQ),A.entities.register(tU,Or,wTQ),BE1({context:A,pluginId:this.id}),$E1({context:A,pluginId:this.id}),GE1({context:A,pluginId:this.id}),ZE1({context:A,pluginId:this.id,config:this.config}),luA(A),ME1({context:A,logger:this.logger,config:this.config})}}function nuA(A){return new duA(A)}aA();WA();aA();var sF=H.object({title:H.string(),section:H.string(),order:H.number().int(),sourcePath:H.string(),description:H.string().optional(),slug:H.string().optional()}),OE1=sF.pick({title:!0,section:!0,order:!0,description:!0}).extend({slug:H.string()}),YT=A2.extend({entityType:H.literal("doc"),metadata:OE1}),aF=YT.extend({frontmatter:sF,body:H.string()});aA();WA();class ouA extends q2{constructor(){super({entityType:"doc",schema:YT,frontmatterSchema:sF})}toMarkdown(A){let Q=this.extractBody(A.content),B=this.parseFrontMatter(A.content,sF);return this.buildMarkdown(Q,B)}fromMarkdown(A){let Q=this.parseFrontMatter(A,sF),B=Q.slug??X1(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 Q7A=new ouA;aA();function RE1(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 bE1(A){let Q=R2(A.content,sF);return aF.parse({...A,frontmatter:Q.metadata,body:Q.content})}class B7A extends m5{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 bE1(A)}async fetch(A,Q,B){let w=this.parseQuery(A);if(!w.query.id){let J=await this.fetchList({...w.query,limit:1000,page:void 0,pageSize:void 0},B.entityService);return Q.parse(this.buildListResult(J.items,null,w.query))}let[$,f]=await Promise.all([this.fetchDetail(w.query.id,B.entityService),this.fetchList({limit:1000},B.entityService)]),I=RE1(f.items),D=I.findIndex((J)=>J.id===$.item.id),U=D>0?I[D-1]:null,Y=D>=0&&D<I.length-1?I[D+1]:null;return Q.parse({doc:$.item,docs:I,prevDoc:U,nextDoc:Y})}buildDetailResult(A,Q){return{doc:A,docs:[A],prevDoc:Q?.prev??null,nextDoc:Q?.next??null}}buildListResult(A,Q,B){return{docs:RE1(A),pagination:Q,baseUrl:B.baseUrl}}}aA();Ew();WA();import{jsxDEV as w$}from"preact/jsx-dev-runtime";var fTQ=["I","II","III","IV","V","VI","VII","VIII","IX","X"];function Pr(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 w7A(A){let Q=new Map;for(let B of Pr(A)){let w=B.metadata.section;Q.set(w,[...Q.get(w)??[],B])}return[...Q.entries()].map(([B,w])=>({section:B,docs:w}))}function JT(A){return`/docs/${A.metadata.slug}`}function $7A(A){return`section-${A+1}`}function XT(A){return fTQ[A]??String(A+1)}var jE1="text-[var(--docs-text)] font-bold",_E1="text-[var(--docs-accent)] font-bold",vE1="text-[var(--docs-text-muted)]",ITQ="docs-font-label text-xs uppercase tracking-[0.18em] text-[var(--docs-accent)]",DTQ="docs-font-display text-[var(--docs-heading)]",PE1="inline-flex items-center justify-center rounded-lg border px-[18px] py-2.5 text-sm font-semibold transition-colors duration-150",kE1="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",suA="docs-font-label text-[13px] text-[var(--docs-text-light)] transition-colors duration-150 hover:text-[var(--docs-text)]",gH={wrap:"mx-auto max-w-6xl px-6 pt-20 md:px-12 md:pt-24",label:ITQ,display:DTQ,button:`${PE1} border-[var(--docs-text)] text-[var(--docs-text)] hover:border-[var(--docs-accent)] hover:text-[var(--docs-accent)]`,primaryButton:`${PE1} border-[var(--docs-accent)] bg-[var(--docs-accent)] text-white hover:bg-transparent hover:text-[var(--docs-accent)]`},TE1=()=>w$("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:[w$("a",{href:"/docs",className:"docs-font-body text-xl font-bold","aria-label":"Brains docs",children:[w$("span",{className:jE1,children:"brains"},void 0,!1,void 0,this),w$("span",{className:_E1,children:"."},void 0,!1,void 0,this),w$("span",{className:vE1,children:"docs"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),w$("div",{className:"docs-header__nav flex items-center gap-4 md:gap-8",children:[w$("a",{className:kE1,href:"/docs/roadmap",children:"Roadmap"},void 0,!1,void 0,this),w$("a",{className:kE1,href:"https://github.com/rizom-ai/brains",children:"GitHub"},void 0,!1,void 0,this),w$("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),yE1=()=>w$("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:[w$("a",{href:"https://rizom.ai",className:"docs-font-body text-[15px] font-bold",children:[w$("span",{className:jE1,children:"rizom"},void 0,!1,void 0,this),w$("span",{className:_E1,children:"."},void 0,!1,void 0,this),w$("span",{className:vE1,children:"ai"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),w$("div",{className:"flex flex-wrap items-center justify-center gap-6 md:justify-end",children:[w$("a",{className:suA,href:"/docs/roadmap",children:"Roadmap"},void 0,!1,void 0,this),w$("a",{className:suA,href:"https://github.com/rizom-ai/brains",children:"GitHub"},void 0,!1,void 0,this),w$("a",{className:suA,href:"https://rizom.ai",children:"Rizom"},void 0,!1,void 0,this),w$("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),UTQ=`
|
|
11508
11508
|
.docs-handbook {
|
|
11509
11509
|
--docs-bg: var(--color-bg, #0d0a1a);
|
|
11510
11510
|
--docs-bg-card: var(--color-bg-card, #1a0a3e);
|
|
@@ -11656,7 +11656,7 @@ facts, owners, or tasks. Return only the required structured JSON.`});WA();var X
|
|
|
11656
11656
|
background: transparent;
|
|
11657
11657
|
}
|
|
11658
11658
|
|
|
11659
|
-
`,xE1=()=>w$("style",{children:UTQ},void 0,!1,void 0,this);import{jsxDEV as K2,Fragment as YTQ}from"preact/jsx-dev-runtime";var f7A=({title:A,description:Q,children:B,detail:w=!1,footer:$=!1,contentClassName:f=""})=>K2(YTQ,{children:[K2(KQ,{title:A,description:Q},void 0,!1,void 0,this),K2(xE1,{},void 0,!1,void 0,this),K2("div",{className:`docs-handbook${w?" docs-handbook--detail":""}`,children:[K2(TE1,{},void 0,!1,void 0,this),K2("div",{className:`${gH.wrap} ${f}`.trim(),children:[B,$&&K2(yE1,{},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),SE1=({docsCount:A,sectionsCount:Q,startDoc:B})=>K2("section",{className:"border-b border-[var(--docs-text)] py-14 md:py-24 md:pb-[72px]",children:[K2("p",{className:`${gH.label} mb-8`,children:"Handbook \xB7 Brains docs"},void 0,!1,void 0,this),K2("h1",{className:`${gH.display} m-0 max-w-[16ch] text-5xl leading-[1.05] tracking-[-0.02em] md:text-7xl`,children:["Build, run, and publish"," ",K2("em",{className:"text-[var(--docs-accent)]",children:"brains."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),K2("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),K2("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:[K2("div",{children:[K2("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),K2("div",{children:[K2("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),K2("div",{children:[K2("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),K2("div",{className:"mt-9 flex flex-wrap gap-3.5",children:[B&&K2("a",{className:gH.primaryButton,href:JT(B),children:"Start reading"},void 0,!1,void 0,this),K2("a",{className:gH.button,href:"#sections",children:"Browse sections"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),gE1=({groups:A})=>K2("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:[K2("p",{className:"m-0 mb-3.5 font-medium text-[var(--docs-text)]",children:"Sections"},void 0,!1,void 0,this),K2("ol",{className:"m-0 list-none p-0",children:A.map((Q,B)=>K2("li",{className:"grid grid-cols-[32px_1fr] gap-2 py-1.5",children:[K2("span",{className:"docs-font-display text-[var(--docs-text-light)] italic",children:[XT(B),"."]},void 0,!0,void 0,this),K2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:`#${$7A(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),hE1=({group:A,index:Q})=>K2("article",{className:"mb-16 last:mb-0",id:$7A(Q),children:[K2("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:[K2("span",{className:"text-right docs-font-display text-3xl leading-[1.1] text-[var(--docs-accent)] italic md:text-4xl",children:[XT(Q),"."]},void 0,!0,void 0,this),K2("h2",{className:`${gH.display} m-0 text-3xl leading-[1.1] tracking-[-0.015em] md:text-4xl`,children:A.section},void 0,!1,void 0,this),K2("span",{className:"docs-chapter__leader"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),K2("ol",{className:"m-0 list-none p-0",children:A.docs.map((B)=>K2("li",{className:"border-b border-[var(--docs-border-light)] last:border-b-0",children:K2("a",{className:"group block py-[18px] pl-12 md:pl-[68px]",href:JT(B),children:[K2("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&&K2("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),mE1=({title:A})=>K2("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:[K2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/",children:"Home"},void 0,!1,void 0,this),K2("span",{children:"/"},void 0,!1,void 0,this),K2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/docs",children:"Docs"},void 0,!1,void 0,this),K2("span",{children:"/"},void 0,!1,void 0,this),K2("span",{children:A},void 0,!1,void 0,this)]},void 0,!0,void 0,this),uE1=({groups:A,activeGroupIndex:Q,activeSlug:B})=>K2("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:K2("nav",{className:"docs-font-label text-xs tracking-[0.06em] text-[var(--docs-text-light)]",children:[K2("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),K2("ol",{className:"m-0 list-none p-0",children:A.map((w,$)=>{let f=$===Q;return K2("li",{className:f?"mb-[22px]":"mb-3.5",children:[K2("a",{className:`mb-2 flex items-baseline gap-2.5 docs-font-label text-[11px] uppercase leading-[1.4] tracking-[0.06em] transition-colors duration-150 hover:text-[var(--docs-text)] ${f?"text-[var(--docs-text)]":"text-[var(--docs-text-muted)]"}`,href:`/docs#${$7A($)}`,children:[K2("span",{className:"docs-font-display text-sm text-[var(--docs-accent)] italic",children:[XT($),"."]},void 0,!0,void 0,this)," ",w.section]},void 0,!0,void 0,this),f&&K2("ol",{className:"mt-0.5 list-none p-0",children:w.docs.map((I)=>{let D=I.metadata.slug===B;return K2("li",{children:K2("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:JT(I),"aria-current":D?"page":void 0,children:I.metadata.title},void 0,!1,void 0,this)},I.id,!1,void 0,this)})},void 0,!1,void 0,this)]},w.section,!0,void 0,this)})},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),cE1=({prevDoc:A,nextDoc:Q})=>{if(!A&&!Q)return null;return K2("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?K2("a",{className:"group border-t border-[var(--docs-border-light)] pt-[18px] transition-colors duration-150 hover:border-[var(--docs-accent)]",href:JT(A),children:[K2("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),K2("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):K2("span",{},void 0,!1,void 0,this),Q&&K2("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:JT(Q),children:[K2("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),K2("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 WT}from"preact/jsx-dev-runtime";var auA=({docs:A})=>{let Q=Pr(A),B=w7A(Q),$=Q.filter((f)=>f.metadata.slug!=="index")[0]??Q[0];return WT(f7A,{title:"Documentation",description:"Brains documentation",children:[WT(SE1,{docsCount:A.length,sectionsCount:B.length,startDoc:$},void 0,!1,void 0,this),WT("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:[WT(gE1,{groups:B},void 0,!1,void 0,this),WT("div",{children:B.map((f,I)=>WT(hE1,{group:f,index:I},f.section,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as bD}from"preact/jsx-dev-runtime";var tuA=({doc:A,docs:Q,prevDoc:B,nextDoc:w})=>{let $=w7A(Q.length>0?Q:[A]),f=Pr(Q.length>0?Q:[A]),I=f.findIndex((U)=>U.metadata.slug===A.metadata.slug),D=Math.max($.findIndex((U)=>U.docs.some((Y)=>Y.metadata.slug===A.metadata.slug)),0);return bD(f7A,{title:A.metadata.title,description:A.metadata.description??A.metadata.section,detail:!0,footer:!0,contentClassName:"pt-16",children:[bD(mE1,{title:A.metadata.title},void 0,!1,void 0,this),bD("div",{className:"grid items-start gap-10 py-8 pb-24 md:grid-cols-[240px_minmax(0,1fr)] md:gap-20",children:[bD(uE1,{groups:$,activeGroupIndex:D,activeSlug:A.metadata.slug},void 0,!1,void 0,this),bD("article",{className:"min-w-0",children:[bD("header",{className:"mb-10 border-b border-[var(--docs-border)] pb-8",children:[bD("p",{className:`${gH.label} m-0 mb-6 flex items-baseline gap-3`,children:[bD("span",{className:"docs-font-display text-lg leading-none tracking-normal normal-case text-[var(--docs-accent)] italic",children:[XT(D),"."]},void 0,!0,void 0,this)," ",A.metadata.section,I>=0?` \xB7 ${I+1}/${f.length}`:""]},void 0,!0,void 0,this),bD("h1",{className:`${gH.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&&bD("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),bD("div",{className:"docs-article__body",children:bD(V$,{markdown:A.body},void 0,!1,void 0,this)},void 0,!1,void 0,this),bD(cE1,{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 JTQ=H.object({docs:H.array(aF),pagination:Z7.nullable(),baseUrl:H.string().optional()}),XTQ=H.object({doc:aF,docs:H.array(aF),prevDoc:aF.nullable(),nextDoc:aF.nullable()});function lE1(){return{"doc-list":P1({name:"doc-list",description:"Documentation index template",schema:JTQ,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:auA}}),"doc-detail":P1({name:"doc-detail",description:"Documentation page template",schema:XTQ,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:tuA}})}}var pE1={name:"@brains/doc",private:!0,version:"0.2.0-alpha.119",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 euA extends jQ{entityType=Q7A.entityType;schema=YT;adapter=Q7A;constructor(){super("docs",pE1,{},void 0)}getTemplates(){return lE1()}getDataSources(){return[new B7A(this.logger.child("DocDataSource"))]}}function AcA(){return new euA}aA();WA();WA();o$();var iE1=H.object({label:H.string(),href:H.string()}),rE1=H.object({label:H.string(),title:H.string(),detail:H.string()}),HTQ=H.object({eyebrow:H.string(),name:H.string(),sub:H.string()}),GTQ=H.object({tone:H.enum(["capture","synthesis","share"]),title:H.string(),text:H.string()}),QcA=H.object({captures:H.number(),links:H.number(),topics:H.number(),summaries:H.number(),peers:H.number()}),HT=H.object({eyebrow:H.string(),headline:H.string(),intro:H.string(),primaryCta:iE1,secondaryCta:iE1,inputs:H.array(rE1).min(1),outputs:H.array(rE1).min(1),core:HTQ,legend:H.array(GTQ).min(1)}),BcA=HT.extend({counts:QcA}),dE1={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."}]},nE1=new lB(HT,{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 I7A(A){return nE1.parse(A)}function oE1(A){return nE1.format(A)}WA();var KTQ=H.object({query:H.object({routeId:H.string().default("home"),sectionId:H.string().default("diagram")}).default({routeId:"home",sectionId:"diagram"})}).passthrough(),FTQ={captures:"base",links:"link",topics:"topic",summaries:"summary",peers:"agent"};class wcA{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=KTQ.parse(A??{}),$=await this.fetchContent(B,w.query.routeId,w.query.sectionId),f=await this.fetchCounts(B);return Q.parse({...$,counts:f})}async fetchContent(A,Q,B){let w=await A.entityService.getEntity({entityType:"site-content",id:`${Q}:${B}`});if(!w?.content)return dE1;return HT.parse(I7A(w.content))}async fetchCounts(A){let Q=await Promise.all(Object.entries(FTQ).map(async([B,w])=>[B,await this.countOrZero(A,w)]));return QcA.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 Q1}from"preact/jsx-dev-runtime";var sE1=H.object({label:H.string(),href:H.string()}),ZTQ=H.object({eyebrow:H.string(),headline:H.string(),intro:H.string(),primaryCta:sE1,secondaryCta:sE1,signals:H.array(H.object({label:H.string(),value:H.string(),note:H.string()}))}),NTQ=H.object({eyebrow:H.string(),title:H.string(),intro:H.string(),steps:H.array(H.object({phase:H.string(),title:H.string(),text:H.string()}))}),zTQ=H.object({title:H.string(),intro:H.string(),cards:H.array(H.object({label:H.string(),title:H.string(),text:H.string()}))}),qTQ=H.object({title:H.string(),intro:H.string(),points:H.array(H.string())}),LTQ={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."]},VTQ="font-body text-[15px] text-theme-muted transition-colors hover:text-theme";function aE1({href:A,label:Q}){return Q1("a",{href:A,className:VTQ,children:Q},void 0,!1,void 0,this)}function ETQ({siteInfo:A,children:Q}){let B=[...A.navigation.primary,...A.navigation.secondary],w=A.cta??{buttonText:"Start here",buttonLink:"/about"};return Q1(tv,{children:[Q1("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:[Q1("a",{href:"/",className:"font-nav text-[20px]","aria-label":"Relay home",children:[Q1("span",{className:"font-bold text-theme",children:"relay"},void 0,!1,void 0,this),Q1("span",{className:"font-bold text-accent",children:"."},void 0,!1,void 0,this),Q1("span",{className:"text-theme-muted",children:"brain"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"flex items-center gap-5 md:gap-8",children:[Q1("div",{className:"hidden items-center gap-6 md:flex",children:B.map(($)=>Q1(aE1,{...$},`${$.href}-${$.label}`,!1,void 0,this))},void 0,!1,void 0,this),Q1("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),Q1("main",{children:Q},void 0,!1,void 0,this),Q1("footer",{className:"relative z-[1] border-t border-theme-light px-6 py-8 md:px-10 xl:px-20",children:Q1("div",{className:"flex flex-col gap-4 md:flex-row md:items-center md:justify-between",children:[Q1("div",{children:[Q1("p",{className:"font-label text-label-sm uppercase tracking-[0.22em] text-theme-light",children:A.copyright},void 0,!1,void 0,this),Q1("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),Q1("div",{className:"flex flex-wrap items-center gap-5",children:[B.map(($)=>Q1(aE1,{...$},`footer-${$.href}-${$.label}`,!1,void 0,this)),Q1("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 MTQ=({sections:A,siteInfo:Q})=>Q1(ETQ,{siteInfo:Q,children:A},void 0,!1,void 0,this);function CTQ({eyebrow:A,headline:Q,intro:B,primaryCta:w,secondaryCta:$,signals:f}){return Q1(Aq,{className:"min-h-[92vh] pt-[152px] pb-20 md:pt-[190px]",children:Q1("div",{className:"grid gap-10 lg:grid-cols-[minmax(0,1fr)_420px] lg:items-end",children:[Q1("div",{children:[Q1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:A},void 0,!1,void 0,this),Q1("h1",{className:"mt-7 max-w-[980px] font-display text-display-lg text-theme",children:Q},void 0,!1,void 0,this),Q1("p",{className:"mt-7 max-w-[720px] font-body text-body-lg text-theme-muted",children:B},void 0,!1,void 0,this),Q1("div",{className:"mt-10 flex flex-col gap-3 sm:flex-row",children:[Q1(EC,{href:w.href,size:"lg",variant:"primary-strong",children:w.label},void 0,!1,void 0,this),Q1(EC,{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),Q1("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:[Q1("p",{className:"font-label text-label-xs uppercase tracking-[0.24em] text-theme-light",children:"Live relay signals"},void 0,!1,void 0,this),Q1("div",{className:"mt-5 grid gap-3",children:f.map((I)=>Q1("div",{className:"rounded-[22px] border border-card-divider bg-bg-muted p-5",children:[Q1("div",{className:"flex items-center justify-between gap-4",children:[Q1("p",{className:"font-label text-label-xs uppercase tracking-[0.18em] text-secondary",children:I.label},void 0,!1,void 0,this),Q1("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),Q1("p",{className:"mt-4 font-display text-display-sm text-theme",children:I.value},void 0,!1,void 0,this),Q1("p",{className:"mt-2 font-body text-body-xs text-theme-muted",children:I.note},void 0,!1,void 0,this)]},I.label,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)}function OTQ({eyebrow:A,title:Q,intro:B,steps:w}){return Q1(Aq,{id:"operating-loop",className:"py-section",children:[Q1("div",{className:"max-w-[840px]",children:[Q1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-secondary",children:A},void 0,!1,void 0,this),Q1("h2",{className:"mt-5 font-display text-display-md text-theme",children:Q},void 0,!1,void 0,this),Q1("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),Q1("div",{className:"mt-12 grid gap-4 md:grid-cols-3",children:w.map(($)=>Q1("article",{className:"min-h-[300px] rounded-[28px] border border-card-panel-border bg-card-panel-bg p-6",children:[Q1("p",{className:"font-label text-label-sm text-accent",children:$.phase},void 0,!1,void 0,this),Q1("h3",{className:"mt-16 font-display text-display-sm text-theme",children:$.title},void 0,!1,void 0,this),Q1("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 RTQ({title:A,intro:Q,cards:B}){return Q1(Aq,{className:"py-section",children:Q1("div",{className:"rounded-[36px] border border-theme-light bg-bg-muted p-6 md:p-10",children:Q1("div",{className:"grid gap-8 lg:grid-cols-[360px_1fr]",children:[Q1("div",{children:[Q1("h2",{className:"font-display text-display-md text-theme",children:A},void 0,!1,void 0,this),Q1("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),Q1("div",{className:"grid gap-4",children:B.map((w)=>Q1("article",{className:"rounded-[24px] border border-card-divider bg-bg-subtle/70 p-5",children:[Q1("p",{className:"font-label text-label-xs uppercase tracking-[0.22em] text-accent",children:w.label},void 0,!1,void 0,this),Q1("h3",{className:"mt-3 font-nav text-heading-lg text-theme",children:w.title},void 0,!1,void 0,this),Q1("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 bTQ({title:A,intro:Q,points:B}){return Q1(Aq,{className:"min-h-[78vh] pt-[150px] pb-section md:pt-[190px]",children:[Q1("div",{className:"max-w-[920px]",children:[Q1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:"Relay model"},void 0,!1,void 0,this),Q1("h1",{className:"mt-6 font-display text-display-lg text-theme",children:A},void 0,!1,void 0,this),Q1("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),Q1("div",{className:"mt-12 grid gap-4 md:grid-cols-3",children:B.map((w)=>Q1("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 PTQ=(A)=>{switch(A){case"capture":return"bg-accent";case"synthesis":return"bg-secondary";case"share":return"bg-accent-bright"}},kTQ=(A)=>new Intl.NumberFormat("en",{notation:A>999?"compact":"standard"}).format(A),kr=(A,Q,B=`${Q}s`)=>`${kTQ(A)} ${A===1?Q:B}`;function jTQ({eyebrow:A,headline:Q,intro:B,primaryCta:w,secondaryCta:$,inputs:f,outputs:I,core:D,legend:U,counts:Y}){let J=[{key:"captures",className:"top-[-10px] left-1/2 -translate-x-1/2",label:kr(Y.captures,"capture")},{key:"topics",className:"top-1/2 right-[-28px] -translate-y-1/2",label:kr(Y.topics,"topic")},{key:"peers",className:"bottom-[-10px] left-1/2 -translate-x-1/2",label:kr(Y.peers,"peer brain")},{key:"summaries",className:"top-1/2 left-[-28px] -translate-y-1/2",label:kr(Y.summaries,"summary","summaries")}];return Q1(Aq,{className:"pt-[150px] pb-section md:pt-[190px]",id:"diagram",children:[Q1("div",{className:"mx-auto max-w-[1040px] text-center",children:[Q1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:A},void 0,!1,void 0,this),Q1("h1",{className:"mx-auto mt-7 max-w-[22ch] font-display text-display-lg text-theme",children:Q},void 0,!1,void 0,this),Q1("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),Q1("div",{className:"mt-10 flex flex-col justify-center gap-3 sm:flex-row",children:[Q1(EC,{href:w.href,size:"lg",variant:"primary-strong",children:w.label},void 0,!1,void 0,this),Q1(EC,{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),Q1("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:[Q1("div",{className:"grid items-center gap-8 lg:grid-cols-[1fr_1.4fr_1fr]",children:[Q1("div",{className:"flex flex-col gap-3.5",children:f.map((X)=>Q1("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:[Q1("p",{className:"font-label text-[10px] uppercase tracking-[0.22em] text-secondary",children:X.label},void 0,!1,void 0,this),Q1("h2",{className:"mt-1.5 font-display text-[18px] font-medium text-theme",children:X.title},void 0,!1,void 0,this),Q1("p",{className:"mt-1 font-body text-[13px] leading-[1.5] text-theme-muted",children:X.detail},void 0,!1,void 0,this)]},`${X.label}-${X.title}`,!0,void 0,this))},void 0,!1,void 0,this),Q1("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:[Q1("div",{className:"absolute inset-0 rounded-full border border-dashed border-accent/30"},void 0,!1,void 0,this),Q1("div",{className:"absolute inset-6 animate-spin rounded-full border border-dashed border-secondary/40 [animation-duration:28s]"},void 0,!1,void 0,this),J.map((X)=>Q1("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 ${X.className}`,children:X.label},X.key,!1,void 0,this)),Q1("div",{className:"relative z-[1] px-6 text-center",children:[Q1("p",{className:"font-label text-[10px] uppercase tracking-[0.28em] text-accent",children:D.eyebrow},void 0,!1,void 0,this),Q1("p",{className:"mt-2 font-display text-[36px] leading-none text-theme",children:D.name},void 0,!1,void 0,this),Q1("p",{className:"mt-2 font-body text-[13px] text-theme-muted",children:D.sub},void 0,!1,void 0,this),Q1("p",{className:"mt-4 font-label text-[10px] uppercase tracking-[0.18em] text-theme-light",children:[kr(Y.links,"link")," indexed"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"flex flex-col gap-3.5",children:I.map((X)=>Q1("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:[Q1("p",{className:"font-label text-[10px] uppercase tracking-[0.22em] text-secondary",children:X.label},void 0,!1,void 0,this),Q1("h2",{className:"mt-1.5 font-display text-[18px] font-medium text-theme",children:X.title},void 0,!1,void 0,this),Q1("p",{className:"mt-1 font-body text-[13px] leading-[1.5] text-theme-muted",children:X.detail},void 0,!1,void 0,this)]},`${X.label}-${X.title}`,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"mt-14 grid gap-4 border-t border-theme-light pt-8 md:grid-cols-3",children:U.map((X)=>Q1("div",{className:"text-left",children:[Q1("h2",{className:"font-display text-[16px] font-medium text-theme",children:[Q1("span",{className:`mr-2.5 inline-block h-3 w-3 rounded-[3px] align-middle ${PTQ(X.tone)}`},void 0,!1,void 0,this),X.title]},void 0,!0,void 0,this),Q1("p",{className:"mt-1.5 font-body text-[13px] leading-[1.6] text-theme-muted",children:X.text},void 0,!1,void 0,this)]},X.title,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}var _TQ=P1({name:"home-diagram",description:"Relay homepage system diagram with live entity counts",schema:BcA,formatter:{parse:(A)=>BcA.parse({...I7A(A),counts:{captures:0,links:0,topics:0,summaries:0,peers:0}}),format:(A)=>oE1(HT.parse(A))},dataSourceId:"relay-site:home-counts",requiredPermission:"public",layout:{component:jTQ}}),vTQ=(A)=>CTQ(ZTQ.parse(A)),TTQ=(A)=>OTQ(NTQ.parse(A)),yTQ=(A)=>RTQ(zTQ.parse(A)),xTQ=(A)=>bTQ(qTQ.parse(A)),tE1={type:"object",label:"CTA",fields:{label:{type:"string",label:"Label"},href:{type:"string",label:"Href"}}},eE1={namespace:"relay-site",sections:{"home-hero":{title:"Home hero",description:"Relay homepage hero section",layout:vTQ,fields:{eyebrow:{type:"string",label:"Eyebrow"},headline:{type:"string",label:"Headline"},intro:{type:"string",label:"Intro"},primaryCta:{...tE1,label:"Primary CTA"},secondaryCta:{...tE1,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:TTQ,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:yTQ,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:xTQ,fields:{title:{type:"string",label:"Title"},intro:{type:"string",label:"Intro"},points:{type:"array",label:"Points",minItems:1,items:{type:"string",label:"Point"}}}}}},STQ=[{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:LTQ}]}],AM1=yuA({packageName:"@brains/relay/site",contentNamespace:"relay-site",themeProfile:"studio",layout:MTQ,routes:STQ,templates:{"home-diagram":_TQ},dataSources:[new wcA]});var QM1={name:"@brains/relay",private:!0,version:"0.2.0-alpha.119",description:"Relay brain model \u2014 collaborative knowledge management",type:"module",files:["src","brain.eval.yaml","env.schema.template"],exports:{".":"./src/index.ts"},scripts:{"build:web-chat":"turbo run build --filter=@brains/web-chat","start:core":"bun run build:web-chat && cd test-apps/core && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start","start:default":"bun run build:web-chat && cd test-apps/default && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start","start:full":"bun run build:web-chat && cd test-apps/full && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start","start:docs":"bun run build:web-chat && cd test-apps/docs && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start",typecheck:"tsc --noEmit",test:"bun test",eval:"brain-eval",lint:"eslint . --ext .ts,.tsx","lint:fix":"eslint . --ext .ts,.tsx --fix"},dependencies:{"@brains/a2a":"workspace:*","@brains/agent-discovery":"workspace:*","@brains/app":"workspace:*","@brains/assessment":"workspace:*","@brains/auth-service":"workspace:*","@brains/cms":"workspace:*","@brains/content-formatters":"workspace:*","@brains/conversation-memory":"workspace:*","@brains/dashboard":"workspace:*","@brains/decks":"workspace:*","@brains/directory-sync":"workspace:*","@brains/discord":"workspace:*","@brains/doc":"workspace:*","@brains/email-resend":"workspace:*","@brains/image-plugin":"workspace:*","@brains/link":"workspace:*","@brains/mcp":"workspace:*","@brains/note":"workspace:*","@brains/notifications":"workspace:*","@brains/plugins":"workspace:*","@brains/prompt":"workspace:*","@brains/rizom-ecosystem":"workspace:*","@brains/site-builder-plugin":"workspace:*","@brains/site-composition":"workspace:*","@brains/site-content":"workspace:*","@brains/site-info":"workspace:*","@brains/site-rizom":"workspace:*","@brains/theme-rizom":"workspace:*","@brains/topics":"workspace:*","@brains/utils":"workspace:*","@brains/web-chat":"workspace:*","@brains/webserver":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/ai-evaluation":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*",typescript:"^5.3.3"}};var BM1=["prompt","directory-sync","note","link","topics","conversation-memory","agents","assessment","auth-service","notifications","email-resend","cms","dashboard","mcp","webserver","web-chat","discord","a2a"],wM1=[...BM1,"image","site-info","site-content","site-builder"],mTQ=[...wM1,"docs","decks"],uTQ=["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.'],$M1=hN({name:"relay",version:QM1.version,model:"gpt-5.4-mini",site:AM1,theme:ev,presets:{core:BM1,default:wM1,full:mTQ},evalDisable:["webserver","web-chat","mcp","discord"],agentInstructions:uTQ,capabilities:[["prompt",zC,void 0],["note",YC,{}],["link",WC,{}],["image",Xh,void 0],["topics",V$A,{includeEntityTypes:["base","link","summary","agent","swot","deck","doc","anchor-profile","brain-character"],extractableStatuses:["published","draft"]}],["conversation-memory",nuA,{memoryVisibility:"shared"}],["docs",AcA,void 0],["decks",Ui,void 0],["agents",Y9A,void 0],["assessment",z9A,void 0],["auth-service",Qu,void 0],["notifications",l0A,void 0],["email-resend",VwA,void 0],["cms",NC,{}],["dashboard",az,void 0],["directory-sync",WM,{seedContent:!0,seedContentPath:hTQ(import.meta.dir,"..","seed-content"),initialSync:!0}],["site-content",Lr,{definitions:eE1}],["rizom-ecosystem",qC,void 0],["site-info",aM,void 0],["site-builder",sM,{}]],interfaces:[["mcp",q3,()=>({})],["discord",Qz,()=>({captureUrls:!0})],["a2a",aj,()=>({})],["webserver",Bz,()=>({})],["web-chat",sj,()=>({})]],permissions:{rules:[{pattern:"cli:*",level:"anchor"},{pattern:"mcp:stdio",level:"anchor"},{pattern:"mcp:http",level:"anchor"},{pattern:"discord:*",level:"public"},{pattern:"web-chat:*",level:"anchor"}],entityActions:{base:{create:"trusted",update:"trusted",delete:"anchor"},link:{create:"trusted",update:"trusted",delete:"anchor"},doc:{create:"trusted",update:"trusted",delete:"anchor"},deck:{create:"trusted",update:"trusted",delete:"anchor"},decision:{create:"trusted",update:"trusted",delete:"anchor"},"action-item":{create:"trusted",update:"trusted",delete:"anchor"},image:{create:"trusted",update:"trusted",delete:"anchor"}}},deployment:{cdn:{enabled:!0,provider:"bunny"}}});import{readFileSync as qgQ}from"fs";import{join as LgQ}from"path";import{execSync as VgQ}from"child_process";import{parseArgs as pTQ}from"util";var iTQ={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"},outputDir:{type:"string"},help:{type:"boolean",short:"h"},version:{type:"boolean",short:"v"}};function WX(A,Q){let B=A[Q];return typeof B==="string"?B:void 0}function wq(A,Q){let B=A[Q];return typeof B==="boolean"?B:void 0}function fM1(A){let{values:Q,positionals:B}=pTQ({args:A,options:iTQ,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:WX(Q,"model"),domain:WX(Q,"domain"),"content-repo":WX(Q,"content-repo"),backend:WX(Q,"backend"),"push-to":WX(Q,"push-to"),"ai-api-key":WX(Q,"ai-api-key"),"no-interactive":wq(Q,"no-interactive"),preview:wq(Q,"preview"),deploy:wq(Q,"deploy"),regen:wq(Q,"regen"),all:wq(Q,"all"),only:WX(Q,"only"),"dry-run":wq(Q,"dry-run"),"startup-check":wq(Q,"startup-check"),"storage-dir":WX(Q,"storage-dir"),yes:wq(Q,"yes"),remote:WX(Q,"remote"),token:WX(Q,"token"),outputDir:WX(Q,"outputDir")}}}jr();import{mkdirSync as JgQ}from"fs";import{join as XgQ}from"path";import{execSync as WgQ}from"child_process";var U7A={name:"@rizom/brain",version:"0.2.0-alpha.119",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 scripts/build.ts && bun dist/brain.js start",typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts"},dependencies:{"@clack/prompts":"^0.11.0","@modelcontextprotocol/sdk":"^1.24.0","@tailwindcss/postcss":"^4.1.13","@tailwindcss/typography":"^0.5.19",postcss:"^8.5.6",preact:"^10.27.2","preact-render-to-string":"^6.3.1",tailwindcss:"^4.1.11"},optionalDependencies:{"@bitwarden/sdk-napi":"^1.0.0","@libsql/client":"^0.15.7","@tailwindcss/oxide":"^4.1.4","better-sqlite3":"^11.8.1",lightningcss:"^1.29.2","playwright-core":"^1.56.0","react-devtools-core":"^6.1.1",sharp:"^0.34.5"},devDependencies:{"@brains/app":"workspace:*","@brains/content-formatters":"workspace:*","@brains/deploy-support":"workspace:*","@brains/eslint-config":"workspace:*","@brains/mcp-service":"workspace:*","@brains/plugins":"workspace:*","@brains/ranger":"workspace:*","@brains/relay":"workspace:*","@brains/rover":"workspace:*","@brains/site-composition":"workspace:*","@brains/site-default":"workspace:*","@brains/site-personal":"workspace:*","@brains/site-professional":"workspace:*","@brains/theme-default":"workspace:*","@brains/theme-rizom":"workspace:*","@brains/typescript-config":"workspace:*","@brains/utils":"workspace:*","@types/bun":"latest",rollup:"^4.60.2","rollup-plugin-dts":"^6.4.1",typescript:"^5.3.3"},publishConfig:{access:"public"},repository:{type:"git",url:"https://github.com/rizom-ai/brains.git",directory:"packages/brain-cli"},license:"Apache-2.0",author:"Yeehaa <yeehaa@rizom.ai> (https://rizom.ai)",homepage:"https://github.com/rizom-ai/brains/tree/main/packages/brain-cli#readme",bugs:"https://github.com/rizom-ai/brains/issues",engines:{bun:">=1.3.3"},keywords:["brain","ai","cli","mcp","agent","personal-ai","knowledge-management"]};import{mkdirSync as qM1,writeFileSync as vr,chmodSync as Tr,existsSync as HcA,readFileSync as GcA}from"fs";import{basename as KcA,dirname as FcA,join as f6,resolve as CyQ}from"path";import{fileURLToPath as OyQ}from"url";var IM1=`ARG BUN_VERSION=1.3.10
|
|
11659
|
+
`,xE1=()=>w$("style",{children:UTQ},void 0,!1,void 0,this);import{jsxDEV as K2,Fragment as YTQ}from"preact/jsx-dev-runtime";var f7A=({title:A,description:Q,children:B,detail:w=!1,footer:$=!1,contentClassName:f=""})=>K2(YTQ,{children:[K2(KQ,{title:A,description:Q},void 0,!1,void 0,this),K2(xE1,{},void 0,!1,void 0,this),K2("div",{className:`docs-handbook${w?" docs-handbook--detail":""}`,children:[K2(TE1,{},void 0,!1,void 0,this),K2("div",{className:`${gH.wrap} ${f}`.trim(),children:[B,$&&K2(yE1,{},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),SE1=({docsCount:A,sectionsCount:Q,startDoc:B})=>K2("section",{className:"border-b border-[var(--docs-text)] py-14 md:py-24 md:pb-[72px]",children:[K2("p",{className:`${gH.label} mb-8`,children:"Handbook \xB7 Brains docs"},void 0,!1,void 0,this),K2("h1",{className:`${gH.display} m-0 max-w-[16ch] text-5xl leading-[1.05] tracking-[-0.02em] md:text-7xl`,children:["Build, run, and publish"," ",K2("em",{className:"text-[var(--docs-accent)]",children:"brains."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),K2("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),K2("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:[K2("div",{children:[K2("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),K2("div",{children:[K2("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),K2("div",{children:[K2("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),K2("div",{className:"mt-9 flex flex-wrap gap-3.5",children:[B&&K2("a",{className:gH.primaryButton,href:JT(B),children:"Start reading"},void 0,!1,void 0,this),K2("a",{className:gH.button,href:"#sections",children:"Browse sections"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),gE1=({groups:A})=>K2("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:[K2("p",{className:"m-0 mb-3.5 font-medium text-[var(--docs-text)]",children:"Sections"},void 0,!1,void 0,this),K2("ol",{className:"m-0 list-none p-0",children:A.map((Q,B)=>K2("li",{className:"grid grid-cols-[32px_1fr] gap-2 py-1.5",children:[K2("span",{className:"docs-font-display text-[var(--docs-text-light)] italic",children:[XT(B),"."]},void 0,!0,void 0,this),K2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:`#${$7A(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),hE1=({group:A,index:Q})=>K2("article",{className:"mb-16 last:mb-0",id:$7A(Q),children:[K2("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:[K2("span",{className:"text-right docs-font-display text-3xl leading-[1.1] text-[var(--docs-accent)] italic md:text-4xl",children:[XT(Q),"."]},void 0,!0,void 0,this),K2("h2",{className:`${gH.display} m-0 text-3xl leading-[1.1] tracking-[-0.015em] md:text-4xl`,children:A.section},void 0,!1,void 0,this),K2("span",{className:"docs-chapter__leader"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),K2("ol",{className:"m-0 list-none p-0",children:A.docs.map((B)=>K2("li",{className:"border-b border-[var(--docs-border-light)] last:border-b-0",children:K2("a",{className:"group block py-[18px] pl-12 md:pl-[68px]",href:JT(B),children:[K2("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&&K2("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),mE1=({title:A})=>K2("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:[K2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/",children:"Home"},void 0,!1,void 0,this),K2("span",{children:"/"},void 0,!1,void 0,this),K2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/docs",children:"Docs"},void 0,!1,void 0,this),K2("span",{children:"/"},void 0,!1,void 0,this),K2("span",{children:A},void 0,!1,void 0,this)]},void 0,!0,void 0,this),uE1=({groups:A,activeGroupIndex:Q,activeSlug:B})=>K2("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:K2("nav",{className:"docs-font-label text-xs tracking-[0.06em] text-[var(--docs-text-light)]",children:[K2("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),K2("ol",{className:"m-0 list-none p-0",children:A.map((w,$)=>{let f=$===Q;return K2("li",{className:f?"mb-[22px]":"mb-3.5",children:[K2("a",{className:`mb-2 flex items-baseline gap-2.5 docs-font-label text-[11px] uppercase leading-[1.4] tracking-[0.06em] transition-colors duration-150 hover:text-[var(--docs-text)] ${f?"text-[var(--docs-text)]":"text-[var(--docs-text-muted)]"}`,href:`/docs#${$7A($)}`,children:[K2("span",{className:"docs-font-display text-sm text-[var(--docs-accent)] italic",children:[XT($),"."]},void 0,!0,void 0,this)," ",w.section]},void 0,!0,void 0,this),f&&K2("ol",{className:"mt-0.5 list-none p-0",children:w.docs.map((I)=>{let D=I.metadata.slug===B;return K2("li",{children:K2("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:JT(I),"aria-current":D?"page":void 0,children:I.metadata.title},void 0,!1,void 0,this)},I.id,!1,void 0,this)})},void 0,!1,void 0,this)]},w.section,!0,void 0,this)})},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),cE1=({prevDoc:A,nextDoc:Q})=>{if(!A&&!Q)return null;return K2("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?K2("a",{className:"group border-t border-[var(--docs-border-light)] pt-[18px] transition-colors duration-150 hover:border-[var(--docs-accent)]",href:JT(A),children:[K2("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),K2("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):K2("span",{},void 0,!1,void 0,this),Q&&K2("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:JT(Q),children:[K2("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),K2("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 WT}from"preact/jsx-dev-runtime";var auA=({docs:A})=>{let Q=Pr(A),B=w7A(Q),$=Q.filter((f)=>f.metadata.slug!=="index")[0]??Q[0];return WT(f7A,{title:"Documentation",description:"Brains documentation",children:[WT(SE1,{docsCount:A.length,sectionsCount:B.length,startDoc:$},void 0,!1,void 0,this),WT("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:[WT(gE1,{groups:B},void 0,!1,void 0,this),WT("div",{children:B.map((f,I)=>WT(hE1,{group:f,index:I},f.section,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as bD}from"preact/jsx-dev-runtime";var tuA=({doc:A,docs:Q,prevDoc:B,nextDoc:w})=>{let $=w7A(Q.length>0?Q:[A]),f=Pr(Q.length>0?Q:[A]),I=f.findIndex((U)=>U.metadata.slug===A.metadata.slug),D=Math.max($.findIndex((U)=>U.docs.some((Y)=>Y.metadata.slug===A.metadata.slug)),0);return bD(f7A,{title:A.metadata.title,description:A.metadata.description??A.metadata.section,detail:!0,footer:!0,contentClassName:"pt-16",children:[bD(mE1,{title:A.metadata.title},void 0,!1,void 0,this),bD("div",{className:"grid items-start gap-10 py-8 pb-24 md:grid-cols-[240px_minmax(0,1fr)] md:gap-20",children:[bD(uE1,{groups:$,activeGroupIndex:D,activeSlug:A.metadata.slug},void 0,!1,void 0,this),bD("article",{className:"min-w-0",children:[bD("header",{className:"mb-10 border-b border-[var(--docs-border)] pb-8",children:[bD("p",{className:`${gH.label} m-0 mb-6 flex items-baseline gap-3`,children:[bD("span",{className:"docs-font-display text-lg leading-none tracking-normal normal-case text-[var(--docs-accent)] italic",children:[XT(D),"."]},void 0,!0,void 0,this)," ",A.metadata.section,I>=0?` \xB7 ${I+1}/${f.length}`:""]},void 0,!0,void 0,this),bD("h1",{className:`${gH.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&&bD("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),bD("div",{className:"docs-article__body",children:bD(V$,{markdown:A.body},void 0,!1,void 0,this)},void 0,!1,void 0,this),bD(cE1,{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 JTQ=H.object({docs:H.array(aF),pagination:Z7.nullable(),baseUrl:H.string().optional()}),XTQ=H.object({doc:aF,docs:H.array(aF),prevDoc:aF.nullable(),nextDoc:aF.nullable()});function lE1(){return{"doc-list":P1({name:"doc-list",description:"Documentation index template",schema:JTQ,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:auA}}),"doc-detail":P1({name:"doc-detail",description:"Documentation page template",schema:XTQ,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:tuA}})}}var pE1={name:"@brains/doc",private:!0,version:"0.2.0-alpha.120",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 euA extends jQ{entityType=Q7A.entityType;schema=YT;adapter=Q7A;constructor(){super("docs",pE1,{},void 0)}getTemplates(){return lE1()}getDataSources(){return[new B7A(this.logger.child("DocDataSource"))]}}function AcA(){return new euA}aA();WA();WA();o$();var iE1=H.object({label:H.string(),href:H.string()}),rE1=H.object({label:H.string(),title:H.string(),detail:H.string()}),HTQ=H.object({eyebrow:H.string(),name:H.string(),sub:H.string()}),GTQ=H.object({tone:H.enum(["capture","synthesis","share"]),title:H.string(),text:H.string()}),QcA=H.object({captures:H.number(),links:H.number(),topics:H.number(),summaries:H.number(),peers:H.number()}),HT=H.object({eyebrow:H.string(),headline:H.string(),intro:H.string(),primaryCta:iE1,secondaryCta:iE1,inputs:H.array(rE1).min(1),outputs:H.array(rE1).min(1),core:HTQ,legend:H.array(GTQ).min(1)}),BcA=HT.extend({counts:QcA}),dE1={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."}]},nE1=new lB(HT,{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 I7A(A){return nE1.parse(A)}function oE1(A){return nE1.format(A)}WA();var KTQ=H.object({query:H.object({routeId:H.string().default("home"),sectionId:H.string().default("diagram")}).default({routeId:"home",sectionId:"diagram"})}).passthrough(),FTQ={captures:"base",links:"link",topics:"topic",summaries:"summary",peers:"agent"};class wcA{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=KTQ.parse(A??{}),$=await this.fetchContent(B,w.query.routeId,w.query.sectionId),f=await this.fetchCounts(B);return Q.parse({...$,counts:f})}async fetchContent(A,Q,B){let w=await A.entityService.getEntity({entityType:"site-content",id:`${Q}:${B}`});if(!w?.content)return dE1;return HT.parse(I7A(w.content))}async fetchCounts(A){let Q=await Promise.all(Object.entries(FTQ).map(async([B,w])=>[B,await this.countOrZero(A,w)]));return QcA.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 Q1}from"preact/jsx-dev-runtime";var sE1=H.object({label:H.string(),href:H.string()}),ZTQ=H.object({eyebrow:H.string(),headline:H.string(),intro:H.string(),primaryCta:sE1,secondaryCta:sE1,signals:H.array(H.object({label:H.string(),value:H.string(),note:H.string()}))}),NTQ=H.object({eyebrow:H.string(),title:H.string(),intro:H.string(),steps:H.array(H.object({phase:H.string(),title:H.string(),text:H.string()}))}),zTQ=H.object({title:H.string(),intro:H.string(),cards:H.array(H.object({label:H.string(),title:H.string(),text:H.string()}))}),qTQ=H.object({title:H.string(),intro:H.string(),points:H.array(H.string())}),LTQ={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."]},VTQ="font-body text-[15px] text-theme-muted transition-colors hover:text-theme";function aE1({href:A,label:Q}){return Q1("a",{href:A,className:VTQ,children:Q},void 0,!1,void 0,this)}function ETQ({siteInfo:A,children:Q}){let B=[...A.navigation.primary,...A.navigation.secondary],w=A.cta??{buttonText:"Start here",buttonLink:"/about"};return Q1(tv,{children:[Q1("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:[Q1("a",{href:"/",className:"font-nav text-[20px]","aria-label":"Relay home",children:[Q1("span",{className:"font-bold text-theme",children:"relay"},void 0,!1,void 0,this),Q1("span",{className:"font-bold text-accent",children:"."},void 0,!1,void 0,this),Q1("span",{className:"text-theme-muted",children:"brain"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"flex items-center gap-5 md:gap-8",children:[Q1("div",{className:"hidden items-center gap-6 md:flex",children:B.map(($)=>Q1(aE1,{...$},`${$.href}-${$.label}`,!1,void 0,this))},void 0,!1,void 0,this),Q1("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),Q1("main",{children:Q},void 0,!1,void 0,this),Q1("footer",{className:"relative z-[1] border-t border-theme-light px-6 py-8 md:px-10 xl:px-20",children:Q1("div",{className:"flex flex-col gap-4 md:flex-row md:items-center md:justify-between",children:[Q1("div",{children:[Q1("p",{className:"font-label text-label-sm uppercase tracking-[0.22em] text-theme-light",children:A.copyright},void 0,!1,void 0,this),Q1("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),Q1("div",{className:"flex flex-wrap items-center gap-5",children:[B.map(($)=>Q1(aE1,{...$},`footer-${$.href}-${$.label}`,!1,void 0,this)),Q1("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 MTQ=({sections:A,siteInfo:Q})=>Q1(ETQ,{siteInfo:Q,children:A},void 0,!1,void 0,this);function CTQ({eyebrow:A,headline:Q,intro:B,primaryCta:w,secondaryCta:$,signals:f}){return Q1(Aq,{className:"min-h-[92vh] pt-[152px] pb-20 md:pt-[190px]",children:Q1("div",{className:"grid gap-10 lg:grid-cols-[minmax(0,1fr)_420px] lg:items-end",children:[Q1("div",{children:[Q1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:A},void 0,!1,void 0,this),Q1("h1",{className:"mt-7 max-w-[980px] font-display text-display-lg text-theme",children:Q},void 0,!1,void 0,this),Q1("p",{className:"mt-7 max-w-[720px] font-body text-body-lg text-theme-muted",children:B},void 0,!1,void 0,this),Q1("div",{className:"mt-10 flex flex-col gap-3 sm:flex-row",children:[Q1(EC,{href:w.href,size:"lg",variant:"primary-strong",children:w.label},void 0,!1,void 0,this),Q1(EC,{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),Q1("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:[Q1("p",{className:"font-label text-label-xs uppercase tracking-[0.24em] text-theme-light",children:"Live relay signals"},void 0,!1,void 0,this),Q1("div",{className:"mt-5 grid gap-3",children:f.map((I)=>Q1("div",{className:"rounded-[22px] border border-card-divider bg-bg-muted p-5",children:[Q1("div",{className:"flex items-center justify-between gap-4",children:[Q1("p",{className:"font-label text-label-xs uppercase tracking-[0.18em] text-secondary",children:I.label},void 0,!1,void 0,this),Q1("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),Q1("p",{className:"mt-4 font-display text-display-sm text-theme",children:I.value},void 0,!1,void 0,this),Q1("p",{className:"mt-2 font-body text-body-xs text-theme-muted",children:I.note},void 0,!1,void 0,this)]},I.label,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)}function OTQ({eyebrow:A,title:Q,intro:B,steps:w}){return Q1(Aq,{id:"operating-loop",className:"py-section",children:[Q1("div",{className:"max-w-[840px]",children:[Q1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-secondary",children:A},void 0,!1,void 0,this),Q1("h2",{className:"mt-5 font-display text-display-md text-theme",children:Q},void 0,!1,void 0,this),Q1("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),Q1("div",{className:"mt-12 grid gap-4 md:grid-cols-3",children:w.map(($)=>Q1("article",{className:"min-h-[300px] rounded-[28px] border border-card-panel-border bg-card-panel-bg p-6",children:[Q1("p",{className:"font-label text-label-sm text-accent",children:$.phase},void 0,!1,void 0,this),Q1("h3",{className:"mt-16 font-display text-display-sm text-theme",children:$.title},void 0,!1,void 0,this),Q1("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 RTQ({title:A,intro:Q,cards:B}){return Q1(Aq,{className:"py-section",children:Q1("div",{className:"rounded-[36px] border border-theme-light bg-bg-muted p-6 md:p-10",children:Q1("div",{className:"grid gap-8 lg:grid-cols-[360px_1fr]",children:[Q1("div",{children:[Q1("h2",{className:"font-display text-display-md text-theme",children:A},void 0,!1,void 0,this),Q1("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),Q1("div",{className:"grid gap-4",children:B.map((w)=>Q1("article",{className:"rounded-[24px] border border-card-divider bg-bg-subtle/70 p-5",children:[Q1("p",{className:"font-label text-label-xs uppercase tracking-[0.22em] text-accent",children:w.label},void 0,!1,void 0,this),Q1("h3",{className:"mt-3 font-nav text-heading-lg text-theme",children:w.title},void 0,!1,void 0,this),Q1("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 bTQ({title:A,intro:Q,points:B}){return Q1(Aq,{className:"min-h-[78vh] pt-[150px] pb-section md:pt-[190px]",children:[Q1("div",{className:"max-w-[920px]",children:[Q1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:"Relay model"},void 0,!1,void 0,this),Q1("h1",{className:"mt-6 font-display text-display-lg text-theme",children:A},void 0,!1,void 0,this),Q1("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),Q1("div",{className:"mt-12 grid gap-4 md:grid-cols-3",children:B.map((w)=>Q1("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 PTQ=(A)=>{switch(A){case"capture":return"bg-accent";case"synthesis":return"bg-secondary";case"share":return"bg-accent-bright"}},kTQ=(A)=>new Intl.NumberFormat("en",{notation:A>999?"compact":"standard"}).format(A),kr=(A,Q,B=`${Q}s`)=>`${kTQ(A)} ${A===1?Q:B}`;function jTQ({eyebrow:A,headline:Q,intro:B,primaryCta:w,secondaryCta:$,inputs:f,outputs:I,core:D,legend:U,counts:Y}){let J=[{key:"captures",className:"top-[-10px] left-1/2 -translate-x-1/2",label:kr(Y.captures,"capture")},{key:"topics",className:"top-1/2 right-[-28px] -translate-y-1/2",label:kr(Y.topics,"topic")},{key:"peers",className:"bottom-[-10px] left-1/2 -translate-x-1/2",label:kr(Y.peers,"peer brain")},{key:"summaries",className:"top-1/2 left-[-28px] -translate-y-1/2",label:kr(Y.summaries,"summary","summaries")}];return Q1(Aq,{className:"pt-[150px] pb-section md:pt-[190px]",id:"diagram",children:[Q1("div",{className:"mx-auto max-w-[1040px] text-center",children:[Q1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:A},void 0,!1,void 0,this),Q1("h1",{className:"mx-auto mt-7 max-w-[22ch] font-display text-display-lg text-theme",children:Q},void 0,!1,void 0,this),Q1("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),Q1("div",{className:"mt-10 flex flex-col justify-center gap-3 sm:flex-row",children:[Q1(EC,{href:w.href,size:"lg",variant:"primary-strong",children:w.label},void 0,!1,void 0,this),Q1(EC,{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),Q1("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:[Q1("div",{className:"grid items-center gap-8 lg:grid-cols-[1fr_1.4fr_1fr]",children:[Q1("div",{className:"flex flex-col gap-3.5",children:f.map((X)=>Q1("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:[Q1("p",{className:"font-label text-[10px] uppercase tracking-[0.22em] text-secondary",children:X.label},void 0,!1,void 0,this),Q1("h2",{className:"mt-1.5 font-display text-[18px] font-medium text-theme",children:X.title},void 0,!1,void 0,this),Q1("p",{className:"mt-1 font-body text-[13px] leading-[1.5] text-theme-muted",children:X.detail},void 0,!1,void 0,this)]},`${X.label}-${X.title}`,!0,void 0,this))},void 0,!1,void 0,this),Q1("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:[Q1("div",{className:"absolute inset-0 rounded-full border border-dashed border-accent/30"},void 0,!1,void 0,this),Q1("div",{className:"absolute inset-6 animate-spin rounded-full border border-dashed border-secondary/40 [animation-duration:28s]"},void 0,!1,void 0,this),J.map((X)=>Q1("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 ${X.className}`,children:X.label},X.key,!1,void 0,this)),Q1("div",{className:"relative z-[1] px-6 text-center",children:[Q1("p",{className:"font-label text-[10px] uppercase tracking-[0.28em] text-accent",children:D.eyebrow},void 0,!1,void 0,this),Q1("p",{className:"mt-2 font-display text-[36px] leading-none text-theme",children:D.name},void 0,!1,void 0,this),Q1("p",{className:"mt-2 font-body text-[13px] text-theme-muted",children:D.sub},void 0,!1,void 0,this),Q1("p",{className:"mt-4 font-label text-[10px] uppercase tracking-[0.18em] text-theme-light",children:[kr(Y.links,"link")," indexed"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"flex flex-col gap-3.5",children:I.map((X)=>Q1("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:[Q1("p",{className:"font-label text-[10px] uppercase tracking-[0.22em] text-secondary",children:X.label},void 0,!1,void 0,this),Q1("h2",{className:"mt-1.5 font-display text-[18px] font-medium text-theme",children:X.title},void 0,!1,void 0,this),Q1("p",{className:"mt-1 font-body text-[13px] leading-[1.5] text-theme-muted",children:X.detail},void 0,!1,void 0,this)]},`${X.label}-${X.title}`,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"mt-14 grid gap-4 border-t border-theme-light pt-8 md:grid-cols-3",children:U.map((X)=>Q1("div",{className:"text-left",children:[Q1("h2",{className:"font-display text-[16px] font-medium text-theme",children:[Q1("span",{className:`mr-2.5 inline-block h-3 w-3 rounded-[3px] align-middle ${PTQ(X.tone)}`},void 0,!1,void 0,this),X.title]},void 0,!0,void 0,this),Q1("p",{className:"mt-1.5 font-body text-[13px] leading-[1.6] text-theme-muted",children:X.text},void 0,!1,void 0,this)]},X.title,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}var _TQ=P1({name:"home-diagram",description:"Relay homepage system diagram with live entity counts",schema:BcA,formatter:{parse:(A)=>BcA.parse({...I7A(A),counts:{captures:0,links:0,topics:0,summaries:0,peers:0}}),format:(A)=>oE1(HT.parse(A))},dataSourceId:"relay-site:home-counts",requiredPermission:"public",layout:{component:jTQ}}),vTQ=(A)=>CTQ(ZTQ.parse(A)),TTQ=(A)=>OTQ(NTQ.parse(A)),yTQ=(A)=>RTQ(zTQ.parse(A)),xTQ=(A)=>bTQ(qTQ.parse(A)),tE1={type:"object",label:"CTA",fields:{label:{type:"string",label:"Label"},href:{type:"string",label:"Href"}}},eE1={namespace:"relay-site",sections:{"home-hero":{title:"Home hero",description:"Relay homepage hero section",layout:vTQ,fields:{eyebrow:{type:"string",label:"Eyebrow"},headline:{type:"string",label:"Headline"},intro:{type:"string",label:"Intro"},primaryCta:{...tE1,label:"Primary CTA"},secondaryCta:{...tE1,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:TTQ,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:yTQ,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:xTQ,fields:{title:{type:"string",label:"Title"},intro:{type:"string",label:"Intro"},points:{type:"array",label:"Points",minItems:1,items:{type:"string",label:"Point"}}}}}},STQ=[{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:LTQ}]}],AM1=yuA({packageName:"@brains/relay/site",contentNamespace:"relay-site",themeProfile:"studio",layout:MTQ,routes:STQ,templates:{"home-diagram":_TQ},dataSources:[new wcA]});var QM1={name:"@brains/relay",private:!0,version:"0.2.0-alpha.120",description:"Relay brain model \u2014 collaborative knowledge management",type:"module",files:["src","brain.eval.yaml","env.schema.template"],exports:{".":"./src/index.ts"},scripts:{"build:web-chat":"turbo run build --filter=@brains/web-chat","start:core":"bun run build:web-chat && cd test-apps/core && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start","start:default":"bun run build:web-chat && cd test-apps/default && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start","start:full":"bun run build:web-chat && cd test-apps/full && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start","start:docs":"bun run build:web-chat && cd test-apps/docs && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start",typecheck:"tsc --noEmit",test:"bun test",eval:"brain-eval",lint:"eslint . --ext .ts,.tsx","lint:fix":"eslint . --ext .ts,.tsx --fix"},dependencies:{"@brains/a2a":"workspace:*","@brains/agent-discovery":"workspace:*","@brains/app":"workspace:*","@brains/assessment":"workspace:*","@brains/auth-service":"workspace:*","@brains/cms":"workspace:*","@brains/content-formatters":"workspace:*","@brains/conversation-memory":"workspace:*","@brains/dashboard":"workspace:*","@brains/decks":"workspace:*","@brains/directory-sync":"workspace:*","@brains/discord":"workspace:*","@brains/doc":"workspace:*","@brains/email-resend":"workspace:*","@brains/image-plugin":"workspace:*","@brains/link":"workspace:*","@brains/mcp":"workspace:*","@brains/note":"workspace:*","@brains/notifications":"workspace:*","@brains/plugins":"workspace:*","@brains/prompt":"workspace:*","@brains/rizom-ecosystem":"workspace:*","@brains/site-builder-plugin":"workspace:*","@brains/site-composition":"workspace:*","@brains/site-content":"workspace:*","@brains/site-info":"workspace:*","@brains/site-rizom":"workspace:*","@brains/theme-rizom":"workspace:*","@brains/topics":"workspace:*","@brains/utils":"workspace:*","@brains/web-chat":"workspace:*","@brains/webserver":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/ai-evaluation":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*",typescript:"^5.3.3"}};var BM1=["prompt","directory-sync","note","link","topics","conversation-memory","agents","assessment","auth-service","notifications","email-resend","cms","dashboard","mcp","webserver","web-chat","discord","a2a"],wM1=[...BM1,"image","site-info","site-content","site-builder"],mTQ=[...wM1,"docs","decks"],uTQ=["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.'],$M1=hN({name:"relay",version:QM1.version,model:"gpt-5.4-mini",site:AM1,theme:ev,presets:{core:BM1,default:wM1,full:mTQ},evalDisable:["webserver","web-chat","mcp","discord"],agentInstructions:uTQ,capabilities:[["prompt",zC,void 0],["note",YC,{}],["link",WC,{}],["image",Xh,void 0],["topics",V$A,{includeEntityTypes:["base","link","summary","agent","swot","deck","doc","anchor-profile","brain-character"],extractableStatuses:["published","draft"]}],["conversation-memory",nuA,{memoryVisibility:"shared"}],["docs",AcA,void 0],["decks",Ui,void 0],["agents",Y9A,void 0],["assessment",z9A,void 0],["auth-service",Qu,void 0],["notifications",l0A,void 0],["email-resend",VwA,void 0],["cms",NC,{}],["dashboard",az,void 0],["directory-sync",WM,{seedContent:!0,seedContentPath:hTQ(import.meta.dir,"..","seed-content"),initialSync:!0}],["site-content",Lr,{definitions:eE1}],["rizom-ecosystem",qC,void 0],["site-info",aM,void 0],["site-builder",sM,{}]],interfaces:[["mcp",q3,()=>({})],["discord",Qz,()=>({captureUrls:!0})],["a2a",aj,()=>({})],["webserver",Bz,()=>({})],["web-chat",sj,()=>({})]],permissions:{rules:[{pattern:"cli:*",level:"anchor"},{pattern:"mcp:stdio",level:"anchor"},{pattern:"mcp:http",level:"anchor"},{pattern:"discord:*",level:"public"},{pattern:"web-chat:*",level:"anchor"}],entityActions:{base:{create:"trusted",update:"trusted",delete:"anchor"},link:{create:"trusted",update:"trusted",delete:"anchor"},doc:{create:"trusted",update:"trusted",delete:"anchor"},deck:{create:"trusted",update:"trusted",delete:"anchor"},decision:{create:"trusted",update:"trusted",delete:"anchor"},"action-item":{create:"trusted",update:"trusted",delete:"anchor"},image:{create:"trusted",update:"trusted",delete:"anchor"}}},deployment:{cdn:{enabled:!0,provider:"bunny"}}});import{readFileSync as qgQ}from"fs";import{join as LgQ}from"path";import{execSync as VgQ}from"child_process";import{parseArgs as pTQ}from"util";var iTQ={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"},outputDir:{type:"string"},help:{type:"boolean",short:"h"},version:{type:"boolean",short:"v"}};function WX(A,Q){let B=A[Q];return typeof B==="string"?B:void 0}function wq(A,Q){let B=A[Q];return typeof B==="boolean"?B:void 0}function fM1(A){let{values:Q,positionals:B}=pTQ({args:A,options:iTQ,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:WX(Q,"model"),domain:WX(Q,"domain"),"content-repo":WX(Q,"content-repo"),backend:WX(Q,"backend"),"push-to":WX(Q,"push-to"),"ai-api-key":WX(Q,"ai-api-key"),"no-interactive":wq(Q,"no-interactive"),preview:wq(Q,"preview"),deploy:wq(Q,"deploy"),regen:wq(Q,"regen"),all:wq(Q,"all"),only:WX(Q,"only"),"dry-run":wq(Q,"dry-run"),"startup-check":wq(Q,"startup-check"),"storage-dir":WX(Q,"storage-dir"),yes:wq(Q,"yes"),remote:WX(Q,"remote"),token:WX(Q,"token"),outputDir:WX(Q,"outputDir")}}}jr();import{mkdirSync as JgQ}from"fs";import{join as XgQ}from"path";import{execSync as WgQ}from"child_process";var U7A={name:"@rizom/brain",version:"0.2.0-alpha.120",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 scripts/build.ts && bun dist/brain.js start",typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts"},dependencies:{"@clack/prompts":"^0.11.0","@modelcontextprotocol/sdk":"^1.24.0","@tailwindcss/postcss":"^4.1.13","@tailwindcss/typography":"^0.5.19",postcss:"^8.5.6",preact:"^10.27.2","preact-render-to-string":"^6.3.1",tailwindcss:"^4.1.11"},optionalDependencies:{"@bitwarden/sdk-napi":"^1.0.0","@libsql/client":"^0.15.7","@tailwindcss/oxide":"^4.1.4","better-sqlite3":"^11.8.1",lightningcss:"^1.29.2","playwright-core":"^1.56.0","react-devtools-core":"^6.1.1",sharp:"^0.34.5"},devDependencies:{"@brains/app":"workspace:*","@brains/content-formatters":"workspace:*","@brains/deploy-support":"workspace:*","@brains/eslint-config":"workspace:*","@brains/mcp-service":"workspace:*","@brains/plugins":"workspace:*","@brains/ranger":"workspace:*","@brains/relay":"workspace:*","@brains/rover":"workspace:*","@brains/site-composition":"workspace:*","@brains/site-default":"workspace:*","@brains/site-personal":"workspace:*","@brains/site-professional":"workspace:*","@brains/theme-default":"workspace:*","@brains/theme-rizom":"workspace:*","@brains/typescript-config":"workspace:*","@brains/utils":"workspace:*","@types/bun":"latest",rollup:"^4.60.2","rollup-plugin-dts":"^6.4.1",typescript:"^5.3.3"},publishConfig:{access:"public"},repository:{type:"git",url:"https://github.com/rizom-ai/brains.git",directory:"packages/brain-cli"},license:"Apache-2.0",author:"Yeehaa <yeehaa@rizom.ai> (https://rizom.ai)",homepage:"https://github.com/rizom-ai/brains/tree/main/packages/brain-cli#readme",bugs:"https://github.com/rizom-ai/brains/issues",engines:{bun:">=1.3.3"},keywords:["brain","ai","cli","mcp","agent","personal-ai","knowledge-management"]};import{mkdirSync as qM1,writeFileSync as vr,chmodSync as Tr,existsSync as HcA,readFileSync as GcA}from"fs";import{basename as KcA,dirname as FcA,join as f6,resolve as CyQ}from"path";import{fileURLToPath as OyQ}from"url";var IM1=`ARG BUN_VERSION=1.3.10
|
|
11660
11660
|
FROM oven/bun:\${BUN_VERSION}-slim AS runtime
|
|
11661
11661
|
|
|
11662
11662
|
WORKDIR /app
|