@rizom/brain 0.2.0-alpha.158 → 0.2.0-alpha.159

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 CHANGED
@@ -430,7 +430,7 @@ ${X}`:"")}function rP0(A,Q,w,$){return async(B,X)=>{if($){let Y={toolName:A,args
430
430
  hash text NOT NULL,
431
431
  created_at numeric
432
432
  )
433
- `;await A.session.run(B);let Y=(await A.values(QA`SELECT id, hash, created_at FROM ${QA.identifier($)} ORDER BY created_at DESC LIMIT 1`))[0]??void 0,Z=[];for(let H of w)if(!Y||Number(Y[2])<H.folderMillis){for(let W of H.sql)Z.push(A.run(QA.raw(W)));Z.push(A.run(QA`INSERT INTO ${QA.identifier($)} ("hash", "created_at") VALUES(${H.hash}, ${H.folderMillis})`))}await A.session.migrate(Z)}var Yl=r(()=>{KOA();k9()});async function UOA(A,Q){let w=Q?.child("entity-migrate")??gQ.getInstance().child("entity-migrate"),{db:$,client:B,url:X}=$20(A);w.debug("Running entity database migrations...");try{await B20(B,X);let Z=import.meta.url.includes("/dist/")?new URL("./migrations/entity-service",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await nI($,{migrationsFolder:Z}),await X20(B),w.debug("Entity database migrations completed successfully")}catch(Y){throw w.error("Entity database migration failed:",Y),Y}finally{B.close()}}var GOA=r(()=>{Yl();NL0();B7()});async function DOA(A,Q){let w=Q?.child("job-queue-migrate")??gQ.getInstance().child("job-queue-migrate"),{db:$,client:B,url:X}=a10(A);w.debug("Running job queue migrations...");try{await t10(B,X);let Z=import.meta.url.includes("/dist/")?new URL("./migrations/job-queue",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await nI($,{migrationsFolder:Z}),w.debug("Job queue migrations completed successfully")}catch(Y){throw w.error("Job queue migration failed:",Y),Y}finally{B.close()}}var qOA=r(()=>{Yl();HL0();B7()});async function zOA(A,Q){let w=Q?.child("conversation-migrate")??gQ.getInstance().child("conversation-migrate"),{db:$,client:B,url:X}=e10(A);w.debug("Running conversation database migrations...");try{if(X.startsWith("file:"))await B.execute("PRAGMA journal_mode = WAL");let Z=import.meta.url.includes("/dist/")?new URL("./migrations/conversation-service",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await nI($,{migrationsFolder:Z}),w.debug("Conversation database migrations completed successfully")}catch(Y){throw w.error("Conversation database migration failed:",Y),Y}finally{B.close()}}var VOA=r(()=>{Yl();qL0();B7()});async function JOA(A,Q){let w=Q?.child("runtime-state-migrate")??gQ.getInstance().child("runtime-state-migrate"),{db:$,client:B,url:X}=Nw0(A);w.debug("Running runtime state migrations...");try{await jw0(B,X);let Z=import.meta.url.includes("/dist/")?new URL("./migrations/runtime-state",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await nI($,{migrationsFolder:Z}),w.debug("Runtime state migrations completed successfully")}catch(Y){throw w.error("Runtime state migration failed:",Y),Y}finally{B.close()}}var IOA=r(()=>{Yl();B7();ZM0()});import{mkdir as jM0}from"fs/promises";function Cw0(A=process.env){return{dataDir:A.XDG_DATA_HOME??"./data",cacheDir:A.XDG_CACHE_HOME??"./cache",distDir:"./dist"}}function gw0(A=process.env){return gI(Cw0(A))}async function yw0(A=process.env){let Q=Cw0(A);try{await jM0(Q.dataDir,{recursive:!0}),await jM0(Q.cacheDir,{recursive:!0}),await jM0(Q.distDir,{recursive:!0})}catch(w){let $=w instanceof Error&&w.message.includes("EACCES")?`Cannot create data directories \u2014 permission denied. Run from a writable directory or check permissions on ${Q.dataDir}`:`Cannot create data directories: ${w instanceof Error?w.message:String(w)}`;throw Error($,{cause:w})}return gI(Q)}var Ew0=r(()=>{vw0()});class Zl{logger;migrations;constructor(A,Q){this.logger=A,this.migrations=Q??{getStandardConfigWithDirectories:()=>yw0(),migrateEntities:UOA,migrateJobQueue:DOA,migrateConversations:zOA,migrateRuntimeState:JOA}}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;if(A?.runtimeStateDatabase)Q.runtimeStateDatabase.url=A.runtimeStateDatabase;await this.migrateEntityDatabase(Q),await this.migrateJobQueueDatabase(Q),await this.migrateConversationDatabase(Q),await this.migrateRuntimeStateDatabase(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)}async migrateRuntimeStateDatabase(A){this.logger.debug("Running runtime state database migrations..."),await this.migrations.migrateRuntimeState({url:A.runtimeStateDatabase.url,...A.runtimeStateDatabase.authToken&&{authToken:A.runtimeStateDatabase.authToken}},this.logger)}}var PM0=r(()=>{GOA();qOA();VOA();IOA();Ew0()});function Js2(){return process.env[Vs2]}function FOA(){return Js2()!=="production"}var Vs2="NODE_ENV";var Tw0;var MM0=r(()=>{C0();Tw0=f.object({theme:f.object({primaryColor:f.string().describe("Primary color for the CLI theme").default("#0066cc"),accentColor:f.string().describe("Accent color for the CLI theme").default("#ff6600")}).describe("Theme configuration for the CLI interface").default({primaryColor:"#0066cc",accentColor:"#ff6600"})})});var LOA;var bOA=r(()=>{LOA={name:"@brains/chat-repl",version:"0.2.0-alpha.158",dependencies:{"@brains/plugins":"workspace:*",chalk:"^5.4.1",ink:"^7.0.6","ink-spinner":"^5.0.0","ink-text-input":"^6.0.0",marked:"^18.0.5",react:"^19.2.7"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14","@types/react":"^19.2.17",typescript:"^7.0.2"},files:["src"],main:"./src/index.ts",module:"./src/index.ts",private:!0,scripts:{dev:"tsc --watch",lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module",types:"./src/index.ts"}});var Uw=h((Fs2,Sw0)=>{(function(){function A(t,G0){Object.defineProperty($.prototype,t,{get:function(){console.warn("%s(...) is deprecated in plain JavaScript React classes. %s",G0[0],G0[1])}})}function Q(t){if(t===null||typeof t!=="object")return null;return t=j0&&t[j0]||t["@@iterator"],typeof t==="function"?t:null}function w(t,G0){t=(t=t.constructor)&&(t.displayName||t.name)||"ReactClass";var J0=t+"."+G0;P0[J0]||(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.",G0,t),P0[J0]=!0)}function $(t,G0,J0){this.props=t,this.context=G0,this.refs=n0,this.updater=J0||E0}function B(){}function X(t,G0,J0){this.props=t,this.context=G0,this.refs=n0,this.updater=J0||E0}function Y(){}function Z(t){return""+t}function H(t){try{Z(t);var G0=!1}catch(I0){G0=!0}if(G0){G0=console;var J0=G0.error,N0=typeof Symbol==="function"&&Symbol.toStringTag&&t[Symbol.toStringTag]||t.constructor.name||"Object";return J0.call(G0,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",N0),Z(t)}}function W(t){if(t==null)return null;if(typeof t==="function")return t.$$typeof===HA?null:t.displayName||t.name||null;if(typeof t==="string")return t;switch(t){case D0:return"Fragment";case f0:return"Profiler";case T:return"StrictMode";case i0:return"Suspense";case k0:return"SuspenseList";case S0:return"Activity"}if(typeof t==="object")switch(typeof t.tag==="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),t.$$typeof){case a:return"Portal";case i:return t.displayName||"Context";case b0:return(t._context.displayName||"Context")+".Consumer";case u0:var G0=t.render;return t=t.displayName,t||(t=G0.displayName||G0.name||"",t=t!==""?"ForwardRef("+t+")":"ForwardRef"),t;case _0:return G0=t.displayName||null,G0!==null?G0:W(t.type)||"Memo";case v0:G0=t._payload,t=t._init;try{return W(t(G0))}catch(J0){}}return null}function K(t){if(t===D0)return"<>";if(typeof t==="object"&&t!==null&&t.$$typeof===v0)return"<...>";try{var G0=W(t);return G0?"<"+G0+">":"<...>"}catch(J0){return"<...>"}}function U(){var t=WA.A;return t===null?null:t.getOwner()}function G(){return Error("react-stack-top-frame")}function q(t){if(o0.call(t,"key")){var G0=Object.getOwnPropertyDescriptor(t,"key").get;if(G0&&G0.isReactWarning)return!1}return t.key!==void 0}function V(t,G0){function J0(){GA||(GA=!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)",G0))}J0.isReactWarning=!0,Object.defineProperty(t,"key",{get:J0,configurable:!0})}function I(){var t=W(this.type);return RA[t]||(RA[t]=!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.")),t=this.props.ref,t!==void 0?t:null}function J(t,G0,J0,N0,I0,r0){var l0=J0.ref;return t={$$typeof:s,type:t,key:G0,props:J0,_owner:N0},(l0!==void 0?l0:null)!==null?Object.defineProperty(t,"ref",{enumerable:!1,get:I}):Object.defineProperty(t,"ref",{enumerable:!1,value:null}),t._store={},Object.defineProperty(t._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(t,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(t,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:I0}),Object.defineProperty(t,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:r0}),Object.freeze&&(Object.freeze(t.props),Object.freeze(t)),t}function k(t,G0){return G0=J(t.type,G0,t.props,t._owner,t._debugStack,t._debugTask),t._store&&(G0._store.validated=t._store.validated),G0}function j(t){_(t)?t._store&&(t._store.validated=1):typeof t==="object"&&t!==null&&t.$$typeof===v0&&(t._payload.status==="fulfilled"?_(t._payload.value)&&t._payload.value._store&&(t._payload.value._store.validated=1):t._store&&(t._store.validated=1))}function _(t){return typeof t==="object"&&t!==null&&t.$$typeof===s}function x(t){var G0={"=":"=0",":":"=2"};return"$"+t.replace(/[=:]/g,function(J0){return G0[J0]})}function v(t,G0){return typeof t==="object"&&t!==null&&t.key!=null?(H(t.key),x(""+t.key)):G0.toString(36)}function O(t){switch(t.status){case"fulfilled":return t.value;case"rejected":throw t.reason;default:switch(typeof t.status==="string"?t.then(Y,Y):(t.status="pending",t.then(function(G0){t.status==="pending"&&(t.status="fulfilled",t.value=G0)},function(G0){t.status==="pending"&&(t.status="rejected",t.reason=G0)})),t.status){case"fulfilled":return t.value;case"rejected":throw t.reason}}throw t}function M(t,G0,J0,N0,I0){var r0=typeof t;if(r0==="undefined"||r0==="boolean")t=null;var l0=!1;if(t===null)l0=!0;else switch(r0){case"bigint":case"string":case"number":l0=!0;break;case"object":switch(t.$$typeof){case s:case a:l0=!0;break;case v0:return l0=t._init,M(l0(t._payload),G0,J0,N0,I0)}}if(l0){l0=t,I0=I0(l0);var BA=N0===""?"."+v(l0,0):N0;return JA(I0)?(J0="",BA!=null&&(J0=BA.replace(x0,"$&/")+"/"),M(I0,G0,J0,"",function(hA){return hA})):I0!=null&&(_(I0)&&(I0.key!=null&&(l0&&l0.key===I0.key||H(I0.key)),J0=k(I0,J0+(I0.key==null||l0&&l0.key===I0.key?"":(""+I0.key).replace(x0,"$&/")+"/")+BA),N0!==""&&l0!=null&&_(l0)&&l0.key==null&&l0._store&&!l0._store.validated&&(J0._store.validated=2),I0=J0),G0.push(I0)),1}if(l0=0,BA=N0===""?".":N0+":",JA(t))for(var YA=0;YA<t.length;YA++)N0=t[YA],r0=BA+v(N0,YA),l0+=M(N0,G0,J0,r0,I0);else if(YA=Q(t),typeof YA==="function")for(YA===t.entries&&(g0||console.warn("Using Maps as children is not supported. Use an array of keyed ReactElements instead."),g0=!0),t=YA.call(t),YA=0;!(N0=t.next()).done;)N0=N0.value,r0=BA+v(N0,YA++),l0+=M(N0,G0,J0,r0,I0);else if(r0==="object"){if(typeof t.then==="function")return M(O(t),G0,J0,N0,I0);throw G0=String(t),Error("Objects are not valid as a React child (found: "+(G0==="[object Object]"?"object with keys {"+Object.keys(t).join(", ")+"}":G0)+"). If you meant to render a collection of children, use an array instead.")}return l0}function S(t,G0,J0){if(t==null)return t;var N0=[],I0=0;return M(t,N0,"","",function(r0){return G0.call(J0,r0,I0++)}),N0}function u(t){if(t._status===-1){var G0=t._ioInfo;G0!=null&&(G0.start=G0.end=performance.now()),G0=t._result;var J0=G0();if(J0.then(function(I0){if(t._status===0||t._status===-1){t._status=1,t._result=I0;var r0=t._ioInfo;r0!=null&&(r0.end=performance.now()),J0.status===void 0&&(J0.status="fulfilled",J0.value=I0)}},function(I0){if(t._status===0||t._status===-1){t._status=2,t._result=I0;var r0=t._ioInfo;r0!=null&&(r0.end=performance.now()),J0.status===void 0&&(J0.status="rejected",J0.reason=I0)}}),G0=t._ioInfo,G0!=null){G0.value=J0;var N0=J0.displayName;typeof N0==="string"&&(G0.name=N0)}t._status===-1&&(t._status=0,t._result=J0)}if(t._status===1)return G0=t._result,G0===void 0&&console.error(`lazy: Expected the result of a dynamic import() call. Instead received: %s
433
+ `;await A.session.run(B);let Y=(await A.values(QA`SELECT id, hash, created_at FROM ${QA.identifier($)} ORDER BY created_at DESC LIMIT 1`))[0]??void 0,Z=[];for(let H of w)if(!Y||Number(Y[2])<H.folderMillis){for(let W of H.sql)Z.push(A.run(QA.raw(W)));Z.push(A.run(QA`INSERT INTO ${QA.identifier($)} ("hash", "created_at") VALUES(${H.hash}, ${H.folderMillis})`))}await A.session.migrate(Z)}var Yl=r(()=>{KOA();k9()});async function UOA(A,Q){let w=Q?.child("entity-migrate")??gQ.getInstance().child("entity-migrate"),{db:$,client:B,url:X}=$20(A);w.debug("Running entity database migrations...");try{await B20(B,X);let Z=import.meta.url.includes("/dist/")?new URL("./migrations/entity-service",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await nI($,{migrationsFolder:Z}),await X20(B),w.debug("Entity database migrations completed successfully")}catch(Y){throw w.error("Entity database migration failed:",Y),Y}finally{B.close()}}var GOA=r(()=>{Yl();NL0();B7()});async function DOA(A,Q){let w=Q?.child("job-queue-migrate")??gQ.getInstance().child("job-queue-migrate"),{db:$,client:B,url:X}=a10(A);w.debug("Running job queue migrations...");try{await t10(B,X);let Z=import.meta.url.includes("/dist/")?new URL("./migrations/job-queue",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await nI($,{migrationsFolder:Z}),w.debug("Job queue migrations completed successfully")}catch(Y){throw w.error("Job queue migration failed:",Y),Y}finally{B.close()}}var qOA=r(()=>{Yl();HL0();B7()});async function zOA(A,Q){let w=Q?.child("conversation-migrate")??gQ.getInstance().child("conversation-migrate"),{db:$,client:B,url:X}=e10(A);w.debug("Running conversation database migrations...");try{if(X.startsWith("file:"))await B.execute("PRAGMA journal_mode = WAL");let Z=import.meta.url.includes("/dist/")?new URL("./migrations/conversation-service",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await nI($,{migrationsFolder:Z}),w.debug("Conversation database migrations completed successfully")}catch(Y){throw w.error("Conversation database migration failed:",Y),Y}finally{B.close()}}var VOA=r(()=>{Yl();qL0();B7()});async function JOA(A,Q){let w=Q?.child("runtime-state-migrate")??gQ.getInstance().child("runtime-state-migrate"),{db:$,client:B,url:X}=Nw0(A);w.debug("Running runtime state migrations...");try{await jw0(B,X);let Z=import.meta.url.includes("/dist/")?new URL("./migrations/runtime-state",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await nI($,{migrationsFolder:Z}),w.debug("Runtime state migrations completed successfully")}catch(Y){throw w.error("Runtime state migration failed:",Y),Y}finally{B.close()}}var IOA=r(()=>{Yl();B7();ZM0()});import{mkdir as jM0}from"fs/promises";function Cw0(A=process.env){return{dataDir:A.XDG_DATA_HOME??"./data",cacheDir:A.XDG_CACHE_HOME??"./cache",distDir:"./dist"}}function gw0(A=process.env){return gI(Cw0(A))}async function yw0(A=process.env){let Q=Cw0(A);try{await jM0(Q.dataDir,{recursive:!0}),await jM0(Q.cacheDir,{recursive:!0}),await jM0(Q.distDir,{recursive:!0})}catch(w){let $=w instanceof Error&&w.message.includes("EACCES")?`Cannot create data directories \u2014 permission denied. Run from a writable directory or check permissions on ${Q.dataDir}`:`Cannot create data directories: ${w instanceof Error?w.message:String(w)}`;throw Error($,{cause:w})}return gI(Q)}var Ew0=r(()=>{vw0()});class Zl{logger;migrations;constructor(A,Q){this.logger=A,this.migrations=Q??{getStandardConfigWithDirectories:()=>yw0(),migrateEntities:UOA,migrateJobQueue:DOA,migrateConversations:zOA,migrateRuntimeState:JOA}}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;if(A?.runtimeStateDatabase)Q.runtimeStateDatabase.url=A.runtimeStateDatabase;await this.migrateEntityDatabase(Q),await this.migrateJobQueueDatabase(Q),await this.migrateConversationDatabase(Q),await this.migrateRuntimeStateDatabase(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)}async migrateRuntimeStateDatabase(A){this.logger.debug("Running runtime state database migrations..."),await this.migrations.migrateRuntimeState({url:A.runtimeStateDatabase.url,...A.runtimeStateDatabase.authToken&&{authToken:A.runtimeStateDatabase.authToken}},this.logger)}}var PM0=r(()=>{GOA();qOA();VOA();IOA();Ew0()});function Js2(){return process.env[Vs2]}function FOA(){return Js2()!=="production"}var Vs2="NODE_ENV";var Tw0;var MM0=r(()=>{C0();Tw0=f.object({theme:f.object({primaryColor:f.string().describe("Primary color for the CLI theme").default("#0066cc"),accentColor:f.string().describe("Accent color for the CLI theme").default("#ff6600")}).describe("Theme configuration for the CLI interface").default({primaryColor:"#0066cc",accentColor:"#ff6600"})})});var LOA;var bOA=r(()=>{LOA={name:"@brains/chat-repl",version:"0.2.0-alpha.159",dependencies:{"@brains/plugins":"workspace:*",chalk:"^5.4.1",ink:"^7.0.6","ink-spinner":"^5.0.0","ink-text-input":"^6.0.0",marked:"^18.0.5",react:"^19.2.7"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14","@types/react":"^19.2.17",typescript:"^7.0.2"},files:["src"],main:"./src/index.ts",module:"./src/index.ts",private:!0,scripts:{dev:"tsc --watch",lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module",types:"./src/index.ts"}});var Uw=h((Fs2,Sw0)=>{(function(){function A(t,G0){Object.defineProperty($.prototype,t,{get:function(){console.warn("%s(...) is deprecated in plain JavaScript React classes. %s",G0[0],G0[1])}})}function Q(t){if(t===null||typeof t!=="object")return null;return t=j0&&t[j0]||t["@@iterator"],typeof t==="function"?t:null}function w(t,G0){t=(t=t.constructor)&&(t.displayName||t.name)||"ReactClass";var J0=t+"."+G0;P0[J0]||(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.",G0,t),P0[J0]=!0)}function $(t,G0,J0){this.props=t,this.context=G0,this.refs=n0,this.updater=J0||E0}function B(){}function X(t,G0,J0){this.props=t,this.context=G0,this.refs=n0,this.updater=J0||E0}function Y(){}function Z(t){return""+t}function H(t){try{Z(t);var G0=!1}catch(I0){G0=!0}if(G0){G0=console;var J0=G0.error,N0=typeof Symbol==="function"&&Symbol.toStringTag&&t[Symbol.toStringTag]||t.constructor.name||"Object";return J0.call(G0,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",N0),Z(t)}}function W(t){if(t==null)return null;if(typeof t==="function")return t.$$typeof===HA?null:t.displayName||t.name||null;if(typeof t==="string")return t;switch(t){case D0:return"Fragment";case f0:return"Profiler";case T:return"StrictMode";case i0:return"Suspense";case k0:return"SuspenseList";case S0:return"Activity"}if(typeof t==="object")switch(typeof t.tag==="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),t.$$typeof){case a:return"Portal";case i:return t.displayName||"Context";case b0:return(t._context.displayName||"Context")+".Consumer";case u0:var G0=t.render;return t=t.displayName,t||(t=G0.displayName||G0.name||"",t=t!==""?"ForwardRef("+t+")":"ForwardRef"),t;case _0:return G0=t.displayName||null,G0!==null?G0:W(t.type)||"Memo";case v0:G0=t._payload,t=t._init;try{return W(t(G0))}catch(J0){}}return null}function K(t){if(t===D0)return"<>";if(typeof t==="object"&&t!==null&&t.$$typeof===v0)return"<...>";try{var G0=W(t);return G0?"<"+G0+">":"<...>"}catch(J0){return"<...>"}}function U(){var t=WA.A;return t===null?null:t.getOwner()}function G(){return Error("react-stack-top-frame")}function q(t){if(o0.call(t,"key")){var G0=Object.getOwnPropertyDescriptor(t,"key").get;if(G0&&G0.isReactWarning)return!1}return t.key!==void 0}function V(t,G0){function J0(){GA||(GA=!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)",G0))}J0.isReactWarning=!0,Object.defineProperty(t,"key",{get:J0,configurable:!0})}function I(){var t=W(this.type);return RA[t]||(RA[t]=!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.")),t=this.props.ref,t!==void 0?t:null}function J(t,G0,J0,N0,I0,r0){var l0=J0.ref;return t={$$typeof:s,type:t,key:G0,props:J0,_owner:N0},(l0!==void 0?l0:null)!==null?Object.defineProperty(t,"ref",{enumerable:!1,get:I}):Object.defineProperty(t,"ref",{enumerable:!1,value:null}),t._store={},Object.defineProperty(t._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(t,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(t,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:I0}),Object.defineProperty(t,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:r0}),Object.freeze&&(Object.freeze(t.props),Object.freeze(t)),t}function k(t,G0){return G0=J(t.type,G0,t.props,t._owner,t._debugStack,t._debugTask),t._store&&(G0._store.validated=t._store.validated),G0}function j(t){_(t)?t._store&&(t._store.validated=1):typeof t==="object"&&t!==null&&t.$$typeof===v0&&(t._payload.status==="fulfilled"?_(t._payload.value)&&t._payload.value._store&&(t._payload.value._store.validated=1):t._store&&(t._store.validated=1))}function _(t){return typeof t==="object"&&t!==null&&t.$$typeof===s}function x(t){var G0={"=":"=0",":":"=2"};return"$"+t.replace(/[=:]/g,function(J0){return G0[J0]})}function v(t,G0){return typeof t==="object"&&t!==null&&t.key!=null?(H(t.key),x(""+t.key)):G0.toString(36)}function O(t){switch(t.status){case"fulfilled":return t.value;case"rejected":throw t.reason;default:switch(typeof t.status==="string"?t.then(Y,Y):(t.status="pending",t.then(function(G0){t.status==="pending"&&(t.status="fulfilled",t.value=G0)},function(G0){t.status==="pending"&&(t.status="rejected",t.reason=G0)})),t.status){case"fulfilled":return t.value;case"rejected":throw t.reason}}throw t}function M(t,G0,J0,N0,I0){var r0=typeof t;if(r0==="undefined"||r0==="boolean")t=null;var l0=!1;if(t===null)l0=!0;else switch(r0){case"bigint":case"string":case"number":l0=!0;break;case"object":switch(t.$$typeof){case s:case a:l0=!0;break;case v0:return l0=t._init,M(l0(t._payload),G0,J0,N0,I0)}}if(l0){l0=t,I0=I0(l0);var BA=N0===""?"."+v(l0,0):N0;return JA(I0)?(J0="",BA!=null&&(J0=BA.replace(x0,"$&/")+"/"),M(I0,G0,J0,"",function(hA){return hA})):I0!=null&&(_(I0)&&(I0.key!=null&&(l0&&l0.key===I0.key||H(I0.key)),J0=k(I0,J0+(I0.key==null||l0&&l0.key===I0.key?"":(""+I0.key).replace(x0,"$&/")+"/")+BA),N0!==""&&l0!=null&&_(l0)&&l0.key==null&&l0._store&&!l0._store.validated&&(J0._store.validated=2),I0=J0),G0.push(I0)),1}if(l0=0,BA=N0===""?".":N0+":",JA(t))for(var YA=0;YA<t.length;YA++)N0=t[YA],r0=BA+v(N0,YA),l0+=M(N0,G0,J0,r0,I0);else if(YA=Q(t),typeof YA==="function")for(YA===t.entries&&(g0||console.warn("Using Maps as children is not supported. Use an array of keyed ReactElements instead."),g0=!0),t=YA.call(t),YA=0;!(N0=t.next()).done;)N0=N0.value,r0=BA+v(N0,YA++),l0+=M(N0,G0,J0,r0,I0);else if(r0==="object"){if(typeof t.then==="function")return M(O(t),G0,J0,N0,I0);throw G0=String(t),Error("Objects are not valid as a React child (found: "+(G0==="[object Object]"?"object with keys {"+Object.keys(t).join(", ")+"}":G0)+"). If you meant to render a collection of children, use an array instead.")}return l0}function S(t,G0,J0){if(t==null)return t;var N0=[],I0=0;return M(t,N0,"","",function(r0){return G0.call(J0,r0,I0++)}),N0}function u(t){if(t._status===-1){var G0=t._ioInfo;G0!=null&&(G0.start=G0.end=performance.now()),G0=t._result;var J0=G0();if(J0.then(function(I0){if(t._status===0||t._status===-1){t._status=1,t._result=I0;var r0=t._ioInfo;r0!=null&&(r0.end=performance.now()),J0.status===void 0&&(J0.status="fulfilled",J0.value=I0)}},function(I0){if(t._status===0||t._status===-1){t._status=2,t._result=I0;var r0=t._ioInfo;r0!=null&&(r0.end=performance.now()),J0.status===void 0&&(J0.status="rejected",J0.reason=I0)}}),G0=t._ioInfo,G0!=null){G0.value=J0;var N0=J0.displayName;typeof N0==="string"&&(G0.name=N0)}t._status===-1&&(t._status=0,t._result=J0)}if(t._status===1)return G0=t._result,G0===void 0&&console.error(`lazy: Expected the result of a dynamic import() call. Instead received: %s
434
434
 
435
435
  Your code should look like:
436
436
  const MyComponent = lazy(() => import('./MyComponent'))
@@ -1717,7 +1717,7 @@ Example bad output: "A dreamlike crystal formation glowing with ethereal light i
1717
1717
  Title: "${A.entityTitle??Z}"
1718
1718
 
1719
1719
  Content:
1720
- ${K}`,g2Q);W=`${$.trim()} ${k.imagePrompt}`}catch(k){this.logger.warn("AI prompt distillation failed, using fallback",{error:dA(k)})}}await this.reportProgress(w,{progress:Yw.PROCESS,message:"Generating image"});let U=this.context.identity.get(),G=this.context.identity.getProfile(),V=agA(U,G)+W,I;try{I=await this.context.ai.generateImage(V,{...B&&{aspectRatio:B}})}catch(k){return this.logger.error("Image generation failed",{jobId:Q,error:dA(k)}),k8.failure(k)}await this.reportProgress(w,{progress:Yw.GENERATE,message:"Creating image entity"});let J=qf.createImageEntity({dataUrl:I.dataUrl,title:Z,status:"draft",attachmentType:"generated",...X&&{sourceEntityType:X},...Y&&{sourceEntityId:Y}});if(await pX({entityService:this.context.entityService,entity:{...J,id:H}}),this.logger.debug("Created image entity",{imageId:H}),X&&Y){await this.reportProgress(w,{progress:Yw.SAVE,message:`Updating ${X} with cover image`});let k=await b_(this.context.entityService,X,Y,this.logger);if(!k)return k8.failure(Error(`Target entity not found: ${X}/${Y}`));let j=t_(k,H);await this.context.entities.update(j),this.logger.debug("Updated target entity with cover image",{targetEntityType:X,targetEntityId:Y,imageId:H})}return await this.reportProgress(w,{progress:Yw.COMPLETE,message:"Image generation complete"}),this.logger.info("Image generation job complete",{jobId:Q,imageId:H,targetEntityType:X,targetEntityId:Y}),{success:!0,imageId:H}}catch(W){let K=dA(W);return this.logger.error("Image generation job failed",{jobId:Q,error:K}),await YD({entityService:this.context.entityService,entityType:"image",id:H,error:K}),k8.failure(W)}}summarizeDataForLog(A){return{title:A.title,promptLength:A.prompt.length,aspectRatio:A.aspectRatio,targetEntityType:A.targetEntityType,targetEntityId:A.targetEntityId}}}fA();C0();e6();p4();var E2Q=f.object({sourceEntityType:f.string().min(1),sourceEntityId:f.string().min(1),attachmentType:f.string().min(1),imageId:f.string().min(1),dedupKey:f.string().min(1).optional(),replace:f.boolean().optional(),targetEntityType:f.string().min(1).optional(),targetEntityId:f.string().min(1).optional(),targetImageField:f.enum(["coverImageId","ogImageId"]).optional()});class ax0 extends D6{context;constructor(A,Q){super(Q,{schema:E2Q,jobTypeName:"image-render-source"});this.context=A}async process(A,Q,w){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 Y=await this.findImageByDedupKey(A.dedupKey);if(Y)return await this.updateTarget(A,Y.id),await this.reportProgress(w,{progress:Yw.COMPLETE,message:"Reusing existing generated image"}),{success:!0,imageId:Y.id,reused:!0}}await this.reportProgress(w,{progress:Yw.PROCESS,message:"Rendering source image"});let $=await this.context.attachments.resolve({sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType});if(!$)return k8.failure(Error(`No attachment provider found for ${A.sourceEntityType}/${A.attachmentType}`));if($.type!=="image")return k8.failure(Error(`Attachment provider returned ${$.type}; expected image`));await this.reportProgress(w,{progress:Yw.GENERATE,message:"Creating image entity"});let B=$.mimeType.split("/")[1]??"png",X=qf.createImageEntity({dataUrl:JM0($.data.toString("base64"),B),title:A.imageId,status:"draft",sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType,...A.dedupKey&&{dedupKey:A.dedupKey}});return await pX({entityService:this.context.entityService,entity:{...X,id:A.imageId}}),await this.updateTarget(A,A.imageId),await this.reportProgress(w,{progress:Yw.COMPLETE,message:"Image render complete"}),{success:!0,imageId:A.imageId,reused:!1}}catch($){let B=dA($);return this.logger.error("Source image render job failed",{jobId:Q,error:B}),await YD({entityService:this.context.entityService,entityType:"image",id:A.imageId,error:B}),k8.failure($)}}async findImageByDedupKey(A){return(await this.context.entityService.listEntities({entityType:"image",options:{filter:{metadata:{dedupKey:A}}}})).find((w)=>w.metadata.status!=="pending"&&w.metadata.status!=="failed")}async updateTarget(A,Q){if(!A.targetEntityType||!A.targetEntityId)return;let w=await b_(this.context.entityService,A.targetEntityType,A.targetEntityId,this.logger);if(!w)throw Error(`Target entity not found: ${A.targetEntityType}/${A.targetEntityId}`);let B=(A.targetImageField??"coverImageId")==="ogImageId"?Bl(w,Q):t_(w,Q);await this.context.entities.update(B)}}fA();C0();e6();p4();b2();var wh={namespace:"upload",refKind:"upload",routePath:"/api/chat/uploads"};function H$0(A){return["image/png","image/jpeg","image/webp","image/gif"].includes(A.toLowerCase())}function W$0(A){let Q=T2Q(A.title,A.filename),w=q1(Q);if(!w)throw Error("Could not derive an image id from the uploaded filename. Provide a title.");return{id:w,title:Q}}function tgA(A,Q){return`data:${A};base64,${Q.toString("base64")}`}function T2Q(A,Q){let w=A?.trim();if(w)return w;return Q.replace(/\.[^.]+$/,"").trim()||Q}var S2Q=f.object({uploadId:f.string().min(1),imageId:f.string().min(1).optional(),title:f.string().optional()});class tx0 extends D6{context;constructor(A,Q){super(A,{schema:S2Q,jobTypeName:"upload-promote"});this.context=Q}async process(A,Q,w){try{await this.reportProgress(w,{progress:10,message:"Reading uploaded image"});let $=await this.context.uploads.scoped(wh).read(A.uploadId);if(!H$0($.record.mediaType))throw Error("Only image uploads can be promoted to image entities");let B=W$0({filename:$.record.filename,...A.title!==void 0?{title:A.title}:{}}),X=A.imageId??B.id;await this.reportProgress(w,{progress:60,message:"Saving uploaded image"});let Y=new Date().toISOString(),Z=qf.createImageEntity({dataUrl:tgA($.record.mediaType,$.content),title:B.title,status:"draft",sourceUploadId:A.uploadId,sourceFilename:$.record.filename,sourceMediaType:$.record.mediaType,attachmentType:"uploaded"}),H=await pX({entityService:this.context.entityService,entity:{id:X,...Z,created:Y,updated:Y}});return await this.reportProgress(w,{progress:100,message:"Uploaded image promoted"}),{entityId:H.entityId,status:"created"}}catch($){if(A.imageId)await YD({entityService:this.context.entityService,entityType:"image",id:A.imageId,error:dA($)});return k8.failure($)}}summarizeDataForLog(A){return{uploadId:A.uploadId,imageId:A.imageId,hasTitle:A.title!==void 0}}}var egA={name:"@brains/image-plugin",version:"0.2.0-alpha.158",description:"Plugin for AI-powered image generation and management",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":"^1.3.14","@types/node":"^20.19.43",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},main:"./src/index.ts",private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var u2Q="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==",c2Q=f.object({defaultAspectRatio:f.enum(["1:1","16:9","9:16","4:3","3:4"]).default("16:9").describe("Default aspect ratio for generated images")});function DU(A){let Q=A?.trim();if(!Q)return;return Q}function l2Q(A){let Q=DU(A.prompt);if(Q)return Q;let w=DU(A.content);if(w&&!sx0(w))return w;return}function p2Q(A){let Q=A.attachmentType==="og-image"?"og":A.attachmentType;return q1(`${Q}-${A.sourceEntityType}-${A.sourceEntityId}`)}function AyA(A){let Q=DU(A.title)??(A.targetEntityId?`cover-${A.targetEntityId}`:A.prompt.slice(0,60).trim());return q1(Q)}async function i2Q(A,Q){let w=`${Q.attachmentType}:${Q.sourceEntityType}:${Q.sourceEntityId}:resolved-attachment`,$=await A.entityService.getEntity({entityType:Q.sourceEntityType,id:Q.sourceEntityId});return $?`${w}:${$.contentHash}`:w}function ex0(A,Q="generated"){let w=encodeURIComponent(A);return{mediaType:"image/png",url:`/api/chat/attachments/image?id=${w}`,downloadUrl:`/api/chat/attachments/image?id=${w}&download=1`,filename:`${A}.png`,source:{entityType:"image",entityId:A,attachmentType:Q}}}function d2Q(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 AR0 extends Zw{entityType=qf.entityType;schema=wl;adapter=qf;constructor(A={}){super("image",egA,A,c2Q)}getEntityTypeConfig(){return{embeddable:!1}}async interceptCreate(A,Q,w){if(A.from?.kind===wh.refKind)return this.promoteUpload(A,w);let $=l2Q(A),B=DU(A.targetEntityType),X=DU(A.targetEntityId),Y=B===this.entityType?X:void 0,Z=A.from;if(Z?.kind==="entity-attachment")return this.enqueueSourceImageRender({...A,from:Z},w);if(!B||!X||Y){if(!$)return{kind:"continue",input:A};let G=DU(A.title)??Y,q=AyA({prompt:$,...G&&{title:G}});await this.createPendingImage(w,{id:q,title:G??$.slice(0,60).trim(),alt:G??$.slice(0,60).trim(),attachmentType:"generated"});let V=await w.jobs.enqueue({type:"image-generate",data:{prompt:$,...G&&{title:G}}});return{kind:"handled",result:{success:!0,data:{entityId:q,status:"generating",jobId:V,attachment:ex0(q)}}}}let H=await T4(w.entityService,B,X,this.logger,"Target entity");if(!H.ok)return{kind:"handled",result:{success:!1,error:H.error}};if(!$)return{kind:"continue",input:{...A,targetEntityId:H.entity.id}};let W=Z$0(H.entity.content),K=AyA({prompt:$,...A.title&&{title:A.title},targetEntityId:H.entity.id});await this.createPendingImage(w,{id:K,title:A.title??`cover-${H.entity.id}`,alt:A.title??`cover-${H.entity.id}`,attachmentType:"generated",sourceEntityType:B,sourceEntityId:H.entity.id});let U=await w.jobs.enqueue({type:"image-generate",data:{prompt:$,...A.title&&{title:A.title},targetEntityType:B,targetEntityId:H.entity.id,entityTitle:typeof H.entity.metadata.title==="string"?H.entity.metadata.title:H.entity.id,...W&&{entityContent:W}}});return{kind:"handled",result:{success:!0,data:{entityId:K,status:"generating",jobId:U,attachment:ex0(K)}}}}async promoteUpload(A,Q){let w=A.from;if(w?.kind!==wh.refKind)return{kind:"handled",result:{success:!1,error:"Unsupported upload ref kind"}};let $=w.id,B;try{B=await Q.uploads.scoped(wh).readRecord($)}catch{return{kind:"handled",result:{success:!1,error:"Upload ref not found"}}}if(!H$0(B.mediaType))return{kind:"handled",result:{success:!1,error:"Only image uploads can be promoted to image entities"}};let X;try{X=W$0({filename:B.filename,...A.title!==void 0?{title:A.title}:{}})}catch(Z){return{kind:"handled",result:{success:!1,error:Z instanceof Error?Z.message:String(Z)}}}await this.createPendingImage(Q,{id:X.id,title:X.title,alt:X.title,sourceUploadId:$,sourceFilename:B.filename,sourceMediaType:B.mediaType,attachmentType:"uploaded"});let Y=await Q.jobs.enqueue({type:"upload-promote",data:{uploadId:$,imageId:X.id,title:X.title}});return{kind:"handled",result:{success:!0,data:{entityId:X.id,status:"generating",jobId:Y,attachment:d2Q({mediaType:B.mediaType,entityId:X.id,filename:B.filename})}}}}async enqueueSourceImageRender(A,Q){let w=DU(A.from.sourceEntityType),$=DU(A.from.sourceEntityId),B=DU(A.from.attachmentType);if(!w||!$||!B)return{kind:"handled",result:{success:!1,error:"Image source requires sourceEntityType, sourceEntityId, and attachmentType"}};let X=await T4(Q.entityService,w,$,this.logger,"Source entity");if(!X.ok)return{kind:"handled",result:{success:!1,error:X.error}};let Y=DU(A.targetEntityType),Z=DU(A.targetEntityId),H;if(Y&&Z){let q=await T4(Q.entityService,Y,Z,this.logger,"Target entity");if(!q.ok)return{kind:"handled",result:{success:!1,error:q.error}};H=q.entity.id}let W={sourceEntityType:w,sourceEntityId:X.entity.id,attachmentType:B},K=await i2Q(Q,W),U=p2Q(W);await this.createPendingImage(Q,{id:U,title:U,alt:U,sourceEntityType:W.sourceEntityType,sourceEntityId:W.sourceEntityId,attachmentType:B,dedupKey:K});let G=await Q.jobs.enqueue({type:"image-render-source",data:{...W,imageId:U,dedupKey:K,...A.replace===!0&&{replace:!0},...Y&&{targetEntityType:Y},...H&&{targetEntityId:H},...B==="og-image"&&{targetImageField:"ogImageId"}}});return{kind:"handled",result:{success:!0,data:{entityId:U,status:"generating",jobId:G,attachment:ex0(U,B)}}}}async createPendingImage(A,Q){let w=new Date().toISOString(),$=qf.createImageEntity({dataUrl:u2Q,title:Q.title,alt:Q.alt,status:"pending",attachmentType:Q.attachmentType,...Q.sourceEntityType&&{sourceEntityType:Q.sourceEntityType},...Q.sourceEntityId&&{sourceEntityId:Q.sourceEntityId},...Q.sourceUploadId&&{sourceUploadId:Q.sourceUploadId},...Q.sourceFilename&&{sourceFilename:Q.sourceFilename},...Q.sourceMediaType&&{sourceMediaType:Q.sourceMediaType},...Q.dedupKey&&{dedupKey:Q.dedupKey}});await k_({entityService:A.entityService,entity:{id:Q.id,...$,created:w,updated:w}})}async getInstructions(){return"Image entities store durable images. Standalone generated images are valid system_generate image calls with a prompt source and no target fields. A prompt source creates a new image; never use it to describe, analyze, or discuss an existing uploaded image. For uploaded-image discussion, answer directly from the attachment/context; if the user later asks to save that discussion as a note, create entityType note from prior-response or exact text. targetEntityType and targetEntityId are only for attaching the result to an existing entity as coverImageId. Cover images and OG/social preview images are distinct domain concepts: cover-image fields use coverImageId, while OG/Open Graph/social preview fields use ogImageId. Rendered OG/social preview images are deterministic attachment-source images with attachmentType og-image."}createGenerationHandler(A){return new f$0(A,this.logger)}async onRegister(A){A.entities.registerUploadSaveHandler({entityType:this.entityType,mediaTypes:["image/*"],handler:async(w)=>{let $=await this.promoteUpload({entityType:this.entityType,...w.title!==void 0?{title:w.title}:{},from:w.upload},A);return $.kind==="handled"?$.result:{success:!1,error:"Image upload save was not handled"}}});let Q=new f$0(A,this.logger);A.jobs.registerHandler("image-generate",Q),A.jobs.registerHandler("image-render-source",new ax0(A,this.logger)),A.jobs.registerHandler("upload-promote",new tx0(this.logger.child("UploadPromotionJobHandler"),A))}}function Yp(A={}){return new AR0(A)}fA();import{StdioServerTransport as r2Q}from"@modelcontextprotocol/sdk/server/stdio.js";C0();var n2Q=f.custom((A)=>typeof A==="object"&&A!==null&&("info"in A)&&typeof A.info==="function"&&("debug"in A)&&typeof A.debug==="function"&&("error"in A)&&typeof A.error==="function"&&("warn"in A)&&typeof A.warn==="function");function QyA(){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 QR0(){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 K$0(A){let Q=n2Q.safeParse(A);if(Q.success)return{info:(w,...$)=>Q.data.info(w,...$),debug:(w,...$)=>Q.data.debug(w,...$),error:(w,...$)=>Q.data.error(w,...$),warn:(w,...$)=>Q.data.warn(w,...$)};return QR0()}class qU{static instance=null;mcpServer=null;transport=null;config;logger;static getInstance(A){return qU.instance??=new qU(A),qU.instance}static resetInstance(){if(qU.instance)qU.instance.stop(),qU.instance=null}static createFresh(A){return new qU(A)}constructor(A={}){this.config=A,this.logger=this.config.logger?K$0(this.config.logger):QyA()}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 r2Q,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 o2Q,timingSafeEqual as s2Q}from"crypto";import{WebStandardStreamableHTTPServerTransport as a2Q}from"@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";import{isInitializeRequest as t2Q}from"@modelcontextprotocol/sdk/types.js";C0();var e2Q=1800000,AQQ=60000,QQQ={"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"},wQQ=f.looseObject({code:f.string().optional()});function $QQ(A){let Q=new URL(A.url),$=A.headers.get("x-forwarded-proto")?.split(",")[0]?.trim(),B=A.headers.get("x-forwarded-host")??A.headers.get("host");if(!B)return Q.origin;return`${$??Q.protocol.replace(":","")}://${B}`}class j3{static instance=null;transports={};sessionLastActivity=new Map;mcpServer=null;mcpTransport=null;server=null;boundPort=null;evictionTimer=null;config;logger;authConfig;sessionIdleTtlMs;constructor(A={}){if(this.config=A,this.logger=this.config.logger?K$0(this.config.logger):QR0(),this.authConfig=A.auth??{},this.sessionIdleTtlMs=A.sessionIdleTtlMs??e2Q,this.evictionTimer=setInterval(()=>this.evictIdleSessions(),Math.min(this.sessionIdleTtlMs,AQQ)),this.evictionTimer.unref(),!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 j3.instance??=new j3(A),j3.instance}static resetInstance(){j3.instance=null}static createFresh(A){return new j3(A)}withCors(A){let Q=new Headers(A.headers);for(let[w,$]of Object.entries(QQQ))Q.set(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,w){let $=this.createJsonResponse({jsonrpc:"2.0",error:{code:-32001,message:A},id:null},Q);if(!w)return $;let B=new Headers($.headers);return B.set("WWW-Authenticate",w),new Response($.body,{status:$.status,statusText:$.statusText,headers:B})}getBearerChallenge(A,Q={}){let w={...this.authConfig.token?{}:{resource_metadata:`${$QQ(A)}/.well-known/oauth-protected-resource`},...Q};return`Bearer ${Object.entries(w).map(([B,X])=>`${B}="${BQQ(X)}"`).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 w=A.headers.get("authorization");if(!w?.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){let $=w.substring(7);if(!XQQ($,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"),{token:$,clientId:"static-token-client",scopes:this.authConfig.requiredScopes??[],extra:{subject:"static-token-operator"}}}try{let $=await this.authConfig.verifyBearerToken?.(A);if(!$)return this.logger.warn("Authentication failed: Invalid token"),this.getAuthErrorResponse("Unauthorized: Invalid token",401,this.getBearerChallenge(A,{error:"invalid_token"}));let B=this.authConfig.requiredScopes??[],X=B.filter((Y)=>!$.scope?.includes(Y));if(X.length>0)return this.logger.warn(`Authentication failed: Missing required scope(s): ${X.join(", ")}`),this.getAuthErrorResponse("Forbidden: Missing required scope",403,this.getBearerChallenge(A,{error:"insufficient_scope",scope:B.join(" ")}));return this.logger.debug("Authentication successful"),{token:w.substring(7),clientId:$.subject,scopes:$.scope??[],extra:{subject:$.subject}}}catch($){return this.logger.warn("Authentication failed: Invalid token",$),this.getAuthErrorResponse("Unauthorized: Invalid token",401,this.getBearerChallenge(A,{error:"invalid_token"}))}}touchSession(A){this.sessionLastActivity.set(A,Date.now())}evictIdleSessions(){let A=Date.now();for(let[Q,w]of this.sessionLastActivity){if(A-w<this.sessionIdleTtlMs)continue;this.logger.info(`Evicting idle session ${Q}`),this.sessionLastActivity.delete(Q);let $=this.transports[Q];if($)delete this.transports[Q],$.close().catch((B)=>{this.logger.error(`Error closing idle transport for session ${Q}:`,B)})}}async handleMcpRequest(A,Q){let w=A.headers.get("mcp-session-id")??void 0;if(A.method==="GET"){if(!w||!this.transports[w])return this.createTextResponse("Invalid or missing session ID",400);return this.touchSession(w),this.logger.debug(`GET /mcp - SSE stream for session ${w}`),this.withCors(await this.transports[w].handleRequest(A,{authInfo:Q}))}if(A.method==="DELETE"){if(!w||!this.transports[w])return this.createTextResponse("Invalid or missing session ID",400);return this.logger.info(`DELETE /mcp - Terminating session ${w}`),this.withCors(await this.transports[w].handleRequest(A,{authInfo:Q}))}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 $;try{$=await A.json()}catch{return this.createJsonResponse({jsonrpc:"2.0",error:{code:-32700,message:"Parse error: Invalid JSON body"},id:null},400)}this.logger.debug(`POST /mcp - Session: ${w??"new"}`);try{let B;if(w&&this.transports[w])B=this.transports[w],this.touchSession(w);else if(!w&&t2Q($))B=new a2Q({sessionIdGenerator:()=>o2Q(),onsessioninitialized:(Y)=>{this.logger.info(`Session initialized: ${Y}`),this.transports[Y]=B,this.touchSession(Y)},onsessionclosed:(Y)=>{this.logger.info(`Session closed: ${Y}`),delete this.transports[Y],this.sessionLastActivity.delete(Y)}}),await(this.mcpTransport?this.mcpTransport.createMcpServer():this.mcpServer).connect(B);else return this.createJsonResponse({jsonrpc:"2.0",error:{code:-32000,message:"Bad Request: Server not initialized"},id:null},400);return this.withCors(await B.handleRequest(A,{parsedBody:$,authInfo:Q}))}catch(B){return this.logger.error("MCP transport error:",B),this.createJsonResponse({jsonrpc:"2.0",error:{code:-32603,message:"Internal error"}},500)}}async handleRequest(A){let Q=new URL(A.url);this.logger.debug(`${A.method} ${Q.pathname}`);let w=await this.authenticate(A);if(w instanceof Response)return w;let $=w??void 0;if(Q.pathname==="/health")return this.createJsonResponse({status:"ok",transport:"streamable-http",timestamp:new Date().toISOString()});if(Q.pathname==="/status")return this.createJsonResponse({status:"ok",sessions:Object.keys(this.transports).length});if(Q.pathname==="/mcp")return this.handleMcpRequest(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")}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:(w)=>this.handleRequest(w)}),this.boundPort=this.server.port??A,this.logger.info(`StreamableHTTP server listening on http://${Q}:${this.boundPort}/mcp`)}catch(w){let $=wQQ.safeParse(w);if($.success&&$.data.code==="EADDRINUSE")this.logger.error(`Port ${A} is already in use`);throw w}}async stop(){if(this.evictionTimer)clearInterval(this.evictionTimer),this.evictionTimer=null;this.sessionLastActivity.clear();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 BQQ(A){return A.replace(/["\\]/g,(Q)=>`\\${Q}`)}function XQQ(A,Q){let w=Buffer.from(A),$=Buffer.from(Q);if(w.length!==$.length)return!1;return s2Q(w,$)}import{randomUUID as UQQ}from"crypto";import{chmod as YQQ,mkdir as ZQQ,readFile as fQQ,rename as wyA,writeFile as HQQ}from"fs/promises";import{dirname as WQQ}from"path";class tX{filePath;parse;empty;logError;onCorrupt;writeQueue=Promise.resolve();constructor(A){this.filePath=A.filePath,this.parse=A.parse,this.empty=A.empty,this.onCorrupt=A.onCorrupt??"quarantine",this.logError=A.logError??((Q,w)=>{console.error(Q,w)})}async enqueueWrite(A){return this.writeQueue=this.writeQueue.then(A,A),this.writeQueue}async read(){let A;try{A=await fQQ(this.filePath,"utf8")}catch(Q){if(Q.code==="ENOENT")return this.empty();throw Q}try{return this.parse(JSON.parse(A))}catch(Q){if(this.onCorrupt==="throw")throw Error(`Corrupt JSON store at ${this.filePath}; refusing to start empty. Inspect or remove the file to proceed.`,{cause:Q});return await this.quarantineCorruptFile(Q),this.empty()}}async write(A){await ZQQ(WQQ(this.filePath),{recursive:!0,mode:448});let Q=`${this.filePath}.tmp`;await HQQ(Q,`${JSON.stringify(A,null,2)}
1720
+ ${K}`,g2Q);W=`${$.trim()} ${k.imagePrompt}`}catch(k){this.logger.warn("AI prompt distillation failed, using fallback",{error:dA(k)})}}await this.reportProgress(w,{progress:Yw.PROCESS,message:"Generating image"});let U=this.context.identity.get(),G=this.context.identity.getProfile(),V=agA(U,G)+W,I;try{I=await this.context.ai.generateImage(V,{...B&&{aspectRatio:B}})}catch(k){return this.logger.error("Image generation failed",{jobId:Q,error:dA(k)}),k8.failure(k)}await this.reportProgress(w,{progress:Yw.GENERATE,message:"Creating image entity"});let J=qf.createImageEntity({dataUrl:I.dataUrl,title:Z,status:"draft",attachmentType:"generated",...X&&{sourceEntityType:X},...Y&&{sourceEntityId:Y}});if(await pX({entityService:this.context.entityService,entity:{...J,id:H}}),this.logger.debug("Created image entity",{imageId:H}),X&&Y){await this.reportProgress(w,{progress:Yw.SAVE,message:`Updating ${X} with cover image`});let k=await b_(this.context.entityService,X,Y,this.logger);if(!k)return k8.failure(Error(`Target entity not found: ${X}/${Y}`));let j=t_(k,H);await this.context.entities.update(j),this.logger.debug("Updated target entity with cover image",{targetEntityType:X,targetEntityId:Y,imageId:H})}return await this.reportProgress(w,{progress:Yw.COMPLETE,message:"Image generation complete"}),this.logger.info("Image generation job complete",{jobId:Q,imageId:H,targetEntityType:X,targetEntityId:Y}),{success:!0,imageId:H}}catch(W){let K=dA(W);return this.logger.error("Image generation job failed",{jobId:Q,error:K}),await YD({entityService:this.context.entityService,entityType:"image",id:H,error:K}),k8.failure(W)}}summarizeDataForLog(A){return{title:A.title,promptLength:A.prompt.length,aspectRatio:A.aspectRatio,targetEntityType:A.targetEntityType,targetEntityId:A.targetEntityId}}}fA();C0();e6();p4();var E2Q=f.object({sourceEntityType:f.string().min(1),sourceEntityId:f.string().min(1),attachmentType:f.string().min(1),imageId:f.string().min(1),dedupKey:f.string().min(1).optional(),replace:f.boolean().optional(),targetEntityType:f.string().min(1).optional(),targetEntityId:f.string().min(1).optional(),targetImageField:f.enum(["coverImageId","ogImageId"]).optional()});class ax0 extends D6{context;constructor(A,Q){super(Q,{schema:E2Q,jobTypeName:"image-render-source"});this.context=A}async process(A,Q,w){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 Y=await this.findImageByDedupKey(A.dedupKey);if(Y)return await this.updateTarget(A,Y.id),await this.reportProgress(w,{progress:Yw.COMPLETE,message:"Reusing existing generated image"}),{success:!0,imageId:Y.id,reused:!0}}await this.reportProgress(w,{progress:Yw.PROCESS,message:"Rendering source image"});let $=await this.context.attachments.resolve({sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType});if(!$)return k8.failure(Error(`No attachment provider found for ${A.sourceEntityType}/${A.attachmentType}`));if($.type!=="image")return k8.failure(Error(`Attachment provider returned ${$.type}; expected image`));await this.reportProgress(w,{progress:Yw.GENERATE,message:"Creating image entity"});let B=$.mimeType.split("/")[1]??"png",X=qf.createImageEntity({dataUrl:JM0($.data.toString("base64"),B),title:A.imageId,status:"draft",sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType,...A.dedupKey&&{dedupKey:A.dedupKey}});return await pX({entityService:this.context.entityService,entity:{...X,id:A.imageId}}),await this.updateTarget(A,A.imageId),await this.reportProgress(w,{progress:Yw.COMPLETE,message:"Image render complete"}),{success:!0,imageId:A.imageId,reused:!1}}catch($){let B=dA($);return this.logger.error("Source image render job failed",{jobId:Q,error:B}),await YD({entityService:this.context.entityService,entityType:"image",id:A.imageId,error:B}),k8.failure($)}}async findImageByDedupKey(A){return(await this.context.entityService.listEntities({entityType:"image",options:{filter:{metadata:{dedupKey:A}}}})).find((w)=>w.metadata.status!=="pending"&&w.metadata.status!=="failed")}async updateTarget(A,Q){if(!A.targetEntityType||!A.targetEntityId)return;let w=await b_(this.context.entityService,A.targetEntityType,A.targetEntityId,this.logger);if(!w)throw Error(`Target entity not found: ${A.targetEntityType}/${A.targetEntityId}`);let B=(A.targetImageField??"coverImageId")==="ogImageId"?Bl(w,Q):t_(w,Q);await this.context.entities.update(B)}}fA();C0();e6();p4();b2();var wh={namespace:"upload",refKind:"upload",routePath:"/api/chat/uploads"};function H$0(A){return["image/png","image/jpeg","image/webp","image/gif"].includes(A.toLowerCase())}function W$0(A){let Q=T2Q(A.title,A.filename),w=q1(Q);if(!w)throw Error("Could not derive an image id from the uploaded filename. Provide a title.");return{id:w,title:Q}}function tgA(A,Q){return`data:${A};base64,${Q.toString("base64")}`}function T2Q(A,Q){let w=A?.trim();if(w)return w;return Q.replace(/\.[^.]+$/,"").trim()||Q}var S2Q=f.object({uploadId:f.string().min(1),imageId:f.string().min(1).optional(),title:f.string().optional()});class tx0 extends D6{context;constructor(A,Q){super(A,{schema:S2Q,jobTypeName:"upload-promote"});this.context=Q}async process(A,Q,w){try{await this.reportProgress(w,{progress:10,message:"Reading uploaded image"});let $=await this.context.uploads.scoped(wh).read(A.uploadId);if(!H$0($.record.mediaType))throw Error("Only image uploads can be promoted to image entities");let B=W$0({filename:$.record.filename,...A.title!==void 0?{title:A.title}:{}}),X=A.imageId??B.id;await this.reportProgress(w,{progress:60,message:"Saving uploaded image"});let Y=new Date().toISOString(),Z=qf.createImageEntity({dataUrl:tgA($.record.mediaType,$.content),title:B.title,status:"draft",sourceUploadId:A.uploadId,sourceFilename:$.record.filename,sourceMediaType:$.record.mediaType,attachmentType:"uploaded"}),H=await pX({entityService:this.context.entityService,entity:{id:X,...Z,created:Y,updated:Y}});return await this.reportProgress(w,{progress:100,message:"Uploaded image promoted"}),{entityId:H.entityId,status:"created"}}catch($){if(A.imageId)await YD({entityService:this.context.entityService,entityType:"image",id:A.imageId,error:dA($)});return k8.failure($)}}summarizeDataForLog(A){return{uploadId:A.uploadId,imageId:A.imageId,hasTitle:A.title!==void 0}}}var egA={name:"@brains/image-plugin",version:"0.2.0-alpha.159",description:"Plugin for AI-powered image generation and management",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":"^1.3.14","@types/node":"^20.19.43",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},main:"./src/index.ts",private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var u2Q="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==",c2Q=f.object({defaultAspectRatio:f.enum(["1:1","16:9","9:16","4:3","3:4"]).default("16:9").describe("Default aspect ratio for generated images")});function DU(A){let Q=A?.trim();if(!Q)return;return Q}function l2Q(A){let Q=DU(A.prompt);if(Q)return Q;let w=DU(A.content);if(w&&!sx0(w))return w;return}function p2Q(A){let Q=A.attachmentType==="og-image"?"og":A.attachmentType;return q1(`${Q}-${A.sourceEntityType}-${A.sourceEntityId}`)}function AyA(A){let Q=DU(A.title)??(A.targetEntityId?`cover-${A.targetEntityId}`:A.prompt.slice(0,60).trim());return q1(Q)}async function i2Q(A,Q){let w=`${Q.attachmentType}:${Q.sourceEntityType}:${Q.sourceEntityId}:resolved-attachment`,$=await A.entityService.getEntity({entityType:Q.sourceEntityType,id:Q.sourceEntityId});return $?`${w}:${$.contentHash}`:w}function ex0(A,Q="generated"){let w=encodeURIComponent(A);return{mediaType:"image/png",url:`/api/chat/attachments/image?id=${w}`,downloadUrl:`/api/chat/attachments/image?id=${w}&download=1`,filename:`${A}.png`,source:{entityType:"image",entityId:A,attachmentType:Q}}}function d2Q(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 AR0 extends Zw{entityType=qf.entityType;schema=wl;adapter=qf;constructor(A={}){super("image",egA,A,c2Q)}getEntityTypeConfig(){return{embeddable:!1}}async interceptCreate(A,Q,w){if(A.from?.kind===wh.refKind)return this.promoteUpload(A,w);let $=l2Q(A),B=DU(A.targetEntityType),X=DU(A.targetEntityId),Y=B===this.entityType?X:void 0,Z=A.from;if(Z?.kind==="entity-attachment")return this.enqueueSourceImageRender({...A,from:Z},w);if(!B||!X||Y){if(!$)return{kind:"continue",input:A};let G=DU(A.title)??Y,q=AyA({prompt:$,...G&&{title:G}});await this.createPendingImage(w,{id:q,title:G??$.slice(0,60).trim(),alt:G??$.slice(0,60).trim(),attachmentType:"generated"});let V=await w.jobs.enqueue({type:"image-generate",data:{prompt:$,...G&&{title:G}}});return{kind:"handled",result:{success:!0,data:{entityId:q,status:"generating",jobId:V,attachment:ex0(q)}}}}let H=await T4(w.entityService,B,X,this.logger,"Target entity");if(!H.ok)return{kind:"handled",result:{success:!1,error:H.error}};if(!$)return{kind:"continue",input:{...A,targetEntityId:H.entity.id}};let W=Z$0(H.entity.content),K=AyA({prompt:$,...A.title&&{title:A.title},targetEntityId:H.entity.id});await this.createPendingImage(w,{id:K,title:A.title??`cover-${H.entity.id}`,alt:A.title??`cover-${H.entity.id}`,attachmentType:"generated",sourceEntityType:B,sourceEntityId:H.entity.id});let U=await w.jobs.enqueue({type:"image-generate",data:{prompt:$,...A.title&&{title:A.title},targetEntityType:B,targetEntityId:H.entity.id,entityTitle:typeof H.entity.metadata.title==="string"?H.entity.metadata.title:H.entity.id,...W&&{entityContent:W}}});return{kind:"handled",result:{success:!0,data:{entityId:K,status:"generating",jobId:U,attachment:ex0(K)}}}}async promoteUpload(A,Q){let w=A.from;if(w?.kind!==wh.refKind)return{kind:"handled",result:{success:!1,error:"Unsupported upload ref kind"}};let $=w.id,B;try{B=await Q.uploads.scoped(wh).readRecord($)}catch{return{kind:"handled",result:{success:!1,error:"Upload ref not found"}}}if(!H$0(B.mediaType))return{kind:"handled",result:{success:!1,error:"Only image uploads can be promoted to image entities"}};let X;try{X=W$0({filename:B.filename,...A.title!==void 0?{title:A.title}:{}})}catch(Z){return{kind:"handled",result:{success:!1,error:Z instanceof Error?Z.message:String(Z)}}}await this.createPendingImage(Q,{id:X.id,title:X.title,alt:X.title,sourceUploadId:$,sourceFilename:B.filename,sourceMediaType:B.mediaType,attachmentType:"uploaded"});let Y=await Q.jobs.enqueue({type:"upload-promote",data:{uploadId:$,imageId:X.id,title:X.title}});return{kind:"handled",result:{success:!0,data:{entityId:X.id,status:"generating",jobId:Y,attachment:d2Q({mediaType:B.mediaType,entityId:X.id,filename:B.filename})}}}}async enqueueSourceImageRender(A,Q){let w=DU(A.from.sourceEntityType),$=DU(A.from.sourceEntityId),B=DU(A.from.attachmentType);if(!w||!$||!B)return{kind:"handled",result:{success:!1,error:"Image source requires sourceEntityType, sourceEntityId, and attachmentType"}};let X=await T4(Q.entityService,w,$,this.logger,"Source entity");if(!X.ok)return{kind:"handled",result:{success:!1,error:X.error}};let Y=DU(A.targetEntityType),Z=DU(A.targetEntityId),H;if(Y&&Z){let q=await T4(Q.entityService,Y,Z,this.logger,"Target entity");if(!q.ok)return{kind:"handled",result:{success:!1,error:q.error}};H=q.entity.id}let W={sourceEntityType:w,sourceEntityId:X.entity.id,attachmentType:B},K=await i2Q(Q,W),U=p2Q(W);await this.createPendingImage(Q,{id:U,title:U,alt:U,sourceEntityType:W.sourceEntityType,sourceEntityId:W.sourceEntityId,attachmentType:B,dedupKey:K});let G=await Q.jobs.enqueue({type:"image-render-source",data:{...W,imageId:U,dedupKey:K,...A.replace===!0&&{replace:!0},...Y&&{targetEntityType:Y},...H&&{targetEntityId:H},...B==="og-image"&&{targetImageField:"ogImageId"}}});return{kind:"handled",result:{success:!0,data:{entityId:U,status:"generating",jobId:G,attachment:ex0(U,B)}}}}async createPendingImage(A,Q){let w=new Date().toISOString(),$=qf.createImageEntity({dataUrl:u2Q,title:Q.title,alt:Q.alt,status:"pending",attachmentType:Q.attachmentType,...Q.sourceEntityType&&{sourceEntityType:Q.sourceEntityType},...Q.sourceEntityId&&{sourceEntityId:Q.sourceEntityId},...Q.sourceUploadId&&{sourceUploadId:Q.sourceUploadId},...Q.sourceFilename&&{sourceFilename:Q.sourceFilename},...Q.sourceMediaType&&{sourceMediaType:Q.sourceMediaType},...Q.dedupKey&&{dedupKey:Q.dedupKey}});await k_({entityService:A.entityService,entity:{id:Q.id,...$,created:w,updated:w}})}async getInstructions(){return"Image entities store durable images. Standalone generated images are valid system_generate image calls with a prompt source and no target fields. A prompt source creates a new image; never use it to describe, analyze, or discuss an existing uploaded image. For uploaded-image discussion, answer directly from the attachment/context; if the user later asks to save that discussion as a note, create entityType note from prior-response or exact text. targetEntityType and targetEntityId are only for attaching the result to an existing entity as coverImageId. Cover images and OG/social preview images are distinct domain concepts: cover-image fields use coverImageId, while OG/Open Graph/social preview fields use ogImageId. Rendered OG/social preview images are deterministic attachment-source images with attachmentType og-image."}createGenerationHandler(A){return new f$0(A,this.logger)}async onRegister(A){A.entities.registerUploadSaveHandler({entityType:this.entityType,mediaTypes:["image/*"],handler:async(w)=>{let $=await this.promoteUpload({entityType:this.entityType,...w.title!==void 0?{title:w.title}:{},from:w.upload},A);return $.kind==="handled"?$.result:{success:!1,error:"Image upload save was not handled"}}});let Q=new f$0(A,this.logger);A.jobs.registerHandler("image-generate",Q),A.jobs.registerHandler("image-render-source",new ax0(A,this.logger)),A.jobs.registerHandler("upload-promote",new tx0(this.logger.child("UploadPromotionJobHandler"),A))}}function Yp(A={}){return new AR0(A)}fA();import{StdioServerTransport as r2Q}from"@modelcontextprotocol/sdk/server/stdio.js";C0();var n2Q=f.custom((A)=>typeof A==="object"&&A!==null&&("info"in A)&&typeof A.info==="function"&&("debug"in A)&&typeof A.debug==="function"&&("error"in A)&&typeof A.error==="function"&&("warn"in A)&&typeof A.warn==="function");function QyA(){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 QR0(){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 K$0(A){let Q=n2Q.safeParse(A);if(Q.success)return{info:(w,...$)=>Q.data.info(w,...$),debug:(w,...$)=>Q.data.debug(w,...$),error:(w,...$)=>Q.data.error(w,...$),warn:(w,...$)=>Q.data.warn(w,...$)};return QR0()}class qU{static instance=null;mcpServer=null;transport=null;config;logger;static getInstance(A){return qU.instance??=new qU(A),qU.instance}static resetInstance(){if(qU.instance)qU.instance.stop(),qU.instance=null}static createFresh(A){return new qU(A)}constructor(A={}){this.config=A,this.logger=this.config.logger?K$0(this.config.logger):QyA()}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 r2Q,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 o2Q,timingSafeEqual as s2Q}from"crypto";import{WebStandardStreamableHTTPServerTransport as a2Q}from"@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";import{isInitializeRequest as t2Q}from"@modelcontextprotocol/sdk/types.js";C0();var e2Q=1800000,AQQ=60000,QQQ={"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"},wQQ=f.looseObject({code:f.string().optional()});function $QQ(A){let Q=new URL(A.url),$=A.headers.get("x-forwarded-proto")?.split(",")[0]?.trim(),B=A.headers.get("x-forwarded-host")??A.headers.get("host");if(!B)return Q.origin;return`${$??Q.protocol.replace(":","")}://${B}`}class j3{static instance=null;transports={};sessionLastActivity=new Map;mcpServer=null;mcpTransport=null;server=null;boundPort=null;evictionTimer=null;config;logger;authConfig;sessionIdleTtlMs;constructor(A={}){if(this.config=A,this.logger=this.config.logger?K$0(this.config.logger):QR0(),this.authConfig=A.auth??{},this.sessionIdleTtlMs=A.sessionIdleTtlMs??e2Q,this.evictionTimer=setInterval(()=>this.evictIdleSessions(),Math.min(this.sessionIdleTtlMs,AQQ)),this.evictionTimer.unref(),!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 j3.instance??=new j3(A),j3.instance}static resetInstance(){j3.instance=null}static createFresh(A){return new j3(A)}withCors(A){let Q=new Headers(A.headers);for(let[w,$]of Object.entries(QQQ))Q.set(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,w){let $=this.createJsonResponse({jsonrpc:"2.0",error:{code:-32001,message:A},id:null},Q);if(!w)return $;let B=new Headers($.headers);return B.set("WWW-Authenticate",w),new Response($.body,{status:$.status,statusText:$.statusText,headers:B})}getBearerChallenge(A,Q={}){let w={...this.authConfig.token?{}:{resource_metadata:`${$QQ(A)}/.well-known/oauth-protected-resource`},...Q};return`Bearer ${Object.entries(w).map(([B,X])=>`${B}="${BQQ(X)}"`).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 w=A.headers.get("authorization");if(!w?.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){let $=w.substring(7);if(!XQQ($,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"),{token:$,clientId:"static-token-client",scopes:this.authConfig.requiredScopes??[],extra:{subject:"static-token-operator"}}}try{let $=await this.authConfig.verifyBearerToken?.(A);if(!$)return this.logger.warn("Authentication failed: Invalid token"),this.getAuthErrorResponse("Unauthorized: Invalid token",401,this.getBearerChallenge(A,{error:"invalid_token"}));let B=this.authConfig.requiredScopes??[],X=B.filter((Y)=>!$.scope?.includes(Y));if(X.length>0)return this.logger.warn(`Authentication failed: Missing required scope(s): ${X.join(", ")}`),this.getAuthErrorResponse("Forbidden: Missing required scope",403,this.getBearerChallenge(A,{error:"insufficient_scope",scope:B.join(" ")}));return this.logger.debug("Authentication successful"),{token:w.substring(7),clientId:$.subject,scopes:$.scope??[],extra:{subject:$.subject}}}catch($){return this.logger.warn("Authentication failed: Invalid token",$),this.getAuthErrorResponse("Unauthorized: Invalid token",401,this.getBearerChallenge(A,{error:"invalid_token"}))}}touchSession(A){this.sessionLastActivity.set(A,Date.now())}evictIdleSessions(){let A=Date.now();for(let[Q,w]of this.sessionLastActivity){if(A-w<this.sessionIdleTtlMs)continue;this.logger.info(`Evicting idle session ${Q}`),this.sessionLastActivity.delete(Q);let $=this.transports[Q];if($)delete this.transports[Q],$.close().catch((B)=>{this.logger.error(`Error closing idle transport for session ${Q}:`,B)})}}async handleMcpRequest(A,Q){let w=A.headers.get("mcp-session-id")??void 0;if(A.method==="GET"){if(!w||!this.transports[w])return this.createTextResponse("Invalid or missing session ID",400);return this.touchSession(w),this.logger.debug(`GET /mcp - SSE stream for session ${w}`),this.withCors(await this.transports[w].handleRequest(A,{authInfo:Q}))}if(A.method==="DELETE"){if(!w||!this.transports[w])return this.createTextResponse("Invalid or missing session ID",400);return this.logger.info(`DELETE /mcp - Terminating session ${w}`),this.withCors(await this.transports[w].handleRequest(A,{authInfo:Q}))}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 $;try{$=await A.json()}catch{return this.createJsonResponse({jsonrpc:"2.0",error:{code:-32700,message:"Parse error: Invalid JSON body"},id:null},400)}this.logger.debug(`POST /mcp - Session: ${w??"new"}`);try{let B;if(w&&this.transports[w])B=this.transports[w],this.touchSession(w);else if(!w&&t2Q($))B=new a2Q({sessionIdGenerator:()=>o2Q(),onsessioninitialized:(Y)=>{this.logger.info(`Session initialized: ${Y}`),this.transports[Y]=B,this.touchSession(Y)},onsessionclosed:(Y)=>{this.logger.info(`Session closed: ${Y}`),delete this.transports[Y],this.sessionLastActivity.delete(Y)}}),await(this.mcpTransport?this.mcpTransport.createMcpServer():this.mcpServer).connect(B);else return this.createJsonResponse({jsonrpc:"2.0",error:{code:-32000,message:"Bad Request: Server not initialized"},id:null},400);return this.withCors(await B.handleRequest(A,{parsedBody:$,authInfo:Q}))}catch(B){return this.logger.error("MCP transport error:",B),this.createJsonResponse({jsonrpc:"2.0",error:{code:-32603,message:"Internal error"}},500)}}async handleRequest(A){let Q=new URL(A.url);this.logger.debug(`${A.method} ${Q.pathname}`);let w=await this.authenticate(A);if(w instanceof Response)return w;let $=w??void 0;if(Q.pathname==="/health")return this.createJsonResponse({status:"ok",transport:"streamable-http",timestamp:new Date().toISOString()});if(Q.pathname==="/status")return this.createJsonResponse({status:"ok",sessions:Object.keys(this.transports).length});if(Q.pathname==="/mcp")return this.handleMcpRequest(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")}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:(w)=>this.handleRequest(w)}),this.boundPort=this.server.port??A,this.logger.info(`StreamableHTTP server listening on http://${Q}:${this.boundPort}/mcp`)}catch(w){let $=wQQ.safeParse(w);if($.success&&$.data.code==="EADDRINUSE")this.logger.error(`Port ${A} is already in use`);throw w}}async stop(){if(this.evictionTimer)clearInterval(this.evictionTimer),this.evictionTimer=null;this.sessionLastActivity.clear();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 BQQ(A){return A.replace(/["\\]/g,(Q)=>`\\${Q}`)}function XQQ(A,Q){let w=Buffer.from(A),$=Buffer.from(Q);if(w.length!==$.length)return!1;return s2Q(w,$)}import{randomUUID as UQQ}from"crypto";import{chmod as YQQ,mkdir as ZQQ,readFile as fQQ,rename as wyA,writeFile as HQQ}from"fs/promises";import{dirname as WQQ}from"path";class tX{filePath;parse;empty;logError;onCorrupt;writeQueue=Promise.resolve();constructor(A){this.filePath=A.filePath,this.parse=A.parse,this.empty=A.empty,this.onCorrupt=A.onCorrupt??"quarantine",this.logError=A.logError??((Q,w)=>{console.error(Q,w)})}async enqueueWrite(A){return this.writeQueue=this.writeQueue.then(A,A),this.writeQueue}async read(){let A;try{A=await fQQ(this.filePath,"utf8")}catch(Q){if(Q.code==="ENOENT")return this.empty();throw Q}try{return this.parse(JSON.parse(A))}catch(Q){if(this.onCorrupt==="throw")throw Error(`Corrupt JSON store at ${this.filePath}; refusing to start empty. Inspect or remove the file to proceed.`,{cause:Q});return await this.quarantineCorruptFile(Q),this.empty()}}async write(A){await ZQQ(WQQ(this.filePath),{recursive:!0,mode:448});let Q=`${this.filePath}.tmp`;await HQQ(Q,`${JSON.stringify(A,null,2)}
1721
1721
  `,{mode:384}),await YQQ(Q,384),await wyA(Q,this.filePath)}async quarantineCorruptFile(A){let Q=`${this.filePath}.corrupt-${process.pid}`;this.logError(`Corrupt JSON store at ${this.filePath}; moving it to ${Q} and starting from an empty store`,A);try{await wyA(this.filePath,Q)}catch(w){this.logError(`Failed to quarantine corrupt JSON store at ${this.filePath}`,w)}}}function $h(A){let Q=A.toISOString();return Q.substring(0,Q.indexOf("T"))}function U$0(){let A=new Date;return A.setDate(A.getDate()-1),A}function $yA(A){let Q=new Date;return Q.setDate(Q.getDate()-A),Q}function x9(){return Math.floor(Date.now()/1000)}C0();import{join as GQQ}from"path";function ByA(A){let Q=A.toLowerCase();return Q==="localhost"||Q==="[::1]"||Q==="::1"||Q.startsWith("127.")}function XyA(A){try{return new URL(A)}catch{return}}function wR0(A,Q){if(A===Q)return!0;let w=XyA(A),$=XyA(Q);if(!w||!$)return!1;if(!ByA(w.hostname)||!ByA($.hostname))return!1;return w.protocol===$.protocol&&w.port===$.port&&KQQ(w.pathname,$.pathname)&&w.search===$.search&&w.hash===$.hash}function KQQ(A,Q){return A===Q||A===`${Q}/debug`||Q===`${A}/debug`}function $R0(A,Q){return A.some((w)=>wR0(w,Q))}var DQQ="oauth-auth-codes.json",qQQ=600,zQQ=f.looseObject({code:f.string(),client_id:f.string(),redirect_uri:f.string(),code_challenge:f.string(),code_challenge_method:f.literal("S256"),scope:f.string().optional(),subject:f.string(),created_at:f.number(),expires_at:f.number(),consumed_at:f.number().optional()}).transform((A)=>({code:A.code,client_id:A.client_id,redirect_uri:A.redirect_uri,code_challenge:A.code_challenge,code_challenge_method:A.code_challenge_method,...A.scope!==void 0?{scope:A.scope}:{},subject:A.subject,created_at:A.created_at,expires_at:A.expires_at,...A.consumed_at!==void 0?{consumed_at:A.consumed_at}:{}})),VQQ=f.looseObject({codes:f.array(f.unknown()).optional()});function JQQ(A){let Q=VQQ.safeParse(A);if(!Q.success)return{codes:[]};return{codes:Q.data.codes?.flatMap(IQQ)??[]}}function IQQ(A){let Q=zQQ.safeParse(A);return Q.success?[Q.data]:[]}async function FQQ(A){let Q=await crypto.subtle.digest("SHA-256",new TextEncoder().encode(A));return Buffer.from(Q).toString("base64url")}class G$0{store;constructor(A){this.store=new tX({filePath:GQQ(A.storageDir,A.storeFile??DQQ),parse:JQQ,empty:()=>({codes:[]})})}async createCode(A){let Q=x9(),w={code:`ocd_${UQQ()}`,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+qQQ};return await this.store.enqueueWrite(async()=>{let $=await this.store.read();$.codes=$.codes.filter((B)=>B.expires_at>Q),$.codes.push(w),await this.store.write($)}),w}async consumeCode(A){let Q=x9(),w;if(await this.store.enqueueWrite(async()=>{let $=await this.store.read(),B=$.codes.findIndex((Z)=>Z.code===A.code),X=B>=0?$.codes[B]:void 0;if(!X)throw new zU("Authorization code not found");if(X.consumed_at!==void 0)throw new zU("Authorization code already consumed");if(X.expires_at<=Q)throw new zU("Authorization code expired");if(X.client_id!==A.clientId)throw new zU("Authorization code client mismatch");if(!wR0(X.redirect_uri,A.redirectUri))throw new zU("Authorization code redirect URI mismatch");let Y=await FQQ(A.codeVerifier);if(X.code_challenge!==Y)throw new zU("PKCE verification failed");w={...X,consumed_at:Q},$.codes[B]=w,await this.store.write($)}),!w)throw new zU("Authorization code not consumed");return w}}class zU extends Error{constructor(A){super(A);this.name="InvalidGrantError"}}import{randomUUID as YyA}from"crypto";C0();import{join as bQQ}from"path";var LQQ="oauth-clients.json",kQQ=f.enum(["none","client_secret_basic","client_secret_post"]),_QQ=f.object({redirect_uris:f.array(f.url()).min(1),token_endpoint_auth_method:kQQ.default("none"),grant_types:f.array(f.enum(["authorization_code","refresh_token"])).default(["authorization_code","refresh_token"]),response_types:f.array(f.literal("code")).default(["code"]),scope:f.string().optional(),client_name:f.string().optional(),client_uri:f.url().optional(),logo_uri:f.url().optional(),contacts:f.array(f.string()).optional()}),NQQ=f.looseObject({client_id:f.string(),client_id_issued_at:f.number(),redirect_uris:f.array(f.string()),token_endpoint_auth_method:f.string().optional(),grant_types:f.array(f.string()).optional(),response_types:f.array(f.string()).optional(),scope:f.string().optional(),client_name:f.string().optional(),client_uri:f.string().optional(),logo_uri:f.string().optional(),contacts:f.array(f.string()).optional(),client_secret:f.string().optional(),client_secret_expires_at:f.number().optional()}).transform((A)=>({client_id:A.client_id,client_id_issued_at:A.client_id_issued_at,redirect_uris:A.redirect_uris,token_endpoint_auth_method:A.token_endpoint_auth_method??"none",grant_types:A.grant_types??["authorization_code","refresh_token"],response_types:A.response_types??["code"],...A.scope!==void 0?{scope:A.scope}:{},...A.client_name!==void 0?{client_name:A.client_name}:{},...A.client_uri!==void 0?{client_uri:A.client_uri}:{},...A.logo_uri!==void 0?{logo_uri:A.logo_uri}:{},...A.contacts!==void 0?{contacts:A.contacts}:{},...A.client_secret!==void 0?{client_secret:A.client_secret}:{},...A.client_secret_expires_at!==void 0?{client_secret_expires_at:A.client_secret_expires_at}:{}})),jQQ=f.looseObject({clients:f.array(f.unknown()).optional()});function PQQ(){return`ocs_${YyA().replaceAll("-","")}`}function MQQ(A){let Q=jQQ.safeParse(A);if(!Q.success)return{clients:[]};return{clients:Q.data.clients?.flatMap(OQQ)??[]}}function OQQ(A){let Q=NQQ.safeParse(A);return Q.success?[Q.data]:[]}class D$0{store;constructor(A){this.store=new tX({filePath:bQQ(A.storageDir,A.storeFile??LQQ),parse:MQQ,empty:()=>({clients:[]})})}async registerClient(A){let Q=_QQ.safeParse(A);if(!Q.success)throw new Zp(Q.error.message);let w=Q.data,$=x9(),B=`oc_${YyA()}`,X=w.token_endpoint_auth_method==="none",Y={client_id:B,client_id_issued_at:$,redirect_uris:w.redirect_uris,token_endpoint_auth_method:w.token_endpoint_auth_method,grant_types:w.grant_types,response_types:w.response_types,...w.scope?{scope:w.scope}:{},...w.client_name?{client_name:w.client_name}:{},...w.client_uri?{client_uri:w.client_uri}:{},...w.logo_uri?{logo_uri:w.logo_uri}:{},...w.contacts?{contacts:w.contacts}:{},...!X?{client_secret:PQQ(),client_secret_expires_at:0}:{}};return await this.store.enqueueWrite(async()=>{let Z=await this.store.read();Z.clients.push(Y),await this.store.write(Z)}),Y}async getClient(A){return(await this.store.read()).clients.find((w)=>w.client_id===A)}}class Zp extends Error{constructor(A){super(A);this.name="InvalidClientMetadataError"}}C0();import{createHash as ZyA,generateKeyPairSync as xQQ}from"crypto";import{mkdir as RQQ,readFile as fyA,writeFile as vQQ,chmod as hQQ}from"fs/promises";import{dirname as CQQ,join as HyA}from"path";var gQQ="oauth-signing-key.jwk",yQQ="a2a-signing-key.jwk",WyA=f.object({kty:f.literal("EC"),crv:f.literal("P-256"),x:f.string(),y:f.string(),d:f.string(),kid:f.string().optional()}),KyA=f.object({kty:f.literal("OKP"),crv:f.literal("Ed25519"),x:f.string(),d:f.string(),kid:f.string().optional()});function EQQ(A){let Q=JSON.stringify({crv:A.crv,kty:A.kty,x:A.x,y:A.y});return ZyA("sha256").update(Q).digest("base64url")}function TQQ(A){let Q=JSON.stringify({crv:A.crv,kty:A.kty,x:A.x});return ZyA("sha256").update(Q).digest("base64url")}function SQQ(A){return{kty:"EC",crv:"P-256",x:A.x,y:A.y,kid:A.kid,use:"sig",alg:"ES256"}}function mQQ(A){return{kty:"OKP",crv:"Ed25519",x:A.x,kid:A.kid,use:"sig",alg:"EdDSA"}}async function uQQ(){let A=await crypto.subtle.generateKey({name:"ECDSA",namedCurve:"P-256"},!0,["sign","verify"]),Q=WyA.safeParse(await crypto.subtle.exportKey("jwk",A.privateKey));if(!Q.success)throw Error("Generated OAuth signing key is not a P-256 private JWK");return UyA(Q.data)}function cQQ(){let{privateKey:A}=xQQ("ed25519"),Q=KyA.safeParse(A.export({format:"jwk"}));if(!Q.success)throw Error("Generated A2A signing key is not an Ed25519 private JWK");return GyA(Q.data)}function UyA(A){return{kty:"EC",crv:"P-256",x:A.x,y:A.y,d:A.d,kid:A.kid??EQQ(A),use:"sig",alg:"ES256"}}function GyA(A){return{kty:"OKP",crv:"Ed25519",x:A.x,d:A.d,kid:A.kid??TQQ(A),use:"sig",alg:"EdDSA"}}class q$0{keyFile;cachedKey;loadPromise;constructor(A){this.keyFile=HyA(A.storageDir,A.keyFile??gQQ)}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 uQQ();return await DyA(this.keyFile,Q),Q}async getPublicJwk(){return SQQ(await this.getPrivateJwk())}async readExistingKey(){try{let A=WyA.safeParse(JSON.parse(await fyA(this.keyFile,"utf8")));if(!A.success)throw Error(`OAuth signing key at ${this.keyFile} is not a private P-256 JWK`);return UyA(A.data)}catch(A){if(qyA(A))return;throw A}}}class BR0{keyFile;cachedKey;loadPromise;constructor(A){this.keyFile=HyA(A.storageDir,A.keyFile??yQQ)}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=cQQ();return await DyA(this.keyFile,Q),Q}async getPublicJwk(){return mQQ(await this.getPrivateJwk())}async readExistingKey(){try{let A=KyA.safeParse(JSON.parse(await fyA(this.keyFile,"utf8")));if(!A.success)throw Error(`A2A signing key at ${this.keyFile} is not a private Ed25519 JWK`);return GyA(A.data)}catch(A){if(qyA(A))return;throw A}}}async function DyA(A,Q){await RQQ(CQQ(A),{recursive:!0,mode:448}),await vQQ(A,`${JSON.stringify(Q,null,2)}
1722
1722
  `,{mode:384}),await hQQ(A,384)}function qyA(A){return A instanceof Error&&"code"in A&&A.code==="ENOENT"}var mQ={};x6(mQ,{trimPadding:()=>VyA,toUTF8String:()=>aQQ,toBuffer:()=>nQQ,toBase64:()=>oQQ,isBase64URL:()=>eQQ,isBase64:()=>tQQ,fromUTF8String:()=>sQQ,fromBuffer:()=>rQQ});var zyA=(A)=>{let Q=typeof Uint8Array>"u"?[]:new Uint8Array(256),w=64;for(let $=0;$<64;$++)Q[A.charCodeAt($)]=$;return Q},lQQ=zyA("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"),pQQ=zyA("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"),iQQ=/^[-A-Za-z0-9\-_]*$/,dQQ=/^[-A-Za-z0-9+/]*={0,3}$/,kD={};kD.toArrayBuffer=(A,Q)=>{let w=A.length,$=A.length*0.75,B,X=0,Y,Z,H,W;if(A[A.length-1]==="="){if($--,A[A.length-2]==="=")$--}let K=new ArrayBuffer($),U=new Uint8Array(K),G=Q?pQQ:lQQ;for(B=0;B<w;B+=4)Y=G[A.charCodeAt(B)],Z=G[A.charCodeAt(B+1)],H=G[A.charCodeAt(B+2)],W=G[A.charCodeAt(B+3)],U[X++]=Y<<2|Z>>4,U[X++]=(Z&15)<<4|H>>2,U[X++]=(H&3)<<6|W&63;return K};kD.fromArrayBuffer=(A,Q)=>{let w=new Uint8Array(A),$,B="",X=w.length,Y=Q?"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_":"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";for($=0;$<X;$+=3)B+=Y[w[$]>>2],B+=Y[(w[$]&3)<<4|w[$+1]>>4],B+=Y[(w[$+1]&15)<<2|w[$+2]>>6],B+=Y[w[$+2]&63];let Z=X%3;if(Z===2)B=B.substring(0,B.length-1)+(Q?"":"=");else if(Z===1)B=B.substring(0,B.length-2)+(Q?"":"==");return B};kD.toString=(A,Q)=>{return new TextDecoder().decode(kD.toArrayBuffer(A,Q))};kD.fromString=(A,Q)=>{return kD.fromArrayBuffer(new TextEncoder().encode(A),Q)};kD.validate=(A,Q)=>{if(!(typeof A==="string"||A instanceof String))return!1;try{return Q?iQQ.test(A):dQQ.test(A)}catch(w){return!1}};kD.base64=kD;var P3=kD;function nQQ(A,Q="base64url"){let w=P3.toArrayBuffer(A,Q==="base64url");return new Uint8Array(w)}function rQQ(A,Q="base64url"){let w=new Uint8Array(A);return P3.fromArrayBuffer(w.buffer,Q==="base64url")}function oQQ(A){let Q=P3.toArrayBuffer(A,!0);return P3.fromArrayBuffer(Q)}function sQQ(A){return P3.fromString(A,!0)}function aQQ(A){return P3.toString(A,!0)}function tQQ(A){return P3.validate(A,!1)}function eQQ(A){return A=VyA(A),P3.validate(A,!0)}function VyA(A){return A.replace(/=/g,"")}var eX={};x6(eX,{encode:()=>FwQ,decodeFirst:()=>IwQ});function Bh(A,Q,w){if(Q<24)return[Q,1];let $=A.byteLength-w-1,B=new DataView(A.buffer,w+1),X,Y=0;switch(Q){case 24:{if($>0)X=B.getUint8(0),Y=2;break}case 25:{if($>1)X=B.getUint16(0,!1),Y=3;break}case 26:{if($>3)X=B.getUint32(0,!1),Y=5;break}case 27:{if($>7){let Z=B.getBigUint64(0,!1);if(Z>=24n&&Z<=Number.MAX_SAFE_INTEGER)return[Number(Z),9]}break}}if(X&&X>=24)return[X,Y];throw Error("Length not supported or not well formed")}var z$0=0,fp=1,XR0=2,YR0=3,ZR0=4,fR0=5,HR0=6,JyA=7;function _D(A,Q){let w=A<<5;if(Q<0)throw Error("CBOR Data Item argument must not be negative");let $;if(typeof Q=="number"){if(!Number.isInteger(Q))throw Error("CBOR Data Item argument must be an integer");$=BigInt(Q)}else $=Q;if(A==fp){if($==0n)throw Error("CBOR Data Item argument cannot be zero when negative");$=$-1n}if($>18446744073709551615n)throw Error("CBOR number out of range");let B=new Uint8Array(8);if(new DataView(B.buffer).setBigUint64(0,$,!1),$<=23)return[w|B[7]];else if($<=255)return[w|24,B[7]];else if($<=65535)return[w|25,...B.slice(6)];else if($<=4294967295)return[w|26,...B.slice(4)];else return[w|27,...B]}class J$0{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 IyA(A,Q,w){return Bh(A,Q,w)}function AwQ(A,Q,w){let[$,B]=IyA(A,Q,w);return[-$-1,B]}function FyA(A,Q,w){let[$,B]=Bh(A,Q,w),X=w+B;return[new Uint8Array(A.buffer.slice(X,X+$)),B+$]}var QwQ=new TextDecoder;function wwQ(A,Q,w){let[$,B]=FyA(A,Q,w);return[QwQ.decode($),B]}function $wQ(A,Q,w){if(Q===0)return[[],1];let[$,B]=Bh(A,Q,w),X=B,Y=[];for(let Z=0;Z<$;Z++){if(A.byteLength-w-X<=0)throw Error("array is not supported or well formed");let[W,K]=JN(A,w+X);Y.push(W),X+=K}return[Y,X]}var V$0="Map is not supported or well formed";function BwQ(A,Q,w){if(Q===0)return[new Map,1];let[$,B]=Bh(A,Q,w),X=B,Y=new Map;for(let Z=0;Z<$;Z++){let H=A.byteLength-w-X;if(H<=0)throw Error(V$0);let[W,K]=JN(A,w+X);if(X+=K,H-=K,H<=0)throw Error(V$0);if(typeof W!=="string"&&typeof W!=="number")throw Error(V$0);if(Y.has(W))throw Error(V$0);let[U,G]=JN(A,w+X);X+=G,Y.set(W,U)}return[Y,X]}function XwQ(A,Q){if(Q+3>A.byteLength)throw Error("CBOR stream ended before end of Float 16");let w=A.getUint16(Q+1,!1);if(w==31744)return[1/0,3];else if(w==32256)return[NaN,3];else if(w==64512)return[-1/0,3];throw Error("Float16 data is unsupported")}function YwQ(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 ZwQ(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 fwQ(A,Q,w){let[$,B]=Bh(A,Q,w),[X,Y]=JN(A,w+B);return[new J$0($,X),B+Y]}function JN(A,Q){if(Q>=A.byteLength)throw Error("CBOR stream ended before tag value");let w=A.getUint8(Q),$=w>>5,B=w&31;switch($){case z$0:return IyA(A,B,Q);case fp:return AwQ(A,B,Q);case XR0:return FyA(A,B,Q);case YR0:return wwQ(A,B,Q);case ZR0:return $wQ(A,B,Q);case fR0:return BwQ(A,B,Q);case HR0:return fwQ(A,B,Q);case JyA:switch(B){case 20:return[!1,1];case 21:return[!0,1];case 22:return[null,1];case 23:return[void 0,1];case 25:return XwQ(A,Q);case 26:return YwQ(A,Q);case 27:return ZwQ(A,Q)}}throw Error(`Unsupported or not well formed at ${Q}`)}function HwQ(A){if(A===!0)return 245;else if(A===!1)return 244;else if(A===null)return 246;return 247}function WwQ(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 KwQ(A){if(typeof A=="number"){if(Number.isSafeInteger(A))if(A<0)return _D(fp,Math.abs(A));else return _D(z$0,A);return[WwQ(A)]}else if(A<0n)return _D(fp,A*-1n);else return _D(z$0,A)}var UwQ=new TextEncoder;function GwQ(A,Q){Q.push(..._D(YR0,A.length)),Q.push(UwQ.encode(A))}function DwQ(A,Q){Q.push(..._D(XR0,A.length)),Q.push(A)}function qwQ(A,Q){Q.push(..._D(ZR0,A.length));for(let w of A)Hp(w,Q)}function zwQ(A,Q){Q.push(new Uint8Array(_D(fR0,A.size)));for(let[w,$]of A.entries())Hp(w,Q),Hp($,Q)}function VwQ(A,Q){Q.push(..._D(HR0,A.tag)),Hp(A.value,Q)}function Hp(A,Q){if(typeof A=="boolean"||A===null||A==null){Q.push(HwQ(A));return}if(typeof A=="number"||typeof A=="bigint"){Q.push(...KwQ(A));return}if(typeof A=="string"){GwQ(A,Q);return}if(A instanceof Uint8Array){DwQ(A,Q);return}if(Array.isArray(A)){qwQ(A,Q);return}if(A instanceof Map){zwQ(A,Q);return}if(A instanceof J$0){VwQ(A,Q);return}throw Error("Not implemented")}function WR0(A,Q){if(A.byteLength===0||A.byteLength<=Q||Q<0)throw Error("No data");if(A instanceof Uint8Array)return JN(new DataView(A.buffer),Q);else if(A instanceof ArrayBuffer)return JN(new DataView(A),Q);return JN(A,Q)}function KR0(A){let Q=[];Hp(A,Q);let w=0;for(let X of Q)if(typeof X=="number")w+=1;else w+=X.length;let $=new Uint8Array(w),B=0;for(let X of Q)if(typeof X=="number")$[B]=X,B+=1;else $.set(X,B),B+=X.length;return $}function IwQ(A){let Q=new Uint8Array(A),w=WR0(Q,0),[$]=w;return $}function FwQ(A){return KR0(A)}var jD={};x6(jD,{verify:()=>wuA,getRandomValues:()=>NyA,digest:()=>_yA});function byA(A){let Q=A.get(vQ.kty);return UR0(Q)&&Q===zf.OKP}function KF(A){let Q=A.get(vQ.kty);return UR0(Q)&&Q===zf.EC2}function Xh(A){let Q=A.get(vQ.kty);return UR0(Q)&&Q===zf.RSA}var vQ;(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"})(vQ||(vQ={}));var zf;(function(A){A[A.OKP=1]="OKP",A[A.EC2=2]="EC2",A[A.RSA=3]="RSA"})(zf||(zf={}));function UR0(A){return Object.values(zf).indexOf(A)>=0}var n4;(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"})(n4||(n4={}));function LyA(A){return Object.values(n4).indexOf(A)>=0}var Gw;(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"})(Gw||(Gw={}));function ND(A){return Object.values(Gw).indexOf(A)>=0}function UF(A){if([Gw.RS1].indexOf(A)>=0)return"SHA-1";else if([Gw.ES256,Gw.PS256,Gw.RS256].indexOf(A)>=0)return"SHA-256";else if([Gw.ES384,Gw.PS384,Gw.RS384].indexOf(A)>=0)return"SHA-384";else if([Gw.ES512,Gw.PS512,Gw.RS512,Gw.EdDSA].indexOf(A)>=0)return"SHA-512";throw Error(`Could not map COSE alg value of ${A} to a WebCrypto alg`)}var Wp=void 0;function LW(){return new Promise((Q,w)=>{if(Wp)return Q(Wp);let $=LwQ.stubThisGlobalThisCrypto();if($)return Wp=$,Q(Wp);return w(new kyA)})}class kyA extends Error{constructor(){super("An instance of the Crypto API could not be located");this.name="MissingWebCrypto"}}var LwQ={stubThisGlobalThisCrypto:()=>globalThis.crypto,setCachedCrypto:(A)=>{Wp=A}};async function _yA(A,Q){let w=await LW(),$=UF(Q),B=await w.subtle.digest($,A);return new Uint8Array(B)}async function NyA(A){return(await LW()).getRandomValues(A),A}async function Yh(A){let Q=await LW(),{keyData:w,algorithm:$}=A;return Q.subtle.importKey("jwk",w,$,!1,["verify"])}async function I$0(A){let{cosePublicKey:Q,signature:w,data:$,shaHashOverride:B}=A,X=await LW(),Y=Q.get(vQ.alg),Z=Q.get(vQ.crv),H=Q.get(vQ.x),W=Q.get(vQ.y);if(!Y)throw Error("Public key was missing alg (EC2)");if(!Z)throw Error("Public key was missing crv (EC2)");if(!H)throw Error("Public key was missing x (EC2)");if(!W)throw Error("Public key was missing y (EC2)");let K;if(Z===n4.P256)K="P-256";else if(Z===n4.P384)K="P-384";else if(Z===n4.P521)K="P-521";else throw Error(`Unexpected COSE crv value of ${Z} (EC2)`);let U={kty:"EC",crv:K,x:mQ.fromBuffer(H),y:mQ.fromBuffer(W),ext:!1},q=await Yh({keyData:U,algorithm:{name:"ECDSA",namedCurve:K}}),V=UF(Y);if(B)V=UF(B);let I={name:"ECDSA",hash:{name:V}};return X.subtle.verify(I,q,w,$)}function GR0(A){if([Gw.EdDSA].indexOf(A)>=0)return"Ed25519";else if([Gw.ES256,Gw.ES384,Gw.ES512,Gw.ES256K].indexOf(A)>=0)return"ECDSA";else if([Gw.RS256,Gw.RS384,Gw.RS512,Gw.RS1].indexOf(A)>=0)return"RSASSA-PKCS1-v1_5";else if([Gw.PS256,Gw.PS384,Gw.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 F$0(A){let{cosePublicKey:Q,signature:w,data:$,shaHashOverride:B}=A,X=await LW(),Y=Q.get(vQ.alg),Z=Q.get(vQ.n),H=Q.get(vQ.e);if(!Y)throw Error("Public key was missing alg (RSA)");if(!ND(Y))throw Error(`Public key had invalid alg ${Y} (RSA)`);if(!Z)throw Error("Public key was missing n (RSA)");if(!H)throw Error("Public key was missing e (RSA)");let W={kty:"RSA",alg:"",n:mQ.fromBuffer(Z),e:mQ.fromBuffer(H),ext:!1},K={name:GR0(Y),hash:{name:UF(Y)}},U={name:GR0(Y)};if(B)K.hash.name=UF(B);if(K.name==="RSASSA-PKCS1-v1_5"){if(K.hash.name==="SHA-256")W.alg="RS256";else if(K.hash.name==="SHA-384")W.alg="RS384";else if(K.hash.name==="SHA-512")W.alg="RS512";else if(K.hash.name==="SHA-1")W.alg="RS1"}else if(K.name==="RSA-PSS"){let q=0;if(K.hash.name==="SHA-256")W.alg="PS256",q=32;else if(K.hash.name==="SHA-384")W.alg="PS384",q=48;else if(K.hash.name==="SHA-512")W.alg="PS512",q=64;U.saltLength=q}else throw Error(`Unexpected RSA key algorithm ${Y} (${K.name})`);let G=await Yh({keyData:W,algorithm:K});return X.subtle.verify(U,G,w,$)}function b$0(A){let Q=c2.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 d5(A){let Q;if(typeof A==="string")if(mQ.isBase64URL(A))Q=mQ.toBase64(A);else if(mQ.isBase64(A))Q=A;else throw Error("Certificate is not a valid base64 or base64url string");else Q=mQ.fromBuffer(A,"base64");let w="";for(let $=0;$<Math.ceil(Q.length/64);$+=1){let B=64*$;w+=`${Q.substr(B,64)}
1723
1723
  `}return w=`-----BEGIN CERTIFICATE-----
@@ -2289,14 +2289,14 @@ ${k}`)}if($!==void 0&&X?.algorithms!==void 0){let J=X.algorithms.map((k)=>k.alg)
2289
2289
  </form>
2290
2290
  </main>
2291
2291
  </body>
2292
- </html>`}function ri(A){let Q=`${new URL(A.url).pathname}${new URL(A.url).search}`;return new Response(MC0(Q,"Operator login required"),{status:401,headers:{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store"}})}function uD(A){return A.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;")}import{randomUUID as o8Q}from"crypto";function qcA(A){return Buffer.from(JSON.stringify(A)).toString("base64url")}function r8Q(A){let Q=new Uint8Array(A);if(Q.length===64)return Q;if(Q[0]!==48)return Q;let w=2;if(Q[1]&&Q[1]>128)w+=Q[1]-128;if(Q[w]!==2)throw Error("Invalid DER ECDSA signature");let $=Q[w+1];if($===void 0)throw Error("Invalid DER ECDSA signature");let B=w+2,X=Q.slice(B,B+$);if(w=B+$,Q[w]!==2)throw Error("Invalid DER ECDSA signature");let Y=Q[w+1];if(Y===void 0)throw Error("Invalid DER ECDSA signature");let Z=w+2,H=Q.slice(Z,Z+Y);return new Uint8Array([...zcA(X),...zcA(H)])}function zcA(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 w=new Uint8Array(32);return w.set(Q,32-Q.length),w}async function xC0(A,Q){let w={typ:"JWT",alg:"ES256",kid:A.kid},$=`${qcA(w)}.${qcA(Q)}`,B=await crypto.subtle.importKey("jwk",A,{name:"ECDSA",namedCurve:"P-256"},!1,["sign"]),X=await crypto.subtle.sign({name:"ECDSA",hash:"SHA-256"},B,new TextEncoder().encode($));return`${$}.${Buffer.from(r8Q(X)).toString("base64url")}`}var s8Q=600;class RC0{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 ri(A);let w=await this.validateAuthorizationRequest(new URL(A.url).searchParams);if(!w.success)return new Response(w.error,{status:400});let $=this.createAuthorizationApprovalToken(Q,w.params);return kC(DcA(w.params,$))}async handleAuthorizeApproval(A){let Q=await this.sessionStore.getSessionFromRequest(A);if(!Q)return ri(A);let w=await A.formData(),$=await this.validateAuthorizationRequest(new URLSearchParams(_C0(w)));if(!$.success)return new Response($.error,{status:400});let B=w.get("approval_token"),X=typeof B==="string"?B:void 0;if(!X||!this.consumeAuthorizationApprovalToken(X,Q,$.params))return new Response("Invalid authorization approval token",{status:400});let Y=await this.authCodeStore.createCode({clientId:$.params.clientId,redirectUri:$.params.redirectUri,codeChallenge:$.params.codeChallenge,...$.params.scope?{scope:$.params.scope}:{},subject:Q.subject}),Z=new URL($.params.redirectUri);if(Z.searchParams.set("code",Y.code),$.params.state)Z.searchParams.set("state",$.params.state);return Response.redirect(Z.toString(),302)}createAuthorizationApprovalToken(A,Q){this.pruneExpiredAuthorizationApprovalTokens();let w=`oat_${o8Q()}`;return this.authorizationApprovalTokens.set(w,{token:w,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)+s8Q}),w}consumeAuthorizationApprovalToken(A,Q,w){this.pruneExpiredAuthorizationApprovalTokens();let $=this.authorizationApprovalTokens.get(A);if(!$)return!1;return this.authorizationApprovalTokens.delete(A),$.sessionId===Q.id&&$.clientId===w.clientId&&$.redirectUri===w.redirectUri&&$.codeChallenge===w.codeChallenge&&$.scope===w.scope&&$.state===w.state}pruneExpiredAuthorizationApprovalTokens(){let A=Math.floor(Date.now()/1000);for(let[Q,w]of this.authorizationApprovalTokens.entries())if(w.expiresAt<=A)this.authorizationApprovalTokens.delete(Q)}async validateAuthorizationRequest(A){let Q=A.get("response_type"),w=A.get("client_id"),$=A.get("redirect_uri"),B=A.get("code_challenge"),X=A.get("code_challenge_method"),Y=A.get("scope")??void 0,Z=A.get("state")??void 0;if(Q!=="code")return{success:!1,error:"Unsupported response_type"};if(!w)return{success:!1,error:"Missing client_id"};if(!$)return{success:!1,error:"Missing redirect_uri"};if(!B)return{success:!1,error:"Missing code_challenge"};if(X!=="S256")return{success:!1,error:"Unsupported code_challenge_method"};let H=await this.clientStore.getClient(w);if(!H)return{success:!1,error:"Unknown client_id"};if(!$R0(H.redirect_uris,$))return{success:!1,error:"Unregistered redirect_uri"};let W=Y??H.scope;return{success:!0,params:{clientId:w,redirectUri:$,codeChallenge:B,...W?{scope:W}:{},...Z?{state:Z}:{},clientName:H.client_name??H.client_id}}}async handleClientRegistration(A){let Q;try{Q=await A.json()}catch{return VB("invalid_client_metadata","Request body must be JSON")}try{let w=await this.clientStore.registerClient(Q);return Nf(w,201)}catch(w){if(w instanceof Zp)return VB("invalid_client_metadata",w.message);throw w}}async handleTokenRequest(A,Q){let w=await kC0(A),$=w.get("grant_type"),B=jC0(A,w),X=B.clientId??w.get("client_id");if(B.error)return VB("invalid_client",B.error);if(!X)return VB("invalid_request","client_id is required");let Y=await this.clientStore.getClient(X),Z=NC0(Y,B);if(Z)return VB("invalid_client",Z);if($==="authorization_code")return this.handleAuthorizationCodeGrant(w,X,Q);if($==="refresh_token")return this.handleRefreshTokenGrant(w,X,Q);return VB("unsupported_grant_type","Only authorization_code and refresh_token are supported")}async handleAuthorizationCodeGrant(A,Q,w){let $=A.get("code"),B=A.get("redirect_uri"),X=A.get("code_verifier");if(!$||!B||!X)return VB("invalid_request","code, redirect_uri, and code_verifier are required");let Y=await this.clientStore.getClient(Q);if(!Y||!$R0(Y.redirect_uris,B))return VB("invalid_grant","Unregistered redirect_uri");try{let Z=await this.authCodeStore.consumeCode({code:$,clientId:Q,redirectUri:B,codeVerifier:X});return await this.createTokenResponse({issuer:w,clientId:Q,subject:Z.subject,...Z.scope?{scope:Z.scope}:{}})}catch(Z){if(Z instanceof zU)return VB("invalid_grant",Z.message);throw Z}}async handleRefreshTokenGrant(A,Q,w){let $=A.get("refresh_token");if(!$)return VB("invalid_request","refresh_token is required");try{let B=await this.refreshTokenStore.rotateToken($,Q);return await this.createTokenResponse({issuer:w,clientId:Q,subject:B.consumed.subject,...B.consumed.scope?{scope:B.consumed.scope}:{},refreshToken:B.replacement.token})}catch(B){if(B instanceof s3)return VB("invalid_grant",B.message);throw B}}async createTokenResponse(A){let Q=Math.floor(Date.now()/1000),w=900,$=await xC0(await this.keyStore.getPrivateJwk(),{iss:A.issuer,sub:A.subject,aud:A.clientId,iat:Q,exp:Q+900,...A.scope?{scope:A.scope}:{}}),B=A.refreshToken??(await this.refreshTokenStore.issueToken({clientId:A.clientId,subject:A.subject,...A.scope?{scope:A.scope}:{}})).token;return Nf({access_token:$,token_type:"Bearer",expires_in:900,...A.scope?{scope:A.scope}:{},refresh_token:B})}async handleRevokeRequest(A){let Q=await kC0(A),w=jC0(A,Q),$=w.clientId??Q.get("client_id")??void 0,B=Q.get("token");if(w.error)return VB("invalid_client",w.error);if(!B)return VB("invalid_request","token is required");if($){let X=await this.clientStore.getClient($),Y=NC0(X,w);if(Y)return VB("invalid_client",Y)}return await this.refreshTokenStore.revokeToken(B,$),new Response(null,{status:200})}}class vC0{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 VB("access_denied","Passkey setup already completed");if(!this.setupFlow.hasValidSetupToken(A))return VB("access_denied","Invalid setup token");let Q=await this.passkeyService.generateRegistrationOptions(AB0(A));return Nf(Q)}async handleRegistrationVerify(A){if(await this.passkeyService.hasCredentials())return VB("access_denied","Passkey setup already completed");if(!this.setupFlow.hasValidSetupToken(A))return VB("access_denied","Invalid setup token");let Q=await this.passkeyService.verifyRegistrationResponse(await A.json(),AB0(A));if(!Q.verified)return VB("access_denied","Passkey registration failed");await this.setupFlow.clearSetupState();let w=await this.sessionStore.createSession(Q.subject??"single-operator",{secure:pi(A)});return Nf({verified:!0},200,{"Set-Cookie":w.cookie})}async handleAuthenticationOptions(A){if(!await this.passkeyService.hasCredentials())return VB("access_denied","No passkey registered");let Q=await this.passkeyService.generateAuthenticationOptions(AB0(A));return Nf(Q)}async handleAuthenticationVerify(A){let Q=await this.passkeyService.verifyAuthenticationResponse(await A.json(),AB0(A));if(!Q.verified)return VB("access_denied","Passkey authentication failed");let w=await this.sessionStore.createSession(Q.subject??"single-operator",{secure:pi(A)});return Nf({verified:!0},200,{"Set-Cookie":w.cookie})}}function AB0(A){let Q=mF(A),w=new URL(Q);return{origin:w.origin,rpID:w.hostname}}import{randomUUID as a8Q}from"crypto";var oi=86400;class hC0{setupStateStore;passkeyService;setupTokenTtlSeconds;setupToken;constructor(A){this.setupStateStore=A.setupStateStore,this.passkeyService=A.passkeyService,this.setupTokenTtlSeconds=A.setupTokenTtlSeconds??oi}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_${a8Q()}`,expiresAt:Math.floor(Date.now()/1000)+this.setupTokenTtlSeconds},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 w=new URL(A.url);return(w.searchParams.get("setup_token")??w.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 PU(A,`/setup?token=${encodeURIComponent(Q.token)}`)}async getOperatorSetupRequired(A){if(await this.passkeyService.hasCredentials())return;let Q=this.getValidSetupToken();if(!Q)return;return{setupUrl:PU(A,`/setup?token=${encodeURIComponent(Q.token)}`),expiresAt:Q.expiresAt,setupTokenId:$C0(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 kC(UcA(Q))}async hasSetupEmailDelivery(A,Q){return this.setupStateStore.hasDelivery(A,Q)}async recordSetupEmailDelivery(A,Q,w={}){await this.setupStateStore.recordDelivery(A,Q,w)}}class QB0{issuer;trustedIssuers;allowLocalhostIssuers;keyStore;a2aKeyStore;clientStore;authCodeStore;sessionStore;peerTrustStore;passkeyService;setupFlow;oauthEndpoints;webauthnEndpoints;logger;constructor(A){this.issuer=jU(A.issuer),this.trustedIssuers=new Set([this.issuer,...(A.trustedIssuers??[]).map((Q)=>jU(Q))]),this.allowLocalhostIssuers=A.allowLocalhostIssuers??SF(this.issuer),this.keyStore=new q$0({storageDir:A.storageDir}),this.a2aKeyStore=new BR0({storageDir:A.storageDir}),this.clientStore=new D$0({storageDir:A.storageDir}),this.authCodeStore=new G$0({storageDir:A.storageDir}),this.sessionStore=new o80({storageDir:A.storageDir}),this.peerTrustStore=new i80({storageDir:A.storageDir}),this.passkeyService=new p80({storageDir:A.storageDir,...A.logger?{logger:A.logger}:{}}),this.setupFlow=new hC0({setupStateStore:new BC0({storageDir:A.storageDir}),passkeyService:this.passkeyService,setupTokenTtlSeconds:A.setupTokenTtlSeconds??oi}),this.oauthEndpoints=new RC0({clientStore:this.clientStore,authCodeStore:this.authCodeStore,refreshTokenStore:new d80({storageDir:A.storageDir}),sessionStore:this.sessionStore,keyStore:this.keyStore}),this.webauthnEndpoints=new vC0({passkeyService:this.passkeyService,sessionStore:this.sessionStore,setupFlow:this.setupFlow}),this.logger=A.logger}getIssuer(){return this.issuer}async initialize(){if(await Promise.all([this.keyStore.getPrivateJwk(),this.a2aKeyStore.getPrivateJwk()]),this.logger?.debug("Auth service signing keys loaded"),!await this.hasPasskeyCredentials()){await this.setupFlow.ensureSetupToken();let A=this.getSetupUrl();if(A)if(SF(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(){let[A,Q]=await Promise.all([this.keyStore.getPublicJwk(),this.a2aKeyStore.getPublicJwk()]);return{keys:[A,Q]}}async getA2ASigningKey(){let A=await this.a2aKeyStore.getPrivateJwk();return{privateJwk:A,keyId:PU(this.issuer,`/.well-known/jwks.json#${A.kid}`)}}grantA2APeerTrust(A){return this.peerTrustStore.grant(A)}getA2APeerTrust(A){return this.peerTrustStore.get(A)}revokeA2APeerTrust(A){return this.peerTrustStore.revoke(A)}getAuthorizationServerMetadata(A=this.issuer){let Q=jU(A);return{issuer:Q,authorization_endpoint:PU(Q,"/authorize"),token_endpoint:PU(Q,"/token"),registration_endpoint:PU(Q,"/register"),revocation_endpoint:PU(Q,"/revoke"),jwks_uri:PU(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:[jU(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 ri(A)}async verifyBearerToken(A,Q={}){let w=LC0(A);if(!w)return;let $=Q.issuer?jU(Q.issuer):this.resolveRequestIssuer(A);return bC0(w,await this.getJwks(),{issuer:$,...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,w={}){await this.setupFlow.recordSetupEmailDelivery(A,Q,w)}async handleRequest(A){let Q;try{Q=this.resolveRequestIssuer(A)}catch($){return this.logger?.warn("Rejected OAuth request from untrusted issuer",{error:$ instanceof Error?$.message:String($)}),new Response("Untrusted OAuth issuer",{status:400})}let w=new URL(A.url).pathname;if(A.method==="OPTIONS"&&HcA(w))return WcA();if(A.method==="GET"){if(w==="/.well-known/oauth-authorization-server")return pF(Nf(this.getAuthorizationServerMetadata(Q)));if(w==="/.well-known/jwks.json")return pF(Nf(await this.getJwks()));if(w==="/.well-known/oauth-protected-resource")return pF(Nf(this.getProtectedResourceMetadata(Q,Q)))}if(A.method==="GET"&&w==="/setup")return this.setupFlow.handleSetupPage(A);if(A.method==="GET"&&w==="/login")return this.handleLoginPage(A);if((A.method==="GET"||A.method==="POST")&&w==="/logout")return this.handleLogout(A);if(A.method==="POST"&&w==="/webauthn/register/options")return this.webauthnEndpoints.handleRegistrationOptions(A);if(A.method==="POST"&&w==="/webauthn/register/verify")return this.webauthnEndpoints.handleRegistrationVerify(A);if(A.method==="POST"&&w==="/webauthn/auth/options")return this.webauthnEndpoints.handleAuthenticationOptions(A);if(A.method==="POST"&&w==="/webauthn/auth/verify")return this.webauthnEndpoints.handleAuthenticationVerify(A);if(A.method==="GET"&&w==="/authorize")return this.oauthEndpoints.handleAuthorizePage(A);if(A.method==="POST"&&w==="/authorize")return this.oauthEndpoints.handleAuthorizeApproval(A);if(A.method==="POST"&&w==="/register")return pF(await this.oauthEndpoints.handleClientRegistration(A));if(A.method==="POST"&&w==="/token")return pF(await this.oauthEndpoints.handleTokenRequest(A,Q));if(A.method==="POST"&&w==="/revoke")return pF(await this.oauthEndpoints.handleRevokeRequest(A));return new Response("Not Found",{status:404})}async handleWellKnownRequest(A){return this.handleRequest(A)}resolveRequestIssuer(A){let Q=mF(A,this.issuer);if(this.trustedIssuers.has(Q)||this.allowLocalhostIssuers&&SF(Q))return Q;throw Error(`Request issuer ${Q} is not in trusted issuers`)}handleLoginPage(A){let Q=PC0(new URL(A.url).searchParams.get("return_to"));return kC(MC0(Q))}async handleLogout(A){await this.sessionStore.revokeSessionFromRequest(A);let Q=PC0(new URL(A.url).searchParams.get("return_to"));return new Response(null,{status:302,headers:{Location:Q,"Set-Cookie":YC0(pi(A)),"Cache-Control":"no-store"}})}}C0();var wB0="email:send",VcA=f.strictObject({to:f.string().email(),subject:f.string().min(1),text:f.string().min(1),html:f.string().min(1).optional(),sensitivity:f.enum(["normal","secret"]).default("normal")});fA();C0();var JcA={name:"@brains/notifications",version:"0.2.0-alpha.158",description:"Generic notification routing for transactional and administrative messages",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":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var CC0="notifications:send",e8Q=f.looseObject({}),ABQ=f.discriminatedUnion("type",[f.strictObject({type:f.literal("email"),address:f.email()})]),QBQ=f.strictObject({recipient:ABQ,title:f.string().min(1),body:f.string().min(1),html:f.string().min(1).optional(),sensitivity:f.enum(["normal","secret"]).default("normal")}),IcA=f.discriminatedUnion("status",[f.strictObject({status:f.literal("sent"),deliveryId:f.string().optional()}),f.strictObject({status:f.literal("failed")})]);class FcA extends Kw{constructor(A={}){super("notifications",JcA,A,e8Q)}async onRegister(A){A.messaging.subscribe(CC0,async(Q)=>{let w=QBQ.parse(Q.payload),$={to:w.recipient.address,subject:w.title,text:w.body,...w.html?{html:w.html}:{},sensitivity:w.sensitivity},B=await A.messaging.send({type:wB0,payload:$});if(!("success"in B)||!B.success||!B.data)return{success:!1,error:"Notification delivery failed"};let X=B.data;if(X.status!=="sent")return{success:!1,error:"Notification delivery failed"};return{success:!0,data:X.id?{status:"sent",deliveryId:X.id}:{status:"sent"}}})}}function $B0(A={}){return new FcA(A)}fA();C0();var bcA={name:"@brains/auth-service",version:"0.2.0-alpha.158",description:"Embedded OAuth/OIDC auth service for brain operator authentication",dependencies:{"@brains/notifications":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*","@simplewebauthn/server":"^13.3.1",jose:"^6.2.3"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14","@types/node":"^20.19.43",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},files:["src"],main:"./src/index.ts",private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module",types:"./src/index.ts"};var $BQ=f.union([f.string().email(),f.object({to:f.string().email(),subject:f.string().min(1),body:f.string().min(1)}).strict()]),BBQ=f.object({issuer:f.string().optional(),trustedIssuers:f.array(f.string()).default([]),allowLocalhostIssuers:f.boolean().optional(),storageDir:f.string().default("./data/auth"),setupTokenTtlSeconds:f.number().int().positive().default(oi),setupEmail:$BQ.optional()}),BB0;function s7(){return BB0}class gC0 extends Kw{service;constructor(A={}){super("auth-service",bcA,A,BBQ)}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 QB0({storageDir:this.config.storageDir,...Q?{issuer:Q}:{},trustedIssuers:this.config.trustedIssuers,...this.config.allowLocalhostIssuers!==void 0?{allowLocalhostIssuers:this.config.allowLocalhostIssuers}:{},setupTokenTtlSeconds:this.config.setupTokenTtlSeconds,logger:A.logger}),await this.service.initialize(),BB0=this.service}async onReady(A){await this.requestSetupEmailIfNeeded(A)}async onShutdown(){if(BB0===this.service)BB0=void 0;this.service=void 0}async getTools(){return[{name:`${this.id}_get_passkey_setup_url`,description:"Get the first-passkey setup URL when operator setup is required. Anchor-only.",inputSchema:{},visibility:"anchor",handler:async()=>{let A=this.getService();if(await A.hasPasskeyCredentials())return{success:!0,data:{status:"complete"}};let Q=await A.getOperatorSetupRequired();if(Q)return{success:!0,data:{status:"setup_required",setupUrl:Q.setupUrl,expiresAt:Q.expiresAt}};return{success:!0,data:{status:"unavailable",reason:"Passkey setup URL is not available."}}},sideEffects:"none"}]}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 w=await Q.getOperatorSetupRequired();if(!w)return;let $=XBQ(this.config.setupEmail,w);if(await Q.hasSetupEmailDelivery(w.setupTokenId,$.to))return;let B=await A.messaging.send({type:CC0,payload:{recipient:{type:"email",address:$.to},title:$.subject,body:$.body,sensitivity:"secret"}});if(!("success"in B)||!B.success||!B.data){A.logger.warn("Passkey setup email delivery was not confirmed");return}let X=IcA.safeParse(B.data);if(!X.success||X.data.status!=="sent"){A.logger.warn("Passkey setup email delivery was not confirmed");return}await Q.recordSetupEmailDelivery(w.setupTokenId,$.to,X.data.deliveryId?{deliveryId:X.data.deliveryId}:{})}}function XBQ(A,Q){if(typeof A==="string"){let w=new Date(Q.expiresAt*1000).toISOString(),$=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 ${w}.`,`Dashboard: ${$}/`,`MCP endpoint: ${$}/mcp`,"The first successful passkey registration completes setup and closes this link."].join(`
2293
- `)}}return{to:A.to,subject:LcA(A.subject,Q),body:LcA(A.body,Q)}}function LcA(A,Q){let w=new Date(Q.expiresAt*1000).toISOString(),$=new URL(Q.setupUrl).origin;return A.replaceAll("{{setupUrl}}",Q.setupUrl).replaceAll("{{expiresAt}}",w).replaceAll("{{origin}}",$)}function si(A={}){return new gC0(A)}C0();var yC0=f.object({transport:f.enum(["stdio","http"]).default("http"),mode:f.enum(["basic","debug"]).default("basic"),httpPort:f.number().describe("Port for HTTP transport (only used when transport is 'http')").default(3333),authToken:f.string().describe("Bearer token for HTTP transport authentication").optional(),sessionIdleTtlMs:f.number().describe("Idle time in ms after which an HTTP session is closed and evicted").default(1800000)});C0();import{createHash as HBQ,randomUUID as WBQ}from"crypto";function YBQ(A){return typeof A==="object"&&A!==null&&!Array.isArray(A)}function ai(A,Q){let w=A?.[Q];return typeof w==="string"&&w.length>0?w:void 0}function ZBQ(A){let Q=YBQ(A.data)?A.data:void 0,w=A.args,$=ai(Q,"entityId")??ai(Q,"id"),B=A.jobId??ai(Q,"jobId"),X=ai(w,"entityType")??ai(w,"type");if(!$&&!B)return;return{toolName:A.toolName,...X?{entityType:X}:{},...$?{entityId:$}:{},...B?{jobId:B}:{}}}function fBQ(A){return A?.map(ZBQ).filter((Q)=>Q!==void 0)??[]}function EC0(A,Q={}){let w=A.pendingConfirmations?.[0];if(w)return{needsConfirmation:!0,toolName:w.toolName,summary:w.summary,...w.completionSummary?{completionSummary:w.completionSummary}:{},...w.preview?{preview:w.preview}:{},args:{approvalId:w.id,...Q.conversationId?{conversationId:Q.conversationId}:{},...w.toolCallId?{toolCallId:w.toolCallId}:{},originalArgs:w.args}};let $=fBQ(A.toolResults);return{success:!0,data:{text:A.text,...Q.conversationId?{conversationId:Q.conversationId}:{},...A.toolResults?{toolResults:A.toolResults}:{},...$.length>0?{readYourWrites:$}:{}}}}var kcA=f.object({message:f.string().min(1),conversationId:f.string().min(1).optional().describe("Opaque conversation handle returned by a previous chat call. Omit it to start a new isolated conversation.")}),_cA=f.object({approvalId:f.string().min(1),confirmed:f.boolean(),conversationId:f.string().min(1).describe("Exact conversation handle returned by the chat confirmation.")});function NcA(A,Q,w,$){let B=A.conversationId??w??$??`conversation-${WBQ()}`,X=HBQ("sha256").update(Q).digest("hex").slice(0,16);return{handle:B,internalId:`mcp:${X}:${B}`}}function jcA(A){return{userPermissionLevel:A.userPermissionLevel??"public",interfaceType:"mcp",...A.channelId?{channelId:A.channelId}:{},...A.channelName?{channelName:A.channelName}:{},actor:{actorId:A.userId,interfaceType:"mcp",role:"user"}}}function PcA(A,Q){return[{name:"chat",description:"Talk to the brain to make changes or get reasoned answers. Use this for any create/update/delete request or questions requiring reasoning across content. For simple lookups, use search/get/list directly.",inputSchema:kcA.shape,visibility:"public",sideEffects:"writes",handler:async(w,$)=>{let B=kcA.parse(w),X=Q();if(!X)return{success:!1,error:"MCP chat tool is not initialized."};let Y=NcA(B,$.userId,$.conversationId,$.channelId),Z=await X.agent.chat(B.message,Y.internalId,{...jcA($)});return EC0(Z,{conversationId:Y.handle})}},{name:"confirm",description:"Resolve a pending confirmation returned by chat. Use this only after chat returns needsConfirmation with an approvalId.",inputSchema:_cA.shape,visibility:"public",sideEffects:"writes",handler:async(w,$)=>{let B=_cA.parse(w),X=Q();if(!X)return{success:!1,error:"MCP confirm tool is not initialized."};let Y=NcA(B,$.userId,$.conversationId,$.channelId),Z=await X.agent.confirmPendingAction(Y.internalId,B.confirmed,B.approvalId,jcA($));return EC0(Z,{conversationId:Y.handle})}}]}fA();function TC0(A,Q){A.messaging.subscribe("job-progress",async(w)=>{let $=gx.safeParse(w.payload);if(!$.success)return Q.warn("Received invalid job-progress message",{error:$.error.message}),{success:!1};let B=$.data,X=B.type,Y=B.status,Z=B.id;if(Q.debug(`${X} ${Z} - ${Y}:`,{id:B.id,message:B.message,progress:B.progress,metadata:B.metadata}),B.batchDetails)Q.debug(`Batch details for ${Z}:`,{totalOperations:B.batchDetails.totalOperations,completedOperations:B.batchDetails.completedOperations,failedOperations:B.batchDetails.failedOperations,currentOperation:B.batchDetails.currentOperation,errors:B.batchDetails.errors});if(B.jobDetails)Q.debug(`Job details for ${Z}:`,{jobType:B.jobDetails.jobType,priority:B.jobDetails.priority,retryCount:B.jobDetails.retryCount});return{success:!0}}),Q.debug("Subscribed to job progress events")}var McA={name:"@brains/mcp",version:"0.2.0-alpha.158",dependencies:{"@brains/auth-service":"workspace:*","@brains/mcp-service":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*","@modelcontextprotocol/sdk":"^1.29.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.3.14","@types/cors":"^2.8.17",typescript:"^7.0.2"},files:["src"],main:"./src/index.ts",module:"./src/index.ts",private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module",types:"./src/index.ts"};class iF extends ZD{mcpTransport;stdioServer;httpServer;domain;constructor(A={}){let Q={...A,authToken:A.authToken??process.env.MCP_AUTH_TOKEN};super("mcp",McA,Q,yC0)}async getTools(){return PcA(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"});TC0(A,this.logger)}getOrCreateHttpServer(){if(this.httpServer)return this.httpServer;let A=s7();return this.httpServer=j3.createFresh({port:this.config.httpPort,logger:this.logger,sessionIdleTtlMs:this.config.sessionIdleTtlMs,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,mode:this.config.mode,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",w=this.context.permissions.getUserLevel("mcp",Q),$=s7(),B=this.config.transport==="http"&&(this.config.authToken?!0:$!==void 0);if(B)w="anchor",this.logger.debug("HTTP authentication configured - authenticated users will have anchor permissions");if(this.config.mode==="debug"){if(this.config.transport==="http"&&!B)throw Error("MCP debug mode requires authenticated HTTP transport; configure authToken or OAuth auth service.");if(w!=="anchor")throw Error("MCP debug mode requires anchor permissions.")}if(this.mcpTransport.setProtocolMode(this.config.mode),this.mcpTransport.setPermissionLevel(w),this.logger.debug(`Starting MCP ${this.config.transport} transport in ${this.config.mode} mode with ${w} permissions`),this.config.transport==="stdio"){this.stdioServer=qU.createFresh();let X=this.mcpTransport.getMcpServer();this.stdioServer.connectMCPServer(X),await this.stdioServer.start(),this.logger.debug("MCP STDIO transport started")}else{this.httpServer=this.getOrCreateHttpServer();let X=this.mcpTransport.getMcpServer();this.httpServer.connectMCPServer(X,this.mcpTransport),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(){qU.resetInstance(),j3.resetInstance()}}fA();function ti(A,Q=2000){if(A.length<=Q)return[A];let w=DBQ(A),$=[],B="";for(let X of w){let Y=B?`
2292
+ </html>`}function ri(A){let Q=`${new URL(A.url).pathname}${new URL(A.url).search}`;return new Response(MC0(Q,"Operator login required"),{status:401,headers:{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store"}})}function uD(A){return A.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;")}import{randomUUID as o8Q}from"crypto";function qcA(A){return Buffer.from(JSON.stringify(A)).toString("base64url")}function r8Q(A){let Q=new Uint8Array(A);if(Q.length===64)return Q;if(Q[0]!==48)return Q;let w=2;if(Q[1]&&Q[1]>128)w+=Q[1]-128;if(Q[w]!==2)throw Error("Invalid DER ECDSA signature");let $=Q[w+1];if($===void 0)throw Error("Invalid DER ECDSA signature");let B=w+2,X=Q.slice(B,B+$);if(w=B+$,Q[w]!==2)throw Error("Invalid DER ECDSA signature");let Y=Q[w+1];if(Y===void 0)throw Error("Invalid DER ECDSA signature");let Z=w+2,H=Q.slice(Z,Z+Y);return new Uint8Array([...zcA(X),...zcA(H)])}function zcA(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 w=new Uint8Array(32);return w.set(Q,32-Q.length),w}async function xC0(A,Q){let w={typ:"JWT",alg:"ES256",kid:A.kid},$=`${qcA(w)}.${qcA(Q)}`,B=await crypto.subtle.importKey("jwk",A,{name:"ECDSA",namedCurve:"P-256"},!1,["sign"]),X=await crypto.subtle.sign({name:"ECDSA",hash:"SHA-256"},B,new TextEncoder().encode($));return`${$}.${Buffer.from(r8Q(X)).toString("base64url")}`}var s8Q=600;class RC0{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 ri(A);let w=await this.validateAuthorizationRequest(new URL(A.url).searchParams);if(!w.success)return new Response(w.error,{status:400});let $=this.createAuthorizationApprovalToken(Q,w.params);return kC(DcA(w.params,$))}async handleAuthorizeApproval(A){let Q=await this.sessionStore.getSessionFromRequest(A);if(!Q)return ri(A);let w=await A.formData(),$=await this.validateAuthorizationRequest(new URLSearchParams(_C0(w)));if(!$.success)return new Response($.error,{status:400});let B=w.get("approval_token"),X=typeof B==="string"?B:void 0;if(!X||!this.consumeAuthorizationApprovalToken(X,Q,$.params))return new Response("Invalid authorization approval token",{status:400});let Y=await this.authCodeStore.createCode({clientId:$.params.clientId,redirectUri:$.params.redirectUri,codeChallenge:$.params.codeChallenge,...$.params.scope?{scope:$.params.scope}:{},subject:Q.subject}),Z=new URL($.params.redirectUri);if(Z.searchParams.set("code",Y.code),$.params.state)Z.searchParams.set("state",$.params.state);return Response.redirect(Z.toString(),302)}createAuthorizationApprovalToken(A,Q){this.pruneExpiredAuthorizationApprovalTokens();let w=`oat_${o8Q()}`;return this.authorizationApprovalTokens.set(w,{token:w,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)+s8Q}),w}consumeAuthorizationApprovalToken(A,Q,w){this.pruneExpiredAuthorizationApprovalTokens();let $=this.authorizationApprovalTokens.get(A);if(!$)return!1;return this.authorizationApprovalTokens.delete(A),$.sessionId===Q.id&&$.clientId===w.clientId&&$.redirectUri===w.redirectUri&&$.codeChallenge===w.codeChallenge&&$.scope===w.scope&&$.state===w.state}pruneExpiredAuthorizationApprovalTokens(){let A=Math.floor(Date.now()/1000);for(let[Q,w]of this.authorizationApprovalTokens.entries())if(w.expiresAt<=A)this.authorizationApprovalTokens.delete(Q)}async validateAuthorizationRequest(A){let Q=A.get("response_type"),w=A.get("client_id"),$=A.get("redirect_uri"),B=A.get("code_challenge"),X=A.get("code_challenge_method"),Y=A.get("scope")??void 0,Z=A.get("state")??void 0;if(Q!=="code")return{success:!1,error:"Unsupported response_type"};if(!w)return{success:!1,error:"Missing client_id"};if(!$)return{success:!1,error:"Missing redirect_uri"};if(!B)return{success:!1,error:"Missing code_challenge"};if(X!=="S256")return{success:!1,error:"Unsupported code_challenge_method"};let H=await this.clientStore.getClient(w);if(!H)return{success:!1,error:"Unknown client_id"};if(!$R0(H.redirect_uris,$))return{success:!1,error:"Unregistered redirect_uri"};let W=Y??H.scope;return{success:!0,params:{clientId:w,redirectUri:$,codeChallenge:B,...W?{scope:W}:{},...Z?{state:Z}:{},clientName:H.client_name??H.client_id}}}async handleClientRegistration(A){let Q;try{Q=await A.json()}catch{return VB("invalid_client_metadata","Request body must be JSON")}try{let w=await this.clientStore.registerClient(Q);return Nf(w,201)}catch(w){if(w instanceof Zp)return VB("invalid_client_metadata",w.message);throw w}}async handleTokenRequest(A,Q){let w=await kC0(A),$=w.get("grant_type"),B=jC0(A,w),X=B.clientId??w.get("client_id");if(B.error)return VB("invalid_client",B.error);if(!X)return VB("invalid_request","client_id is required");let Y=await this.clientStore.getClient(X),Z=NC0(Y,B);if(Z)return VB("invalid_client",Z);if($==="authorization_code")return this.handleAuthorizationCodeGrant(w,X,Q);if($==="refresh_token")return this.handleRefreshTokenGrant(w,X,Q);return VB("unsupported_grant_type","Only authorization_code and refresh_token are supported")}async handleAuthorizationCodeGrant(A,Q,w){let $=A.get("code"),B=A.get("redirect_uri"),X=A.get("code_verifier");if(!$||!B||!X)return VB("invalid_request","code, redirect_uri, and code_verifier are required");let Y=await this.clientStore.getClient(Q);if(!Y||!$R0(Y.redirect_uris,B))return VB("invalid_grant","Unregistered redirect_uri");try{let Z=await this.authCodeStore.consumeCode({code:$,clientId:Q,redirectUri:B,codeVerifier:X});return await this.createTokenResponse({issuer:w,clientId:Q,subject:Z.subject,...Z.scope?{scope:Z.scope}:{}})}catch(Z){if(Z instanceof zU)return VB("invalid_grant",Z.message);throw Z}}async handleRefreshTokenGrant(A,Q,w){let $=A.get("refresh_token");if(!$)return VB("invalid_request","refresh_token is required");try{let B=await this.refreshTokenStore.rotateToken($,Q);return await this.createTokenResponse({issuer:w,clientId:Q,subject:B.consumed.subject,...B.consumed.scope?{scope:B.consumed.scope}:{},refreshToken:B.replacement.token})}catch(B){if(B instanceof s3)return VB("invalid_grant",B.message);throw B}}async createTokenResponse(A){let Q=Math.floor(Date.now()/1000),w=900,$=await xC0(await this.keyStore.getPrivateJwk(),{iss:A.issuer,sub:A.subject,aud:A.clientId,iat:Q,exp:Q+900,...A.scope?{scope:A.scope}:{}}),B=A.refreshToken??(await this.refreshTokenStore.issueToken({clientId:A.clientId,subject:A.subject,...A.scope?{scope:A.scope}:{}})).token;return Nf({access_token:$,token_type:"Bearer",expires_in:900,...A.scope?{scope:A.scope}:{},refresh_token:B})}async handleRevokeRequest(A){let Q=await kC0(A),w=jC0(A,Q),$=w.clientId??Q.get("client_id")??void 0,B=Q.get("token");if(w.error)return VB("invalid_client",w.error);if(!B)return VB("invalid_request","token is required");if($){let X=await this.clientStore.getClient($),Y=NC0(X,w);if(Y)return VB("invalid_client",Y)}return await this.refreshTokenStore.revokeToken(B,$),new Response(null,{status:200})}}class vC0{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 VB("access_denied","Passkey setup already completed");if(!this.setupFlow.hasValidSetupToken(A))return VB("access_denied","Invalid setup token");let Q=await this.passkeyService.generateRegistrationOptions(AB0(A));return Nf(Q)}async handleRegistrationVerify(A){if(await this.passkeyService.hasCredentials())return VB("access_denied","Passkey setup already completed");if(!this.setupFlow.hasValidSetupToken(A))return VB("access_denied","Invalid setup token");let Q=await this.passkeyService.verifyRegistrationResponse(await A.json(),AB0(A));if(!Q.verified)return VB("access_denied","Passkey registration failed");await this.setupFlow.clearSetupState();let w=await this.sessionStore.createSession(Q.subject??"single-operator",{secure:pi(A)});return Nf({verified:!0},200,{"Set-Cookie":w.cookie})}async handleAuthenticationOptions(A){if(!await this.passkeyService.hasCredentials())return VB("access_denied","No passkey registered");let Q=await this.passkeyService.generateAuthenticationOptions(AB0(A));return Nf(Q)}async handleAuthenticationVerify(A){let Q=await this.passkeyService.verifyAuthenticationResponse(await A.json(),AB0(A));if(!Q.verified)return VB("access_denied","Passkey authentication failed");let w=await this.sessionStore.createSession(Q.subject??"single-operator",{secure:pi(A)});return Nf({verified:!0},200,{"Set-Cookie":w.cookie})}}function AB0(A){let Q=mF(A),w=new URL(Q);return{origin:w.origin,rpID:w.hostname}}import{randomUUID as a8Q}from"crypto";var oi=86400;class hC0{setupStateStore;passkeyService;setupTokenTtlSeconds;setupToken;constructor(A){this.setupStateStore=A.setupStateStore,this.passkeyService=A.passkeyService,this.setupTokenTtlSeconds=A.setupTokenTtlSeconds??oi}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_${a8Q()}`,expiresAt:Math.floor(Date.now()/1000)+this.setupTokenTtlSeconds},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 w=new URL(A.url);return(w.searchParams.get("setup_token")??w.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 PU(A,`/setup?token=${encodeURIComponent(Q.token)}`)}async getOperatorSetupRequired(A){if(await this.passkeyService.hasCredentials())return;let Q=this.getValidSetupToken();if(!Q)return;return{setupUrl:PU(A,`/setup?token=${encodeURIComponent(Q.token)}`),expiresAt:Q.expiresAt,setupTokenId:$C0(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 kC(UcA(Q))}async hasSetupEmailDelivery(A,Q){return this.setupStateStore.hasDelivery(A,Q)}async recordSetupEmailDelivery(A,Q,w={}){await this.setupStateStore.recordDelivery(A,Q,w)}}class QB0{issuer;trustedIssuers;allowLocalhostIssuers;keyStore;a2aKeyStore;clientStore;authCodeStore;sessionStore;peerTrustStore;passkeyService;setupFlow;oauthEndpoints;webauthnEndpoints;logger;constructor(A){this.issuer=jU(A.issuer),this.trustedIssuers=new Set([this.issuer,...(A.trustedIssuers??[]).map((Q)=>jU(Q))]),this.allowLocalhostIssuers=A.allowLocalhostIssuers??SF(this.issuer),this.keyStore=new q$0({storageDir:A.storageDir}),this.a2aKeyStore=new BR0({storageDir:A.storageDir}),this.clientStore=new D$0({storageDir:A.storageDir}),this.authCodeStore=new G$0({storageDir:A.storageDir}),this.sessionStore=new o80({storageDir:A.storageDir}),this.peerTrustStore=new i80({storageDir:A.storageDir}),this.passkeyService=new p80({storageDir:A.storageDir,...A.logger?{logger:A.logger}:{}}),this.setupFlow=new hC0({setupStateStore:new BC0({storageDir:A.storageDir}),passkeyService:this.passkeyService,setupTokenTtlSeconds:A.setupTokenTtlSeconds??oi}),this.oauthEndpoints=new RC0({clientStore:this.clientStore,authCodeStore:this.authCodeStore,refreshTokenStore:new d80({storageDir:A.storageDir}),sessionStore:this.sessionStore,keyStore:this.keyStore}),this.webauthnEndpoints=new vC0({passkeyService:this.passkeyService,sessionStore:this.sessionStore,setupFlow:this.setupFlow}),this.logger=A.logger}getIssuer(){return this.issuer}async initialize(){if(await Promise.all([this.keyStore.getPrivateJwk(),this.a2aKeyStore.getPrivateJwk()]),this.logger?.debug("Auth service signing keys loaded"),!await this.hasPasskeyCredentials()){await this.setupFlow.ensureSetupToken();let A=this.getSetupUrl();if(A)if(SF(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(){let[A,Q]=await Promise.all([this.keyStore.getPublicJwk(),this.a2aKeyStore.getPublicJwk()]);return{keys:[A,Q]}}async getA2ASigningKey(){let A=await this.a2aKeyStore.getPrivateJwk();return{privateJwk:A,keyId:PU(this.issuer,`/.well-known/jwks.json#${A.kid}`)}}grantA2APeerTrust(A){return this.peerTrustStore.grant(A)}getA2APeerTrust(A){return this.peerTrustStore.get(A)}revokeA2APeerTrust(A){return this.peerTrustStore.revoke(A)}getAuthorizationServerMetadata(A=this.issuer){let Q=jU(A);return{issuer:Q,authorization_endpoint:PU(Q,"/authorize"),token_endpoint:PU(Q,"/token"),registration_endpoint:PU(Q,"/register"),revocation_endpoint:PU(Q,"/revoke"),jwks_uri:PU(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:[jU(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 ri(A)}async verifyBearerToken(A,Q={}){let w=LC0(A);if(!w)return;let $=Q.issuer?jU(Q.issuer):this.resolveRequestIssuer(A);return bC0(w,await this.getJwks(),{issuer:$,...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,w={}){await this.setupFlow.recordSetupEmailDelivery(A,Q,w)}async handleRequest(A){let Q;try{Q=this.resolveRequestIssuer(A)}catch($){return this.logger?.warn("Rejected OAuth request from untrusted issuer",{error:$ instanceof Error?$.message:String($)}),new Response("Untrusted OAuth issuer",{status:400})}let w=new URL(A.url).pathname;if(A.method==="OPTIONS"&&HcA(w))return WcA();if(A.method==="GET"){if(w==="/.well-known/oauth-authorization-server")return pF(Nf(this.getAuthorizationServerMetadata(Q)));if(w==="/.well-known/jwks.json")return pF(Nf(await this.getJwks()));if(w==="/.well-known/oauth-protected-resource")return pF(Nf(this.getProtectedResourceMetadata(Q,Q)))}if(A.method==="GET"&&w==="/setup")return this.setupFlow.handleSetupPage(A);if(A.method==="GET"&&w==="/login")return this.handleLoginPage(A);if((A.method==="GET"||A.method==="POST")&&w==="/logout")return this.handleLogout(A);if(A.method==="POST"&&w==="/webauthn/register/options")return this.webauthnEndpoints.handleRegistrationOptions(A);if(A.method==="POST"&&w==="/webauthn/register/verify")return this.webauthnEndpoints.handleRegistrationVerify(A);if(A.method==="POST"&&w==="/webauthn/auth/options")return this.webauthnEndpoints.handleAuthenticationOptions(A);if(A.method==="POST"&&w==="/webauthn/auth/verify")return this.webauthnEndpoints.handleAuthenticationVerify(A);if(A.method==="GET"&&w==="/authorize")return this.oauthEndpoints.handleAuthorizePage(A);if(A.method==="POST"&&w==="/authorize")return this.oauthEndpoints.handleAuthorizeApproval(A);if(A.method==="POST"&&w==="/register")return pF(await this.oauthEndpoints.handleClientRegistration(A));if(A.method==="POST"&&w==="/token")return pF(await this.oauthEndpoints.handleTokenRequest(A,Q));if(A.method==="POST"&&w==="/revoke")return pF(await this.oauthEndpoints.handleRevokeRequest(A));return new Response("Not Found",{status:404})}async handleWellKnownRequest(A){return this.handleRequest(A)}resolveRequestIssuer(A){let Q=mF(A,this.issuer);if(this.trustedIssuers.has(Q)||this.allowLocalhostIssuers&&SF(Q))return Q;throw Error(`Request issuer ${Q} is not in trusted issuers`)}handleLoginPage(A){let Q=PC0(new URL(A.url).searchParams.get("return_to"));return kC(MC0(Q))}async handleLogout(A){await this.sessionStore.revokeSessionFromRequest(A);let Q=PC0(new URL(A.url).searchParams.get("return_to"));return new Response(null,{status:302,headers:{Location:Q,"Set-Cookie":YC0(pi(A)),"Cache-Control":"no-store"}})}}C0();var wB0="email:send",VcA=f.strictObject({to:f.string().email(),subject:f.string().min(1),text:f.string().min(1),html:f.string().min(1).optional(),sensitivity:f.enum(["normal","secret"]).default("normal")});fA();C0();var JcA={name:"@brains/notifications",version:"0.2.0-alpha.159",description:"Generic notification routing for transactional and administrative messages",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":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var CC0="notifications:send",e8Q=f.looseObject({}),ABQ=f.discriminatedUnion("type",[f.strictObject({type:f.literal("email"),address:f.email()})]),QBQ=f.strictObject({recipient:ABQ,title:f.string().min(1),body:f.string().min(1),html:f.string().min(1).optional(),sensitivity:f.enum(["normal","secret"]).default("normal")}),IcA=f.discriminatedUnion("status",[f.strictObject({status:f.literal("sent"),deliveryId:f.string().optional()}),f.strictObject({status:f.literal("failed")})]);class FcA extends Kw{constructor(A={}){super("notifications",JcA,A,e8Q)}async onRegister(A){A.messaging.subscribe(CC0,async(Q)=>{let w=QBQ.parse(Q.payload),$={to:w.recipient.address,subject:w.title,text:w.body,...w.html?{html:w.html}:{},sensitivity:w.sensitivity},B=await A.messaging.send({type:wB0,payload:$});if(!("success"in B)||!B.success||!B.data)return{success:!1,error:"Notification delivery failed"};let X=B.data;if(X.status!=="sent")return{success:!1,error:"Notification delivery failed"};return{success:!0,data:X.id?{status:"sent",deliveryId:X.id}:{status:"sent"}}})}}function $B0(A={}){return new FcA(A)}fA();C0();var bcA={name:"@brains/auth-service",version:"0.2.0-alpha.159",description:"Embedded OAuth/OIDC auth service for brain operator authentication",dependencies:{"@brains/notifications":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*","@simplewebauthn/server":"^13.3.1",jose:"^6.2.3"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14","@types/node":"^20.19.43",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},files:["src"],main:"./src/index.ts",private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module",types:"./src/index.ts"};var $BQ=f.union([f.string().email(),f.object({to:f.string().email(),subject:f.string().min(1),body:f.string().min(1)}).strict()]),BBQ=f.object({issuer:f.string().optional(),trustedIssuers:f.array(f.string()).default([]),allowLocalhostIssuers:f.boolean().optional(),storageDir:f.string().default("./data/auth"),setupTokenTtlSeconds:f.number().int().positive().default(oi),setupEmail:$BQ.optional()}),BB0;function s7(){return BB0}class gC0 extends Kw{service;constructor(A={}){super("auth-service",bcA,A,BBQ)}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 QB0({storageDir:this.config.storageDir,...Q?{issuer:Q}:{},trustedIssuers:this.config.trustedIssuers,...this.config.allowLocalhostIssuers!==void 0?{allowLocalhostIssuers:this.config.allowLocalhostIssuers}:{},setupTokenTtlSeconds:this.config.setupTokenTtlSeconds,logger:A.logger}),await this.service.initialize(),BB0=this.service}async onReady(A){await this.requestSetupEmailIfNeeded(A)}async onShutdown(){if(BB0===this.service)BB0=void 0;this.service=void 0}async getTools(){return[{name:`${this.id}_get_passkey_setup_url`,description:"Get the first-passkey setup URL when operator setup is required. Anchor-only.",inputSchema:{},visibility:"anchor",handler:async()=>{let A=this.getService();if(await A.hasPasskeyCredentials())return{success:!0,data:{status:"complete"}};let Q=await A.getOperatorSetupRequired();if(Q)return{success:!0,data:{status:"setup_required",setupUrl:Q.setupUrl,expiresAt:Q.expiresAt}};return{success:!0,data:{status:"unavailable",reason:"Passkey setup URL is not available."}}},sideEffects:"none"}]}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 w=await Q.getOperatorSetupRequired();if(!w)return;let $=XBQ(this.config.setupEmail,w);if(await Q.hasSetupEmailDelivery(w.setupTokenId,$.to))return;let B=await A.messaging.send({type:CC0,payload:{recipient:{type:"email",address:$.to},title:$.subject,body:$.body,sensitivity:"secret"}});if(!("success"in B)||!B.success||!B.data){A.logger.warn("Passkey setup email delivery was not confirmed");return}let X=IcA.safeParse(B.data);if(!X.success||X.data.status!=="sent"){A.logger.warn("Passkey setup email delivery was not confirmed");return}await Q.recordSetupEmailDelivery(w.setupTokenId,$.to,X.data.deliveryId?{deliveryId:X.data.deliveryId}:{})}}function XBQ(A,Q){if(typeof A==="string"){let w=new Date(Q.expiresAt*1000).toISOString(),$=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 ${w}.`,`Dashboard: ${$}/`,`MCP endpoint: ${$}/mcp`,"The first successful passkey registration completes setup and closes this link."].join(`
2293
+ `)}}return{to:A.to,subject:LcA(A.subject,Q),body:LcA(A.body,Q)}}function LcA(A,Q){let w=new Date(Q.expiresAt*1000).toISOString(),$=new URL(Q.setupUrl).origin;return A.replaceAll("{{setupUrl}}",Q.setupUrl).replaceAll("{{expiresAt}}",w).replaceAll("{{origin}}",$)}function si(A={}){return new gC0(A)}C0();var yC0=f.object({transport:f.enum(["stdio","http"]).default("http"),mode:f.enum(["basic","debug"]).default("basic"),httpPort:f.number().describe("Port for HTTP transport (only used when transport is 'http')").default(3333),authToken:f.string().describe("Bearer token for HTTP transport authentication").optional(),sessionIdleTtlMs:f.number().describe("Idle time in ms after which an HTTP session is closed and evicted").default(1800000)});C0();import{createHash as HBQ,randomUUID as WBQ}from"crypto";function YBQ(A){return typeof A==="object"&&A!==null&&!Array.isArray(A)}function ai(A,Q){let w=A?.[Q];return typeof w==="string"&&w.length>0?w:void 0}function ZBQ(A){let Q=YBQ(A.data)?A.data:void 0,w=A.args,$=ai(Q,"entityId")??ai(Q,"id"),B=A.jobId??ai(Q,"jobId"),X=ai(w,"entityType")??ai(w,"type");if(!$&&!B)return;return{toolName:A.toolName,...X?{entityType:X}:{},...$?{entityId:$}:{},...B?{jobId:B}:{}}}function fBQ(A){return A?.map(ZBQ).filter((Q)=>Q!==void 0)??[]}function EC0(A,Q={}){let w=A.pendingConfirmations?.[0];if(w)return{needsConfirmation:!0,toolName:w.toolName,summary:w.summary,...w.completionSummary?{completionSummary:w.completionSummary}:{},...w.preview?{preview:w.preview}:{},args:{approvalId:w.id,...Q.conversationId?{conversationId:Q.conversationId}:{},...w.toolCallId?{toolCallId:w.toolCallId}:{},originalArgs:w.args}};let $=fBQ(A.toolResults);return{success:!0,data:{text:A.text,...Q.conversationId?{conversationId:Q.conversationId}:{},...A.toolResults?{toolResults:A.toolResults}:{},...$.length>0?{readYourWrites:$}:{}}}}var kcA=f.object({message:f.string().min(1),conversationId:f.string().min(1).optional().describe("Opaque conversation handle returned by a previous chat call. Omit it to start a new isolated conversation.")}),_cA=f.object({approvalId:f.string().min(1),confirmed:f.boolean(),conversationId:f.string().min(1).describe("Exact conversation handle returned by the chat confirmation.")});function NcA(A,Q,w,$){let B=A.conversationId??w??$??`conversation-${WBQ()}`,X=HBQ("sha256").update(Q).digest("hex").slice(0,16);return{handle:B,internalId:`mcp:${X}:${B}`}}function jcA(A){return{userPermissionLevel:A.userPermissionLevel??"public",interfaceType:"mcp",...A.channelId?{channelId:A.channelId}:{},...A.channelName?{channelName:A.channelName}:{},actor:{actorId:A.userId,interfaceType:"mcp",role:"user"}}}function PcA(A,Q){return[{name:"chat",description:"Talk to the brain to make changes or get reasoned answers. Use this for any create/update/delete request or questions requiring reasoning across content. For simple lookups, use search/get/list directly.",inputSchema:kcA.shape,visibility:"public",sideEffects:"writes",handler:async(w,$)=>{let B=kcA.parse(w),X=Q();if(!X)return{success:!1,error:"MCP chat tool is not initialized."};let Y=NcA(B,$.userId,$.conversationId,$.channelId),Z=await X.agent.chat(B.message,Y.internalId,{...jcA($)});return EC0(Z,{conversationId:Y.handle})}},{name:"confirm",description:"Resolve a pending confirmation returned by chat. Use this only after chat returns needsConfirmation with an approvalId.",inputSchema:_cA.shape,visibility:"public",sideEffects:"writes",handler:async(w,$)=>{let B=_cA.parse(w),X=Q();if(!X)return{success:!1,error:"MCP confirm tool is not initialized."};let Y=NcA(B,$.userId,$.conversationId,$.channelId),Z=await X.agent.confirmPendingAction(Y.internalId,B.confirmed,B.approvalId,jcA($));return EC0(Z,{conversationId:Y.handle})}}]}fA();function TC0(A,Q){A.messaging.subscribe("job-progress",async(w)=>{let $=gx.safeParse(w.payload);if(!$.success)return Q.warn("Received invalid job-progress message",{error:$.error.message}),{success:!1};let B=$.data,X=B.type,Y=B.status,Z=B.id;if(Q.debug(`${X} ${Z} - ${Y}:`,{id:B.id,message:B.message,progress:B.progress,metadata:B.metadata}),B.batchDetails)Q.debug(`Batch details for ${Z}:`,{totalOperations:B.batchDetails.totalOperations,completedOperations:B.batchDetails.completedOperations,failedOperations:B.batchDetails.failedOperations,currentOperation:B.batchDetails.currentOperation,errors:B.batchDetails.errors});if(B.jobDetails)Q.debug(`Job details for ${Z}:`,{jobType:B.jobDetails.jobType,priority:B.jobDetails.priority,retryCount:B.jobDetails.retryCount});return{success:!0}}),Q.debug("Subscribed to job progress events")}var McA={name:"@brains/mcp",version:"0.2.0-alpha.159",dependencies:{"@brains/auth-service":"workspace:*","@brains/mcp-service":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*","@modelcontextprotocol/sdk":"^1.29.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.3.14","@types/cors":"^2.8.17",typescript:"^7.0.2"},files:["src"],main:"./src/index.ts",module:"./src/index.ts",private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module",types:"./src/index.ts"};class iF extends ZD{mcpTransport;stdioServer;httpServer;domain;constructor(A={}){let Q={...A,authToken:A.authToken??process.env.MCP_AUTH_TOKEN};super("mcp",McA,Q,yC0)}async getTools(){return PcA(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"});TC0(A,this.logger)}getOrCreateHttpServer(){if(this.httpServer)return this.httpServer;let A=s7();return this.httpServer=j3.createFresh({port:this.config.httpPort,logger:this.logger,sessionIdleTtlMs:this.config.sessionIdleTtlMs,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,mode:this.config.mode,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",w=this.context.permissions.getUserLevel("mcp",Q),$=s7(),B=this.config.transport==="http"&&(this.config.authToken?!0:$!==void 0);if(B)w="anchor",this.logger.debug("HTTP authentication configured - authenticated users will have anchor permissions");if(this.config.mode==="debug"){if(this.config.transport==="http"&&!B)throw Error("MCP debug mode requires authenticated HTTP transport; configure authToken or OAuth auth service.");if(w!=="anchor")throw Error("MCP debug mode requires anchor permissions.")}if(this.mcpTransport.setProtocolMode(this.config.mode),this.mcpTransport.setPermissionLevel(w),this.logger.debug(`Starting MCP ${this.config.transport} transport in ${this.config.mode} mode with ${w} permissions`),this.config.transport==="stdio"){this.stdioServer=qU.createFresh();let X=this.mcpTransport.getMcpServer();this.stdioServer.connectMCPServer(X),await this.stdioServer.start(),this.logger.debug("MCP STDIO transport started")}else{this.httpServer=this.getOrCreateHttpServer();let X=this.mcpTransport.getMcpServer();this.httpServer.connectMCPServer(X,this.mcpTransport),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(){qU.resetInstance(),j3.resetInstance()}}fA();function ti(A,Q=2000){if(A.length<=Q)return[A];let w=DBQ(A),$=[],B="";for(let X of w){let Y=B?`
2294
2294
 
2295
2295
  `:"";if(B.length+Y.length+X.length<=Q){B+=Y+X;continue}if(B)$.push(B),B="";if(X.length<=Q){B=X;continue}UBQ(X,Q,$,(Z)=>{B=Z})}if(B)$.push(B);return $}function UBQ(A,Q,w,$){let B="",X=A.split(`
2296
2296
  `);for(let Y of X){let Z=B?`
2297
2297
  `:"";if(B.length+Z.length+Y.length<=Q){B+=Z+Y;continue}if(B)w.push(B),B="";if(Y.length<=Q){B=Y;continue}GBQ(Y,Q,w,(H)=>{B=H})}$(B)}function GBQ(A,Q,w,$){let B="",X=A.split(" ");for(let Y of X){let Z=B?" ":"";if(B.length+Z.length+Y.length<=Q){B+=Z+Y;continue}if(B)w.push(B);if(Y.length>Q)for(let H=0;H<Y.length;H+=Q){let W=Y.slice(H,H+Q);if(H+Q>=Y.length)B=W;else w.push(W)}else B=Y}$(B)}function DBQ(A){let Q=[],w=A.split(`
2298
2298
  `),$="",B=!1;for(let X of w){if(X.startsWith("```"))B=!B;if(!B&&X===""&&$){Q.push($),$="";continue}$+=($?`
2299
- `:"")+X}if($)Q.push($);return Q}b2();var Cf=D1(Ac0(),1);fA();C0();var Qc0=f.object({botToken:f.string().min(1).describe("Discord bot token"),allowedChannels:f.array(f.string()).default([]),requireMention:f.boolean().default(!0),allowDMs:f.boolean().default(!0),showTypingIndicator:f.boolean().default(!0),statusMessage:f.string().default("Mention me to chat"),useThreads:f.boolean().default(!0),threadAutoArchive:f.union([f.literal(60),f.literal(1440),f.literal(4320),f.literal(10080)]).default(1440),...vu.shape,captureUrlEmoji:f.string().default("\uD83D\uDD16")});var mb1={name:"@brains/discord",version:"0.2.0-alpha.158",description:"Discord interface for Brains",dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*","discord.js":"^14.26.4"},devDependencies:{"@brains/core":"workspace:*","@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14"},exports:{".":"./src/index.ts","./env-schema":"./src/env-schema.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var En=2000,lcQ={completed:"Action completed",declined:"Action declined",failed:"Action failed"},pcQ={completed:2278750,declined:9741240,failed:15680580},icQ=8388608,dcQ=8000,ncQ=100;function _70(A){return!!A&&typeof A==="object"&&"send"in A&&"sendTyping"in A}class xb extends nK{client=null;fetchText;pendingConfirmations=new Map;typingIntervals=new Map;constructor(A,Q={}){super("discord",mb1,A,Qc0);this.fetchText=Q.fetchText??OMA}async onRegister(A){await super.onRegister(A),this.client=new Cf.Client({intents:[Cf.GatewayIntentBits.Guilds,Cf.GatewayIntentBits.GuildMessages,Cf.GatewayIntentBits.MessageContent,Cf.GatewayIntentBits.DirectMessages],partials:[Cf.Partials.Channel]}),this.client.on(Cf.Events.MessageCreate,(Q)=>{this.handleMessage(Q)}),this.client.on(Cf.Events.InteractionCreate,(Q)=>{this.handleInteraction(Q)}),this.client.once(Cf.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 w=this.client.channels.cache.get(A);if(!_70(w))return;let $=ti(Q,En);for(let B of $)w.send(B).catch((X)=>this.logger.error("Failed to send message",{error:X}))}async sendMessageWithId({channelId:A,message:Q,approvalCard:w,approvalCards:$}){let B=$??(w?[w]:[]),X=B.length>0?this.buildApprovalMessagePayload(Q,B):Q;return this.sendPayloadWithId(A,X)}async sendPayloadWithId(A,Q){if(!A||!this.client)return;let w=this.client.channels.cache.get(A);if(!_70(w))return;if(typeof Q!=="string")return(await w.send(Q)).id;let $=ti(Q,En),B;for(let X of $)B=(await w.send(X)).id;return B}async editMessage({channelId:A,messageId:Q,newMessage:w}){if(!A||!this.client)return!1;let $=this.client.channels.cache.get(A);if(!_70($))return!1;try{return await(await $.messages.fetch(Q)).edit(w.slice(0,En)),!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,w=A.channel.isThread();if(Q&&!this.config.allowDMs)return;let $=!!this.client?.user&&A.mentions.has(this.client.user,{ignoreEveryone:!0});if(A.author.bot&&!$)return;let B=w&&"ownerId"in A.channel&&A.channel.ownerId===this.client?.user?.id,X=this.getSpaceChannelId(A),Y=!Q&&this.isConfiguredSpace(X),Z={channelId:X,isBot:A.author.bot};if(this.config.allowedChannels.length>0&&!Q&&!this.isAllowedChannel(A.channel.id,X))return;let H=Q||B||!this.config.requireMention||$;if(Y&&(!H||this.willRouteUseNonSpaceConversation(A)))await this.capturePassiveSpaceMessage(A,X).catch((U)=>this.logger.error("Passive Discord space capture failed",{error:U,channelId:X}));if(!H){if(this.config.captureUrls){let U=this.extractCaptureableUrls(A.content,this.config.blockedUrlDomains);if(U.length>0){await A.react(this.config.captureUrlEmoji).catch((G)=>this.logger.debug("React failed",{error:G}));for(let G of U)await this.captureUrlViaAgent(G,A.channel.id,A.author.id,"discord",Z).catch((q)=>this.logger.error("URL capture failed",{error:q,url:G}))}}return}let W=this.stripMention(A.content);if(A.attachments.size>0){let U=this.context.permissions.getUserLevel("discord",A.author.id,Z);if(U==="anchor"||U==="trusted")for(let q of A.attachments.values()){let V=q.name,I=q.contentType??void 0,J=q.size;if(!this.isUploadableTextFile(V,I))continue;if(!this.isFileSizeAllowed(J))continue;try{let k=await this.fetchText(q.url);W+=`
2299
+ `:"")+X}if($)Q.push($);return Q}b2();var Cf=D1(Ac0(),1);fA();C0();var Qc0=f.object({botToken:f.string().min(1).describe("Discord bot token"),allowedChannels:f.array(f.string()).default([]),requireMention:f.boolean().default(!0),allowDMs:f.boolean().default(!0),showTypingIndicator:f.boolean().default(!0),statusMessage:f.string().default("Mention me to chat"),useThreads:f.boolean().default(!0),threadAutoArchive:f.union([f.literal(60),f.literal(1440),f.literal(4320),f.literal(10080)]).default(1440),...vu.shape,captureUrlEmoji:f.string().default("\uD83D\uDD16")});var mb1={name:"@brains/discord",version:"0.2.0-alpha.159",description:"Discord interface for Brains",dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*","discord.js":"^14.26.4"},devDependencies:{"@brains/core":"workspace:*","@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14"},exports:{".":"./src/index.ts","./env-schema":"./src/env-schema.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var En=2000,lcQ={completed:"Action completed",declined:"Action declined",failed:"Action failed"},pcQ={completed:2278750,declined:9741240,failed:15680580},icQ=8388608,dcQ=8000,ncQ=100;function _70(A){return!!A&&typeof A==="object"&&"send"in A&&"sendTyping"in A}class xb extends nK{client=null;fetchText;pendingConfirmations=new Map;typingIntervals=new Map;constructor(A,Q={}){super("discord",mb1,A,Qc0);this.fetchText=Q.fetchText??OMA}async onRegister(A){await super.onRegister(A),this.client=new Cf.Client({intents:[Cf.GatewayIntentBits.Guilds,Cf.GatewayIntentBits.GuildMessages,Cf.GatewayIntentBits.MessageContent,Cf.GatewayIntentBits.DirectMessages],partials:[Cf.Partials.Channel]}),this.client.on(Cf.Events.MessageCreate,(Q)=>{this.handleMessage(Q)}),this.client.on(Cf.Events.InteractionCreate,(Q)=>{this.handleInteraction(Q)}),this.client.once(Cf.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 w=this.client.channels.cache.get(A);if(!_70(w))return;let $=ti(Q,En);for(let B of $)w.send(B).catch((X)=>this.logger.error("Failed to send message",{error:X}))}async sendMessageWithId({channelId:A,message:Q,approvalCard:w,approvalCards:$}){let B=$??(w?[w]:[]),X=B.length>0?this.buildApprovalMessagePayload(Q,B):Q;return this.sendPayloadWithId(A,X)}async sendPayloadWithId(A,Q){if(!A||!this.client)return;let w=this.client.channels.cache.get(A);if(!_70(w))return;if(typeof Q!=="string")return(await w.send(Q)).id;let $=ti(Q,En),B;for(let X of $)B=(await w.send(X)).id;return B}async editMessage({channelId:A,messageId:Q,newMessage:w}){if(!A||!this.client)return!1;let $=this.client.channels.cache.get(A);if(!_70($))return!1;try{return await(await $.messages.fetch(Q)).edit(w.slice(0,En)),!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,w=A.channel.isThread();if(Q&&!this.config.allowDMs)return;let $=!!this.client?.user&&A.mentions.has(this.client.user,{ignoreEveryone:!0});if(A.author.bot&&!$)return;let B=w&&"ownerId"in A.channel&&A.channel.ownerId===this.client?.user?.id,X=this.getSpaceChannelId(A),Y=!Q&&this.isConfiguredSpace(X),Z={channelId:X,isBot:A.author.bot};if(this.config.allowedChannels.length>0&&!Q&&!this.isAllowedChannel(A.channel.id,X))return;let H=Q||B||!this.config.requireMention||$;if(Y&&(!H||this.willRouteUseNonSpaceConversation(A)))await this.capturePassiveSpaceMessage(A,X).catch((U)=>this.logger.error("Passive Discord space capture failed",{error:U,channelId:X}));if(!H){if(this.config.captureUrls){let U=this.extractCaptureableUrls(A.content,this.config.blockedUrlDomains);if(U.length>0){await A.react(this.config.captureUrlEmoji).catch((G)=>this.logger.debug("React failed",{error:G}));for(let G of U)await this.captureUrlViaAgent(G,A.channel.id,A.author.id,"discord",Z).catch((q)=>this.logger.error("URL capture failed",{error:q,url:G}))}}return}let W=this.stripMention(A.content);if(A.attachments.size>0){let U=this.context.permissions.getUserLevel("discord",A.author.id,Z);if(U==="anchor"||U==="trusted")for(let q of A.attachments.values()){let V=q.name,I=q.contentType??void 0,J=q.size;if(!this.isUploadableTextFile(V,I))continue;if(!this.isFileSizeAllowed(J))continue;try{let k=await this.fetchText(q.url);W+=`
2300
2300
 
2301
2301
  `+this.formatFileUploadMessage(V,k)}catch(k){this.logger.error("Failed to download attachment",{error:k,filename:V})}}}if(W=W.trim(),!W)return;let K=A.channel.id;await this.routeToAgent(W,K,A,Z)}async handleInteraction(A){if(!this.context||!A.isButton())return;let Q=this.parseApprovalButtonCustomId(A.customId);if(!Q)return;let w=`discord-${A.channelId}`;if(!this.pendingConfirmations.get(w)?.has(Q.approvalId)){await A.reply({content:"This approval is no longer pending or has changed.",ephemeral:!0}).catch((Y)=>this.logger.debug("Failed to reply to stale approval button",{error:Y}));return}await A.deferUpdate().catch((Y)=>this.logger.debug("Failed to defer approval button",{error:Y})),await this.clearApprovalInteractionComponents(A);let B=this.buildInteractionConfirmationContext(A),X=await this.context.agent.confirmPendingAction(w,Q.confirmed,Q.approvalId,B);await this.handleAgentResponseToolStatuses(X,w),this.syncPendingApprovalsAfterResolution(w,Q.approvalId,X),await this.sendApprovalResultMessage({channelId:A.channelId,response:X,userPermissionLevel:B.userPermissionLevel??"public"})}async clearApprovalInteractionComponents(A){await A.message.edit({components:[]}).catch((Q)=>this.logger.debug("Failed to clear approval buttons",{error:Q}))}buildInteractionConfirmationContext(A){if(!this.context)throw Error("Discord context is not registered");return{userPermissionLevel:this.context.permissions.getUserLevel("discord",A.user.id,{channelId:A.channelId}),interfaceType:"discord",channelId:A.channelId,actor:{actorId:`discord:${A.user.id}`,interfaceType:"discord",role:"user",displayName:A.user.displayName,username:A.user.username,isBot:Boolean(A.user.bot)}}}async capturePassiveSpaceMessage(A,Q){if(!this.context)return;let w=this.stripMention(A.content).trim();if(!w)return;let $=`discord-${Q}`,B=this.getChannelName(A);await this.context.conversations.start({sessionId:$,interfaceType:"discord",channelId:Q,metadata:{channelName:B,interfaceType:"discord",channelId:Q}}),await this.context.conversations.addMessage({conversationId:$,role:"user",content:w,metadata:this.buildUserMessageMetadata(A,Q,B,{threadId:A.channel.isThread()?A.channel.id:void 0})})}async routeToAgent(A,Q,w,$){if(!this.context)return;let B=this.context.agent,X=Q;if(this.config.useThreads&&w.guild&&!w.channel.isThread())try{X=(await w.startThread({name:mX(A,ncQ),autoArchiveDuration:this.config.threadAutoArchive})).id}catch(W){this.logger.error("Failed to create thread",{error:W})}let Y=`discord-${X}`,Z=this.context.permissions.getUserLevel("discord",w.author.id,$),H=this.getChannelName(w);this.startProcessingInput(X);try{let W=this.client?.channels.cache.get(X);if(_70(W))this.startTypingIndicator(W);if(this.pendingConfirmations.has(Y)){if(await this.handleConfirmationResponse(A,Y,X,w,$))return}let K=await B.chat(A,Y,{userPermissionLevel:Z,interfaceType:"discord",channelId:X,channelName:H,...this.buildUserMessageMetadata(w,Q,H,{threadId:X!==Q||w.channel.isThread()?X:void 0})});await this.handleAgentResponseToolStatuses(K,Y);let U=P_(K.cards);if(U.length>0)this.pendingConfirmations.set(Y,new Set(U.map((q)=>q.id)));else if(K.pendingConfirmations)this.pendingConfirmations.set(Y,new Set(K.pendingConfirmations.map((q)=>q.id)));else this.pendingConfirmations.delete(Y);let G=await this.sendMessageWithId({channelId:X,message:JR(K.text,U),approvalCards:U});if(G&&K.toolResults){for(let q of K.toolResults)if(q.jobId)this.trackAgentResponseForJob(q.jobId,G,X)}}catch(W){this.logger.error("Error handling message",{error:W,channelId:X}),this.sendMessageToChannel({channelId:X,message:`**Error:** ${W instanceof Error?W.message:"Unknown error"}`})}finally{this.endProcessingInput(),this.stopTypingIndicator(X)}}buildApprovalMessagePayload(A,Q){let w=Q.length>1;return{content:mX(A.trim().length>0?`${A}
2302
2302
 
@@ -2366,7 +2366,7 @@ ${A.value}
2366
2366
  `);if(M70(A))return this.renderList(A,0,(Q)=>this.nodeToDiscordMarkdown(Q));if(A.type==="break")return`
2367
2367
  `;if(A.type==="thematicBreak")return"---";if(Ul0(A))return`\`\`\`
2368
2368
  ${Gl0(A)}
2369
- \`\`\``;return this.defaultNodeToText(A,(Q)=>this.nodeToDiscordMarkdown(Q))}};var Yh1={DeferredChannelMessageWithSource:5,DeferredUpdateMessage:6},S70="https://discord.com/api/v10",Zh1=2000,PsQ=/^[0-9a-f]{64}$/,MsQ=/^[0-9a-f]+$/,OsQ=class A{name="discord";userName;botUserId;apiBaseUrl;botToken;publicKey;applicationId;mentionRoleIds;interactionFlags;chat=null;logger;formatConverter=new jsQ;requestContext=new zsQ;threadParentCache=new Map;static THREAD_PARENT_CACHE_TTL=300000;constructor(Q={}){let w=Q.botToken??process.env.DISCORD_BOT_TOKEN;if(!w)throw new pW("discord","botToken is required. Set DISCORD_BOT_TOKEN or provide it in config.");let $=Q.publicKey??process.env.DISCORD_PUBLIC_KEY;if(!$)throw new pW("discord","publicKey is required. Set DISCORD_PUBLIC_KEY or provide it in config.");let B=Q.applicationId??process.env.DISCORD_APPLICATION_ID;if(!B)throw new pW("discord","applicationId is required. Set DISCORD_APPLICATION_ID or provide it in config.");if(this.apiBaseUrl=Q.apiUrl??process.env.DISCORD_API_URL??S70,this.botToken=w,this.publicKey=$.trim().toLowerCase(),this.applicationId=B,this.mentionRoleIds=Q.mentionRoleIds??(process.env.DISCORD_MENTION_ROLE_IDS?process.env.DISCORD_MENTION_ROLE_IDS.split(",").map((X)=>X.trim()):[]),this.botUserId=B,this.interactionFlags=Q.interactionFlags,this.logger=Q.logger??new g70("info").child("discord"),this.userName=Q.userName??"bot",!PsQ.test(this.publicKey))this.logger.error("Invalid Discord public key format",{length:this.publicKey.length,isHex:MsQ.test(this.publicKey)})}async initialize(Q){this.chat=Q,this.logger.info("Discord adapter initialized")}async getUser(Q){try{let $=await(await this.discordFetch(`/users/${Q}`,"GET")).json();return{avatarUrl:$.avatar?`https://cdn.discordapp.com/avatars/${$.id}/${$.avatar}.png`:void 0,email:void 0,fullName:$.global_name||$.username,isBot:$.bot??!1,userId:$.id,userName:$.username}}catch{return null}}async handleWebhook(Q,w){let $=await Q.arrayBuffer(),B=new Uint8Array($),X=new TextDecoder().decode(B),Y=Q.headers.get("x-discord-gateway-token");if(Y){if(Y!==this.botToken)return this.logger.warn("Invalid gateway token"),new Response("Invalid gateway token",{status:401});this.logger.info("Discord forwarded Gateway event received");try{let U=JSON.parse(X);return this.handleForwardedGatewayEvent(U,w)}catch{return new Response("Invalid JSON",{status:400})}}this.logger.info("Discord webhook received",{bodyLength:X.length,bodyBytesLength:B.length,hasSignature:!!Q.headers.get("x-signature-ed25519"),hasTimestamp:!!Q.headers.get("x-signature-timestamp")});let Z=Q.headers.get("x-signature-ed25519"),H=Q.headers.get("x-signature-timestamp");if(!await this.verifySignature(B,Z,H))return this.logger.warn("Discord signature verification failed, returning 401"),new Response("Invalid signature",{status:401});this.logger.info("Discord signature verification passed");let K;try{K=JSON.parse(X)}catch{return new Response("Invalid JSON",{status:400})}if(this.logger.info("Discord interaction parsed",{type:K.type,typeIsPing:K.type===Tg.Ping,expectedPingType:Tg.Ping,id:K.id}),K.type===Tg.Ping){let U=JSON.stringify({type:sn.InteractionResponseType.PONG});return this.logger.info("Discord PING received, responding with PONG",{responseBody:U,responseType:sn.InteractionResponseType.PONG}),new Response(U,{status:200,headers:{"Content-Type":"application/json"}})}if(K.type===Tg.MessageComponent)return this.handleComponentInteraction(K,w),this.respondToInteraction({type:Yh1.DeferredUpdateMessage});if(K.type===Tg.ApplicationCommand){let U=this.getApplicationCommandContext(K),G=this.getInteractionFlags(U);return this.handleApplicationCommandInteraction(U,w),this.respondToInteraction({...G===void 0?{}:{data:{flags:G}},type:Yh1.DeferredChannelMessageWithSource})}return new Response("Unknown interaction type",{status:400})}async verifySignature(Q,w,$){if(!(w&&$))return this.logger.warn("Discord signature verification failed: missing headers",{hasSignature:!!w,hasTimestamp:!!$}),!1;try{this.logger.info("Discord signature verification attempt",{bodyBytesLength:Q.length,signatureLength:w.length,timestampLength:$.length,publicKeyLength:this.publicKey.length,timestamp:$,signaturePrefix:w.slice(0,16),publicKey:this.publicKey});let B=await sn.verifyKey(Q,w,$,this.publicKey);if(!B){let X=new TextDecoder().decode(Q);this.logger.warn("Discord signature verification failed: invalid signature",{publicKeyLength:this.publicKey.length,signatureLength:w.length,publicKeyPrefix:this.publicKey.slice(0,8),publicKeySuffix:this.publicKey.slice(-8),timestamp:$,bodyLength:Q.length,bodyPrefix:X.slice(0,50)})}return B}catch(B){return this.logger.warn("Discord signature verification failed: exception",{error:B}),!1}}respondToInteraction(Q){return Response.json(Q)}handleComponentInteraction(Q,w){if(!this.chat){this.logger.warn("Chat instance not initialized, ignoring interaction");return}let $=Q.data?.custom_id;if(!$){this.logger.warn("No custom_id in component interaction");return}let B=Q.member?.user||Q.user;if(!B){this.logger.warn("No user in component interaction");return}let X=Q.channel_id,Y=Q.guild_id||"@me",Z=Q.message?.id;if(!(X&&Z)){this.logger.warn("Missing channel_id or message_id in interaction");return}let H=Q.channel,W=H?.type===11||H?.type===12,K=W&&H?.parent_id?H.parent_id:X,U=W?this.encodeThreadId({guildId:Y,channelId:K,threadId:X}):this.encodeThreadId({guildId:Y,channelId:X}),G=JsQ($),q={actionId:G.actionId,value:G.value??G.actionId,user:{userId:B.id,userName:B.username,fullName:B.global_name||B.username,isBot:B.bot??!1,isMe:!1},messageId:Z,threadId:U,adapter:this,raw:Q};this.logger.debug("Processing Discord button action",{actionId:$,messageId:Z,threadId:U}),this.chat.processAction(q,w)}getApplicationCommandContext(Q){let w=Q.data?.name;if(!w)return this.logger.warn("No command name in application command interaction"),null;let $=Q.member?.user||Q.user;if(!$)return this.logger.warn("No user in application command interaction"),null;let B=Q.channel_id;if(!B)return this.logger.warn("Missing channel_id in application command interaction"),null;let X=Q.guild_id||"@me",Y=Q.channel,Z=Y?.type===11||Y?.type===12,H=Z&&Y?.parent_id?Y.parent_id:B,W=Z?this.encodeThreadId({guildId:X,channelId:H,threadId:B}):this.encodeThreadId({guildId:X,channelId:B}),{command:K,text:U}=this.parseSlashCommand(w,Q.data?.options);return{channelId:W,command:K,interaction:Q,text:U,user:$}}getInteractionFlags(Q){if(!(Q&&this.interactionFlags))return;return this.interactionFlags(Q)}handleApplicationCommandInteraction(Q,w){if(!this.chat){this.logger.warn("Chat instance not initialized, ignoring interaction");return}if(!Q)return;let{channelId:$,command:B,interaction:X,text:Y,user:Z}=Q;this.logger.debug("Processing Discord slash command",{command:B,text:Y,userId:Z.id,channelId:$}),this.requestContext.run({slashCommand:{channelId:$,interactionToken:X.token,initialResponseSent:!1}},()=>{this.chat?.processSlashCommand({command:B,text:Y,user:{userId:Z.id,userName:Z.username,fullName:Z.global_name||Z.username,isBot:Z.bot??!1,isMe:Z.id===this.applicationId},adapter:this,raw:X,channelId:$},w)})}parseSlashCommand(Q,w){let $=[Q.startsWith("/")?Q:`/${Q}`],B=[],X=(Y)=>{for(let Z of Y){if(Z.value!==void 0){B.push(String(Z.value));continue}if(Z.options&&Z.options.length>0)$.push(Z.name),X(Z.options)}};if(w&&w.length>0)X(w);return{command:$.join(" "),text:B.join(" ").trim()}}async handleGatewayInteraction(Q){if(Q.isChatInputCommand()){let w=this.getApplicationCommandContext(this.normalizeGatewaySlashCommandInteraction(Q)),$=this.getInteractionFlags(w);await Q.deferReply($===void 0?void 0:{flags:$}),this.handleApplicationCommandInteraction(w);return}if(Q.isMessageComponent())await Q.deferUpdate(),this.handleComponentInteraction(this.normalizeGatewayComponentInteraction(Q))}normalizeGatewaySlashCommandInteraction(Q){return{application_id:Q.applicationId,channel:this.normalizeGatewayChannel(Q),channel_id:Q.channelId??void 0,data:{name:Q.commandName,options:this.normalizeGatewayCommandOptions(Q.options.data),type:Q.commandType},guild_id:Q.guildId??void 0,id:Q.id,token:Q.token,type:Q.type,user:this.normalizeGatewayUser(Q.user),version:Q.version}}normalizeGatewayComponentInteraction(Q){let w="values"in Q&&Array.isArray(Q.values)?Q.values:void 0;return{application_id:Q.applicationId,channel:this.normalizeGatewayChannel(Q),channel_id:Q.channelId??void 0,data:{component_type:Q.componentType,custom_id:Q.customId,values:w},guild_id:Q.guildId??void 0,id:Q.id,message:{id:Q.message.id},token:Q.token,type:Q.type,user:this.normalizeGatewayUser(Q.user),version:Q.version}}normalizeGatewayChannel(Q){if(!Q.channel)return;let w="parentId"in Q.channel&&typeof Q.channel.parentId==="string"?Q.channel.parentId:void 0;return{id:Q.channel.id,parent_id:w,type:Q.channel.type}}normalizeGatewayCommandOptions(Q){return Q.map((w)=>({name:w.name,options:w.options?this.normalizeGatewayCommandOptions(w.options):void 0,type:w.type,value:w.value}))}normalizeGatewayUser(Q){return{avatar:Q.avatar??void 0,bot:Q.bot,discriminator:Q.discriminator,global_name:Q.globalName??void 0,id:Q.id,username:Q.username}}async handleForwardedGatewayEvent(Q,w){switch(this.logger.info("Processing forwarded Gateway event",{type:Q.type,timestamp:Q.timestamp}),Q.type){case"GATEWAY_MESSAGE_CREATE":await this.handleForwardedMessage(Q.data,w);break;case"GATEWAY_MESSAGE_REACTION_ADD":await this.handleForwardedReaction(Q.data,!0,w);break;case"GATEWAY_MESSAGE_REACTION_REMOVE":await this.handleForwardedReaction(Q.data,!1,w);break;default:this.logger.debug("Forwarded Gateway event (no handler)",{type:Q.type})}return new Response(JSON.stringify({ok:!0}),{status:200,headers:{"Content-Type":"application/json"}})}async handleForwardedMessage(Q,w){if(!this.chat)return;let $=Q.guild_id||"@me",B=Q.channel_id,X,Y=B;if(Q.thread)X=Q.thread.id,Y=Q.thread.parent_id;else if(Q.channel_type===11||Q.channel_type===12)try{let q=await(await this.discordFetch(`/channels/${B}`,"GET")).json();if(q.parent_id)X=B,Y=q.parent_id,this.logger.debug("Fetched thread parent for forwarded message",{threadId:B,parentId:q.parent_id})}catch(G){this.logger.error("Failed to fetch thread parent",{error:String(G),channelId:B})}let Z=Q.is_mention||Q.mentions.some((G)=>G.id===this.applicationId),H=this.mentionRoleIds.length>0&&Q.mention_roles?.some((G)=>this.mentionRoleIds.includes(G)),W=Z||H;if(!X&&W)try{let G=await this.createDiscordThread(B,Q.id);X=G.id,this.logger.debug("Created Discord thread for forwarded mention",{channelId:B,messageId:Q.id,threadId:G.id})}catch(G){this.logger.error("Failed to create Discord thread for mention",{error:String(G),messageId:Q.id})}let K=this.encodeThreadId({guildId:$,channelId:Y,threadId:X}),U=new U5({id:Q.id,threadId:K,text:Q.content,formatted:this.formatConverter.toAst(Q.content),author:{userId:Q.author.id,userName:Q.author.username,fullName:Q.author.global_name||Q.author.username,isBot:Q.author.bot===!0,isMe:Q.author.id===this.applicationId},metadata:{dateSent:new Date(Q.timestamp),edited:!1},attachments:Q.attachments.map((G)=>({type:this.getAttachmentType(G.content_type),url:G.url,name:G.filename,mimeType:G.content_type,size:G.size})),raw:Q,isMention:W});try{await this.chat.handleIncomingMessage(this,K,U)}catch(G){this.logger.error("Error handling forwarded message",{error:String(G),messageId:Q.id})}}async handleForwardedReaction(Q,w,$){if(!this.chat)return;let B=Q.guild_id||"@me",X=Q.channel_id,Y,Z=X;if(Q.channel_type===AP.GuildPublicThread||Q.channel_type===AP.GuildPrivateThread){let q=this.threadParentCache.get(X);if(q&&q.expiresAt>Date.now())Y=X,Z=q.parentId;else try{let I=await(await this.discordFetch(`/channels/${X}`,"GET")).json();if(I.parent_id)Y=X,Z=I.parent_id,this.threadParentCache.set(X,{parentId:I.parent_id,expiresAt:Date.now()+A.THREAD_PARENT_CACHE_TTL})}catch(V){this.logger.error("Failed to fetch thread parent for reaction",{error:String(V),channelId:X})}}let H=this.encodeThreadId({guildId:B,channelId:Z,threadId:Y}),W=Q.emoji.name||"unknown",K=this.normalizeDiscordEmoji(W),U=Q.user??Q.member?.user;if(!U){this.logger.warn("Reaction event missing user info",{data:Q});return}let G={adapter:this,threadId:H,messageId:Q.message_id,emoji:K,rawEmoji:Q.emoji.id?`<:${W}:${Q.emoji.id}>`:W,added:w,user:{userId:U.id,userName:U.username,fullName:U.username,isBot:U.bot===!0,isMe:U.id===this.applicationId},raw:Q};this.chat.processReaction(G)}async postMessage(Q,w){let{channelId:$,threadId:B}=this.decodeThreadId(Q),X=Q;if(B)$=B;let Y={},Z=[],H=[],W=T70(w);if(W){let V=tl0(W);Z.push(...V.embeds),H.push(...V.components)}else Y.content=this.truncateContent(sj(this.formatConverter.renderPostable(w),"discord"));if(Z.length>0)Y.embeds=Z;if(H.length>0)Y.components=H;let K=xl0(w),U=this.tryPostSlashResponse(X,Y,K);if(U)return U;if(K.length>0)return this.postMessageWithFiles($,X,Y,K);this.logger.debug("Discord API: POST message",{channelId:$,contentLength:Y.content?.length||0,embedCount:Z.length,componentCount:H.length});let q=await(await this.discordFetch(`/channels/${$}/messages`,"POST",Y)).json();return this.logger.debug("Discord API: POST message response",{messageId:q.id}),{id:q.id,threadId:X,raw:q}}tryPostSlashResponse(Q,w,$){let B=this.requestContext.getStore()?.slashCommand;if(!B||B.channelId!==Q)return;return this.postSlashCommandResponse(B,Q,w,$)}async postSlashCommandResponse(Q,w,$,B){let X=!Q.initialResponseSent;Q.initialResponseSent=!0;let Y=X?`/webhooks/${this.applicationId}/${Q.interactionToken}/messages/@original`:`/webhooks/${this.applicationId}/${Q.interactionToken}?wait=true`,Z=X?"PATCH":"POST";this.logger.debug("Discord interaction webhook: responding to slash command",{threadId:w,isInitialResponse:X,hasFiles:B.length>0});let W=await(B.length>0?await this.discordInteractionFetchWithFiles(Y,Z,$,B):await this.discordInteractionFetch(Y,Z,$)).json();return{id:W.id,threadId:w,raw:W}}async createDiscordThread(Q,w){let $=`Thread ${new Date().toLocaleString()}`;this.logger.debug("Discord API: POST thread",{channelId:Q,messageId:w,threadName:$});try{let X=await(await this.discordFetch(`/channels/${Q}/messages/${w}/threads`,"POST",{name:$,auto_archive_duration:1440})).json();return this.logger.debug("Discord API: POST thread response",{threadId:X.id,threadName:X.name}),X}catch(B){if(B instanceof Cb&&typeof B.message==="string"&&B.message.includes('"code"')&&B.message.includes("160004"))return this.logger.debug("Thread already exists for message, reusing existing thread",{channelId:Q,messageId:w}),{id:w,name:$};throw B}}truncateContent(Q){if(Q.length<=Zh1)return Q;return`${Q.slice(0,Zh1-3)}...`}async postMessageWithFiles(Q,w,$,B){let X=new FormData;X.append("payload_json",JSON.stringify($));for(let H=0;H<B.length;H++){let W=B[H];if(!W)continue;let K=await Rl0(W.data,{platform:"discord"});if(!K)continue;let U=new Blob([new Uint8Array(K)],{type:W.mimeType||"application/octet-stream"});X.append(`files[${H}]`,U,W.filename)}let Y=await fetch(`${S70}/channels/${Q}/messages`,{method:"POST",headers:{Authorization:`Bot ${this.botToken}`},body:X});if(!Y.ok){let H=await Y.text();throw new Cb("discord",`Failed to post message: ${Y.status} ${H}`)}let Z=await Y.json();return{id:Z.id,threadId:w,raw:Z}}async discordInteractionFetch(Q,w,$){let B=await fetch(`${S70}${Q}`,{method:w,headers:$?{"Content-Type":"application/json"}:void 0,body:$?JSON.stringify($):void 0});if(!B.ok){let X=await B.text();throw this.logger.error("Discord interaction API error",{path:Q,method:w,status:B.status,error:X}),new Cb("discord",`Discord interaction API error: ${B.status} ${X}`)}return B}async discordInteractionFetchWithFiles(Q,w,$,B){let X=new FormData;X.append("payload_json",JSON.stringify($));for(let Z=0;Z<B.length;Z++){let H=B[Z];if(!H)continue;let W=await Rl0(H.data,{platform:"discord"});if(!W)continue;let K=new Blob([new Uint8Array(W)],{type:H.mimeType||"application/octet-stream"});X.append(`files[${Z}]`,K,H.filename)}let Y=await fetch(`${S70}${Q}`,{method:w,body:X});if(!Y.ok){let Z=await Y.text();throw this.logger.error("Discord interaction API error",{path:Q,method:w,status:Y.status,error:Z}),new Cb("discord",`Discord interaction API error: ${Y.status} ${Z}`)}return Y}async editMessage(Q,w,$){let{channelId:B,threadId:X}=this.decodeThreadId(Q),Y=X||B,Z={},H=[],W=[],K=T70($);if(K){let q=tl0(K);H.push(...q.embeds),W.push(...q.components),Z.content=""}else Z.content=this.truncateContent(sj(this.formatConverter.renderPostable($),"discord"));if(H.length>0)Z.embeds=H;if(W.length>0)Z.components=W;this.logger.debug("Discord API: PATCH message",{channelId:Y,messageId:w,contentLength:Z.content?.length||0});let G=await(await this.discordFetch(`/channels/${Y}/messages/${w}`,"PATCH",Z)).json();return this.logger.debug("Discord API: PATCH message response",{messageId:G.id}),{id:G.id,threadId:Q,raw:G}}async deleteMessage(Q,w){let{channelId:$,threadId:B}=this.decodeThreadId(Q),X=B||$;this.logger.debug("Discord API: DELETE message",{channelId:X,messageId:w}),await this.discordFetch(`/channels/${X}/messages/${w}`,"DELETE"),this.logger.debug("Discord API: DELETE message response",{ok:!0})}async addReaction(Q,w,$){let{channelId:B,threadId:X}=this.decodeThreadId(Q),Y=X||B,Z=this.encodeEmoji($);this.logger.debug("Discord API: PUT reaction",{channelId:Y,messageId:w,emoji:Z}),await this.discordFetch(`/channels/${Y}/messages/${w}/reactions/${Z}/@me`,"PUT"),this.logger.debug("Discord API: PUT reaction response",{ok:!0})}async removeReaction(Q,w,$){let{channelId:B,threadId:X}=this.decodeThreadId(Q),Y=X||B,Z=this.encodeEmoji($);this.logger.debug("Discord API: DELETE reaction",{channelId:Y,messageId:w,emoji:Z}),await this.discordFetch(`/channels/${Y}/messages/${w}/reactions/${Z}/@me`,"DELETE"),this.logger.debug("Discord API: DELETE reaction response",{ok:!0})}encodeEmoji(Q){let w=pn.toDiscord?pn.toDiscord(Q):String(Q);return encodeURIComponent(w)}async startTyping(Q,w){let{channelId:$,threadId:B}=this.decodeThreadId(Q),X=B||$;this.logger.debug("Discord API: POST typing",{channelId:X}),await this.discordFetch(`/channels/${X}/typing`,"POST")}async fetchMessages(Q,w={}){let{channelId:$,threadId:B}=this.decodeThreadId(Q),X=B||$,Y=w.limit||50,Z=w.direction??"backward",H=new URLSearchParams;if(H.set("limit",String(Y)),w.cursor)if(Z==="backward")H.set("before",w.cursor);else H.set("after",w.cursor);this.logger.debug("Discord API: GET messages",{channelId:X,limit:Y,direction:Z,cursor:w.cursor});let K=await(await this.discordFetch(`/channels/${X}/messages?${H.toString()}`,"GET")).json();this.logger.debug("Discord API: GET messages response",{messageCount:K.length});let G=[...K].reverse().map((V)=>this.parseDiscordMessage(V,Q)),q;if(K.length===Y)if(Z==="backward")q=K.at(-1)?.id;else q=K[0]?.id;return{messages:G,nextCursor:q}}async fetchThread(Q){let{channelId:w,guildId:$}=this.decodeThreadId(Q);this.logger.debug("Discord API: GET channel",{channelId:w});let X=await(await this.discordFetch(`/channels/${w}`,"GET")).json();return{id:Q,channelId:w,channelName:X.name,isDM:X.type===AP.DM||X.type===AP.GroupDM,metadata:{guildId:$,channelType:X.type,raw:X}}}async openDM(Q){this.logger.debug("Discord API: POST DM channel",{userId:Q});let $=await(await this.discordFetch("/users/@me/channels","POST",{recipient_id:Q})).json();return this.logger.debug("Discord API: POST DM channel response",{channelId:$.id}),this.encodeThreadId({guildId:"@me",channelId:$.id})}isDM(Q){let{guildId:w}=this.decodeThreadId(Q);return w==="@me"}encodeThreadId(Q){let w=Q.threadId?`:${Q.threadId}`:"";return`discord:${Q.guildId}:${Q.channelId}${w}`}decodeThreadId(Q){let w=Q.split(":");if(w.length<3||w[0]!=="discord")throw new pW("discord",`Invalid Discord thread ID: ${Q}`);return{guildId:w[1],channelId:w[2],threadId:w[3]}}parseMessage(Q){let w=Q,$=w.guild_id||"@me",B=this.encodeThreadId({guildId:$,channelId:w.channel_id});return this.parseDiscordMessage(w,B)}parseDiscordMessage(Q,w){let $=Q.type===BM1.ThreadStarterMessage&&Q.referenced_message?Q.referenced_message:Q,B=$.author,X=B.bot??!1,Y=B.id===this.botUserId;return new U5({id:$.id,threadId:w,text:this.formatConverter.extractPlainText($.content),formatted:this.formatConverter.toAst($.content),raw:Q,author:{userId:B.id,userName:B.username,fullName:B.global_name||B.username,isBot:X,isMe:Y},metadata:{dateSent:new Date($.timestamp),edited:$.edited_timestamp!==null,editedAt:$.edited_timestamp?new Date($.edited_timestamp):void 0},attachments:($.attachments||[]).map((Z)=>({type:this.getAttachmentType(Z.content_type),url:Z.url,name:Z.filename,mimeType:Z.content_type,size:Z.size,width:Z.width??void 0,height:Z.height??void 0}))})}getAttachmentType(Q){if(!Q)return"file";if(Q.startsWith("image/"))return"image";if(Q.startsWith("video/"))return"video";if(Q.startsWith("audio/"))return"audio";return"file"}rehydrateAttachment(Q){let w=Q.fetchMetadata?.url??Q.url;if(!w)return Q;return{...Q,fetchData:()=>this.downloadAttachment(w)}}async downloadAttachment(Q){let w;try{w=await fetch(Q)}catch($){throw new Cb("discord","Failed to download Discord attachment",$ instanceof Error?$:void 0)}if(!w.ok)throw new Cb("discord",`Failed to download Discord attachment: ${w.status}`);return Buffer.from(await w.arrayBuffer())}renderFormatted(Q){return this.formatConverter.fromAst(Q)}async discordFetch(Q,w,$){let B=`${this.apiBaseUrl}${Q}`,X={Authorization:`Bot ${this.botToken}`};if($)X["Content-Type"]="application/json";let Y=await fetch(B,{method:w,headers:X,body:$?JSON.stringify($):void 0});if(!Y.ok){let Z=await Y.text();throw this.logger.error("Discord API error",{path:Q,method:w,status:Y.status,error:Z}),new Cb("discord",`Discord API error: ${Y.status} ${Z}`)}return Y}async startGatewayListener(Q,w=180000,$,B){if(!this.chat)return new Response("Chat instance not initialized",{status:500});if(!Q.waitUntil)return new Response("waitUntil not provided",{status:500});this.logger.info("Starting Discord Gateway listener",{durationMs:w,webhookUrl:B?"configured":"not configured"});let X=this.runGatewayListener(w,$,B);return Q.waitUntil(X),new Response(JSON.stringify({status:"listening",durationMs:w,message:`Gateway listener started, will run for ${w/1000} seconds`}),{status:200,headers:{"Content-Type":"application/json"}})}async runGatewayListener(Q,w,$){let B=new _7.Client({intents:[_7.GatewayIntentBits.Guilds,_7.GatewayIntentBits.GuildMessages,_7.GatewayIntentBits.MessageContent,_7.GatewayIntentBits.DirectMessages,_7.GatewayIntentBits.GuildMessageReactions,_7.GatewayIntentBits.DirectMessageReactions],partials:[_7.Partials.Channel]}),X=!1;if($)B.on("raw",async(Y)=>{if(X)return;if(!Y.t)return;this.logger.info("Discord Gateway forwarding event",{type:Y.t}),await this.forwardGatewayEvent($,{type:`GATEWAY_${Y.t}`,timestamp:Date.now(),data:Y.d})});else this.setupLegacyGatewayHandlers(B,()=>X);B.on(_7.Events.ClientReady,()=>{this.logger.info("Discord Gateway connected",{username:B.user?.username,id:B.user?.id})}),B.on(_7.Events.Error,(Y)=>{this.logger.error("Discord Gateway error",{error:String(Y)})});try{await B.login(this.botToken),await new Promise((Y)=>{let Z=setTimeout(Y,Q);if(w){if(w.aborted){clearTimeout(Z),Y();return}w.addEventListener("abort",()=>{this.logger.info("Discord Gateway listener received abort signal (new listener started)"),clearTimeout(Z),Y()},{once:!0})}}),this.logger.info("Discord Gateway listener duration elapsed, disconnecting")}catch(Y){this.logger.error("Discord Gateway listener error",{error:String(Y)})}finally{X=!0,B.destroy(),this.logger.info("Discord Gateway listener stopped")}}setupLegacyGatewayHandlers(Q,w){Q.on(_7.Events.MessageCreate,async($)=>{if(w()){this.logger.debug("Ignoring message - Gateway is shutting down");return}if($.author.bot){this.logger.debug("Ignoring message from bot",{authorId:$.author.id,authorName:$.author.username,isMe:$.author.id===Q.user?.id});return}let B=$.mentions.has(Q.user?.id??""),X=this.mentionRoleIds.length>0&&$.mentions.roles.some((Z)=>this.mentionRoleIds.includes(Z.id)),Y=B||X;this.logger.info("Discord Gateway message received",{channelId:$.channelId,guildId:$.guildId,authorId:$.author.id,isMentioned:Y,isUserMentioned:B,isRoleMentioned:X,content:$.content.slice(0,100)}),await this.handleGatewayMessage($,Y)}),Q.on(_7.Events.InteractionCreate,async($)=>{if(w()){this.logger.debug("Ignoring interaction - Gateway is shutting down");return}this.logger.info("Discord Gateway interaction received",{id:$.id,type:$.type});try{await this.handleGatewayInteraction($)}catch(B){this.logger.error("Error handling Gateway interaction",{error:String(B),interactionId:$.id})}}),Q.on(_7.Events.MessageReactionAdd,async($,B)=>{if(w()){this.logger.debug("Ignoring reaction - Gateway is shutting down");return}if(B.bot){this.logger.debug("Ignoring reaction from bot",{userId:B.id,isMe:B.id===Q.user?.id});return}if(this.logger.info("Discord Gateway reaction added",{emoji:$.emoji.name,messageId:$.message.id,channelId:$.message.channelId,userId:B.id}),B.username)await this.handleGatewayReaction($,B,!0)}),Q.on(_7.Events.MessageReactionRemove,async($,B)=>{if(w()){this.logger.debug("Ignoring reaction removal - Gateway is shutting down");return}if(B.bot){this.logger.debug("Ignoring reaction removal from bot",{userId:B.id,isMe:B.id===Q.user?.id});return}if(this.logger.info("Discord Gateway reaction removed",{emoji:$.emoji.name,messageId:$.message.id,channelId:$.message.channelId,userId:B.id}),B.username)await this.handleGatewayReaction($,B,!1)})}async forwardGatewayEvent(Q,w){try{this.logger.debug("Forwarding Gateway event to webhook",{type:w.type,webhookUrl:Q});let $=await fetch(Q,{method:"POST",headers:{"Content-Type":"application/json","x-discord-gateway-token":this.botToken},body:JSON.stringify(w)});if($.ok)this.logger.debug("Gateway event forwarded successfully",{type:w.type});else{let B=await $.text();this.logger.error("Failed to forward Gateway event",{type:w.type,status:$.status,error:B})}}catch($){this.logger.error("Error forwarding Gateway event",{type:w.type,error:String($)})}}async handleGatewayMessage(Q,w){if(!this.chat)return;let $=Q.guildId||"@me",B=Q.channelId,X=Q.channel.isThread(),Y,Z=B;if(X&&"parentId"in Q.channel&&Q.channel.parentId)Y=B,Z=Q.channel.parentId;if(!Y&&w)try{let K=await this.createDiscordThread(B,Q.id);Y=K.id,this.logger.debug("Created Discord thread for incoming mention",{channelId:B,messageId:Q.id,threadId:K.id})}catch(K){this.logger.error("Failed to create Discord thread for mention",{error:String(K),messageId:Q.id})}let H=this.encodeThreadId({guildId:$,channelId:Z,threadId:Y}),W=new U5({id:Q.id,threadId:H,text:Q.content,formatted:this.formatConverter.toAst(Q.content),author:{userId:Q.author.id,userName:Q.author.username,fullName:Q.author.displayName||Q.author.username,isBot:Q.author.bot,isMe:!1},metadata:{dateSent:Q.createdAt,edited:Q.editedAt!==null,editedAt:Q.editedAt??void 0},attachments:Q.attachments.map((K)=>({type:this.getAttachmentType(K.contentType),url:K.url,name:K.name,mimeType:K.contentType??void 0,size:K.size})),raw:{id:Q.id,channel_id:B,guild_id:$,content:Q.content,author:{id:Q.author.id,username:Q.author.username},timestamp:Q.createdAt.toISOString()},isMention:w});try{await this.chat.handleIncomingMessage(this,H,W)}catch(K){this.logger.error("Error handling Gateway message",{error:String(K),messageId:Q.id})}}async handleGatewayReaction(Q,w,$){if(!this.chat)return;let B=Q.message.guildId||"@me",X=Q.message.channelId,Y=Q.message.channel?.isThread?.(),Z=X,H;if(Y&&Q.message.channel?.parentId)H=X,Z=Q.message.channel.parentId;let W=this.encodeThreadId({guildId:B,channelId:Z,threadId:H}),K=Q.emoji.name||"unknown",U=this.normalizeDiscordEmoji(K),G={adapter:this,threadId:W,messageId:Q.message.id,emoji:U,rawEmoji:Q.emoji.id?`<:${K}:${Q.emoji.id}>`:K,added:$,user:{userId:w.id,userName:w.username,fullName:w.username,isBot:w.bot===!0,isMe:w.id===this.applicationId},raw:{emoji:Q.emoji,message_id:Q.message.id,channel_id:Q.message.channelId,guild_id:Q.message.guildId,user_id:w.id}};this.chat.processReaction(G)}channelIdFromThreadId(Q){return Q.split(":").slice(0,3).join(":")}async fetchChannelMessages(Q,w={}){let B=Q.split(":")[2];if(!B)throw new pW("discord",`Invalid Discord channel ID: ${Q}`);let X=w.limit||50,Y=w.direction??"backward",Z=new URLSearchParams;if(Z.set("limit",String(X)),w.cursor)if(Y==="backward")Z.set("before",w.cursor);else Z.set("after",w.cursor);this.logger.debug("Discord API: GET channel messages",{channelId:B,limit:X,direction:Y,cursor:w.cursor});let W=await(await this.discordFetch(`/channels/${B}/messages?${Z.toString()}`,"GET")).json();this.logger.debug("Discord API: GET channel messages response",{messageCount:W.length});let U=[...W].reverse().map((q)=>this.parseDiscordMessage(q,Q)),G;if(W.length===X)if(Y==="backward")G=W.at(-1)?.id;else G=W[0]?.id;return{messages:U,nextCursor:G}}async listThreads(Q,w={}){let $=Q.split(":"),B=$[1],X=$[2];if(!(B&&X))throw new pW("discord",`Invalid Discord channel ID: ${Q}`);this.logger.debug("Discord API: GET threads",{guildId:B,channelId:X});let H=((await(await this.discordFetch(`/guilds/${B}/threads/active`,"GET")).json()).threads||[]).filter((J)=>J.parent_id===X),W=[];try{W=(await(await this.discordFetch(`/channels/${X}/threads/archived/public?limit=${w.limit||50}`,"GET")).json()).threads||[]}catch{this.logger.debug("Could not fetch archived threads (may lack permissions)")}let K=[...H,...W],U=new Set,G=K.filter((J)=>{if(U.has(J.id))return!1;return U.add(J.id),!0}),q=w.limit||50,V=G.slice(0,q),I=[];for(let J of V){let k=this.encodeThreadId({guildId:B,channelId:X,threadId:J.id});try{let x=(await(await this.discordFetch(`/channels/${J.id}/messages?limit=1&after=0`,"GET")).json())[0];if(x)I.push({id:k,rootMessage:this.parseDiscordMessage(x,k),replyCount:J.total_message_sent??J.message_count,lastReplyAt:J.thread_metadata?.archive_timestamp?new Date(J.thread_metadata.archive_timestamp):void 0})}catch{I.push({id:k,rootMessage:new U5({id:J.id,threadId:k,text:J.name,formatted:this.formatConverter.toAst(J.name),raw:J,author:{userId:"unknown",userName:"unknown",fullName:"unknown",isBot:!1,isMe:!1},metadata:{dateSent:new Date,edited:!1},attachments:[]}),replyCount:J.total_message_sent??J.message_count})}}return this.logger.debug("Discord API: listThreads result",{threadCount:I.length}),{threads:I,nextCursor:G.length>q?String(q):void 0}}async fetchChannelInfo(Q){let $=Q.split(":")[2];if(!$)throw new pW("discord",`Invalid Discord channel ID: ${Q}`);this.logger.debug("Discord API: GET channel info",{channelId:$});let X=await(await this.discordFetch(`/channels/${$}`,"GET")).json();return{id:Q,name:X.name,isDM:X.type===AP.DM||X.type===AP.GroupDM,memberCount:X.member_count,metadata:{channelType:X.type,raw:X}}}async postChannelMessage(Q,w){let B=Q.split(":")[2];if(!B)throw new pW("discord",`Invalid Discord channel ID: ${Q}`);let X={},Y=[],Z=[],H=T70(w);if(H){let q=tl0(H);Y.push(...q.embeds),Z.push(...q.components)}else X.content=this.truncateContent(sj(this.formatConverter.renderPostable(w),"discord"));if(Y.length>0)X.embeds=Y;if(Z.length>0)X.components=Z;let W=xl0(w),K=this.tryPostSlashResponse(Q,X,W);if(K)return K;if(W.length>0)return this.postMessageWithFiles(B,Q,X,W);this.logger.debug("Discord API: POST channel message",{channelId:B,contentLength:X.content?.length||0});let G=await(await this.discordFetch(`/channels/${B}/messages`,"POST",X)).json();return{id:G.id,threadId:Q,raw:G}}normalizeDiscordEmoji(Q){let $={"\uD83D\uDC4D":"thumbs_up","\uD83D\uDC4E":"thumbs_down","\u2764\uFE0F":"heart","\u2764":"heart","\uD83D\uDD25":"fire","\uD83D\uDE80":"rocket","\uD83D\uDE4C":"raised_hands","\u2705":"check","\u274C":"x","\uD83D\uDC4B":"wave","\uD83E\uDD14":"thinking","\uD83D\uDE0A":"smile","\uD83D\uDE02":"laugh","\uD83C\uDF89":"party","\u2B50":"star","\u2728":"sparkles","\uD83D\uDC40":"eyes","\uD83D\uDCAF":"100"}[Q]||Q;return hb($)}};function Wh1(A){return new OsQ(A??{})}var xsQ=class{subscriptions=new Set;locks=new Map;cache=new Map;queues=new Map;connected=!1;connectPromise=null;async connect(){if(this.connected)return;if(!this.connectPromise)this.connectPromise=Promise.resolve().then(()=>{this.connected=!0});await this.connectPromise}async disconnect(){this.connected=!1,this.connectPromise=null,this.subscriptions.clear(),this.locks.clear(),this.queues.clear()}async subscribe(A){this.ensureConnected(),this.subscriptions.add(A)}async unsubscribe(A){this.ensureConnected(),this.subscriptions.delete(A)}async isSubscribed(A){return this.ensureConnected(),this.subscriptions.has(A)}async acquireLock(A,Q){this.ensureConnected(),this.cleanExpiredLocks();let w=this.locks.get(A);if(w&&w.expiresAt>Date.now())return null;let $={threadId:A,token:RsQ(),expiresAt:Date.now()+Q};return this.locks.set(A,$),$}async forceReleaseLock(A){this.ensureConnected(),this.locks.delete(A)}async releaseLock(A){this.ensureConnected();let Q=this.locks.get(A.threadId);if(Q&&Q.token===A.token)this.locks.delete(A.threadId)}async extendLock(A,Q){this.ensureConnected();let w=this.locks.get(A.threadId);if(!w||w.token!==A.token)return!1;if(w.expiresAt<Date.now())return this.locks.delete(A.threadId),!1;return w.expiresAt=Date.now()+Q,!0}async get(A){this.ensureConnected();let Q=this.cache.get(A);if(!Q)return null;if(Q.expiresAt!==null&&Q.expiresAt<=Date.now())return this.cache.delete(A),null;return Q.value}async set(A,Q,w){this.ensureConnected(),this.cache.set(A,{value:Q,expiresAt:w?Date.now()+w:null})}async setIfNotExists(A,Q,w){this.ensureConnected();let $=this.cache.get(A);if($)if($.expiresAt!==null&&$.expiresAt<=Date.now())this.cache.delete(A);else return!1;return this.cache.set(A,{value:Q,expiresAt:w?Date.now()+w:null}),!0}async delete(A){this.ensureConnected(),this.cache.delete(A)}async appendToList(A,Q,w){this.ensureConnected();let $=this.cache.get(A),B;if($&&$.expiresAt!==null&&$.expiresAt<=Date.now())B=[];else if($&&Array.isArray($.value))B=$.value;else B=[];if(B.push(Q),w?.maxLength&&B.length>w.maxLength)B=B.slice(B.length-w.maxLength);this.cache.set(A,{value:B,expiresAt:w?.ttlMs?Date.now()+w.ttlMs:null})}async enqueue(A,Q,w){this.ensureConnected();let $=this.queues.get(A);if(!$)$=[],this.queues.set(A,$);if($.push(Q),$.length>w)$.splice(0,$.length-w);return $.length}async dequeue(A){this.ensureConnected();let Q=this.queues.get(A);if(!Q||Q.length===0)return null;let w=Q.shift();if(Q.length===0)this.queues.delete(A);return w??null}async queueDepth(A){return this.ensureConnected(),this.queues.get(A)?.length??0}async getList(A){this.ensureConnected();let Q=this.cache.get(A);if(!Q)return[];if(Q.expiresAt!==null&&Q.expiresAt<=Date.now())return this.cache.delete(A),[];if(Array.isArray(Q.value))return Q.value;return[]}ensureConnected(){if(!this.connected)throw Error("MemoryStateAdapter is not connected. Call connect() first.")}cleanExpiredLocks(){let A=Date.now();for(let[Q,w]of this.locks)if(w.expiresAt<=A)this.locks.delete(Q)}_getSubscriptionCount(){return this.subscriptions.size}_getLockCount(){return this.cleanExpiredLocks(),this.locks.size}};function RsQ(){return`mem_${Date.now()}_${Math.random().toString(36).substring(2,15)}`}function m70(A){return new xsQ}C0();var vsQ=f.object({subscribedAt:f.string().datetime(),routingMode:f.enum(["auto","mention-required"]).optional(),mentionRequiredNoticeSent:f.boolean().optional()}),hsQ="chat.discord.subscriptions";function el0(A){return A.scoped({namespace:hsQ,schema:vsQ})}function Kh1(A,Q=m70()){let w=el0(A);return new Uh1(Q,w)}class Uh1{memoryState;subscriptions;constructor(A,Q){this.memoryState=A,this.subscriptions=Q}connect(){return this.memoryState.connect()}disconnect(){return this.memoryState.disconnect()}async subscribe(A){await this.subscriptions.set(A,{subscribedAt:new Date().toISOString()})}async unsubscribe(A){await this.subscriptions.delete(A)}isSubscribed(A){return this.subscriptions.has(A)}acquireLock(A,Q){return this.memoryState.acquireLock(A,Q)}appendToList(A,Q,w){return this.memoryState.appendToList(A,Q,w)}delete(A){return this.memoryState.delete(A)}dequeue(A){return this.memoryState.dequeue(A)}enqueue(A,Q,w){return this.memoryState.enqueue(A,Q,w)}extendLock(A,Q){return this.memoryState.extendLock(A,Q)}forceReleaseLock(A){return this.memoryState.forceReleaseLock(A)}get(A){return this.memoryState.get(A)}getList(A){return this.memoryState.getList(A)}queueDepth(A){return this.memoryState.queueDepth(A)}releaseLock(A){return this.memoryState.releaseLock(A)}set(A,Q,w){return this.memoryState.set(A,Q,w)}setIfNotExists(A,Q,w){return this.memoryState.setIfNotExists(A,Q,w)}}function Gh1(A){let{discord:Q}=A;if(!Q)return new Pl0({userName:A.userName,adapters:{},state:m70()});let w=Wh1({botToken:Q.botToken,publicKey:Q.publicKey,applicationId:Q.applicationId,mentionRoleIds:Q.mentionRoleIds});return A.gatewayLoop.setAdapter(w),new Pl0({userName:A.userName,adapters:{discord:w},concurrency:{strategy:"queue",maxQueueSize:5,onQueueFull:"drop-oldest"},state:Kh1(A.runtimeState)})}class Ap0{deps;constructor(A){this.deps=A}async subscribeOwnedThread(A,Q){if(!this.deps.isBotCreatedThread(A,Q))return;try{await A.subscribe(),await this.deps.getSubscriptions()?.set(A.id,{subscribedAt:new Date().toISOString()})}catch(w){this.deps.logger.debug("Discord thread subscription failed",{error:w,threadId:A.id})}}async shouldRouteSubscribedMessage(A,Q){if(this.deps.getPlatform(A)!=="discord")return!1;if(A.isDM)return!0;let w=await this.deps.getSubscriptions()?.get(A.id);if(!w)return!1;if(w.routingMode==="mention-required"){if(!Q.isMention&&!w.mentionRequiredNoticeSent)await this.postMentionRequiredNotice(A,w);return Boolean(Q.isMention)}if(!await this.shouldRequireMentionInSubscribedThread(A))return!0;let B={...w,routingMode:"mention-required"};if(!Q.isMention&&!w.mentionRequiredNoticeSent)await this.postMentionRequiredNotice(A,B);else await this.deps.getSubscriptions()?.set(A.id,B);return Boolean(Q.isMention)}async postMentionRequiredNotice(A,Q){await A.post("I\u2019ll stop auto-replying now that more people joined. Mention me if you need me."),await this.deps.getSubscriptions()?.set(A.id,{...Q,routingMode:"mention-required",mentionRequiredNoticeSent:!0})}async shouldRequireMentionInSubscribedThread(A){try{return(await A.getParticipants()).filter(($)=>!$.isBot&&!$.isMe).length>1}catch(Q){return this.deps.logger.debug("Failed to inspect Discord thread participants",{error:Q,threadId:A.id}),!1}}}fA();class Qp0{deps;constructor(A){this.deps=A}async build(A,Q,w,$){let B={message:w.text.trim(),attachments:[],notices:[]};if(w.attachments.length===0)return B;if(!($==="anchor"||$==="trusted"))return B;let Y=this.deps.getUploadStore();if(!Y)return B;for(let Z of w.attachments){let H=Z.name;if(!H)continue;let W=B3(H,"upload"),K=vI(W,Z.mimeType),U=Z.size??0,G=o20(W,K);if(!G){B.notices.push(`Unsupported file upload type: ${W}`);continue}if(!s20(G,U)){B.notices.push(`File upload too large: ${W}`);continue}try{let q=await this.readAttachmentData(Z);if(!q)continue;let V=X3({filename:W,mediaType:K,content:q,fallbackFilename:"upload"});if(!V.ok){B.notices.push(V.message);continue}let I=await Y.save({filename:V.filename,mediaType:V.mediaType,content:q,metadata:this.buildMetadata(A,Q,w)});B.attachments.push(qh1(I.filename,I.mediaType,q,I.ref,V.kind==="text"))}catch(q){this.deps.logger.error("Failed to read chat attachment",{error:q,filename:W}),B.notices.push(`Could not read file upload: ${W}`)}}return B}async readAttachmentData(A){if(A.fetchData)return A.fetchData();if(!A.url)return;let Q=await fetch(A.url);if(!Q.ok)throw Error(`Attachment download failed with status ${Q.status}`);let w=await Q.arrayBuffer();return Buffer.from(new Uint8Array(w))}buildMetadata(A,Q,w){let $=this.deps.getThreadIdParts(Q.id);return{interfaceType:A,channelId:Q.id,parentChannelId:Q.channelId,messageId:w.id,uploaderId:w.author.userId,uploaderUsername:w.author.userName,...$.guildId?{guildId:$.guildId}:{},...$.threadId?{threadId:$.threadId}:{}}}}function Dh1(A,Q,w,$){return qh1(A,Q,w,$,hI(A,Q))}function qh1(A,Q,w,$,B){if(B)return{kind:"text",filename:A,mediaType:Q,content:w.toString("utf8").replace(/^\uFEFF/,""),sizeBytes:w.byteLength,source:$};return{kind:"file",filename:A,mediaType:Q,data:w,sizeBytes:w.byteLength,source:$}}function an(){return{namespace:"discord-chat",refKind:"discord-chat-upload",routePath:"/api/webhooks/chat/discord/uploads"}}function Bq(A){let Q=A.split(":");if(Q[0]!=="discord")return{};return{...Q[1]?{guildId:Q[1]}:{},...Q[2]?{channelId:Q[2]}:{},...Q[3]?{threadId:Q[3]}:{}}}function CsQ(A){let Q=A.raw;if(typeof Q!=="object"||Q===null)return;let w=Q.channel_id;return typeof w==="string"?w:void 0}function zh1(A,Q){if(A.isDM)return!1;let w=Bq(A.id);if(!w.threadId)return!1;let $=CsQ(Q);return $!==void 0&&$!==w.threadId}function u70(A,Q){if(Q.allowedChannels.length===0||A.isDM)return!0;let w=Bq(A.id);return[A.id,A.channelId,w.channelId,w.threadId].some(($)=>typeof $==="string"&&Q.allowedChannels.includes($))}function wp0(A,Q,w){if(A.isDM&&!w.allowDMs)return!1;if(Q.author.isMe)return!1;if(Q.author.isBot&&!Q.isMention)return!1;return u70(A,w)}function $p0(A,Q,w){if(Q!=="discord")return!0;if(!w)return!1;if(A.isDM&&!w.allowDMs)return!1;return u70(A,w)}function Bp0(A,Q){return{channelId:Bq(A.id).channelId??A.channelId,isBot:Boolean(Q.author.isBot)}}function mg(A){return A.isDM?"DM":A.channelId}var gsQ="https://discord.com/api/v10";async function Vh1(A){let Q=Bq(A.threadId),w=Q.threadId??Q.channelId;if(!w)return;let $=A.fetchFn??fetch;try{let B=await $(`${gsQ}/channels/${w}/messages/${A.messageId}`,{method:"PATCH",headers:{Authorization:`Bot ${A.botToken}`,"Content-Type":"application/json"},body:JSON.stringify({components:[]})});if(!B.ok)A.logger.debug("Failed to clear Discord message components",{messageId:A.messageId,channelId:w,status:B.status})}catch(B){A.logger.debug("Failed to clear Discord message components",{error:B,messageId:A.messageId,channelId:w})}}var Jh1={name:"@brains/chat",version:"0.2.0-alpha.158",description:"Discord Chat SDK interface for Brains",dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*","@chat-adapter/discord":"^4.29.0","@chat-adapter/state-memory":"^4.29.0",chat:"^4.29.0"},devDependencies:{"@brains/core":"workspace:*","@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14"},exports:{".":"./src/index.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var EsQ=/https?:\/\/\S+/i,TsQ=/[\s\S]+/,SsQ=1000,msQ=f.looseObject({type:f.literal("card"),children:f.array(f.looseObject({type:f.string()})),imageUrl:f.string().optional(),subtitle:f.string().optional(),title:f.string().optional()}),usQ=f.object({card:f.custom((A)=>msQ.safeParse(A).success),fallbackText:f.string().optional()});class c70 extends nK{threadRegistry=new N70;pendingApprovals;uploadContinuity;promptActions=new $c0(SsQ);toolStatusMessenger=new Bc0(this.threadRegistry);cardBuilder=new fc0({getDisplayBaseUrl:()=>this.getPreferredDisplayBaseUrl(),registerPromptAction:(A,Q)=>this.registerPromptAction(A,Q)});artifactDelivery=new Wc0({getContext:()=>this.context,getDisplayBaseUrl:()=>this.getPreferredDisplayBaseUrl(),logger:this.logger});approvalCards=new Kc0({cardBuilder:this.cardBuilder,clearMessageComponents:async(A,Q)=>{let w=this.config.adapters.discord?.botToken;if(!w)return;await Vh1({threadId:A,messageId:Q,botToken:w,logger:this.logger})}});subscriptionRouter=new Ap0({getSubscriptions:()=>this.discordSubscriptions,getPlatform:(A)=>this.getPlatform(A),isBotCreatedThread:zh1,logger:this.logger});chatInputBuilder=new Qp0({getUploadStore:()=>this.context?.uploads.scoped(an()),getThreadIdParts:Bq,logger:this.logger});gatewayLoop;discordApp;discordSubscriptions;constructor(A={}){super("chat",Jh1,A,wc0);this.gatewayLoop=new Uc0({getApp:()=>this.discordApp.instance,gatewayRunMs:this.config.gatewayRunMs,gatewayRestartDelayMs:this.config.gatewayRestartDelayMs,logger:this.logger}),this.discordApp=new Gc0({discord:this.config.adapters.discord,getUploadStore:()=>this.context?.uploads.scoped(an()),buildApp:(Q)=>Gh1({userName:this.config.userName,discord:this.config.adapters.discord,gatewayLoop:this.gatewayLoop,runtimeState:Q})}),this.pendingApprovals=new Eu({loadMessages:async(Q)=>{return await this.context?.conversations.getMessages(Q,{limit:50})??[]},onRestoreError:(Q,w)=>{this.logger.debug("Failed to load pending chat approvals",{error:Q,conversationId:w})}}),this.uploadContinuity=new lu({sourceKind:"discord-chat-upload",loadMessages:async(Q)=>{return await this.context?.conversations.getMessages(Q,{limit:50})??[]},restoreAttachment:async(Q)=>{let w=this.context?.uploads.scoped(an());if(!w)throw Error("Chat upload store unavailable");let $=await w.read(Q);return Dh1($.record.filename,$.record.mediaType,$.content,$.record.ref)},onLoadError:(Q,w)=>{this.logger.debug("Failed to load prior chat uploads",{error:Q,conversationId:w})},onRestoreError:(Q,w)=>{this.logger.debug("Failed to restore prior chat upload",{error:Q,uploadId:w})}})}async onRegister(A){await super.onRegister(A),this.discordSubscriptions=el0(A.runtimeState),this.registerChatHandlers(this.discordApp.build(A.runtimeState))}getWebRoutes(){return this.discordApp.getWebRoutes()}createDaemon(){if(!this.config.adapters.discord)return;return{start:async()=>{await this.discordApp.initialize(),this.gatewayLoop.start()},stop:async()=>{await this.gatewayLoop.stop(),this.threadRegistry.clear(),this.uploadContinuity.clear(),this.toolStatusMessenger.clear(),await this.discordApp.shutdown()},healthCheck:async()=>({status:this.gatewayLoop.isRunning()?"healthy":"error",message:this.gatewayLoop.isRunning()?"Chat gateway loop running":"Chat gateway loop stopped",lastCheck:new Date})}}sendMessageToChannel({channelId:A,message:Q}){let w=this.threadRegistry.get(A);if(!w)return;let $=this.toDiscordCardOutput(Q);if($){w.post($).catch((B)=>this.logger.error("Failed to send chat message",{error:B,channelId:A}));return}if(typeof Q!=="string")return;for(let B of Tn(A,Q))w.post(B).catch((X)=>this.logger.error("Failed to send chat message",{error:X,channelId:A}))}async sendMessageWithId({channelId:A,message:Q}){let w=this.threadRegistry.get(A);if(!w)return;let $=this.toDiscordCardOutput(Q);if($){let X=await w.post($);return this.threadRegistry.trackMessage(w.id,X),X.id}if(typeof Q!=="string")return;let B;for(let X of Tn(A,Q))B=await w.post(X),this.threadRegistry.trackMessage(w.id,B);return B?.id}async editMessage({channelId:A,messageId:Q,newMessage:w}){let $=this.threadRegistry.getMessage(A,Q);if(!$)return!1;try{let B=await $.edit(this.toDiscordCardOutput(w)??(typeof w==="string"?w:""));if(A)this.threadRegistry.trackMessage(A,B);return!0}catch{return!1}}supportsMessageEditing(){return!0}toDiscordCardOutput(A){let Q=usQ.safeParse(A);if(!Q.success)return;let{card:w,fallbackText:$}=Q.data;if($===void 0)return{card:w};return{card:w,fallbackText:$}}formatProgressOutput(A){return Zc0(A)}formatCompletionOutput(A){return Zc0(A)}async handleProgressEvent(A,Q){let w=A.metadata.interfaceType;if(w&&w!==this.id){if(!this.isEnabledPlatform(w))return;let $={...A,metadata:{...A.metadata,interfaceType:this.id}};await super.handleProgressEvent($,$.metadata);return}await super.handleProgressEvent(A,Q)}async handleToolActivityEvent(A){if(A.interfaceType===this.id){await super.handleToolActivityEvent(A);return}if(!this.isEnabledPlatform(A.interfaceType))return;await super.handleToolActivityEvent({...A,interfaceType:this.id})}async handleToolStatusUpdate(A){if(A.interfaceType!==this.id||!A.channelId)return;await this.toolStatusMessenger.handle(A)}isEnabledPlatform(A){return pb1(A,Boolean(this.config.adapters.discord))}registerChatHandlers(A){if(A.onDirectMessage(async(Q,w,$,B)=>{await this.handleRoutedMessage(Q,w,B)}),A.onNewMention(async(Q,w,$)=>{let B=this.getPlatformConfig(Q);if(B&&wp0(Q,w,B)&&!Q.isDM&&B.useThreads)await this.subscriptionRouter.subscribeOwnedThread(Q,w);await this.handleRoutedMessage(Q,w,$)}),A.onSubscribedMessage(async(Q,w,$)=>{if(!await this.subscriptionRouter.shouldRouteSubscribedMessage(Q,w))return;await this.handleRoutedMessage(Q,w,$)}),this.config.adapters.discord&&!this.config.adapters.discord.requireMention)A.onNewMessage(TsQ,async(Q,w,$)=>{await this.handleRoutedMessage(Q,w,$)});A.onNewMessage(EsQ,async(Q,w)=>{await this.handlePassiveUrlCapture(Q,w)}),A.onAction([j70,Xc0],async(Q)=>{await this.handleApprovalAction(Q)}),A.onAction(Yc0,async(Q)=>{await this.handlePromptAction(Q)})}async handlePromptAction(A){if(!this.context||!A.thread||!A.value)return;let Q=A.adapter.name;if(!this.isEnabledPlatform(Q))return;let w=A.thread;if(!$p0(w,Q,this.config.adapters.discord))return;let $=this.promptActions.get(A.value);if($?.threadId!==w.id){await w.post(this.formatNoticePayload("That suggested action is no longer available.","Action unavailable"));return}this.promptActions.consume(A.value);let B=Bq(w.id),X=this.context.permissions.getUserLevel(Q,A.user.userId,{channelId:B.channelId??w.channelId,isBot:Boolean(A.user.isBot)}),Y=this.getConversationId(Q,w.id),Z=w.id;await this.runAgentTurn({thread:w,channelId:Z,logLabel:"Error handling chat prompt action",body:async()=>{if(!this.context)return;let H=await this.context.agent.chat($.prompt,Y,{userPermissionLevel:X,interfaceType:Q,channelId:Z,channelName:mg(w),...this.buildActionEventMetadata(Q,w,A)});await this.renderAgentResponse({thread:w,channelId:Z,conversationId:Y,response:H,userPermissionLevel:X})}})}async handleApprovalAction(A){if(!this.context||!A.thread||!A.value)return;let Q=A.adapter.name;if(!this.isEnabledPlatform(Q))return;let w=this.getConversationId(Q,A.thread.id);if(!(await this.getPendingApprovalIds(w)).has(A.value)){await A.thread.post(this.formatNoticePayload("That approval is no longer pending."));return}let B=A.thread;if(!$p0(B,Q,this.config.adapters.discord))return;let X=Bq(B.id),Y=this.context.permissions.getUserLevel(Q,A.user.userId,{channelId:X.channelId??B.channelId,isBot:Boolean(A.user.isBot)});await this.confirmApproval({thread:B,conversationId:w,approvalId:A.value,confirmed:A.actionId===j70,userPermissionLevel:Y,metadata:this.buildActionEventMetadata(Q,B,A)})}async handleRoutedMessage(A,Q,w){if(!this.context)return;let $=this.getPlatform(A);if($!=="discord")return;let B=this.getPlatformConfig(A);if(!B)return;if(!wp0(A,Q,B))return;await this.routeToAgent($,A,Q,w)}async runAgentTurn(A){this.startProcessingInput(A.channelId);try{if(this.getPlatformConfig(A.thread)?.showTypingIndicator)await A.thread.startTyping().catch((Q)=>this.logger.debug("Typing indicator failed",{error:Q,channelId:A.channelId}));await A.body()}catch(Q){this.logger.error(A.logLabel,{error:Q,channelId:A.channelId}),await this.postTurnError(A.thread,A.channelId,Q)}finally{this.endProcessingInput()}}async postTurnError(A,Q,w){let $=this.formatErrorPayload(w),B=this.toDiscordCardOutput($);if(B){await A.post(B);return}let X=typeof $==="string"?$:"Message failed.";for(let Y of Tn(Q,X))await A.post(Y)}async routeToAgent(A,Q,w,$){if(!this.context)return;this.threadRegistry.set(Q);let B=this.getConversationId(A,Q.id),X=Q.id,Y=Bp0(Q,w),Z=this.context.permissions.getUserLevel(A,w.author.userId,Y),H=await this.chatInputBuilder.build(A,Q,w,Z),W=[...H.attachments];if(await this.attachPriorUploads(B,H,Z),await this.postUploadNotices(Q,H.notices),!H.message&&H.attachments.length===0)return;this.rememberUploadAttachments(B,W),await this.runAgentTurn({thread:Q,channelId:X,logLabel:"Error handling chat message",body:async()=>{if(!this.context)return;let K=await this.getPendingApprovalIds(B);if(K.size>0){if(await this.handleConfirmationResponse(H.message,B,Q,K,Z,this.buildUserMessageMetadata(A,Q,w)))return}let U=this.buildCoalescedAgentInput(H.message,$),G=await this.context.agent.chat(U.message,B,{userPermissionLevel:Z,interfaceType:A,channelId:X,channelName:mg(Q),...this.buildUserMessageMetadata(A,Q,w,U.metadata),...H.attachments.length>0?{attachments:H.attachments}:{}});await this.renderAgentResponse({thread:Q,channelId:X,conversationId:B,response:G,userPermissionLevel:Z})}})}async renderAgentResponse(A){if(A.confirmation)this.syncPendingConfirmationsFromResponse(A.conversationId,A.response,A.confirmation.approvalId);else this.rememberPendingConfirmationsFromResponse(A.conversationId,A.response);await this.handleAgentResponseToolStatuses(A.response,A.conversationId);let Q=await this.artifactDelivery.resolve(A.response.cards,A.userPermissionLevel),w=M_(A.response,{deniedCardIds:Q.deniedCardIds});if(A.confirmation)await this.approvalCards.resolve(A.conversationId,A.confirmation.approvalId,A.confirmation.confirmed);let $=A.confirmation?this.formatConfirmationResponsePayload(A.response,A.confirmation.confirmed,this.getRemainingApprovalHelp(A.conversationId,A.response),Q.deniedCardIds):this.formatAgentResponseText(w,Q.deniedCardIds),B=await this.sendAgentResponseWithFiles({thread:A.thread,channelId:A.channelId,message:$,files:Q.files}),X=await this.sendArtifactCards(A.thread,w);await this.sendSupplementalCards(A.thread,w);let Y=w.directives.find((H)=>H.kind==="approvals");await this.approvalCards.trackPendingConfirmations(A.thread,A.conversationId,Y?.confirmations);let Z=X??B;if(Z)for(let H of w.jobIds)this.trackAgentResponseForJob(H,Z,A.channelId)}rememberPendingConfirmationsFromResponse(A,Q){this.pendingApprovals.rememberFromResponse(A,Q)}async getPendingApprovalIds(A){return this.pendingApprovals.getApprovalIds(A)}async handleConfirmationResponse(A,Q,w,$,B,X){if(!hu(A,$))return!1;let Y=y20({message:A,approvalIds:$});if(Y.kind==="not-confirmation")return this.pendingApprovals.deleteConversation(Q),await w.post(this.formatNoticePayload("No pending approval to resolve.")),!0;if(Y.kind==="notice")return await w.post(this.formatNoticePayload(Y.message)),!0;return await this.confirmApproval({thread:w,conversationId:Q,approvalId:Y.approvalId,confirmed:Y.confirmed,userPermissionLevel:B,...X?{metadata:X}:{}}),!0}async confirmApproval(A){let Q=await this.context?.agent.confirmPendingAction(A.conversationId,A.confirmed,A.approvalId,{userPermissionLevel:A.userPermissionLevel,interfaceType:"discord",channelId:A.thread.id,channelName:mg(A.thread),...A.metadata});if(this.removePendingApproval(A.conversationId,A.approvalId),!Q)return;await this.renderAgentResponse({thread:A.thread,channelId:A.thread.id,conversationId:A.conversationId,response:Q,userPermissionLevel:A.userPermissionLevel,confirmation:{approvalId:A.approvalId,confirmed:A.confirmed}})}formatNoticePayload(A,Q="Approval notice"){return{card:{type:"card",title:Q,children:[{type:"text",content:A}]},fallbackText:A}}formatErrorPayload(A){let Q=A instanceof Error?A.message:"Unknown error";return{card:{type:"card",title:"Message failed",children:[{type:"text",content:Q}]},fallbackText:`Message failed: ${Q}`}}formatAgentResponseText(A,Q){return A.directives.flatMap((w)=>{if(w.kind==="text")return[w.text];if(w.kind==="denied-artifact")return[this.cardBuilder.formatStructuredCard(w.card,Q)];return[]}).filter((w)=>w.trim().length>0).join(`
2369
+ \`\`\``;return this.defaultNodeToText(A,(Q)=>this.nodeToDiscordMarkdown(Q))}};var Yh1={DeferredChannelMessageWithSource:5,DeferredUpdateMessage:6},S70="https://discord.com/api/v10",Zh1=2000,PsQ=/^[0-9a-f]{64}$/,MsQ=/^[0-9a-f]+$/,OsQ=class A{name="discord";userName;botUserId;apiBaseUrl;botToken;publicKey;applicationId;mentionRoleIds;interactionFlags;chat=null;logger;formatConverter=new jsQ;requestContext=new zsQ;threadParentCache=new Map;static THREAD_PARENT_CACHE_TTL=300000;constructor(Q={}){let w=Q.botToken??process.env.DISCORD_BOT_TOKEN;if(!w)throw new pW("discord","botToken is required. Set DISCORD_BOT_TOKEN or provide it in config.");let $=Q.publicKey??process.env.DISCORD_PUBLIC_KEY;if(!$)throw new pW("discord","publicKey is required. Set DISCORD_PUBLIC_KEY or provide it in config.");let B=Q.applicationId??process.env.DISCORD_APPLICATION_ID;if(!B)throw new pW("discord","applicationId is required. Set DISCORD_APPLICATION_ID or provide it in config.");if(this.apiBaseUrl=Q.apiUrl??process.env.DISCORD_API_URL??S70,this.botToken=w,this.publicKey=$.trim().toLowerCase(),this.applicationId=B,this.mentionRoleIds=Q.mentionRoleIds??(process.env.DISCORD_MENTION_ROLE_IDS?process.env.DISCORD_MENTION_ROLE_IDS.split(",").map((X)=>X.trim()):[]),this.botUserId=B,this.interactionFlags=Q.interactionFlags,this.logger=Q.logger??new g70("info").child("discord"),this.userName=Q.userName??"bot",!PsQ.test(this.publicKey))this.logger.error("Invalid Discord public key format",{length:this.publicKey.length,isHex:MsQ.test(this.publicKey)})}async initialize(Q){this.chat=Q,this.logger.info("Discord adapter initialized")}async getUser(Q){try{let $=await(await this.discordFetch(`/users/${Q}`,"GET")).json();return{avatarUrl:$.avatar?`https://cdn.discordapp.com/avatars/${$.id}/${$.avatar}.png`:void 0,email:void 0,fullName:$.global_name||$.username,isBot:$.bot??!1,userId:$.id,userName:$.username}}catch{return null}}async handleWebhook(Q,w){let $=await Q.arrayBuffer(),B=new Uint8Array($),X=new TextDecoder().decode(B),Y=Q.headers.get("x-discord-gateway-token");if(Y){if(Y!==this.botToken)return this.logger.warn("Invalid gateway token"),new Response("Invalid gateway token",{status:401});this.logger.info("Discord forwarded Gateway event received");try{let U=JSON.parse(X);return this.handleForwardedGatewayEvent(U,w)}catch{return new Response("Invalid JSON",{status:400})}}this.logger.info("Discord webhook received",{bodyLength:X.length,bodyBytesLength:B.length,hasSignature:!!Q.headers.get("x-signature-ed25519"),hasTimestamp:!!Q.headers.get("x-signature-timestamp")});let Z=Q.headers.get("x-signature-ed25519"),H=Q.headers.get("x-signature-timestamp");if(!await this.verifySignature(B,Z,H))return this.logger.warn("Discord signature verification failed, returning 401"),new Response("Invalid signature",{status:401});this.logger.info("Discord signature verification passed");let K;try{K=JSON.parse(X)}catch{return new Response("Invalid JSON",{status:400})}if(this.logger.info("Discord interaction parsed",{type:K.type,typeIsPing:K.type===Tg.Ping,expectedPingType:Tg.Ping,id:K.id}),K.type===Tg.Ping){let U=JSON.stringify({type:sn.InteractionResponseType.PONG});return this.logger.info("Discord PING received, responding with PONG",{responseBody:U,responseType:sn.InteractionResponseType.PONG}),new Response(U,{status:200,headers:{"Content-Type":"application/json"}})}if(K.type===Tg.MessageComponent)return this.handleComponentInteraction(K,w),this.respondToInteraction({type:Yh1.DeferredUpdateMessage});if(K.type===Tg.ApplicationCommand){let U=this.getApplicationCommandContext(K),G=this.getInteractionFlags(U);return this.handleApplicationCommandInteraction(U,w),this.respondToInteraction({...G===void 0?{}:{data:{flags:G}},type:Yh1.DeferredChannelMessageWithSource})}return new Response("Unknown interaction type",{status:400})}async verifySignature(Q,w,$){if(!(w&&$))return this.logger.warn("Discord signature verification failed: missing headers",{hasSignature:!!w,hasTimestamp:!!$}),!1;try{this.logger.info("Discord signature verification attempt",{bodyBytesLength:Q.length,signatureLength:w.length,timestampLength:$.length,publicKeyLength:this.publicKey.length,timestamp:$,signaturePrefix:w.slice(0,16),publicKey:this.publicKey});let B=await sn.verifyKey(Q,w,$,this.publicKey);if(!B){let X=new TextDecoder().decode(Q);this.logger.warn("Discord signature verification failed: invalid signature",{publicKeyLength:this.publicKey.length,signatureLength:w.length,publicKeyPrefix:this.publicKey.slice(0,8),publicKeySuffix:this.publicKey.slice(-8),timestamp:$,bodyLength:Q.length,bodyPrefix:X.slice(0,50)})}return B}catch(B){return this.logger.warn("Discord signature verification failed: exception",{error:B}),!1}}respondToInteraction(Q){return Response.json(Q)}handleComponentInteraction(Q,w){if(!this.chat){this.logger.warn("Chat instance not initialized, ignoring interaction");return}let $=Q.data?.custom_id;if(!$){this.logger.warn("No custom_id in component interaction");return}let B=Q.member?.user||Q.user;if(!B){this.logger.warn("No user in component interaction");return}let X=Q.channel_id,Y=Q.guild_id||"@me",Z=Q.message?.id;if(!(X&&Z)){this.logger.warn("Missing channel_id or message_id in interaction");return}let H=Q.channel,W=H?.type===11||H?.type===12,K=W&&H?.parent_id?H.parent_id:X,U=W?this.encodeThreadId({guildId:Y,channelId:K,threadId:X}):this.encodeThreadId({guildId:Y,channelId:X}),G=JsQ($),q={actionId:G.actionId,value:G.value??G.actionId,user:{userId:B.id,userName:B.username,fullName:B.global_name||B.username,isBot:B.bot??!1,isMe:!1},messageId:Z,threadId:U,adapter:this,raw:Q};this.logger.debug("Processing Discord button action",{actionId:$,messageId:Z,threadId:U}),this.chat.processAction(q,w)}getApplicationCommandContext(Q){let w=Q.data?.name;if(!w)return this.logger.warn("No command name in application command interaction"),null;let $=Q.member?.user||Q.user;if(!$)return this.logger.warn("No user in application command interaction"),null;let B=Q.channel_id;if(!B)return this.logger.warn("Missing channel_id in application command interaction"),null;let X=Q.guild_id||"@me",Y=Q.channel,Z=Y?.type===11||Y?.type===12,H=Z&&Y?.parent_id?Y.parent_id:B,W=Z?this.encodeThreadId({guildId:X,channelId:H,threadId:B}):this.encodeThreadId({guildId:X,channelId:B}),{command:K,text:U}=this.parseSlashCommand(w,Q.data?.options);return{channelId:W,command:K,interaction:Q,text:U,user:$}}getInteractionFlags(Q){if(!(Q&&this.interactionFlags))return;return this.interactionFlags(Q)}handleApplicationCommandInteraction(Q,w){if(!this.chat){this.logger.warn("Chat instance not initialized, ignoring interaction");return}if(!Q)return;let{channelId:$,command:B,interaction:X,text:Y,user:Z}=Q;this.logger.debug("Processing Discord slash command",{command:B,text:Y,userId:Z.id,channelId:$}),this.requestContext.run({slashCommand:{channelId:$,interactionToken:X.token,initialResponseSent:!1}},()=>{this.chat?.processSlashCommand({command:B,text:Y,user:{userId:Z.id,userName:Z.username,fullName:Z.global_name||Z.username,isBot:Z.bot??!1,isMe:Z.id===this.applicationId},adapter:this,raw:X,channelId:$},w)})}parseSlashCommand(Q,w){let $=[Q.startsWith("/")?Q:`/${Q}`],B=[],X=(Y)=>{for(let Z of Y){if(Z.value!==void 0){B.push(String(Z.value));continue}if(Z.options&&Z.options.length>0)$.push(Z.name),X(Z.options)}};if(w&&w.length>0)X(w);return{command:$.join(" "),text:B.join(" ").trim()}}async handleGatewayInteraction(Q){if(Q.isChatInputCommand()){let w=this.getApplicationCommandContext(this.normalizeGatewaySlashCommandInteraction(Q)),$=this.getInteractionFlags(w);await Q.deferReply($===void 0?void 0:{flags:$}),this.handleApplicationCommandInteraction(w);return}if(Q.isMessageComponent())await Q.deferUpdate(),this.handleComponentInteraction(this.normalizeGatewayComponentInteraction(Q))}normalizeGatewaySlashCommandInteraction(Q){return{application_id:Q.applicationId,channel:this.normalizeGatewayChannel(Q),channel_id:Q.channelId??void 0,data:{name:Q.commandName,options:this.normalizeGatewayCommandOptions(Q.options.data),type:Q.commandType},guild_id:Q.guildId??void 0,id:Q.id,token:Q.token,type:Q.type,user:this.normalizeGatewayUser(Q.user),version:Q.version}}normalizeGatewayComponentInteraction(Q){let w="values"in Q&&Array.isArray(Q.values)?Q.values:void 0;return{application_id:Q.applicationId,channel:this.normalizeGatewayChannel(Q),channel_id:Q.channelId??void 0,data:{component_type:Q.componentType,custom_id:Q.customId,values:w},guild_id:Q.guildId??void 0,id:Q.id,message:{id:Q.message.id},token:Q.token,type:Q.type,user:this.normalizeGatewayUser(Q.user),version:Q.version}}normalizeGatewayChannel(Q){if(!Q.channel)return;let w="parentId"in Q.channel&&typeof Q.channel.parentId==="string"?Q.channel.parentId:void 0;return{id:Q.channel.id,parent_id:w,type:Q.channel.type}}normalizeGatewayCommandOptions(Q){return Q.map((w)=>({name:w.name,options:w.options?this.normalizeGatewayCommandOptions(w.options):void 0,type:w.type,value:w.value}))}normalizeGatewayUser(Q){return{avatar:Q.avatar??void 0,bot:Q.bot,discriminator:Q.discriminator,global_name:Q.globalName??void 0,id:Q.id,username:Q.username}}async handleForwardedGatewayEvent(Q,w){switch(this.logger.info("Processing forwarded Gateway event",{type:Q.type,timestamp:Q.timestamp}),Q.type){case"GATEWAY_MESSAGE_CREATE":await this.handleForwardedMessage(Q.data,w);break;case"GATEWAY_MESSAGE_REACTION_ADD":await this.handleForwardedReaction(Q.data,!0,w);break;case"GATEWAY_MESSAGE_REACTION_REMOVE":await this.handleForwardedReaction(Q.data,!1,w);break;default:this.logger.debug("Forwarded Gateway event (no handler)",{type:Q.type})}return new Response(JSON.stringify({ok:!0}),{status:200,headers:{"Content-Type":"application/json"}})}async handleForwardedMessage(Q,w){if(!this.chat)return;let $=Q.guild_id||"@me",B=Q.channel_id,X,Y=B;if(Q.thread)X=Q.thread.id,Y=Q.thread.parent_id;else if(Q.channel_type===11||Q.channel_type===12)try{let q=await(await this.discordFetch(`/channels/${B}`,"GET")).json();if(q.parent_id)X=B,Y=q.parent_id,this.logger.debug("Fetched thread parent for forwarded message",{threadId:B,parentId:q.parent_id})}catch(G){this.logger.error("Failed to fetch thread parent",{error:String(G),channelId:B})}let Z=Q.is_mention||Q.mentions.some((G)=>G.id===this.applicationId),H=this.mentionRoleIds.length>0&&Q.mention_roles?.some((G)=>this.mentionRoleIds.includes(G)),W=Z||H;if(!X&&W)try{let G=await this.createDiscordThread(B,Q.id);X=G.id,this.logger.debug("Created Discord thread for forwarded mention",{channelId:B,messageId:Q.id,threadId:G.id})}catch(G){this.logger.error("Failed to create Discord thread for mention",{error:String(G),messageId:Q.id})}let K=this.encodeThreadId({guildId:$,channelId:Y,threadId:X}),U=new U5({id:Q.id,threadId:K,text:Q.content,formatted:this.formatConverter.toAst(Q.content),author:{userId:Q.author.id,userName:Q.author.username,fullName:Q.author.global_name||Q.author.username,isBot:Q.author.bot===!0,isMe:Q.author.id===this.applicationId},metadata:{dateSent:new Date(Q.timestamp),edited:!1},attachments:Q.attachments.map((G)=>({type:this.getAttachmentType(G.content_type),url:G.url,name:G.filename,mimeType:G.content_type,size:G.size})),raw:Q,isMention:W});try{await this.chat.handleIncomingMessage(this,K,U)}catch(G){this.logger.error("Error handling forwarded message",{error:String(G),messageId:Q.id})}}async handleForwardedReaction(Q,w,$){if(!this.chat)return;let B=Q.guild_id||"@me",X=Q.channel_id,Y,Z=X;if(Q.channel_type===AP.GuildPublicThread||Q.channel_type===AP.GuildPrivateThread){let q=this.threadParentCache.get(X);if(q&&q.expiresAt>Date.now())Y=X,Z=q.parentId;else try{let I=await(await this.discordFetch(`/channels/${X}`,"GET")).json();if(I.parent_id)Y=X,Z=I.parent_id,this.threadParentCache.set(X,{parentId:I.parent_id,expiresAt:Date.now()+A.THREAD_PARENT_CACHE_TTL})}catch(V){this.logger.error("Failed to fetch thread parent for reaction",{error:String(V),channelId:X})}}let H=this.encodeThreadId({guildId:B,channelId:Z,threadId:Y}),W=Q.emoji.name||"unknown",K=this.normalizeDiscordEmoji(W),U=Q.user??Q.member?.user;if(!U){this.logger.warn("Reaction event missing user info",{data:Q});return}let G={adapter:this,threadId:H,messageId:Q.message_id,emoji:K,rawEmoji:Q.emoji.id?`<:${W}:${Q.emoji.id}>`:W,added:w,user:{userId:U.id,userName:U.username,fullName:U.username,isBot:U.bot===!0,isMe:U.id===this.applicationId},raw:Q};this.chat.processReaction(G)}async postMessage(Q,w){let{channelId:$,threadId:B}=this.decodeThreadId(Q),X=Q;if(B)$=B;let Y={},Z=[],H=[],W=T70(w);if(W){let V=tl0(W);Z.push(...V.embeds),H.push(...V.components)}else Y.content=this.truncateContent(sj(this.formatConverter.renderPostable(w),"discord"));if(Z.length>0)Y.embeds=Z;if(H.length>0)Y.components=H;let K=xl0(w),U=this.tryPostSlashResponse(X,Y,K);if(U)return U;if(K.length>0)return this.postMessageWithFiles($,X,Y,K);this.logger.debug("Discord API: POST message",{channelId:$,contentLength:Y.content?.length||0,embedCount:Z.length,componentCount:H.length});let q=await(await this.discordFetch(`/channels/${$}/messages`,"POST",Y)).json();return this.logger.debug("Discord API: POST message response",{messageId:q.id}),{id:q.id,threadId:X,raw:q}}tryPostSlashResponse(Q,w,$){let B=this.requestContext.getStore()?.slashCommand;if(!B||B.channelId!==Q)return;return this.postSlashCommandResponse(B,Q,w,$)}async postSlashCommandResponse(Q,w,$,B){let X=!Q.initialResponseSent;Q.initialResponseSent=!0;let Y=X?`/webhooks/${this.applicationId}/${Q.interactionToken}/messages/@original`:`/webhooks/${this.applicationId}/${Q.interactionToken}?wait=true`,Z=X?"PATCH":"POST";this.logger.debug("Discord interaction webhook: responding to slash command",{threadId:w,isInitialResponse:X,hasFiles:B.length>0});let W=await(B.length>0?await this.discordInteractionFetchWithFiles(Y,Z,$,B):await this.discordInteractionFetch(Y,Z,$)).json();return{id:W.id,threadId:w,raw:W}}async createDiscordThread(Q,w){let $=`Thread ${new Date().toLocaleString()}`;this.logger.debug("Discord API: POST thread",{channelId:Q,messageId:w,threadName:$});try{let X=await(await this.discordFetch(`/channels/${Q}/messages/${w}/threads`,"POST",{name:$,auto_archive_duration:1440})).json();return this.logger.debug("Discord API: POST thread response",{threadId:X.id,threadName:X.name}),X}catch(B){if(B instanceof Cb&&typeof B.message==="string"&&B.message.includes('"code"')&&B.message.includes("160004"))return this.logger.debug("Thread already exists for message, reusing existing thread",{channelId:Q,messageId:w}),{id:w,name:$};throw B}}truncateContent(Q){if(Q.length<=Zh1)return Q;return`${Q.slice(0,Zh1-3)}...`}async postMessageWithFiles(Q,w,$,B){let X=new FormData;X.append("payload_json",JSON.stringify($));for(let H=0;H<B.length;H++){let W=B[H];if(!W)continue;let K=await Rl0(W.data,{platform:"discord"});if(!K)continue;let U=new Blob([new Uint8Array(K)],{type:W.mimeType||"application/octet-stream"});X.append(`files[${H}]`,U,W.filename)}let Y=await fetch(`${S70}/channels/${Q}/messages`,{method:"POST",headers:{Authorization:`Bot ${this.botToken}`},body:X});if(!Y.ok){let H=await Y.text();throw new Cb("discord",`Failed to post message: ${Y.status} ${H}`)}let Z=await Y.json();return{id:Z.id,threadId:w,raw:Z}}async discordInteractionFetch(Q,w,$){let B=await fetch(`${S70}${Q}`,{method:w,headers:$?{"Content-Type":"application/json"}:void 0,body:$?JSON.stringify($):void 0});if(!B.ok){let X=await B.text();throw this.logger.error("Discord interaction API error",{path:Q,method:w,status:B.status,error:X}),new Cb("discord",`Discord interaction API error: ${B.status} ${X}`)}return B}async discordInteractionFetchWithFiles(Q,w,$,B){let X=new FormData;X.append("payload_json",JSON.stringify($));for(let Z=0;Z<B.length;Z++){let H=B[Z];if(!H)continue;let W=await Rl0(H.data,{platform:"discord"});if(!W)continue;let K=new Blob([new Uint8Array(W)],{type:H.mimeType||"application/octet-stream"});X.append(`files[${Z}]`,K,H.filename)}let Y=await fetch(`${S70}${Q}`,{method:w,body:X});if(!Y.ok){let Z=await Y.text();throw this.logger.error("Discord interaction API error",{path:Q,method:w,status:Y.status,error:Z}),new Cb("discord",`Discord interaction API error: ${Y.status} ${Z}`)}return Y}async editMessage(Q,w,$){let{channelId:B,threadId:X}=this.decodeThreadId(Q),Y=X||B,Z={},H=[],W=[],K=T70($);if(K){let q=tl0(K);H.push(...q.embeds),W.push(...q.components),Z.content=""}else Z.content=this.truncateContent(sj(this.formatConverter.renderPostable($),"discord"));if(H.length>0)Z.embeds=H;if(W.length>0)Z.components=W;this.logger.debug("Discord API: PATCH message",{channelId:Y,messageId:w,contentLength:Z.content?.length||0});let G=await(await this.discordFetch(`/channels/${Y}/messages/${w}`,"PATCH",Z)).json();return this.logger.debug("Discord API: PATCH message response",{messageId:G.id}),{id:G.id,threadId:Q,raw:G}}async deleteMessage(Q,w){let{channelId:$,threadId:B}=this.decodeThreadId(Q),X=B||$;this.logger.debug("Discord API: DELETE message",{channelId:X,messageId:w}),await this.discordFetch(`/channels/${X}/messages/${w}`,"DELETE"),this.logger.debug("Discord API: DELETE message response",{ok:!0})}async addReaction(Q,w,$){let{channelId:B,threadId:X}=this.decodeThreadId(Q),Y=X||B,Z=this.encodeEmoji($);this.logger.debug("Discord API: PUT reaction",{channelId:Y,messageId:w,emoji:Z}),await this.discordFetch(`/channels/${Y}/messages/${w}/reactions/${Z}/@me`,"PUT"),this.logger.debug("Discord API: PUT reaction response",{ok:!0})}async removeReaction(Q,w,$){let{channelId:B,threadId:X}=this.decodeThreadId(Q),Y=X||B,Z=this.encodeEmoji($);this.logger.debug("Discord API: DELETE reaction",{channelId:Y,messageId:w,emoji:Z}),await this.discordFetch(`/channels/${Y}/messages/${w}/reactions/${Z}/@me`,"DELETE"),this.logger.debug("Discord API: DELETE reaction response",{ok:!0})}encodeEmoji(Q){let w=pn.toDiscord?pn.toDiscord(Q):String(Q);return encodeURIComponent(w)}async startTyping(Q,w){let{channelId:$,threadId:B}=this.decodeThreadId(Q),X=B||$;this.logger.debug("Discord API: POST typing",{channelId:X}),await this.discordFetch(`/channels/${X}/typing`,"POST")}async fetchMessages(Q,w={}){let{channelId:$,threadId:B}=this.decodeThreadId(Q),X=B||$,Y=w.limit||50,Z=w.direction??"backward",H=new URLSearchParams;if(H.set("limit",String(Y)),w.cursor)if(Z==="backward")H.set("before",w.cursor);else H.set("after",w.cursor);this.logger.debug("Discord API: GET messages",{channelId:X,limit:Y,direction:Z,cursor:w.cursor});let K=await(await this.discordFetch(`/channels/${X}/messages?${H.toString()}`,"GET")).json();this.logger.debug("Discord API: GET messages response",{messageCount:K.length});let G=[...K].reverse().map((V)=>this.parseDiscordMessage(V,Q)),q;if(K.length===Y)if(Z==="backward")q=K.at(-1)?.id;else q=K[0]?.id;return{messages:G,nextCursor:q}}async fetchThread(Q){let{channelId:w,guildId:$}=this.decodeThreadId(Q);this.logger.debug("Discord API: GET channel",{channelId:w});let X=await(await this.discordFetch(`/channels/${w}`,"GET")).json();return{id:Q,channelId:w,channelName:X.name,isDM:X.type===AP.DM||X.type===AP.GroupDM,metadata:{guildId:$,channelType:X.type,raw:X}}}async openDM(Q){this.logger.debug("Discord API: POST DM channel",{userId:Q});let $=await(await this.discordFetch("/users/@me/channels","POST",{recipient_id:Q})).json();return this.logger.debug("Discord API: POST DM channel response",{channelId:$.id}),this.encodeThreadId({guildId:"@me",channelId:$.id})}isDM(Q){let{guildId:w}=this.decodeThreadId(Q);return w==="@me"}encodeThreadId(Q){let w=Q.threadId?`:${Q.threadId}`:"";return`discord:${Q.guildId}:${Q.channelId}${w}`}decodeThreadId(Q){let w=Q.split(":");if(w.length<3||w[0]!=="discord")throw new pW("discord",`Invalid Discord thread ID: ${Q}`);return{guildId:w[1],channelId:w[2],threadId:w[3]}}parseMessage(Q){let w=Q,$=w.guild_id||"@me",B=this.encodeThreadId({guildId:$,channelId:w.channel_id});return this.parseDiscordMessage(w,B)}parseDiscordMessage(Q,w){let $=Q.type===BM1.ThreadStarterMessage&&Q.referenced_message?Q.referenced_message:Q,B=$.author,X=B.bot??!1,Y=B.id===this.botUserId;return new U5({id:$.id,threadId:w,text:this.formatConverter.extractPlainText($.content),formatted:this.formatConverter.toAst($.content),raw:Q,author:{userId:B.id,userName:B.username,fullName:B.global_name||B.username,isBot:X,isMe:Y},metadata:{dateSent:new Date($.timestamp),edited:$.edited_timestamp!==null,editedAt:$.edited_timestamp?new Date($.edited_timestamp):void 0},attachments:($.attachments||[]).map((Z)=>({type:this.getAttachmentType(Z.content_type),url:Z.url,name:Z.filename,mimeType:Z.content_type,size:Z.size,width:Z.width??void 0,height:Z.height??void 0}))})}getAttachmentType(Q){if(!Q)return"file";if(Q.startsWith("image/"))return"image";if(Q.startsWith("video/"))return"video";if(Q.startsWith("audio/"))return"audio";return"file"}rehydrateAttachment(Q){let w=Q.fetchMetadata?.url??Q.url;if(!w)return Q;return{...Q,fetchData:()=>this.downloadAttachment(w)}}async downloadAttachment(Q){let w;try{w=await fetch(Q)}catch($){throw new Cb("discord","Failed to download Discord attachment",$ instanceof Error?$:void 0)}if(!w.ok)throw new Cb("discord",`Failed to download Discord attachment: ${w.status}`);return Buffer.from(await w.arrayBuffer())}renderFormatted(Q){return this.formatConverter.fromAst(Q)}async discordFetch(Q,w,$){let B=`${this.apiBaseUrl}${Q}`,X={Authorization:`Bot ${this.botToken}`};if($)X["Content-Type"]="application/json";let Y=await fetch(B,{method:w,headers:X,body:$?JSON.stringify($):void 0});if(!Y.ok){let Z=await Y.text();throw this.logger.error("Discord API error",{path:Q,method:w,status:Y.status,error:Z}),new Cb("discord",`Discord API error: ${Y.status} ${Z}`)}return Y}async startGatewayListener(Q,w=180000,$,B){if(!this.chat)return new Response("Chat instance not initialized",{status:500});if(!Q.waitUntil)return new Response("waitUntil not provided",{status:500});this.logger.info("Starting Discord Gateway listener",{durationMs:w,webhookUrl:B?"configured":"not configured"});let X=this.runGatewayListener(w,$,B);return Q.waitUntil(X),new Response(JSON.stringify({status:"listening",durationMs:w,message:`Gateway listener started, will run for ${w/1000} seconds`}),{status:200,headers:{"Content-Type":"application/json"}})}async runGatewayListener(Q,w,$){let B=new _7.Client({intents:[_7.GatewayIntentBits.Guilds,_7.GatewayIntentBits.GuildMessages,_7.GatewayIntentBits.MessageContent,_7.GatewayIntentBits.DirectMessages,_7.GatewayIntentBits.GuildMessageReactions,_7.GatewayIntentBits.DirectMessageReactions],partials:[_7.Partials.Channel]}),X=!1;if($)B.on("raw",async(Y)=>{if(X)return;if(!Y.t)return;this.logger.info("Discord Gateway forwarding event",{type:Y.t}),await this.forwardGatewayEvent($,{type:`GATEWAY_${Y.t}`,timestamp:Date.now(),data:Y.d})});else this.setupLegacyGatewayHandlers(B,()=>X);B.on(_7.Events.ClientReady,()=>{this.logger.info("Discord Gateway connected",{username:B.user?.username,id:B.user?.id})}),B.on(_7.Events.Error,(Y)=>{this.logger.error("Discord Gateway error",{error:String(Y)})});try{await B.login(this.botToken),await new Promise((Y)=>{let Z=setTimeout(Y,Q);if(w){if(w.aborted){clearTimeout(Z),Y();return}w.addEventListener("abort",()=>{this.logger.info("Discord Gateway listener received abort signal (new listener started)"),clearTimeout(Z),Y()},{once:!0})}}),this.logger.info("Discord Gateway listener duration elapsed, disconnecting")}catch(Y){this.logger.error("Discord Gateway listener error",{error:String(Y)})}finally{X=!0,B.destroy(),this.logger.info("Discord Gateway listener stopped")}}setupLegacyGatewayHandlers(Q,w){Q.on(_7.Events.MessageCreate,async($)=>{if(w()){this.logger.debug("Ignoring message - Gateway is shutting down");return}if($.author.bot){this.logger.debug("Ignoring message from bot",{authorId:$.author.id,authorName:$.author.username,isMe:$.author.id===Q.user?.id});return}let B=$.mentions.has(Q.user?.id??""),X=this.mentionRoleIds.length>0&&$.mentions.roles.some((Z)=>this.mentionRoleIds.includes(Z.id)),Y=B||X;this.logger.info("Discord Gateway message received",{channelId:$.channelId,guildId:$.guildId,authorId:$.author.id,isMentioned:Y,isUserMentioned:B,isRoleMentioned:X,content:$.content.slice(0,100)}),await this.handleGatewayMessage($,Y)}),Q.on(_7.Events.InteractionCreate,async($)=>{if(w()){this.logger.debug("Ignoring interaction - Gateway is shutting down");return}this.logger.info("Discord Gateway interaction received",{id:$.id,type:$.type});try{await this.handleGatewayInteraction($)}catch(B){this.logger.error("Error handling Gateway interaction",{error:String(B),interactionId:$.id})}}),Q.on(_7.Events.MessageReactionAdd,async($,B)=>{if(w()){this.logger.debug("Ignoring reaction - Gateway is shutting down");return}if(B.bot){this.logger.debug("Ignoring reaction from bot",{userId:B.id,isMe:B.id===Q.user?.id});return}if(this.logger.info("Discord Gateway reaction added",{emoji:$.emoji.name,messageId:$.message.id,channelId:$.message.channelId,userId:B.id}),B.username)await this.handleGatewayReaction($,B,!0)}),Q.on(_7.Events.MessageReactionRemove,async($,B)=>{if(w()){this.logger.debug("Ignoring reaction removal - Gateway is shutting down");return}if(B.bot){this.logger.debug("Ignoring reaction removal from bot",{userId:B.id,isMe:B.id===Q.user?.id});return}if(this.logger.info("Discord Gateway reaction removed",{emoji:$.emoji.name,messageId:$.message.id,channelId:$.message.channelId,userId:B.id}),B.username)await this.handleGatewayReaction($,B,!1)})}async forwardGatewayEvent(Q,w){try{this.logger.debug("Forwarding Gateway event to webhook",{type:w.type,webhookUrl:Q});let $=await fetch(Q,{method:"POST",headers:{"Content-Type":"application/json","x-discord-gateway-token":this.botToken},body:JSON.stringify(w)});if($.ok)this.logger.debug("Gateway event forwarded successfully",{type:w.type});else{let B=await $.text();this.logger.error("Failed to forward Gateway event",{type:w.type,status:$.status,error:B})}}catch($){this.logger.error("Error forwarding Gateway event",{type:w.type,error:String($)})}}async handleGatewayMessage(Q,w){if(!this.chat)return;let $=Q.guildId||"@me",B=Q.channelId,X=Q.channel.isThread(),Y,Z=B;if(X&&"parentId"in Q.channel&&Q.channel.parentId)Y=B,Z=Q.channel.parentId;if(!Y&&w)try{let K=await this.createDiscordThread(B,Q.id);Y=K.id,this.logger.debug("Created Discord thread for incoming mention",{channelId:B,messageId:Q.id,threadId:K.id})}catch(K){this.logger.error("Failed to create Discord thread for mention",{error:String(K),messageId:Q.id})}let H=this.encodeThreadId({guildId:$,channelId:Z,threadId:Y}),W=new U5({id:Q.id,threadId:H,text:Q.content,formatted:this.formatConverter.toAst(Q.content),author:{userId:Q.author.id,userName:Q.author.username,fullName:Q.author.displayName||Q.author.username,isBot:Q.author.bot,isMe:!1},metadata:{dateSent:Q.createdAt,edited:Q.editedAt!==null,editedAt:Q.editedAt??void 0},attachments:Q.attachments.map((K)=>({type:this.getAttachmentType(K.contentType),url:K.url,name:K.name,mimeType:K.contentType??void 0,size:K.size})),raw:{id:Q.id,channel_id:B,guild_id:$,content:Q.content,author:{id:Q.author.id,username:Q.author.username},timestamp:Q.createdAt.toISOString()},isMention:w});try{await this.chat.handleIncomingMessage(this,H,W)}catch(K){this.logger.error("Error handling Gateway message",{error:String(K),messageId:Q.id})}}async handleGatewayReaction(Q,w,$){if(!this.chat)return;let B=Q.message.guildId||"@me",X=Q.message.channelId,Y=Q.message.channel?.isThread?.(),Z=X,H;if(Y&&Q.message.channel?.parentId)H=X,Z=Q.message.channel.parentId;let W=this.encodeThreadId({guildId:B,channelId:Z,threadId:H}),K=Q.emoji.name||"unknown",U=this.normalizeDiscordEmoji(K),G={adapter:this,threadId:W,messageId:Q.message.id,emoji:U,rawEmoji:Q.emoji.id?`<:${K}:${Q.emoji.id}>`:K,added:$,user:{userId:w.id,userName:w.username,fullName:w.username,isBot:w.bot===!0,isMe:w.id===this.applicationId},raw:{emoji:Q.emoji,message_id:Q.message.id,channel_id:Q.message.channelId,guild_id:Q.message.guildId,user_id:w.id}};this.chat.processReaction(G)}channelIdFromThreadId(Q){return Q.split(":").slice(0,3).join(":")}async fetchChannelMessages(Q,w={}){let B=Q.split(":")[2];if(!B)throw new pW("discord",`Invalid Discord channel ID: ${Q}`);let X=w.limit||50,Y=w.direction??"backward",Z=new URLSearchParams;if(Z.set("limit",String(X)),w.cursor)if(Y==="backward")Z.set("before",w.cursor);else Z.set("after",w.cursor);this.logger.debug("Discord API: GET channel messages",{channelId:B,limit:X,direction:Y,cursor:w.cursor});let W=await(await this.discordFetch(`/channels/${B}/messages?${Z.toString()}`,"GET")).json();this.logger.debug("Discord API: GET channel messages response",{messageCount:W.length});let U=[...W].reverse().map((q)=>this.parseDiscordMessage(q,Q)),G;if(W.length===X)if(Y==="backward")G=W.at(-1)?.id;else G=W[0]?.id;return{messages:U,nextCursor:G}}async listThreads(Q,w={}){let $=Q.split(":"),B=$[1],X=$[2];if(!(B&&X))throw new pW("discord",`Invalid Discord channel ID: ${Q}`);this.logger.debug("Discord API: GET threads",{guildId:B,channelId:X});let H=((await(await this.discordFetch(`/guilds/${B}/threads/active`,"GET")).json()).threads||[]).filter((J)=>J.parent_id===X),W=[];try{W=(await(await this.discordFetch(`/channels/${X}/threads/archived/public?limit=${w.limit||50}`,"GET")).json()).threads||[]}catch{this.logger.debug("Could not fetch archived threads (may lack permissions)")}let K=[...H,...W],U=new Set,G=K.filter((J)=>{if(U.has(J.id))return!1;return U.add(J.id),!0}),q=w.limit||50,V=G.slice(0,q),I=[];for(let J of V){let k=this.encodeThreadId({guildId:B,channelId:X,threadId:J.id});try{let x=(await(await this.discordFetch(`/channels/${J.id}/messages?limit=1&after=0`,"GET")).json())[0];if(x)I.push({id:k,rootMessage:this.parseDiscordMessage(x,k),replyCount:J.total_message_sent??J.message_count,lastReplyAt:J.thread_metadata?.archive_timestamp?new Date(J.thread_metadata.archive_timestamp):void 0})}catch{I.push({id:k,rootMessage:new U5({id:J.id,threadId:k,text:J.name,formatted:this.formatConverter.toAst(J.name),raw:J,author:{userId:"unknown",userName:"unknown",fullName:"unknown",isBot:!1,isMe:!1},metadata:{dateSent:new Date,edited:!1},attachments:[]}),replyCount:J.total_message_sent??J.message_count})}}return this.logger.debug("Discord API: listThreads result",{threadCount:I.length}),{threads:I,nextCursor:G.length>q?String(q):void 0}}async fetchChannelInfo(Q){let $=Q.split(":")[2];if(!$)throw new pW("discord",`Invalid Discord channel ID: ${Q}`);this.logger.debug("Discord API: GET channel info",{channelId:$});let X=await(await this.discordFetch(`/channels/${$}`,"GET")).json();return{id:Q,name:X.name,isDM:X.type===AP.DM||X.type===AP.GroupDM,memberCount:X.member_count,metadata:{channelType:X.type,raw:X}}}async postChannelMessage(Q,w){let B=Q.split(":")[2];if(!B)throw new pW("discord",`Invalid Discord channel ID: ${Q}`);let X={},Y=[],Z=[],H=T70(w);if(H){let q=tl0(H);Y.push(...q.embeds),Z.push(...q.components)}else X.content=this.truncateContent(sj(this.formatConverter.renderPostable(w),"discord"));if(Y.length>0)X.embeds=Y;if(Z.length>0)X.components=Z;let W=xl0(w),K=this.tryPostSlashResponse(Q,X,W);if(K)return K;if(W.length>0)return this.postMessageWithFiles(B,Q,X,W);this.logger.debug("Discord API: POST channel message",{channelId:B,contentLength:X.content?.length||0});let G=await(await this.discordFetch(`/channels/${B}/messages`,"POST",X)).json();return{id:G.id,threadId:Q,raw:G}}normalizeDiscordEmoji(Q){let $={"\uD83D\uDC4D":"thumbs_up","\uD83D\uDC4E":"thumbs_down","\u2764\uFE0F":"heart","\u2764":"heart","\uD83D\uDD25":"fire","\uD83D\uDE80":"rocket","\uD83D\uDE4C":"raised_hands","\u2705":"check","\u274C":"x","\uD83D\uDC4B":"wave","\uD83E\uDD14":"thinking","\uD83D\uDE0A":"smile","\uD83D\uDE02":"laugh","\uD83C\uDF89":"party","\u2B50":"star","\u2728":"sparkles","\uD83D\uDC40":"eyes","\uD83D\uDCAF":"100"}[Q]||Q;return hb($)}};function Wh1(A){return new OsQ(A??{})}var xsQ=class{subscriptions=new Set;locks=new Map;cache=new Map;queues=new Map;connected=!1;connectPromise=null;async connect(){if(this.connected)return;if(!this.connectPromise)this.connectPromise=Promise.resolve().then(()=>{this.connected=!0});await this.connectPromise}async disconnect(){this.connected=!1,this.connectPromise=null,this.subscriptions.clear(),this.locks.clear(),this.queues.clear()}async subscribe(A){this.ensureConnected(),this.subscriptions.add(A)}async unsubscribe(A){this.ensureConnected(),this.subscriptions.delete(A)}async isSubscribed(A){return this.ensureConnected(),this.subscriptions.has(A)}async acquireLock(A,Q){this.ensureConnected(),this.cleanExpiredLocks();let w=this.locks.get(A);if(w&&w.expiresAt>Date.now())return null;let $={threadId:A,token:RsQ(),expiresAt:Date.now()+Q};return this.locks.set(A,$),$}async forceReleaseLock(A){this.ensureConnected(),this.locks.delete(A)}async releaseLock(A){this.ensureConnected();let Q=this.locks.get(A.threadId);if(Q&&Q.token===A.token)this.locks.delete(A.threadId)}async extendLock(A,Q){this.ensureConnected();let w=this.locks.get(A.threadId);if(!w||w.token!==A.token)return!1;if(w.expiresAt<Date.now())return this.locks.delete(A.threadId),!1;return w.expiresAt=Date.now()+Q,!0}async get(A){this.ensureConnected();let Q=this.cache.get(A);if(!Q)return null;if(Q.expiresAt!==null&&Q.expiresAt<=Date.now())return this.cache.delete(A),null;return Q.value}async set(A,Q,w){this.ensureConnected(),this.cache.set(A,{value:Q,expiresAt:w?Date.now()+w:null})}async setIfNotExists(A,Q,w){this.ensureConnected();let $=this.cache.get(A);if($)if($.expiresAt!==null&&$.expiresAt<=Date.now())this.cache.delete(A);else return!1;return this.cache.set(A,{value:Q,expiresAt:w?Date.now()+w:null}),!0}async delete(A){this.ensureConnected(),this.cache.delete(A)}async appendToList(A,Q,w){this.ensureConnected();let $=this.cache.get(A),B;if($&&$.expiresAt!==null&&$.expiresAt<=Date.now())B=[];else if($&&Array.isArray($.value))B=$.value;else B=[];if(B.push(Q),w?.maxLength&&B.length>w.maxLength)B=B.slice(B.length-w.maxLength);this.cache.set(A,{value:B,expiresAt:w?.ttlMs?Date.now()+w.ttlMs:null})}async enqueue(A,Q,w){this.ensureConnected();let $=this.queues.get(A);if(!$)$=[],this.queues.set(A,$);if($.push(Q),$.length>w)$.splice(0,$.length-w);return $.length}async dequeue(A){this.ensureConnected();let Q=this.queues.get(A);if(!Q||Q.length===0)return null;let w=Q.shift();if(Q.length===0)this.queues.delete(A);return w??null}async queueDepth(A){return this.ensureConnected(),this.queues.get(A)?.length??0}async getList(A){this.ensureConnected();let Q=this.cache.get(A);if(!Q)return[];if(Q.expiresAt!==null&&Q.expiresAt<=Date.now())return this.cache.delete(A),[];if(Array.isArray(Q.value))return Q.value;return[]}ensureConnected(){if(!this.connected)throw Error("MemoryStateAdapter is not connected. Call connect() first.")}cleanExpiredLocks(){let A=Date.now();for(let[Q,w]of this.locks)if(w.expiresAt<=A)this.locks.delete(Q)}_getSubscriptionCount(){return this.subscriptions.size}_getLockCount(){return this.cleanExpiredLocks(),this.locks.size}};function RsQ(){return`mem_${Date.now()}_${Math.random().toString(36).substring(2,15)}`}function m70(A){return new xsQ}C0();var vsQ=f.object({subscribedAt:f.string().datetime(),routingMode:f.enum(["auto","mention-required"]).optional(),mentionRequiredNoticeSent:f.boolean().optional()}),hsQ="chat.discord.subscriptions";function el0(A){return A.scoped({namespace:hsQ,schema:vsQ})}function Kh1(A,Q=m70()){let w=el0(A);return new Uh1(Q,w)}class Uh1{memoryState;subscriptions;constructor(A,Q){this.memoryState=A,this.subscriptions=Q}connect(){return this.memoryState.connect()}disconnect(){return this.memoryState.disconnect()}async subscribe(A){await this.subscriptions.set(A,{subscribedAt:new Date().toISOString()})}async unsubscribe(A){await this.subscriptions.delete(A)}isSubscribed(A){return this.subscriptions.has(A)}acquireLock(A,Q){return this.memoryState.acquireLock(A,Q)}appendToList(A,Q,w){return this.memoryState.appendToList(A,Q,w)}delete(A){return this.memoryState.delete(A)}dequeue(A){return this.memoryState.dequeue(A)}enqueue(A,Q,w){return this.memoryState.enqueue(A,Q,w)}extendLock(A,Q){return this.memoryState.extendLock(A,Q)}forceReleaseLock(A){return this.memoryState.forceReleaseLock(A)}get(A){return this.memoryState.get(A)}getList(A){return this.memoryState.getList(A)}queueDepth(A){return this.memoryState.queueDepth(A)}releaseLock(A){return this.memoryState.releaseLock(A)}set(A,Q,w){return this.memoryState.set(A,Q,w)}setIfNotExists(A,Q,w){return this.memoryState.setIfNotExists(A,Q,w)}}function Gh1(A){let{discord:Q}=A;if(!Q)return new Pl0({userName:A.userName,adapters:{},state:m70()});let w=Wh1({botToken:Q.botToken,publicKey:Q.publicKey,applicationId:Q.applicationId,mentionRoleIds:Q.mentionRoleIds});return A.gatewayLoop.setAdapter(w),new Pl0({userName:A.userName,adapters:{discord:w},concurrency:{strategy:"queue",maxQueueSize:5,onQueueFull:"drop-oldest"},state:Kh1(A.runtimeState)})}class Ap0{deps;constructor(A){this.deps=A}async subscribeOwnedThread(A,Q){if(!this.deps.isBotCreatedThread(A,Q))return;try{await A.subscribe(),await this.deps.getSubscriptions()?.set(A.id,{subscribedAt:new Date().toISOString()})}catch(w){this.deps.logger.debug("Discord thread subscription failed",{error:w,threadId:A.id})}}async shouldRouteSubscribedMessage(A,Q){if(this.deps.getPlatform(A)!=="discord")return!1;if(A.isDM)return!0;let w=await this.deps.getSubscriptions()?.get(A.id);if(!w)return!1;if(w.routingMode==="mention-required"){if(!Q.isMention&&!w.mentionRequiredNoticeSent)await this.postMentionRequiredNotice(A,w);return Boolean(Q.isMention)}if(!await this.shouldRequireMentionInSubscribedThread(A))return!0;let B={...w,routingMode:"mention-required"};if(!Q.isMention&&!w.mentionRequiredNoticeSent)await this.postMentionRequiredNotice(A,B);else await this.deps.getSubscriptions()?.set(A.id,B);return Boolean(Q.isMention)}async postMentionRequiredNotice(A,Q){await A.post("I\u2019ll stop auto-replying now that more people joined. Mention me if you need me."),await this.deps.getSubscriptions()?.set(A.id,{...Q,routingMode:"mention-required",mentionRequiredNoticeSent:!0})}async shouldRequireMentionInSubscribedThread(A){try{return(await A.getParticipants()).filter(($)=>!$.isBot&&!$.isMe).length>1}catch(Q){return this.deps.logger.debug("Failed to inspect Discord thread participants",{error:Q,threadId:A.id}),!1}}}fA();class Qp0{deps;constructor(A){this.deps=A}async build(A,Q,w,$){let B={message:w.text.trim(),attachments:[],notices:[]};if(w.attachments.length===0)return B;if(!($==="anchor"||$==="trusted"))return B;let Y=this.deps.getUploadStore();if(!Y)return B;for(let Z of w.attachments){let H=Z.name;if(!H)continue;let W=B3(H,"upload"),K=vI(W,Z.mimeType),U=Z.size??0,G=o20(W,K);if(!G){B.notices.push(`Unsupported file upload type: ${W}`);continue}if(!s20(G,U)){B.notices.push(`File upload too large: ${W}`);continue}try{let q=await this.readAttachmentData(Z);if(!q)continue;let V=X3({filename:W,mediaType:K,content:q,fallbackFilename:"upload"});if(!V.ok){B.notices.push(V.message);continue}let I=await Y.save({filename:V.filename,mediaType:V.mediaType,content:q,metadata:this.buildMetadata(A,Q,w)});B.attachments.push(qh1(I.filename,I.mediaType,q,I.ref,V.kind==="text"))}catch(q){this.deps.logger.error("Failed to read chat attachment",{error:q,filename:W}),B.notices.push(`Could not read file upload: ${W}`)}}return B}async readAttachmentData(A){if(A.fetchData)return A.fetchData();if(!A.url)return;let Q=await fetch(A.url);if(!Q.ok)throw Error(`Attachment download failed with status ${Q.status}`);let w=await Q.arrayBuffer();return Buffer.from(new Uint8Array(w))}buildMetadata(A,Q,w){let $=this.deps.getThreadIdParts(Q.id);return{interfaceType:A,channelId:Q.id,parentChannelId:Q.channelId,messageId:w.id,uploaderId:w.author.userId,uploaderUsername:w.author.userName,...$.guildId?{guildId:$.guildId}:{},...$.threadId?{threadId:$.threadId}:{}}}}function Dh1(A,Q,w,$){return qh1(A,Q,w,$,hI(A,Q))}function qh1(A,Q,w,$,B){if(B)return{kind:"text",filename:A,mediaType:Q,content:w.toString("utf8").replace(/^\uFEFF/,""),sizeBytes:w.byteLength,source:$};return{kind:"file",filename:A,mediaType:Q,data:w,sizeBytes:w.byteLength,source:$}}function an(){return{namespace:"discord-chat",refKind:"discord-chat-upload",routePath:"/api/webhooks/chat/discord/uploads"}}function Bq(A){let Q=A.split(":");if(Q[0]!=="discord")return{};return{...Q[1]?{guildId:Q[1]}:{},...Q[2]?{channelId:Q[2]}:{},...Q[3]?{threadId:Q[3]}:{}}}function CsQ(A){let Q=A.raw;if(typeof Q!=="object"||Q===null)return;let w=Q.channel_id;return typeof w==="string"?w:void 0}function zh1(A,Q){if(A.isDM)return!1;let w=Bq(A.id);if(!w.threadId)return!1;let $=CsQ(Q);return $!==void 0&&$!==w.threadId}function u70(A,Q){if(Q.allowedChannels.length===0||A.isDM)return!0;let w=Bq(A.id);return[A.id,A.channelId,w.channelId,w.threadId].some(($)=>typeof $==="string"&&Q.allowedChannels.includes($))}function wp0(A,Q,w){if(A.isDM&&!w.allowDMs)return!1;if(Q.author.isMe)return!1;if(Q.author.isBot&&!Q.isMention)return!1;return u70(A,w)}function $p0(A,Q,w){if(Q!=="discord")return!0;if(!w)return!1;if(A.isDM&&!w.allowDMs)return!1;return u70(A,w)}function Bp0(A,Q){return{channelId:Bq(A.id).channelId??A.channelId,isBot:Boolean(Q.author.isBot)}}function mg(A){return A.isDM?"DM":A.channelId}var gsQ="https://discord.com/api/v10";async function Vh1(A){let Q=Bq(A.threadId),w=Q.threadId??Q.channelId;if(!w)return;let $=A.fetchFn??fetch;try{let B=await $(`${gsQ}/channels/${w}/messages/${A.messageId}`,{method:"PATCH",headers:{Authorization:`Bot ${A.botToken}`,"Content-Type":"application/json"},body:JSON.stringify({components:[]})});if(!B.ok)A.logger.debug("Failed to clear Discord message components",{messageId:A.messageId,channelId:w,status:B.status})}catch(B){A.logger.debug("Failed to clear Discord message components",{error:B,messageId:A.messageId,channelId:w})}}var Jh1={name:"@brains/chat",version:"0.2.0-alpha.159",description:"Discord Chat SDK interface for Brains",dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*","@chat-adapter/discord":"^4.29.0","@chat-adapter/state-memory":"^4.29.0",chat:"^4.29.0"},devDependencies:{"@brains/core":"workspace:*","@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14"},exports:{".":"./src/index.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var EsQ=/https?:\/\/\S+/i,TsQ=/[\s\S]+/,SsQ=1000,msQ=f.looseObject({type:f.literal("card"),children:f.array(f.looseObject({type:f.string()})),imageUrl:f.string().optional(),subtitle:f.string().optional(),title:f.string().optional()}),usQ=f.object({card:f.custom((A)=>msQ.safeParse(A).success),fallbackText:f.string().optional()});class c70 extends nK{threadRegistry=new N70;pendingApprovals;uploadContinuity;promptActions=new $c0(SsQ);toolStatusMessenger=new Bc0(this.threadRegistry);cardBuilder=new fc0({getDisplayBaseUrl:()=>this.getPreferredDisplayBaseUrl(),registerPromptAction:(A,Q)=>this.registerPromptAction(A,Q)});artifactDelivery=new Wc0({getContext:()=>this.context,getDisplayBaseUrl:()=>this.getPreferredDisplayBaseUrl(),logger:this.logger});approvalCards=new Kc0({cardBuilder:this.cardBuilder,clearMessageComponents:async(A,Q)=>{let w=this.config.adapters.discord?.botToken;if(!w)return;await Vh1({threadId:A,messageId:Q,botToken:w,logger:this.logger})}});subscriptionRouter=new Ap0({getSubscriptions:()=>this.discordSubscriptions,getPlatform:(A)=>this.getPlatform(A),isBotCreatedThread:zh1,logger:this.logger});chatInputBuilder=new Qp0({getUploadStore:()=>this.context?.uploads.scoped(an()),getThreadIdParts:Bq,logger:this.logger});gatewayLoop;discordApp;discordSubscriptions;constructor(A={}){super("chat",Jh1,A,wc0);this.gatewayLoop=new Uc0({getApp:()=>this.discordApp.instance,gatewayRunMs:this.config.gatewayRunMs,gatewayRestartDelayMs:this.config.gatewayRestartDelayMs,logger:this.logger}),this.discordApp=new Gc0({discord:this.config.adapters.discord,getUploadStore:()=>this.context?.uploads.scoped(an()),buildApp:(Q)=>Gh1({userName:this.config.userName,discord:this.config.adapters.discord,gatewayLoop:this.gatewayLoop,runtimeState:Q})}),this.pendingApprovals=new Eu({loadMessages:async(Q)=>{return await this.context?.conversations.getMessages(Q,{limit:50})??[]},onRestoreError:(Q,w)=>{this.logger.debug("Failed to load pending chat approvals",{error:Q,conversationId:w})}}),this.uploadContinuity=new lu({sourceKind:"discord-chat-upload",loadMessages:async(Q)=>{return await this.context?.conversations.getMessages(Q,{limit:50})??[]},restoreAttachment:async(Q)=>{let w=this.context?.uploads.scoped(an());if(!w)throw Error("Chat upload store unavailable");let $=await w.read(Q);return Dh1($.record.filename,$.record.mediaType,$.content,$.record.ref)},onLoadError:(Q,w)=>{this.logger.debug("Failed to load prior chat uploads",{error:Q,conversationId:w})},onRestoreError:(Q,w)=>{this.logger.debug("Failed to restore prior chat upload",{error:Q,uploadId:w})}})}async onRegister(A){await super.onRegister(A),this.discordSubscriptions=el0(A.runtimeState),this.registerChatHandlers(this.discordApp.build(A.runtimeState))}getWebRoutes(){return this.discordApp.getWebRoutes()}createDaemon(){if(!this.config.adapters.discord)return;return{start:async()=>{await this.discordApp.initialize(),this.gatewayLoop.start()},stop:async()=>{await this.gatewayLoop.stop(),this.threadRegistry.clear(),this.uploadContinuity.clear(),this.toolStatusMessenger.clear(),await this.discordApp.shutdown()},healthCheck:async()=>({status:this.gatewayLoop.isRunning()?"healthy":"error",message:this.gatewayLoop.isRunning()?"Chat gateway loop running":"Chat gateway loop stopped",lastCheck:new Date})}}sendMessageToChannel({channelId:A,message:Q}){let w=this.threadRegistry.get(A);if(!w)return;let $=this.toDiscordCardOutput(Q);if($){w.post($).catch((B)=>this.logger.error("Failed to send chat message",{error:B,channelId:A}));return}if(typeof Q!=="string")return;for(let B of Tn(A,Q))w.post(B).catch((X)=>this.logger.error("Failed to send chat message",{error:X,channelId:A}))}async sendMessageWithId({channelId:A,message:Q}){let w=this.threadRegistry.get(A);if(!w)return;let $=this.toDiscordCardOutput(Q);if($){let X=await w.post($);return this.threadRegistry.trackMessage(w.id,X),X.id}if(typeof Q!=="string")return;let B;for(let X of Tn(A,Q))B=await w.post(X),this.threadRegistry.trackMessage(w.id,B);return B?.id}async editMessage({channelId:A,messageId:Q,newMessage:w}){let $=this.threadRegistry.getMessage(A,Q);if(!$)return!1;try{let B=await $.edit(this.toDiscordCardOutput(w)??(typeof w==="string"?w:""));if(A)this.threadRegistry.trackMessage(A,B);return!0}catch{return!1}}supportsMessageEditing(){return!0}toDiscordCardOutput(A){let Q=usQ.safeParse(A);if(!Q.success)return;let{card:w,fallbackText:$}=Q.data;if($===void 0)return{card:w};return{card:w,fallbackText:$}}formatProgressOutput(A){return Zc0(A)}formatCompletionOutput(A){return Zc0(A)}async handleProgressEvent(A,Q){let w=A.metadata.interfaceType;if(w&&w!==this.id){if(!this.isEnabledPlatform(w))return;let $={...A,metadata:{...A.metadata,interfaceType:this.id}};await super.handleProgressEvent($,$.metadata);return}await super.handleProgressEvent(A,Q)}async handleToolActivityEvent(A){if(A.interfaceType===this.id){await super.handleToolActivityEvent(A);return}if(!this.isEnabledPlatform(A.interfaceType))return;await super.handleToolActivityEvent({...A,interfaceType:this.id})}async handleToolStatusUpdate(A){if(A.interfaceType!==this.id||!A.channelId)return;await this.toolStatusMessenger.handle(A)}isEnabledPlatform(A){return pb1(A,Boolean(this.config.adapters.discord))}registerChatHandlers(A){if(A.onDirectMessage(async(Q,w,$,B)=>{await this.handleRoutedMessage(Q,w,B)}),A.onNewMention(async(Q,w,$)=>{let B=this.getPlatformConfig(Q);if(B&&wp0(Q,w,B)&&!Q.isDM&&B.useThreads)await this.subscriptionRouter.subscribeOwnedThread(Q,w);await this.handleRoutedMessage(Q,w,$)}),A.onSubscribedMessage(async(Q,w,$)=>{if(!await this.subscriptionRouter.shouldRouteSubscribedMessage(Q,w))return;await this.handleRoutedMessage(Q,w,$)}),this.config.adapters.discord&&!this.config.adapters.discord.requireMention)A.onNewMessage(TsQ,async(Q,w,$)=>{await this.handleRoutedMessage(Q,w,$)});A.onNewMessage(EsQ,async(Q,w)=>{await this.handlePassiveUrlCapture(Q,w)}),A.onAction([j70,Xc0],async(Q)=>{await this.handleApprovalAction(Q)}),A.onAction(Yc0,async(Q)=>{await this.handlePromptAction(Q)})}async handlePromptAction(A){if(!this.context||!A.thread||!A.value)return;let Q=A.adapter.name;if(!this.isEnabledPlatform(Q))return;let w=A.thread;if(!$p0(w,Q,this.config.adapters.discord))return;let $=this.promptActions.get(A.value);if($?.threadId!==w.id){await w.post(this.formatNoticePayload("That suggested action is no longer available.","Action unavailable"));return}this.promptActions.consume(A.value);let B=Bq(w.id),X=this.context.permissions.getUserLevel(Q,A.user.userId,{channelId:B.channelId??w.channelId,isBot:Boolean(A.user.isBot)}),Y=this.getConversationId(Q,w.id),Z=w.id;await this.runAgentTurn({thread:w,channelId:Z,logLabel:"Error handling chat prompt action",body:async()=>{if(!this.context)return;let H=await this.context.agent.chat($.prompt,Y,{userPermissionLevel:X,interfaceType:Q,channelId:Z,channelName:mg(w),...this.buildActionEventMetadata(Q,w,A)});await this.renderAgentResponse({thread:w,channelId:Z,conversationId:Y,response:H,userPermissionLevel:X})}})}async handleApprovalAction(A){if(!this.context||!A.thread||!A.value)return;let Q=A.adapter.name;if(!this.isEnabledPlatform(Q))return;let w=this.getConversationId(Q,A.thread.id);if(!(await this.getPendingApprovalIds(w)).has(A.value)){await A.thread.post(this.formatNoticePayload("That approval is no longer pending."));return}let B=A.thread;if(!$p0(B,Q,this.config.adapters.discord))return;let X=Bq(B.id),Y=this.context.permissions.getUserLevel(Q,A.user.userId,{channelId:X.channelId??B.channelId,isBot:Boolean(A.user.isBot)});await this.confirmApproval({thread:B,conversationId:w,approvalId:A.value,confirmed:A.actionId===j70,userPermissionLevel:Y,metadata:this.buildActionEventMetadata(Q,B,A)})}async handleRoutedMessage(A,Q,w){if(!this.context)return;let $=this.getPlatform(A);if($!=="discord")return;let B=this.getPlatformConfig(A);if(!B)return;if(!wp0(A,Q,B))return;await this.routeToAgent($,A,Q,w)}async runAgentTurn(A){this.startProcessingInput(A.channelId);try{if(this.getPlatformConfig(A.thread)?.showTypingIndicator)await A.thread.startTyping().catch((Q)=>this.logger.debug("Typing indicator failed",{error:Q,channelId:A.channelId}));await A.body()}catch(Q){this.logger.error(A.logLabel,{error:Q,channelId:A.channelId}),await this.postTurnError(A.thread,A.channelId,Q)}finally{this.endProcessingInput()}}async postTurnError(A,Q,w){let $=this.formatErrorPayload(w),B=this.toDiscordCardOutput($);if(B){await A.post(B);return}let X=typeof $==="string"?$:"Message failed.";for(let Y of Tn(Q,X))await A.post(Y)}async routeToAgent(A,Q,w,$){if(!this.context)return;this.threadRegistry.set(Q);let B=this.getConversationId(A,Q.id),X=Q.id,Y=Bp0(Q,w),Z=this.context.permissions.getUserLevel(A,w.author.userId,Y),H=await this.chatInputBuilder.build(A,Q,w,Z),W=[...H.attachments];if(await this.attachPriorUploads(B,H,Z),await this.postUploadNotices(Q,H.notices),!H.message&&H.attachments.length===0)return;this.rememberUploadAttachments(B,W),await this.runAgentTurn({thread:Q,channelId:X,logLabel:"Error handling chat message",body:async()=>{if(!this.context)return;let K=await this.getPendingApprovalIds(B);if(K.size>0){if(await this.handleConfirmationResponse(H.message,B,Q,K,Z,this.buildUserMessageMetadata(A,Q,w)))return}let U=this.buildCoalescedAgentInput(H.message,$),G=await this.context.agent.chat(U.message,B,{userPermissionLevel:Z,interfaceType:A,channelId:X,channelName:mg(Q),...this.buildUserMessageMetadata(A,Q,w,U.metadata),...H.attachments.length>0?{attachments:H.attachments}:{}});await this.renderAgentResponse({thread:Q,channelId:X,conversationId:B,response:G,userPermissionLevel:Z})}})}async renderAgentResponse(A){if(A.confirmation)this.syncPendingConfirmationsFromResponse(A.conversationId,A.response,A.confirmation.approvalId);else this.rememberPendingConfirmationsFromResponse(A.conversationId,A.response);await this.handleAgentResponseToolStatuses(A.response,A.conversationId);let Q=await this.artifactDelivery.resolve(A.response.cards,A.userPermissionLevel),w=M_(A.response,{deniedCardIds:Q.deniedCardIds});if(A.confirmation)await this.approvalCards.resolve(A.conversationId,A.confirmation.approvalId,A.confirmation.confirmed);let $=A.confirmation?this.formatConfirmationResponsePayload(A.response,A.confirmation.confirmed,this.getRemainingApprovalHelp(A.conversationId,A.response),Q.deniedCardIds):this.formatAgentResponseText(w,Q.deniedCardIds),B=await this.sendAgentResponseWithFiles({thread:A.thread,channelId:A.channelId,message:$,files:Q.files}),X=await this.sendArtifactCards(A.thread,w);await this.sendSupplementalCards(A.thread,w);let Y=w.directives.find((H)=>H.kind==="approvals");await this.approvalCards.trackPendingConfirmations(A.thread,A.conversationId,Y?.confirmations);let Z=X??B;if(Z)for(let H of w.jobIds)this.trackAgentResponseForJob(H,Z,A.channelId)}rememberPendingConfirmationsFromResponse(A,Q){this.pendingApprovals.rememberFromResponse(A,Q)}async getPendingApprovalIds(A){return this.pendingApprovals.getApprovalIds(A)}async handleConfirmationResponse(A,Q,w,$,B,X){if(!hu(A,$))return!1;let Y=y20({message:A,approvalIds:$});if(Y.kind==="not-confirmation")return this.pendingApprovals.deleteConversation(Q),await w.post(this.formatNoticePayload("No pending approval to resolve.")),!0;if(Y.kind==="notice")return await w.post(this.formatNoticePayload(Y.message)),!0;return await this.confirmApproval({thread:w,conversationId:Q,approvalId:Y.approvalId,confirmed:Y.confirmed,userPermissionLevel:B,...X?{metadata:X}:{}}),!0}async confirmApproval(A){let Q=await this.context?.agent.confirmPendingAction(A.conversationId,A.confirmed,A.approvalId,{userPermissionLevel:A.userPermissionLevel,interfaceType:"discord",channelId:A.thread.id,channelName:mg(A.thread),...A.metadata});if(this.removePendingApproval(A.conversationId,A.approvalId),!Q)return;await this.renderAgentResponse({thread:A.thread,channelId:A.thread.id,conversationId:A.conversationId,response:Q,userPermissionLevel:A.userPermissionLevel,confirmation:{approvalId:A.approvalId,confirmed:A.confirmed}})}formatNoticePayload(A,Q="Approval notice"){return{card:{type:"card",title:Q,children:[{type:"text",content:A}]},fallbackText:A}}formatErrorPayload(A){let Q=A instanceof Error?A.message:"Unknown error";return{card:{type:"card",title:"Message failed",children:[{type:"text",content:Q}]},fallbackText:`Message failed: ${Q}`}}formatAgentResponseText(A,Q){return A.directives.flatMap((w)=>{if(w.kind==="text")return[w.text];if(w.kind==="denied-artifact")return[this.cardBuilder.formatStructuredCard(w.card,Q)];return[]}).filter((w)=>w.trim().length>0).join(`
2370
2370
 
2371
2371
  `)}formatConfirmationResponsePayload(A,Q,w,$){let B=i20({response:A,confirmed:Q,remainingApprovalHelp:w,deniedCardIds:$,formatCard:(X)=>this.cardBuilder.formatStructuredCard(X,$),formatPendingConfirmationHelp:bR});return{card:{type:"card",title:l20(B.variant),children:B.parts.map((X)=>({type:"text",content:X}))},fallbackText:B.parts.join(`
2372
2372
 
@@ -2438,7 +2438,7 @@ ${Gl0(A)}
2438
2438
  <p>Once built, this page will be replaced with your actual website.</p>
2439
2439
  </div>
2440
2440
  </body>
2441
- </html>`;var QC1={name:"@brains/webserver",version:"0.2.0-alpha.158",dependencies:{"@brains/plugins":"workspace:*","@hono/bun-compress":"^0.1.1",hono:"^4.12.25"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/messaging-service":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14","@types/node":"^20.19.43",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};class yb extends ZD{serverManager;siteUrl;previewUrl;constructor(A={}){super("webserver",QC1,A,Lp0)}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 A40({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,w=this.siteUrl??A?.productionUrl??`http://localhost:${this.config.productionPort}`,$=this.previewUrl??A?.previewUrl??`http://localhost:${this.config.previewPort}`,B=[];if(Q){if(B.push(`Production: ${w}`),A?.previewUrl)B.push(`Preview: ${$}`)}return{status:Q?"healthy":"error",message:Q?B.join(", "):"Webserver not running",lastCheck:new Date,details:{preview:!!A?.previewUrl,production:Q,previewUrl:A?.previewUrl?$:void 0,productionUrl:Q?w:void 0}}}}}async handleProgressEvent(A,Q){}async ensureDistDirectories(){let{mkdir:A,writeFile:Q}=await import("fs/promises");if(this.config.enablePreview&&this.config.previewDistDir&&!wC1(this.config.previewDistDir))await A(this.config.previewDistDir,{recursive:!0}),await Q($C1(this.config.previewDistDir,"index.html"),kp0),this.logger.debug(`Created preview directory at ${this.config.previewDistDir}`);if(!wC1(this.config.productionDistDir))await A(this.config.productionDistDir,{recursive:!0}),await Q($C1(this.config.productionDistDir,"index.html"),kp0),this.logger.debug(`Created production directory at ${this.config.productionDistDir}`)}}e6();fA();C0();p_();var BC1={name:"@brains/web-chat",version:"0.2.0-alpha.158",description:"Web chat interface for Brains",dependencies:{"@ai-sdk/react":"^3.0.208","@brains/auth-service":"workspace:*","@brains/console-theme":"workspace:*","@brains/contracts":"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.206","class-variance-authority":"^0.7.0",cmdk:"^1.1.1","lucide-react":"^1.20.0",nanoid:"^5.0.4","radix-ui":"^1.6.0",react:"^19.2.7","react-dom":"^19.2.7",shiki:"^4.2.0",streamdown:"^2.5.0","tailwind-merge":"^3.6.0","use-stick-to-bottom":"^1.1.6"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14","@types/react":"^19.2.17","@types/react-dom":"^19.0.3",typescript:"^7.0.2",vite:"^8.0.16"},exports:{".":"./src/index.ts"},files:["src","dist","package.json"],private:!0,scripts:{build:"bun scripts/build-ui.ts","build:ui":"bun scripts/build-ui.ts",lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit && tsc --noEmit -p ui-react/tsconfig.json"},type:"module"};fA();async function XC1(A,Q){let w=await Q.resolvePermissionLevel(A);if(w==="public")return Q.createOperatorLoginRequiredResponse(A);let $=new URL(A.url),B=$.searchParams.get("id")?.trim();if(!B)return new Response("Missing document id",{status:400});let X=await ZC1({entityType:"document",id:B,permissionLevel:w,entityService:Q.entityService});if(!X)return new Response("Document not found",{status:404});if(typeof X.content!=="string")return new Response("Document content is not a PDF",{status:415});let Y=A3("document",X.content);if(!Y)return new Response("Document content is not a PDF",{status:415});let Z=Q3(X.metadata,B,"document",Y.mimeType);return fC1({requestUrl:$,data:Y.data,mediaType:Y.mimeType,filename:Z})}async function YC1(A,Q){let w=await Q.resolvePermissionLevel(A);if(w==="public")return Q.createOperatorLoginRequiredResponse(A);let $=new URL(A.url),B=$.searchParams.get("id")?.trim();if(!B)return new Response("Missing image id",{status:400});let X=await ZC1({entityType:"image",id:B,permissionLevel:w,entityService:Q.entityService});if(!X)return new Response("Image not found",{status:404});if(typeof X.content!=="string")return new Response("Image content is not an image",{status:415});let Y=A3("image",X.content);if(!Y)return new Response("Image content is not an image",{status:415});let Z=Q3(X.metadata,B,"image",Y.mimeType);return fC1({requestUrl:$,data:Y.data,mediaType:Y.mimeType,filename:Z})}async function ZC1(A){let Q={entityType:A.entityType,id:A.id},w=await w3({entityRef:Q,userLevel:A.permissionLevel,getEntity:($)=>A.entityService.getEntity($),getVisibleEntity:($,B)=>A.entityService.getEntity({...$,visibilityScope:B})});return w.status==="visible"?w.entity:void 0}function fC1(A){let Q=new Headers({"Content-Type":A.mediaType,"Content-Length":String(A.data.byteLength),"Content-Disposition":xI({disposition:A.requestUrl.searchParams.has("download")?"attachment":"inline",filename:A.filename})});return new Response(A.data,{headers:Q})}C0();fA();var Br="upload",HC1=KR;var yaQ={namespace:"upload",refKind:Br,routePath:"/api/chat/uploads"};function Q40(){return yaQ}fA();q_0();var WC1=n20;var KC1=r20;var EaQ="file",TaQ=16384;async function UC1(A,Q){if(!await Q.resolveOperatorSession(A))return new Response("Forbidden",{status:403});let w=Number(A.headers.get("content-length"));if(Number.isFinite(w)&&w>KC1+TaQ)return new Response("File upload too large",{status:400});let $;try{$=await A.formData()}catch{return new Response("Invalid multipart upload",{status:400})}let B=$.get(EaQ);if(!(B instanceof File))return new Response("Missing upload file",{status:400});let X=Buffer.from(await B.arrayBuffer()),Y=X3({filename:B.name,mediaType:B.type,content:X});if(!Y.ok)return new Response(Y.message,{status:400});let Z=Q.getUploadStore(),H=await Z.save({filename:Y.filename,mediaType:Y.mediaType,content:X});return Response.json(Z.toResponseBody(H),{status:201})}async function GC1(A,Q){if(!await Q.resolveOperatorSession(A))return new Response("Forbidden",{status:403});let w=new URL(A.url).searchParams.get("id")?.trim();if(!w)return new Response("Missing upload id",{status:400});let $=await zC1(w,Q.getUploadStore());if($ instanceof Response)return $;let{record:B,content:X}=$,Y=VC1(B,X);if(Y instanceof Response)return Y;let Z=new URL(A.url).searchParams.has("download")?"attachment":"inline",H=new Uint8Array(X).buffer;return new Response(H,{headers:{"Content-Type":B.mediaType,"Content-Length":String(X.byteLength),"Content-Disposition":xI({disposition:Z,filename:B.filename})}})}function DC1(A){let Q=B3(A.filename??WC1),w=maQ(A.url);if(!w)return new Response(`Unsupported file upload URL: ${Q}`,{status:400});let $=X3({filename:Q,mediaType:A.mediaType,content:w.buffer});if(!$.ok)return new Response($.message,{status:400});return JC1($,w.buffer)}async function qC1(A,Q){let w=await zC1(A,Q);if(w instanceof Response)return w;let{record:$,content:B}=w,X=VC1($,B);if(X instanceof Response)return X;return JC1(X,B,{kind:Br,id:A})}async function zC1(A,Q){try{return await Q.read(A)}catch(w){if(w instanceof fD)return SaQ(w);throw w}}function VC1(A,Q){let w=X3({filename:A.filename,mediaType:A.mediaType,content:Q});if(!w.ok)return new Response(w.message,{status:400});return w}function JC1(A,Q,w){if(A.kind==="text")return{kind:"text",filename:A.filename,mediaType:A.mediaType,content:A.text,sizeBytes:A.sizeBytes,...w!==void 0?{source:w}:{}};return{kind:"file",filename:A.filename,mediaType:A.mediaType,data:new Uint8Array(Q),sizeBytes:A.sizeBytes,...w!==void 0?{source:w}:{}}}function SaQ(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 maQ(A){let Q=/^data:[^,]*,(.*)$/s.exec(A);if(!Q)return null;let $=A.slice(5,A.indexOf(",")).split(";").some((B)=>B.toLowerCase()==="base64");try{let B=$?Buffer.from(Q[1]??"","base64"):Buffer.from(decodeURIComponent(Q[1]??""),"utf8");return{buffer:B,byteLength:B.byteLength}}catch{return null}}var uaQ=f.object({type:f.literal("text"),text:f.string()}),caQ=f.object({type:f.literal("file"),mediaType:f.string().optional(),filename:f.string().optional(),url:f.string()}),laQ=f.looseObject({state:f.literal("approval-responded"),approval:f.object({id:f.string(),approved:f.boolean()})}),paQ=f.object({id:f.string().optional(),role:f.string(),parts:f.array(f.unknown()).optional(),content:f.string().optional()}),IC1=f.object({id:f.string().optional(),messages:f.array(paQ).min(1),trigger:f.string().optional()}),iaQ=f.object({kind:f.literal(Br),id:f.string().regex(HC1)}),daQ=f.object({type:f.literal("data-upload"),data:f.object({ref:iaQ})});async function FC1(A,Q){let w=naQ(A);if(!w)return{message:"",attachments:[]};let $=[],B=[];for(let Y of w.parts??[]){let Z=uaQ.safeParse(Y);if(Z.success){if(Z.data.text.length>0)$.push(Z.data.text);continue}let H=caQ.safeParse(Y);if(H.success){let K=DC1(H.data);if(K instanceof Response)return K;B.push(K);continue}let W=daQ.safeParse(Y);if(W.success){let K=await qC1(W.data.data.ref.id,Q.uploadStore);if(K instanceof Response)return K;B.push(K);continue}if(raQ(Y)==="data-upload")return new Response("Invalid upload ref",{status:400})}return{message:$.length>0?$.join(`
2441
+ </html>`;var QC1={name:"@brains/webserver",version:"0.2.0-alpha.159",dependencies:{"@brains/plugins":"workspace:*","@hono/bun-compress":"^0.1.1",hono:"^4.12.25"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/messaging-service":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14","@types/node":"^20.19.43",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};class yb extends ZD{serverManager;siteUrl;previewUrl;constructor(A={}){super("webserver",QC1,A,Lp0)}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 A40({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,w=this.siteUrl??A?.productionUrl??`http://localhost:${this.config.productionPort}`,$=this.previewUrl??A?.previewUrl??`http://localhost:${this.config.previewPort}`,B=[];if(Q){if(B.push(`Production: ${w}`),A?.previewUrl)B.push(`Preview: ${$}`)}return{status:Q?"healthy":"error",message:Q?B.join(", "):"Webserver not running",lastCheck:new Date,details:{preview:!!A?.previewUrl,production:Q,previewUrl:A?.previewUrl?$:void 0,productionUrl:Q?w:void 0}}}}}async handleProgressEvent(A,Q){}async ensureDistDirectories(){let{mkdir:A,writeFile:Q}=await import("fs/promises");if(this.config.enablePreview&&this.config.previewDistDir&&!wC1(this.config.previewDistDir))await A(this.config.previewDistDir,{recursive:!0}),await Q($C1(this.config.previewDistDir,"index.html"),kp0),this.logger.debug(`Created preview directory at ${this.config.previewDistDir}`);if(!wC1(this.config.productionDistDir))await A(this.config.productionDistDir,{recursive:!0}),await Q($C1(this.config.productionDistDir,"index.html"),kp0),this.logger.debug(`Created production directory at ${this.config.productionDistDir}`)}}e6();fA();C0();p_();var BC1={name:"@brains/web-chat",version:"0.2.0-alpha.159",description:"Web chat interface for Brains",dependencies:{"@ai-sdk/react":"^3.0.208","@brains/auth-service":"workspace:*","@brains/console-theme":"workspace:*","@brains/contracts":"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.206","class-variance-authority":"^0.7.0",cmdk:"^1.1.1","lucide-react":"^1.20.0",nanoid:"^5.0.4","radix-ui":"^1.6.0",react:"^19.2.7","react-dom":"^19.2.7",shiki:"^4.2.0",streamdown:"^2.5.0","tailwind-merge":"^3.6.0","use-stick-to-bottom":"^1.1.6"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14","@types/react":"^19.2.17","@types/react-dom":"^19.0.3",typescript:"^7.0.2",vite:"^8.0.16"},exports:{".":"./src/index.ts"},files:["src","dist","package.json"],private:!0,scripts:{build:"bun scripts/build-ui.ts","build:ui":"bun scripts/build-ui.ts",lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit && tsc --noEmit -p ui-react/tsconfig.json"},type:"module"};fA();async function XC1(A,Q){let w=await Q.resolvePermissionLevel(A);if(w==="public")return Q.createOperatorLoginRequiredResponse(A);let $=new URL(A.url),B=$.searchParams.get("id")?.trim();if(!B)return new Response("Missing document id",{status:400});let X=await ZC1({entityType:"document",id:B,permissionLevel:w,entityService:Q.entityService});if(!X)return new Response("Document not found",{status:404});if(typeof X.content!=="string")return new Response("Document content is not a PDF",{status:415});let Y=A3("document",X.content);if(!Y)return new Response("Document content is not a PDF",{status:415});let Z=Q3(X.metadata,B,"document",Y.mimeType);return fC1({requestUrl:$,data:Y.data,mediaType:Y.mimeType,filename:Z})}async function YC1(A,Q){let w=await Q.resolvePermissionLevel(A);if(w==="public")return Q.createOperatorLoginRequiredResponse(A);let $=new URL(A.url),B=$.searchParams.get("id")?.trim();if(!B)return new Response("Missing image id",{status:400});let X=await ZC1({entityType:"image",id:B,permissionLevel:w,entityService:Q.entityService});if(!X)return new Response("Image not found",{status:404});if(typeof X.content!=="string")return new Response("Image content is not an image",{status:415});let Y=A3("image",X.content);if(!Y)return new Response("Image content is not an image",{status:415});let Z=Q3(X.metadata,B,"image",Y.mimeType);return fC1({requestUrl:$,data:Y.data,mediaType:Y.mimeType,filename:Z})}async function ZC1(A){let Q={entityType:A.entityType,id:A.id},w=await w3({entityRef:Q,userLevel:A.permissionLevel,getEntity:($)=>A.entityService.getEntity($),getVisibleEntity:($,B)=>A.entityService.getEntity({...$,visibilityScope:B})});return w.status==="visible"?w.entity:void 0}function fC1(A){let Q=new Headers({"Content-Type":A.mediaType,"Content-Length":String(A.data.byteLength),"Content-Disposition":xI({disposition:A.requestUrl.searchParams.has("download")?"attachment":"inline",filename:A.filename})});return new Response(A.data,{headers:Q})}C0();fA();var Br="upload",HC1=KR;var yaQ={namespace:"upload",refKind:Br,routePath:"/api/chat/uploads"};function Q40(){return yaQ}fA();q_0();var WC1=n20;var KC1=r20;var EaQ="file",TaQ=16384;async function UC1(A,Q){if(!await Q.resolveOperatorSession(A))return new Response("Forbidden",{status:403});let w=Number(A.headers.get("content-length"));if(Number.isFinite(w)&&w>KC1+TaQ)return new Response("File upload too large",{status:400});let $;try{$=await A.formData()}catch{return new Response("Invalid multipart upload",{status:400})}let B=$.get(EaQ);if(!(B instanceof File))return new Response("Missing upload file",{status:400});let X=Buffer.from(await B.arrayBuffer()),Y=X3({filename:B.name,mediaType:B.type,content:X});if(!Y.ok)return new Response(Y.message,{status:400});let Z=Q.getUploadStore(),H=await Z.save({filename:Y.filename,mediaType:Y.mediaType,content:X});return Response.json(Z.toResponseBody(H),{status:201})}async function GC1(A,Q){if(!await Q.resolveOperatorSession(A))return new Response("Forbidden",{status:403});let w=new URL(A.url).searchParams.get("id")?.trim();if(!w)return new Response("Missing upload id",{status:400});let $=await zC1(w,Q.getUploadStore());if($ instanceof Response)return $;let{record:B,content:X}=$,Y=VC1(B,X);if(Y instanceof Response)return Y;let Z=new URL(A.url).searchParams.has("download")?"attachment":"inline",H=new Uint8Array(X).buffer;return new Response(H,{headers:{"Content-Type":B.mediaType,"Content-Length":String(X.byteLength),"Content-Disposition":xI({disposition:Z,filename:B.filename})}})}function DC1(A){let Q=B3(A.filename??WC1),w=maQ(A.url);if(!w)return new Response(`Unsupported file upload URL: ${Q}`,{status:400});let $=X3({filename:Q,mediaType:A.mediaType,content:w.buffer});if(!$.ok)return new Response($.message,{status:400});return JC1($,w.buffer)}async function qC1(A,Q){let w=await zC1(A,Q);if(w instanceof Response)return w;let{record:$,content:B}=w,X=VC1($,B);if(X instanceof Response)return X;return JC1(X,B,{kind:Br,id:A})}async function zC1(A,Q){try{return await Q.read(A)}catch(w){if(w instanceof fD)return SaQ(w);throw w}}function VC1(A,Q){let w=X3({filename:A.filename,mediaType:A.mediaType,content:Q});if(!w.ok)return new Response(w.message,{status:400});return w}function JC1(A,Q,w){if(A.kind==="text")return{kind:"text",filename:A.filename,mediaType:A.mediaType,content:A.text,sizeBytes:A.sizeBytes,...w!==void 0?{source:w}:{}};return{kind:"file",filename:A.filename,mediaType:A.mediaType,data:new Uint8Array(Q),sizeBytes:A.sizeBytes,...w!==void 0?{source:w}:{}}}function SaQ(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 maQ(A){let Q=/^data:[^,]*,(.*)$/s.exec(A);if(!Q)return null;let $=A.slice(5,A.indexOf(",")).split(";").some((B)=>B.toLowerCase()==="base64");try{let B=$?Buffer.from(Q[1]??"","base64"):Buffer.from(decodeURIComponent(Q[1]??""),"utf8");return{buffer:B,byteLength:B.byteLength}}catch{return null}}var uaQ=f.object({type:f.literal("text"),text:f.string()}),caQ=f.object({type:f.literal("file"),mediaType:f.string().optional(),filename:f.string().optional(),url:f.string()}),laQ=f.looseObject({state:f.literal("approval-responded"),approval:f.object({id:f.string(),approved:f.boolean()})}),paQ=f.object({id:f.string().optional(),role:f.string(),parts:f.array(f.unknown()).optional(),content:f.string().optional()}),IC1=f.object({id:f.string().optional(),messages:f.array(paQ).min(1),trigger:f.string().optional()}),iaQ=f.object({kind:f.literal(Br),id:f.string().regex(HC1)}),daQ=f.object({type:f.literal("data-upload"),data:f.object({ref:iaQ})});async function FC1(A,Q){let w=naQ(A);if(!w)return{message:"",attachments:[]};let $=[],B=[];for(let Y of w.parts??[]){let Z=uaQ.safeParse(Y);if(Z.success){if(Z.data.text.length>0)$.push(Z.data.text);continue}let H=caQ.safeParse(Y);if(H.success){let K=DC1(H.data);if(K instanceof Response)return K;B.push(K);continue}let W=daQ.safeParse(Y);if(W.success){let K=await qC1(W.data.data.ref.id,Q.uploadStore);if(K instanceof Response)return K;B.push(K);continue}if(raQ(Y)==="data-upload")return new Response("Invalid upload ref",{status:400})}return{message:$.length>0?$.join(`
2442
2442
 
2443
2443
  `):w.content??"",attachments:B,...w.id?{messageId:w.id}:{}}}function bC1(A){let Q=A.messages.at(-1);if(!Q||Q.role==="user")return[];return(Q.parts??[]).map((w)=>laQ.safeParse(w)).filter((w)=>w.success).map((w)=>w.data.approval)}function naQ(A){for(let Q=A.messages.length-1;Q>=0;Q-=1){let w=A.messages[Q];if(w?.role==="user")return w}return}function raQ(A){if(typeof A!=="object"||A===null||!("type"in A))return;let Q=A.type;return typeof Q==="string"?Q:void 0}fA();var oaQ=/\n{0,2}\[Entities affected this turn: [\s\S]*? Reference these IDs directly in follow-ups instead of searching for them\.\]\s*$/;function w40(A){return A.replace(oaQ,"").trimEnd()}fA();function LC1(A,Q,w){A.write({type:"text-start",id:Q}),A.write({type:"text-delta",id:Q,delta:w}),A.write({type:"text-end",id:Q})}function _p0(A,Q){let w=Q.directives.flatMap(($)=>{switch($.kind){case"artifact":case"supplemental":return[$.card];case"approvals":return $.cards;default:return[]}});for(let $ of w){let B=AQ0($);if(B.kind==="attachment"){A.write({type:"data-attachment",id:B.id,data:B});continue}if(B.kind==="sources"){A.write({type:"data-sources",id:B.id,data:B});continue}if(B.kind==="actions"){A.write({type:"data-actions",id:B.id,data:B});continue}let X=B.toolCallId??B.id,Y=B.input??{};switch(A.write({type:"tool-input-available",toolCallId:X,toolName:B.toolName,input:Y,dynamic:!0,title:B.preview?`${B.summary}
2444
2444
 
@@ -5729,7 +5729,7 @@ ${hC1}</style></head><body>${Yr(A)}<main id="root" data-web-chat-root>Brain Chat
5729
5729
  `);B=Y.pop()??"";for(let Z of Y){let H=Z.split(`
5730
5730
  `).find((I)=>I.startsWith("data: "));if(!H)continue;let W;try{let I=StQ.safeParse(JSON.parse(H.slice(6)));if(!I.success)continue;W=I.data}catch{return w.cancel().catch(()=>{}),{success:!1,error:"Malformed SSE event from remote agent"}}let K=W.result;if(!K?.final)continue;w.cancel().catch(()=>{});let U=K.status,G=U?.state??"unknown",V=(U?.message?.parts??[]).filter((I)=>I.kind==="text"&&typeof I.text==="string").map((I)=>I.text).join(`
5731
5731
  `)||"No response text";return{success:!0,data:{state:G,response:V}}}X=await fg1(w,Q)}return{success:!1,error:"Stream ended without a terminal event"}}class Zr extends Error{timeoutMs;constructor(A){super(`request timed out after ${A}ms`);this.timeoutMs=A,this.name="A2ARequestTimeoutError"}}class fr extends Error{timeoutMs;constructor(A){super(`A2A stream stalled waiting for final event after ${A}ms`);this.timeoutMs=A,this.name="A2AStreamIdleTimeoutError"}}async function rtQ(A,Q,w,$){let B=new AbortController,X;try{return await Promise.race([A(Q,{...w,signal:B.signal}),new Promise((Y,Z)=>{X=setTimeout(()=>{B.abort(),Z(new Zr($))},$)})])}catch(Y){if(Y instanceof Zr)throw Y;if(B.signal.aborted)throw new Zr($);throw Y}finally{if(X)clearTimeout(X)}}async function fg1(A,Q){let w;try{return await Promise.race([A.read(),new Promise(($,B)=>{w=setTimeout(()=>B(new fr(Q)),Q)})])}catch($){if($ instanceof fr)A.cancel().catch(()=>{});throw $}finally{if(w)clearTimeout(w)}}function otQ(A){if(A instanceof Zr||A instanceof fr)return!1;return A instanceof Error}function gp0(A,Q){let w=Q>1?` after ${Q} attempts`:"";if(A instanceof fr)return`${A.message}${w}`;let $=A instanceof Error?A.message:"Unknown network error";return`Failed to reach remote agent${w}: ${$}`}async function yp0(A,Q={},w={}){let $=Q.fetch??globalThis.fetch,B={requestTimeoutMs:Q.requestTimeoutMs??mtQ,streamIdleTimeoutMs:Q.streamIdleTimeoutMs??utQ,maxNetworkAttempts:Q.maxNetworkAttempts??ctQ},X=itQ(A.agent);if(!X.ok)return{success:!1,error:X.error};let{agentId:Y}=X;if(!Q.entityService)return{success:!1,error:"Agent directory is unavailable. Add the agent first, then try again."};let Z=await Q.entityService.getEntity({entityType:"agent",id:Y,visibilityScope:T5("agent_call is anchor-only and resolves saved remote agents at any visibility")});if(!Z){if(w.requireSaved)return{success:!1,error:`Agent ${Y} is not saved or approved.`,code:"agent_not_saved"};if(!dtQ(Y))return{success:!1,error:`Agent ${A.agent} is not an exact domain-like id and is not saved. Connect or clarify the agent first.`,code:"agent_not_saved"};let U=`https://${Y}`,G=await Yg1(U,$);if(!G)return{success:!1,error:`Could not verify an A2A Agent Card for ${Y}. Connect/save it first if you want to add it to the directory.`,code:"agent_card_unavailable"};let q=Xg1(G.url,Y);if(!q.ok)return{success:!1,error:q.error};let V=await Zg1(G.url,A.message,$,Q.requestSigner,B);if("success"in V&&V.success===!0){let I=typeof V.data==="object"&&V.data!==null?V.data:{};return{...V,data:{...I,agentCall:{mode:"one-shot",agent:Y},agentContactCandidate:{source:{kind:"url",url:X.sourceUrl??Y}}}}}return V}if(Z.metadata.status==="archived")return{success:!1,error:`Agent ${Y} is archived and cannot be contacted until it is restored and approved.`,code:"agent_archived"};if(Z.metadata.status!=="approved")return{success:!1,error:`Agent ${Y} is discovered but not approved yet. Approve it first.`,code:"agent_not_approved"};let H=`https://${Y}`,W=await Yg1(H,$);if(!W)return{success:!1,error:`Could not fetch Agent Card from ${H}`};let K=Xg1(W.url,Y);if(!K.ok)return{success:!1,error:K.error};return Zg1(W.url,A.message,$,Q.requestSigner,B)}function Wg1(A={}){return{name:"agent_call",description:"Call a remote A2A agent by exact domain-like target or saved local agent id. Use this when the user asks what an exact domain-like agent id has to say, asks to talk/message/contact that id, or asks that agent for its skills/capabilities. For saved agents, the tool enforces approved/not-archived status before network contact. For unsaved exact domains, the tool verifies the A2A Agent Card over HTTPS and may perform a one-shot call without saving; it returns a typed save/connect candidate after success. Use bare ids such as yeehaa.io, docs.rizom.ai, or save-it-regression.example; .example test domains are exact domain-like ids. If the user provides an HTTPS URL such as https://docs.rizom.ai/a2a, pass only the hostname docs.rizom.ai. For follow-ups to a prior exact-id call, call again with the same id so the tool revalidates current state. Never pass a full URL, a display name like Brain, or a non-HTTPS URL. If the user gives an ambiguous name, ask them to connect/save or clarify the agent first.",inputSchema:ltQ,visibility:"trusted",sideEffects:"external",handler:async(Q)=>{let w=ptQ.safeParse(Q);if(!w.success)return{success:!1,error:`Invalid input: ${w.error.message}`};return yp0(w.data,A)}}}fA();C0();var stQ=f.object({agent:f.string().trim().min(1).max(253),instruction:f.string().trim().min(1).max(2000),selection:f.string().min(1).max(8000)});function Kg1(A,Q){A.messaging.subscribe("a2a:call:request",async(w)=>{let $=stQ.safeParse(w.payload);if(!$.success)return{success:!1,error:"Invalid A2A call request"};let{agent:B,instruction:X,selection:Y}=$.data,Z=await yp0({agent:B,message:["A CMS author is asking about selected markdown.",`Instruction: ${X}`,"","Selected markdown:",Y].join(`
5732
- `)},Q,{requireSaved:!0});if("success"in Z&&Z.success===!0)return{success:!0,data:Z.data};return{success:!1,error:"error"in Z?Z.error:"Agent call failed"}}),A.messaging.subscribe("a2a:call:agents",async()=>{if(!A.entityService.hasEntityType("agent"))return{success:!0,data:{agents:[]}};return{success:!0,data:{agents:(await A.entityService.listEntities({entityType:"agent",options:{filter:{visibilityScope:T5("operator CMS lists approved A2A contacts at any visibility")}}})).filter((B)=>B.metadata.status==="approved").map((B)=>{let X=B.metadata.name;return{id:B.id,label:typeof X==="string"&&X.length>0?X:B.id}}).sort((B,X)=>B.label.localeCompare(X.label))}}})}var Ep0={name:"@brains/a2a",version:"0.2.0-alpha.158",dependencies:{"@a2a-js/sdk":"^0.3.13","@brains/auth-service":"workspace:*","@brains/http-signatures":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*",hono:"^4.12.25"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14",typescript:"^7.0.2"},files:["src"],main:"./src/index.ts",module:"./src/index.ts",private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module",types:"./src/index.ts"};var ttQ={"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Signature, Signature-Input, Content-Digest, Date","X-Content-Type-Options":"nosniff"};class ng extends ZD{agentCard;taskManager=new Cp0;agentService;jwksResolver=new vp0;app;hasWebserver=!1;constructor(A={}){if(Object.prototype.hasOwnProperty.call(A,"trustedTokens"))throw Error("trustedTokens legacy config is no longer supported");if(Object.prototype.hasOwnProperty.call(A,"outboundTokens"))throw Error("outboundTokens legacy config is no longer supported");super("a2a",Ep0,A,sC1)}async onRegister(A){if(await super.onRegister(A),this.hasWebserver=A.plugins.has("webserver"),this.agentService=A.agent,Kg1(A,this.createClientDeps(A)),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(),w=A.identity.getProfile(),$=A.tools.listForPermissionLevel("public"),B;if(A.entityService.hasEntityType("skill"))try{let X=await A.entityService.listEntities({entityType:"skill",options:{filter:{visibilityScope:"public"}}});if(X.length>0)B=X.map((Y)=>iu.safeParse(Y.metadata)).filter((Y)=>Y.success).map((Y)=>Y.data)}catch{}this.agentCard=aC1({character:Q,profile:w,version:Ep0.version,domain:A.domain,organization:this.config.organization,tools:$,skills:B,authEnabled:!1}),this.logger.debug("Agent Card rebuilt",{skills:this.agentCard.skills.length})}getAgentCard(){return this.agentCard}async resolveCaller(A,Q){let w=new URL(A.url),$=new URL(`${w.pathname}${w.search}`,mF(A)),B=await nC1({method:A.method,url:$.toString(),headers:A.headers,body:Q},this.jwksResolver);if(B){let X=await s7()?.getA2APeerTrust(B.domain);return{permissionLevel:X?.keyFingerprint===B.keyFingerprint?X.grantedLevel:"public",callerDomain:B.domain}}return{permissionLevel:"public",callerDomain:null}}withCors(A){let Q=new Headers(A.headers);for(let[w,$]of Object.entries(ttQ))Q.set(w,$);return new Response(A.body,{status:A.status,statusText:A.statusText,headers:Q})}getOrCreateApp(){if(this.app)return this.app;let A=new cg;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 w=await Q.req.text(),$;try{$=await this.resolveCaller(Q.req.raw,w)}catch{return this.withCors(Q.json({error:"Invalid HTTP signature"},401))}let B;try{B=JSON.parse(w)}catch{return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32700,message:"Parse error"},id:null}))}let X=Ag1.safeParse(B);if(!X.success)return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32600,message:"Invalid request"},id:null}));if(X.data.method==="message/stream"){let Z=wg1.safeParse(X.data.params??{});if(!Z.success)return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32602,message:`Invalid params: ${Z.error.message}`},id:X.data.id}));let H=$g1(X.data.id,Z.data.message,{taskManager:this.taskManager,agentService:this.agentService,callerPermissionLevel:$.permissionLevel,callerDomain:$.callerDomain});if("error"in H)return this.withCors(Q.json(H));let{stream:W}=H;return this.withCors(new Response(W,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}}))}let Y=await Qg1(X.data,{taskManager:this.taskManager,agentService:this.agentService,callerPermissionLevel:$.permissionLevel,callerDomain:$.callerDomain});return this.withCors(Q.json(Y))}),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}]}createRequestSigner(){let A=s7();if(!A)return;let Q=A.getIssuer();if(SF(Q)||new URL(Q).protocol!=="https:")return;return async(w)=>{let $=await A.getA2ASigningKey();await dC1(w,$.privateJwk,$.keyId)}}createClientDeps(A){return{requestSigner:this.createRequestSigner(),requestTimeoutMs:this.config.requestTimeoutMs,streamIdleTimeoutMs:this.config.streamIdleTimeoutMs,maxNetworkAttempts:this.config.maxNetworkAttempts,entityService:A.entityService}}async getTools(){return[Wg1(this.createClientDeps(this.getContext()))]}async getInstructions(){return"## Agent-to-agent calls\n- Use `agent_call` for exact domain-like agent ids (for example `yeehaa.io`, `docs.rizom.ai`, or `save-it-regression.example`). A domain-like id is bare text with a dot and no slash/protocol; `.example` test domains are still exact domain-like ids. For saved agents, the tool validates approval before network contact. For unsaved exact domains, it verifies the Agent Card over HTTPS and may perform a one-shot call without saving.\n- Pass only an exact domain-like agent id to `agent_call`. If the user provides an HTTPS URL, pass only its hostname as the agent id (for `https://docs.rizom.ai/a2a`, pass `docs.rizom.ai`). Never pass a full URL, a non-HTTPS URL, or a display name like `Brain`.\n- If the user names an exact domain-like agent id such as `yeehaa.io`, `docs.rizom.ai`, or `refusal-followup.example`, call `agent_call` directly with that id. Do not preflight with `system_list` or `system_get`; the tool reports structured errors such as invalid Agent Card, not approved, or archived.\n- If the user asks you to ask, message, contact, hear what an exact domain-like agent id has to say, or ask that agent for its own skills/capabilities, treat that as an agent call request first and call `agent_call` in the same turn. Do not stop after listing the agent, drafting the question, searching general content locally, or reading saved agent entity metadata.\n- After `agent_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- Do not create, capture, or generate a note containing the user's question in the same turn as an agent contact request. The user asked to ask the agent, not to persist the question.\n- If `agent_call` succeeds for an unsaved one-shot domain, you may offer to save/connect that agent for future calls, but do not auto-save it.\n- If `agent_call` fails because auth, re-authentication, network, invalid Agent Card, or the remote agent is unavailable, report that failure directly. Do not say the agent was saved, connected, or may need to be saved/connected first. If useful, offer to add the agent contact using the word \"add\". Do not answer from memory, local docs, onboarding docs, or general knowledge; the requested agent was the source.\n- Each new turn that asks the same exact domain-like agent id 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 `agent_call`. Do not assume the previous turn's agent 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 domain-like 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 `agent_call` validate the current directory state again.\n- When the user provides an HTTPS URL for an agent, use its hostname as the exact domain-like id for `agent_call`; the runtime verifies/contact over HTTPS. If the user provides a non-HTTPS URL, ask for the HTTPS agent URL or exact domain-like id instead.\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 `agent_call` later in the same turn.\n- If `agent_call` reports that an exact domain-like agent id cannot be verified, tell the user the agent could not be verified/contacted. Do not create a wish, reminder, todo, note, fallback task, or any new entity.\n- For non-HTTPS URLs and ambiguous display names, do not call `agent_call`; ask the user for the HTTPS agent URL, exact domain-like id, or a clarification first.\n- Use `agent_connect`, not generic entity creation, when the user explicitly asks you to add, save, or connect an agent contact.\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")}}}}fA();C0();var Ug1={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 Gg1={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 Dg1={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 qg1={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 zg1={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 Vg1={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 Jg1={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 Ig1={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 Fg1={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 feQ=f.object({type:f.string()}).catchall(f.unknown()),HeQ=f.object({lexicon:f.literal(1),id:f.string(),defs:f.object({main:f.object({type:f.literal("record"),key:f.string().min(1),record:f.object({type:f.literal("object"),required:f.array(f.string()).optional(),properties:f.record(f.string(),feQ)})})})});function SU(A){return HeQ.parse(A)}var S6={"ai.rizom.brain.card":SU(Ug1),"ai.rizom.brain.deck":SU(Gg1),"ai.rizom.brain.link":SU(Dg1),"ai.rizom.brain.note":SU(qg1),"ai.rizom.brain.post":SU(zg1),"ai.rizom.brain.project":SU(Vg1),"ai.rizom.brain.series":SU(Jg1),"ai.rizom.brain.socialPost":SU(Ig1),"ai.rizom.brain.topic":SU(Fg1)},WeQ="Additive optional fields are compatible; required-field, type, or constraint changes require a migration plan or new NSID.";function IV(A){return{status:"approved",version:"1.0.0",revision:1,owner:"Rizom",steward:"Rizom protocol registry",projectionPackage:A,compatibility:WeQ}}var bg1={"ai.rizom.brain.card":IV("@brains/atproto"),"ai.rizom.brain.deck":IV("@brains/decks"),"ai.rizom.brain.link":IV("@brains/link"),"ai.rizom.brain.note":IV("@brains/note"),"ai.rizom.brain.post":IV("@brains/blog"),"ai.rizom.brain.project":IV("@brains/portfolio"),"ai.rizom.brain.series":IV("@brains/series"),"ai.rizom.brain.socialPost":IV("@brains/social-media"),"ai.rizom.brain.topic":IV("@brains/topics")};function rg(){return Object.values(S6)}function f40(A){if(!(A in S6))return;return S6[A]}function H40(){return Object.entries(bg1).map(([A,Q])=>({id:A,...Q}))}C0();function W40(A){return typeof A==="object"&&A!==null&&!Array.isArray(A)}var KeQ=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})$/;function UeQ(A){let Q=f.string(),w=A.maxLength!==void 0?Q.max(A.maxLength):Q;if(A.knownValues)w=w.refine(($)=>A.knownValues?.includes($),{message:`expected one of ${A.knownValues.join(", ")}`});if(A.format==="datetime")w=w.refine(($)=>KeQ.test($)&&!Number.isNaN(Date.parse($)),{message:"expected datetime"});if(A.format==="uri")w=w.refine(($)=>{try{return new URL($),!0}catch{return!1}},{message:"expected uri"});return w}function Lg1(A){switch(A.type){case"string":return UeQ(A);case"integer":return f.number().int();case"boolean":return f.boolean();case"array":{let Q=A.items?Lg1(A.items):f.unknown(),w=f.array(Q);if(A.maxLength!==void 0)w=w.max(A.maxLength);return w}case"object":return GeQ(A);case"blob":return f.custom(W40,{message:"expected blob"});default:return f.unknown()}}function kg1(A){let Q=new Set(A.required??[]),w={};for(let[$,B]of Object.entries(A.properties??{})){let X=Lg1(B);w[$]=Q.has($)?X:X.optional()}return w}function GeQ(A){return f.object(kg1(A)).passthrough()}function Tp0(A,Q,w,$=[]){let B=Object.keys(A).filter((X)=>!Q.has(X));if(B.length===0)return;w.addIssue({code:f.ZodIssueCode.custom,path:$,message:`unrecognized field(s): ${B.join(", ")}`})}function DeQ(A,Q){if(Tp0(A,new Set(["$type","siteUrl","brain","anchor","skills","model","version","createdAt","updatedAt"]),Q),W40(A.brain))Tp0(A.brain,new Set(["did","name","role","purpose","values"]),Q,["brain"]);if(W40(A.anchor))Tp0(A.anchor,new Set(["did","name","kind"]),Q,["anchor"])}function mU(A){let Q=f.object({...kg1(A.defs.main.record),$type:f.literal(A.id).optional()}).passthrough();return A.id==="ai.rizom.brain.card"?Q.superRefine(DeQ):Q}var Sp0={"ai.rizom.brain.card":mU(S6["ai.rizom.brain.card"]),"ai.rizom.brain.deck":mU(S6["ai.rizom.brain.deck"]),"ai.rizom.brain.link":mU(S6["ai.rizom.brain.link"]),"ai.rizom.brain.note":mU(S6["ai.rizom.brain.note"]),"ai.rizom.brain.post":mU(S6["ai.rizom.brain.post"]),"ai.rizom.brain.project":mU(S6["ai.rizom.brain.project"]),"ai.rizom.brain.series":mU(S6["ai.rizom.brain.series"]),"ai.rizom.brain.socialPost":mU(S6["ai.rizom.brain.socialPost"]),"ai.rizom.brain.topic":mU(S6["ai.rizom.brain.topic"])};function qeQ(A,Q){let w=A;for(let $ of Q){if(typeof $==="symbol")return;if(Array.isArray(w)){w=w[Number($)];continue}if(!W40(w))return;w=w[String($)]}return w}function zeQ(A,Q,w){let $=w.path.join(".");if($==="$type")return`AT Protocol record $type must match lexicon id: ${String(Q.$type)} !== ${A.id}`;if(w.code==="invalid_type"&&qeQ(Q,w.path)===void 0)return`Missing required AT Protocol record field: ${$}`;if(w.code==="invalid_type")return`Invalid AT Protocol record field ${$}: expected ${w.expected}`;if(w.code==="too_big")return`Invalid AT Protocol record field ${$}: exceeds maxLength ${w.maximum}`;if(w.code==="custom")return`Invalid AT Protocol record field ${$}: ${w.message}`;if(w.code==="unrecognized_keys")return`Unrecognized AT Protocol record field(s): ${w.keys.join(", ")}`;return`Invalid AT Protocol record field ${$}: ${w.message}`}function FV(A,Q){let w=mU(A).safeParse(Q);if(w.success)return;let $=w.error.issues[0];if(!$)throw w.error;throw Error(zeQ(A,Q,$))}C0();var Hr="atproto:brain-card-discovered",mp0="atproto:brain-discovered",up0="atproto:brain-card-refreshed",VeQ=f.custom((A)=>Sp0["ai.rizom.brain.card"].safeParse(A).success),cp0=f.object({repoDid:f.string().min(1),uri:f.string().min(1),cid:f.string().min(1),record:VeQ}).strict(),JeQ=f.object({agentId:f.string().min(1),name:f.string().min(1),url:f.string().url(),status:f.enum(["discovered","approved"]),repoDid:f.string().min(1).optional(),brainDid:f.string().min(1).optional(),anchorDid:f.string().min(1).optional(),cardUri:f.string().min(1).optional(),cardCid:f.string().min(1).optional()}).strict();class kB{static instance;projections=new Map;static getInstance(){return this.instance??=new kB,this.instance}static createFresh(){return new kB}static resetInstance(){this.instance=void 0}register(A){this.validateProjection(A);let Q=this.get(A.entityType);if(Q&&!this.isEquivalentProjection(Q,A))throw Error(`AT Protocol projection already registered for entity type ${A.entityType}`);let w=this.projections.get(A.entityType)??[];return w.push(A),this.projections.set(A.entityType,w),this.createUnregister(A.entityType,A)}get(A){let Q=this.projections.get(A);return Q?.[Q.length-1]}has(A){return this.get(A)!==void 0}list(){let A=[];for(let Q of this.projections.keys()){let w=this.get(Q);if(w)A.push(w)}return A}listLexicons(){return this.list().map((A)=>A.lexicon)}createUnregister(A,Q){let w=!0;return()=>{if(!w)return;w=!1;let $=this.projections.get(A);if(!$)return;let B=$.lastIndexOf(Q);if(B!==-1)$.splice(B,1);if($.length===0)this.projections.delete(A)}}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}`)}}C0();var _g1={name:"@brains/atproto-registry",version:"0.2.0-alpha.158",description:"Canonical Rizom AT Protocol lexicon registry",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":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var jg1=f.object({enabled:f.boolean().default(!0)}),lp0="/atproto/lexicons",FeQ=f.strictObject({nsid:f.string(),record:f.record(f.string(),f.unknown())});function Ng1(A){return new Response(`${JSON.stringify(A,null,2)}
5732
+ `)},Q,{requireSaved:!0});if("success"in Z&&Z.success===!0)return{success:!0,data:Z.data};return{success:!1,error:"error"in Z?Z.error:"Agent call failed"}}),A.messaging.subscribe("a2a:call:agents",async()=>{if(!A.entityService.hasEntityType("agent"))return{success:!0,data:{agents:[]}};return{success:!0,data:{agents:(await A.entityService.listEntities({entityType:"agent",options:{filter:{visibilityScope:T5("operator CMS lists approved A2A contacts at any visibility")}}})).filter((B)=>B.metadata.status==="approved").map((B)=>{let X=B.metadata.name;return{id:B.id,label:typeof X==="string"&&X.length>0?X:B.id}}).sort((B,X)=>B.label.localeCompare(X.label))}}})}var Ep0={name:"@brains/a2a",version:"0.2.0-alpha.159",dependencies:{"@a2a-js/sdk":"^0.3.13","@brains/auth-service":"workspace:*","@brains/http-signatures":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*",hono:"^4.12.25"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14",typescript:"^7.0.2"},files:["src"],main:"./src/index.ts",module:"./src/index.ts",private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module",types:"./src/index.ts"};var ttQ={"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Signature, Signature-Input, Content-Digest, Date","X-Content-Type-Options":"nosniff"};class ng extends ZD{agentCard;taskManager=new Cp0;agentService;jwksResolver=new vp0;app;hasWebserver=!1;constructor(A={}){if(Object.prototype.hasOwnProperty.call(A,"trustedTokens"))throw Error("trustedTokens legacy config is no longer supported");if(Object.prototype.hasOwnProperty.call(A,"outboundTokens"))throw Error("outboundTokens legacy config is no longer supported");super("a2a",Ep0,A,sC1)}async onRegister(A){if(await super.onRegister(A),this.hasWebserver=A.plugins.has("webserver"),this.agentService=A.agent,Kg1(A,this.createClientDeps(A)),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(),w=A.identity.getProfile(),$=A.tools.listForPermissionLevel("public"),B;if(A.entityService.hasEntityType("skill"))try{let X=await A.entityService.listEntities({entityType:"skill",options:{filter:{visibilityScope:"public"}}});if(X.length>0)B=X.map((Y)=>iu.safeParse(Y.metadata)).filter((Y)=>Y.success).map((Y)=>Y.data)}catch{}this.agentCard=aC1({character:Q,profile:w,version:Ep0.version,domain:A.domain,organization:this.config.organization,tools:$,skills:B,authEnabled:!1}),this.logger.debug("Agent Card rebuilt",{skills:this.agentCard.skills.length})}getAgentCard(){return this.agentCard}async resolveCaller(A,Q){let w=new URL(A.url),$=new URL(`${w.pathname}${w.search}`,mF(A)),B=await nC1({method:A.method,url:$.toString(),headers:A.headers,body:Q},this.jwksResolver);if(B){let X=await s7()?.getA2APeerTrust(B.domain);return{permissionLevel:X?.keyFingerprint===B.keyFingerprint?X.grantedLevel:"public",callerDomain:B.domain}}return{permissionLevel:"public",callerDomain:null}}withCors(A){let Q=new Headers(A.headers);for(let[w,$]of Object.entries(ttQ))Q.set(w,$);return new Response(A.body,{status:A.status,statusText:A.statusText,headers:Q})}getOrCreateApp(){if(this.app)return this.app;let A=new cg;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 w=await Q.req.text(),$;try{$=await this.resolveCaller(Q.req.raw,w)}catch{return this.withCors(Q.json({error:"Invalid HTTP signature"},401))}let B;try{B=JSON.parse(w)}catch{return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32700,message:"Parse error"},id:null}))}let X=Ag1.safeParse(B);if(!X.success)return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32600,message:"Invalid request"},id:null}));if(X.data.method==="message/stream"){let Z=wg1.safeParse(X.data.params??{});if(!Z.success)return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32602,message:`Invalid params: ${Z.error.message}`},id:X.data.id}));let H=$g1(X.data.id,Z.data.message,{taskManager:this.taskManager,agentService:this.agentService,callerPermissionLevel:$.permissionLevel,callerDomain:$.callerDomain});if("error"in H)return this.withCors(Q.json(H));let{stream:W}=H;return this.withCors(new Response(W,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}}))}let Y=await Qg1(X.data,{taskManager:this.taskManager,agentService:this.agentService,callerPermissionLevel:$.permissionLevel,callerDomain:$.callerDomain});return this.withCors(Q.json(Y))}),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}]}createRequestSigner(){let A=s7();if(!A)return;let Q=A.getIssuer();if(SF(Q)||new URL(Q).protocol!=="https:")return;return async(w)=>{let $=await A.getA2ASigningKey();await dC1(w,$.privateJwk,$.keyId)}}createClientDeps(A){return{requestSigner:this.createRequestSigner(),requestTimeoutMs:this.config.requestTimeoutMs,streamIdleTimeoutMs:this.config.streamIdleTimeoutMs,maxNetworkAttempts:this.config.maxNetworkAttempts,entityService:A.entityService}}async getTools(){return[Wg1(this.createClientDeps(this.getContext()))]}async getInstructions(){return"## Agent-to-agent calls\n- Use `agent_call` for exact domain-like agent ids (for example `yeehaa.io`, `docs.rizom.ai`, or `save-it-regression.example`). A domain-like id is bare text with a dot and no slash/protocol; `.example` test domains are still exact domain-like ids. For saved agents, the tool validates approval before network contact. For unsaved exact domains, it verifies the Agent Card over HTTPS and may perform a one-shot call without saving.\n- Pass only an exact domain-like agent id to `agent_call`. If the user provides an HTTPS URL, pass only its hostname as the agent id (for `https://docs.rizom.ai/a2a`, pass `docs.rizom.ai`). Never pass a full URL, a non-HTTPS URL, or a display name like `Brain`.\n- If the user names an exact domain-like agent id such as `yeehaa.io`, `docs.rizom.ai`, or `refusal-followup.example`, call `agent_call` directly with that id. Do not preflight with `system_list` or `system_get`; the tool reports structured errors such as invalid Agent Card, not approved, or archived.\n- If the user asks you to ask, message, contact, hear what an exact domain-like agent id has to say, or ask that agent for its own skills/capabilities, treat that as an agent call request first and call `agent_call` in the same turn. Do not stop after listing the agent, drafting the question, searching general content locally, or reading saved agent entity metadata.\n- After `agent_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- Do not create, capture, or generate a note containing the user's question in the same turn as an agent contact request. The user asked to ask the agent, not to persist the question.\n- If `agent_call` succeeds for an unsaved one-shot domain, you may offer to save/connect that agent for future calls, but do not auto-save it.\n- If `agent_call` fails because auth, re-authentication, network, invalid Agent Card, or the remote agent is unavailable, report that failure directly. Do not say the agent was saved, connected, or may need to be saved/connected first. If useful, offer to add the agent contact using the word \"add\". Do not answer from memory, local docs, onboarding docs, or general knowledge; the requested agent was the source.\n- Each new turn that asks the same exact domain-like agent id 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 `agent_call`. Do not assume the previous turn's agent 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 domain-like 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 `agent_call` validate the current directory state again.\n- When the user provides an HTTPS URL for an agent, use its hostname as the exact domain-like id for `agent_call`; the runtime verifies/contact over HTTPS. If the user provides a non-HTTPS URL, ask for the HTTPS agent URL or exact domain-like id instead.\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 `agent_call` later in the same turn.\n- If `agent_call` reports that an exact domain-like agent id cannot be verified, tell the user the agent could not be verified/contacted. Do not create a wish, reminder, todo, note, fallback task, or any new entity.\n- For non-HTTPS URLs and ambiguous display names, do not call `agent_call`; ask the user for the HTTPS agent URL, exact domain-like id, or a clarification first.\n- Use `agent_connect`, not generic entity creation, when the user explicitly asks you to add, save, or connect an agent contact.\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")}}}}fA();C0();var Ug1={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 Gg1={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 Dg1={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 qg1={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 zg1={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 Vg1={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 Jg1={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 Ig1={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 Fg1={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 feQ=f.object({type:f.string()}).catchall(f.unknown()),HeQ=f.object({lexicon:f.literal(1),id:f.string(),defs:f.object({main:f.object({type:f.literal("record"),key:f.string().min(1),record:f.object({type:f.literal("object"),required:f.array(f.string()).optional(),properties:f.record(f.string(),feQ)})})})});function SU(A){return HeQ.parse(A)}var S6={"ai.rizom.brain.card":SU(Ug1),"ai.rizom.brain.deck":SU(Gg1),"ai.rizom.brain.link":SU(Dg1),"ai.rizom.brain.note":SU(qg1),"ai.rizom.brain.post":SU(zg1),"ai.rizom.brain.project":SU(Vg1),"ai.rizom.brain.series":SU(Jg1),"ai.rizom.brain.socialPost":SU(Ig1),"ai.rizom.brain.topic":SU(Fg1)},WeQ="Additive optional fields are compatible; required-field, type, or constraint changes require a migration plan or new NSID.";function IV(A){return{status:"approved",version:"1.0.0",revision:1,owner:"Rizom",steward:"Rizom protocol registry",projectionPackage:A,compatibility:WeQ}}var bg1={"ai.rizom.brain.card":IV("@brains/atproto"),"ai.rizom.brain.deck":IV("@brains/decks"),"ai.rizom.brain.link":IV("@brains/link"),"ai.rizom.brain.note":IV("@brains/note"),"ai.rizom.brain.post":IV("@brains/blog"),"ai.rizom.brain.project":IV("@brains/portfolio"),"ai.rizom.brain.series":IV("@brains/series"),"ai.rizom.brain.socialPost":IV("@brains/social-media"),"ai.rizom.brain.topic":IV("@brains/topics")};function rg(){return Object.values(S6)}function f40(A){if(!(A in S6))return;return S6[A]}function H40(){return Object.entries(bg1).map(([A,Q])=>({id:A,...Q}))}C0();function W40(A){return typeof A==="object"&&A!==null&&!Array.isArray(A)}var KeQ=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})$/;function UeQ(A){let Q=f.string(),w=A.maxLength!==void 0?Q.max(A.maxLength):Q;if(A.knownValues)w=w.refine(($)=>A.knownValues?.includes($),{message:`expected one of ${A.knownValues.join(", ")}`});if(A.format==="datetime")w=w.refine(($)=>KeQ.test($)&&!Number.isNaN(Date.parse($)),{message:"expected datetime"});if(A.format==="uri")w=w.refine(($)=>{try{return new URL($),!0}catch{return!1}},{message:"expected uri"});return w}function Lg1(A){switch(A.type){case"string":return UeQ(A);case"integer":return f.number().int();case"boolean":return f.boolean();case"array":{let Q=A.items?Lg1(A.items):f.unknown(),w=f.array(Q);if(A.maxLength!==void 0)w=w.max(A.maxLength);return w}case"object":return GeQ(A);case"blob":return f.custom(W40,{message:"expected blob"});default:return f.unknown()}}function kg1(A){let Q=new Set(A.required??[]),w={};for(let[$,B]of Object.entries(A.properties??{})){let X=Lg1(B);w[$]=Q.has($)?X:X.optional()}return w}function GeQ(A){return f.object(kg1(A)).passthrough()}function Tp0(A,Q,w,$=[]){let B=Object.keys(A).filter((X)=>!Q.has(X));if(B.length===0)return;w.addIssue({code:f.ZodIssueCode.custom,path:$,message:`unrecognized field(s): ${B.join(", ")}`})}function DeQ(A,Q){if(Tp0(A,new Set(["$type","siteUrl","brain","anchor","skills","model","version","createdAt","updatedAt"]),Q),W40(A.brain))Tp0(A.brain,new Set(["did","name","role","purpose","values"]),Q,["brain"]);if(W40(A.anchor))Tp0(A.anchor,new Set(["did","name","kind"]),Q,["anchor"])}function mU(A){let Q=f.object({...kg1(A.defs.main.record),$type:f.literal(A.id).optional()}).passthrough();return A.id==="ai.rizom.brain.card"?Q.superRefine(DeQ):Q}var Sp0={"ai.rizom.brain.card":mU(S6["ai.rizom.brain.card"]),"ai.rizom.brain.deck":mU(S6["ai.rizom.brain.deck"]),"ai.rizom.brain.link":mU(S6["ai.rizom.brain.link"]),"ai.rizom.brain.note":mU(S6["ai.rizom.brain.note"]),"ai.rizom.brain.post":mU(S6["ai.rizom.brain.post"]),"ai.rizom.brain.project":mU(S6["ai.rizom.brain.project"]),"ai.rizom.brain.series":mU(S6["ai.rizom.brain.series"]),"ai.rizom.brain.socialPost":mU(S6["ai.rizom.brain.socialPost"]),"ai.rizom.brain.topic":mU(S6["ai.rizom.brain.topic"])};function qeQ(A,Q){let w=A;for(let $ of Q){if(typeof $==="symbol")return;if(Array.isArray(w)){w=w[Number($)];continue}if(!W40(w))return;w=w[String($)]}return w}function zeQ(A,Q,w){let $=w.path.join(".");if($==="$type")return`AT Protocol record $type must match lexicon id: ${String(Q.$type)} !== ${A.id}`;if(w.code==="invalid_type"&&qeQ(Q,w.path)===void 0)return`Missing required AT Protocol record field: ${$}`;if(w.code==="invalid_type")return`Invalid AT Protocol record field ${$}: expected ${w.expected}`;if(w.code==="too_big")return`Invalid AT Protocol record field ${$}: exceeds maxLength ${w.maximum}`;if(w.code==="custom")return`Invalid AT Protocol record field ${$}: ${w.message}`;if(w.code==="unrecognized_keys")return`Unrecognized AT Protocol record field(s): ${w.keys.join(", ")}`;return`Invalid AT Protocol record field ${$}: ${w.message}`}function FV(A,Q){let w=mU(A).safeParse(Q);if(w.success)return;let $=w.error.issues[0];if(!$)throw w.error;throw Error(zeQ(A,Q,$))}C0();var Hr="atproto:brain-card-discovered",mp0="atproto:brain-discovered",up0="atproto:brain-card-refreshed",VeQ=f.custom((A)=>Sp0["ai.rizom.brain.card"].safeParse(A).success),cp0=f.object({repoDid:f.string().min(1),uri:f.string().min(1),cid:f.string().min(1),record:VeQ}).strict(),JeQ=f.object({agentId:f.string().min(1),name:f.string().min(1),url:f.string().url(),status:f.enum(["discovered","approved"]),repoDid:f.string().min(1).optional(),brainDid:f.string().min(1).optional(),anchorDid:f.string().min(1).optional(),cardUri:f.string().min(1).optional(),cardCid:f.string().min(1).optional()}).strict();class kB{static instance;projections=new Map;static getInstance(){return this.instance??=new kB,this.instance}static createFresh(){return new kB}static resetInstance(){this.instance=void 0}register(A){this.validateProjection(A);let Q=this.get(A.entityType);if(Q&&!this.isEquivalentProjection(Q,A))throw Error(`AT Protocol projection already registered for entity type ${A.entityType}`);let w=this.projections.get(A.entityType)??[];return w.push(A),this.projections.set(A.entityType,w),this.createUnregister(A.entityType,A)}get(A){let Q=this.projections.get(A);return Q?.[Q.length-1]}has(A){return this.get(A)!==void 0}list(){let A=[];for(let Q of this.projections.keys()){let w=this.get(Q);if(w)A.push(w)}return A}listLexicons(){return this.list().map((A)=>A.lexicon)}createUnregister(A,Q){let w=!0;return()=>{if(!w)return;w=!1;let $=this.projections.get(A);if(!$)return;let B=$.lastIndexOf(Q);if(B!==-1)$.splice(B,1);if($.length===0)this.projections.delete(A)}}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}`)}}C0();var _g1={name:"@brains/atproto-registry",version:"0.2.0-alpha.159",description:"Canonical Rizom AT Protocol lexicon registry",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":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var jg1=f.object({enabled:f.boolean().default(!0)}),lp0="/atproto/lexicons",FeQ=f.strictObject({nsid:f.string(),record:f.record(f.string(),f.unknown())});function Ng1(A){return new Response(`${JSON.stringify(A,null,2)}
5733
5733
  `,{headers:{"Content-Type":"application/json"}})}class pp0 extends Kw{constructor(A={}){super("atproto-registry",_g1,A,jg1)}getWebRoutes(){if(!this.config.enabled)return[];return[{path:`${lp0}/index.json`,method:"GET",public:!0,handler:()=>Ng1(this.getIndex())},...rg().map((A)=>({path:`${lp0}/${A.id}.json`,method:"GET",public:!0,handler:()=>Ng1(A)}))]}getIndex(){return{lexicons:H40().map((A)=>({...A,path:`${lp0}/${A.id}.json`}))}}getLexicon(A){return f40(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:f.string().describe("Canonical lexicon NSID"),record:f.record(f.string(),f.unknown()).describe("Record payload to validate")},handler:async(A)=>{let Q=FeQ.safeParse(A);if(!Q.success)return{success:!1,error:`Invalid input: ${Q.error.message}`};let w=this.getLexicon(Q.data.nsid);if(!w)return{success:!1,error:`Unknown AT Protocol lexicon: ${Q.data.nsid}`};try{return FV(w,Q.data.record),{success:!0,data:{valid:!0}}}catch($){return{success:!0,data:{valid:!1,error:$ instanceof Error?$.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:rg().length,nsids:rg().map((A)=>A.id),metadata:H40()}})}}}function Wr(A={}){return new pp0(A)}fA();class ip0{logger;handleImport;handleDelete;deleteOnFileRemoval;fileOperations;constructor(A,Q,w,$,B=!0){if(this.logger=A,this.fileOperations=$,this.deleteOnFileRemoval=B,w)this.handleImport=async(X)=>{let Y=await w({type:"directory-import",data:{paths:[X]}});this.logger.debug("Queued import job for file change",{jobId:Y,path:X})},this.handleDelete=async(X)=>{if(!this.deleteOnFileRemoval){this.logger.warn("File deleted but deleteOnFileRemoval is disabled",{path:X});return}try{let{entityType:Y,id:Z}=this.fileOperations.parseEntityFromPath(X),H=await w({type:"directory-delete",data:{entityId:Z,entityType:Y,filePath:X}});this.logger.info("Queued delete job for removed file",{jobId:H,path:X,entityId:Z,entityType:Y})}catch(Y){this.logger.warn("Could not extract entity info from deleted file",{path:X,error:Y})}};else this.handleImport=async(X)=>{await Q([X])},this.handleDelete=async(X)=>{this.logger.warn("File deleted but no job queue available",{path:X})}}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(w){this.logger.error("Failed to handle file change",{event:A,path:Q,error:w})}}}import{EventEmitter as seQ}from"events";import{stat as aeQ,Stats as $a$}from"fs";import{readdir as teQ,stat as eeQ}from"fs/promises";import*as z6 from"path";import{lstat as Pg1,readdir as beQ,realpath as LeQ,stat as keQ}from"fs/promises";import{join as _eQ,relative as NeQ,resolve as Mg1,sep as jeQ}from"path";import{Readable as PeQ}from"stream";var cf={FILE_TYPE:"files",DIR_TYPE:"directories",FILE_DIR_TYPE:"files_directories",EVERYTHING_TYPE:"all"},dp0={root:".",fileFilter:(A)=>!0,directoryFilter:(A)=>!0,type:cf.FILE_TYPE,lstat:!1,depth:2147483648,alwaysStat:!1,highWaterMark:4096};Object.freeze(dp0);var vg1="READDIRP_RECURSIVE_ERROR",MeQ=new Set(["ENOENT","EPERM","EACCES","ELOOP",vg1]),Og1=[cf.DIR_TYPE,cf.EVERYTHING_TYPE,cf.FILE_DIR_TYPE,cf.FILE_TYPE],OeQ=new Set([cf.DIR_TYPE,cf.EVERYTHING_TYPE,cf.FILE_DIR_TYPE]),xeQ=new Set([cf.EVERYTHING_TYPE,cf.FILE_DIR_TYPE,cf.FILE_TYPE]),ReQ=(A)=>MeQ.has(A.code),veQ=process.platform==="win32",xg1=(A)=>!0,Rg1=(A)=>{if(A===void 0)return xg1;if(typeof A==="function")return A;if(typeof A==="string"){let Q=A.trim();return(w)=>w.basename===Q}if(Array.isArray(A)){let Q=A.map((w)=>w.trim());return(w)=>Q.some(($)=>w.basename===$)}return xg1};class np0 extends PeQ{parents;reading;parent;_stat;_maxDepth;_wantsDir;_wantsFile;_wantsEverything;_root;_isDirent;_statsProp;_rdOptions;_fileFilter;_directoryFilter;constructor(A={}){super({objectMode:!0,autoDestroy:!0,highWaterMark:A.highWaterMark});let Q={...dp0,...A},{root:w,type:$}=Q;this._fileFilter=Rg1(Q.fileFilter),this._directoryFilter=Rg1(Q.directoryFilter);let B=Q.lstat?Pg1:keQ;if(veQ)this._stat=(X)=>B(X,{bigint:!0});else this._stat=B;this._maxDepth=Q.depth!=null&&Number.isSafeInteger(Q.depth)?Q.depth:dp0.depth,this._wantsDir=$?OeQ.has($):!1,this._wantsFile=$?xeQ.has($):!1,this._wantsEverything=$===cf.EVERYTHING_TYPE,this._root=Mg1(w),this._isDirent=!Q.alwaysStat,this._statsProp=this._isDirent?"dirent":"stats",this._rdOptions={encoding:"utf8",withFileTypes:this._isDirent},this.parents=[this._exploreDir(w,1)],this.reading=!1,this.parent=void 0}async _read(A){if(this.reading)return;this.reading=!0;try{while(!this.destroyed&&A>0){let Q=this.parent,w=Q&&Q.files;if(w&&w.length>0){let{path:$,depth:B}=Q,X=w.splice(0,A).map((Z)=>this._formatEntry(Z,$)),Y=await Promise.all(X);for(let Z of Y){if(!Z)continue;if(this.destroyed)return;let H=await this._getEntryType(Z);if(H==="directory"&&this._directoryFilter(Z)){if(B<=this._maxDepth)this.parents.push(this._exploreDir(Z.fullPath,B+1));if(this._wantsDir)this.push(Z),A--}else if((H==="file"||this._includeAsFile(Z))&&this._fileFilter(Z)){if(this._wantsFile)this.push(Z),A--}}}else{let $=this.parents.pop();if(!$){this.push(null);break}if(this.parent=await $,this.destroyed)return}}}catch(Q){this.destroy(Q)}finally{this.reading=!1}}async _exploreDir(A,Q){let w;try{w=await beQ(A,this._rdOptions)}catch($){this._onError($)}return{files:w,depth:Q,path:A}}async _formatEntry(A,Q){let w,$=this._isDirent?A.name:A;try{let B=Mg1(_eQ(Q,$));w={path:NeQ(this._root,B),fullPath:B,basename:$},w[this._statsProp]=this._isDirent?A:await this._stat(B)}catch(B){this._onError(B);return}return w}_onError(A){if(ReQ(A)&&!this.destroyed)this.emit("warn",A);else this.destroy(A)}async _getEntryType(A){if(!A&&this._statsProp in A)return"";let Q=A[this._statsProp];if(Q.isFile())return"file";if(Q.isDirectory())return"directory";if(Q&&Q.isSymbolicLink()){let w=A.fullPath;try{let $=await LeQ(w),B=await Pg1($);if(B.isFile())return"file";if(B.isDirectory()){let X=$.length;if(w.startsWith($)&&w.substr(X,1)===jeQ){let Y=Error(`Circular symlink detected: "${w}" points to "${$}"`);return Y.code=vg1,this._onError(Y)}return"directory"}}catch($){return this._onError($),""}}}_includeAsFile(A){let Q=A&&A[this._statsProp];return Q&&this._wantsEverything&&!Q.isDirectory()}}function hg1(A,Q={}){let w=Q.entryType||Q.type;if(w==="both")w=cf.FILE_DIR_TYPE;if(w)Q.type=w;if(!A)throw Error("readdirp: root argument is required. Usage: readdirp(root, options)");else if(typeof A!=="string")throw TypeError("readdirp: root argument must be a string. Usage: readdirp(root, options)");else if(w&&!Og1.includes(w))throw Error(`readdirp: Invalid type passed. Use one of ${Og1.join(", ")}`);return Q.root=A,new np0(Q)}import{watch as heQ,unwatchFile as Cg1,watchFile as CeQ}from"fs";import{realpath as rp0,lstat as geQ,open as yeQ,stat as yg1}from"fs/promises";import{type as EeQ}from"os";import*as t8 from"path";var TeQ="data",ap0="end",Eg1="close",D40=()=>{};var q40=process.platform,tp0=q40==="win32",SeQ=q40==="darwin",meQ=q40==="linux",ueQ=q40==="freebsd",Tg1=EeQ()==="OS400",M8={ALL:"all",READY:"ready",ADD:"add",CHANGE:"change",ADD_DIR:"addDir",UNLINK:"unlink",UNLINK_DIR:"unlinkDir",RAW:"raw",ERROR:"error"},uU=M8,ceQ="watch",leQ={lstat:geQ,stat:yg1},YP="listeners",K40="errHandlers",og="rawEmitters",peQ=[YP,K40,og],ieQ=new Set(["3dm","3ds","3g2","3gp","7z","a","aac","adp","afdesign","afphoto","afpub","ai","aif","aiff","alz","ape","apk","appimage","ar","arj","asf","au","avi","bak","baml","bh","bin","bk","bmp","btif","bz2","bzip2","cab","caf","cgm","class","cmx","cpio","cr2","cur","dat","dcm","deb","dex","djvu","dll","dmg","dng","doc","docm","docx","dot","dotm","dra","DS_Store","dsk","dts","dtshd","dvb","dwg","dxf","ecelp4800","ecelp7470","ecelp9600","egg","eol","eot","epub","exe","f4v","fbs","fh","fla","flac","flatpak","fli","flv","fpx","fst","fvt","g3","gh","gif","graffle","gz","gzip","h261","h263","h264","icns","ico","ief","img","ipa","iso","jar","jpeg","jpg","jpgv","jpm","jxr","key","ktx","lha","lib","lvp","lz","lzh","lzma","lzo","m3u","m4a","m4v","mar","mdi","mht","mid","midi","mj2","mka","mkv","mmr","mng","mobi","mov","movie","mp3","mp4","mp4a","mpeg","mpg","mpga","mxu","nef","npx","numbers","nupkg","o","odp","ods","odt","oga","ogg","ogv","otf","ott","pages","pbm","pcx","pdb","pdf","pea","pgm","pic","png","pnm","pot","potm","potx","ppa","ppam","ppm","pps","ppsm","ppsx","ppt","pptm","pptx","psd","pya","pyc","pyo","pyv","qt","rar","ras","raw","resources","rgb","rip","rlc","rmf","rmvb","rpm","rtf","rz","s3m","s7z","scpt","sgi","shar","snap","sil","sketch","slk","smv","snk","so","stl","suo","sub","swf","tar","tbz","tbz2","tga","tgz","thmx","tif","tiff","tlz","ttc","ttf","txz","udf","uvh","uvi","uvm","uvp","uvs","uvu","viv","vob","war","wav","wax","wbmp","wdp","weba","webm","webp","whl","wim","wm","wma","wmv","wmx","woff","woff2","wrm","wvx","xbm","xif","xla","xlam","xls","xlsb","xlsm","xlsx","xlt","xltm","xltx","xm","xmind","xpi","xpm","xwd","xz","z","zip","zipx"]),deQ=(A)=>ieQ.has(t8.extname(A).slice(1).toLowerCase()),sp0=(A,Q)=>{if(A instanceof Set)A.forEach(Q);else Q(A)},Kr=(A,Q,w)=>{let $=A[Q];if(!($ instanceof Set))A[Q]=$=new Set([$]);$.add(w)},neQ=(A)=>(Q)=>{let w=A[Q];if(w instanceof Set)w.clear();else delete A[Q]},Ur=(A,Q,w)=>{let $=A[Q];if($ instanceof Set)$.delete(w);else if($===w)delete A[Q]},Sg1=(A)=>A instanceof Set?A.size===0:!A,U40=new Map;function gg1(A,Q,w,$,B){let X=(Y,Z)=>{if(w(A),B(Y,Z,{watchedPath:A}),Z&&A!==Z)G40(t8.resolve(A,Z),YP,t8.join(A,Z))};try{return heQ(A,{persistent:Q.persistent},X)}catch(Y){$(Y);return}}var G40=(A,Q,w,$,B)=>{let X=U40.get(A);if(!X)return;sp0(X[Q],(Y)=>{Y(w,$,B)})},reQ=(A,Q,w,$)=>{let{listener:B,errHandler:X,rawEmitter:Y}=$,Z=U40.get(Q),H;if(!w.persistent){if(H=gg1(A,w,B,X,Y),!H)return;return H.close.bind(H)}if(Z)Kr(Z,YP,B),Kr(Z,K40,X),Kr(Z,og,Y);else{if(H=gg1(A,w,G40.bind(null,Q,YP),X,G40.bind(null,Q,og)),!H)return;H.on(uU.ERROR,async(W)=>{let K=G40.bind(null,Q,K40);if(Z)Z.watcherUnusable=!0;if(tp0&&W.code==="EPERM")try{await(await yeQ(A,"r")).close(),K(W)}catch(U){}else K(W)}),Z={listeners:B,errHandlers:X,rawEmitters:Y,watcher:H},U40.set(Q,Z)}return()=>{if(Ur(Z,YP,B),Ur(Z,K40,X),Ur(Z,og,Y),Sg1(Z.listeners))Z.watcher.close(),U40.delete(Q),peQ.forEach(neQ(Z)),Z.watcher=void 0,Object.freeze(Z)}},op0=new Map,oeQ=(A,Q,w,$)=>{let{listener:B,rawEmitter:X}=$,Y=op0.get(Q),Z=Y&&Y.options;if(Z&&(Z.persistent<w.persistent||Z.interval>w.interval))Cg1(Q),Y=void 0;if(Y)Kr(Y,YP,B),Kr(Y,og,X);else Y={listeners:B,rawEmitters:X,options:w,watcher:CeQ(Q,w,(H,W)=>{sp0(Y.rawEmitters,(U)=>{U(uU.CHANGE,Q,{curr:H,prev:W})});let K=H.mtimeMs;if(H.size!==W.size||K>W.mtimeMs||K===0)sp0(Y.listeners,(U)=>U(A,H))})},op0.set(Q,Y);return()=>{if(Ur(Y,YP,B),Ur(Y,og,X),Sg1(Y.listeners))op0.delete(Q),Cg1(Q),Y.options=Y.watcher=void 0,Object.freeze(Y)}};class ep0{fsw;_boundHandleError;constructor(A){this.fsw=A,this._boundHandleError=(Q)=>A._handleError(Q)}_watchWithNodeFs(A,Q){let w=this.fsw.options,$=t8.dirname(A),B=t8.basename(A);this.fsw._getWatchedDir($).add(B);let Y=t8.resolve(A),Z={persistent:w.persistent};if(!Q)Q=D40;let H;if(w.usePolling){let W=w.interval!==w.binaryInterval;Z.interval=W&&deQ(B)?w.binaryInterval:w.interval,H=oeQ(A,Y,Z,{listener:Q,rawEmitter:this.fsw._emitRaw})}else H=reQ(A,Y,Z,{listener:Q,errHandler:this._boundHandleError,rawEmitter:this.fsw._emitRaw});return H}_handleFile(A,Q,w){if(this.fsw.closed)return;let $=t8.dirname(A),B=t8.basename(A),X=this.fsw._getWatchedDir($),Y=Q;if(X.has(B))return;let Z=async(W,K)=>{if(!this.fsw._throttle(ceQ,A,5))return;if(!K||K.mtimeMs===0)try{let U=await yg1(A);if(this.fsw.closed)return;let{atimeMs:G,mtimeMs:q}=U;if(!G||G<=q||q!==Y.mtimeMs)this.fsw._emit(uU.CHANGE,A,U);if((SeQ||meQ||ueQ)&&Y.ino!==U.ino){this.fsw._closeFile(W),Y=U;let V=this._watchWithNodeFs(A,Z);if(V)this.fsw._addPathCloser(W,V)}else Y=U}catch(U){this.fsw._remove($,B)}else if(X.has(B)){let{atimeMs:U,mtimeMs:G}=K;if(!U||U<=G||G!==Y.mtimeMs)this.fsw._emit(uU.CHANGE,A,K);Y=K}},H=this._watchWithNodeFs(A,Z);if(!(w&&this.fsw.options.ignoreInitial)&&this.fsw._isntIgnored(A)){if(!this.fsw._throttle(uU.ADD,A,0))return;this.fsw._emit(uU.ADD,A,Q)}return H}async _handleSymlink(A,Q,w,$){if(this.fsw.closed)return;let B=A.fullPath,X=this.fsw._getWatchedDir(Q);if(!this.fsw.options.followSymlinks){this.fsw._incrReadyCount();let Y;try{Y=await rp0(w)}catch(Z){return this.fsw._emitReady(),!0}if(this.fsw.closed)return;if(X.has($)){if(this.fsw._symlinkPaths.get(B)!==Y)this.fsw._symlinkPaths.set(B,Y),this.fsw._emit(uU.CHANGE,w,A.stats)}else X.add($),this.fsw._symlinkPaths.set(B,Y),this.fsw._emit(uU.ADD,w,A.stats);return this.fsw._emitReady(),!0}if(this.fsw._symlinkPaths.has(B))return!0;this.fsw._symlinkPaths.set(B,!0)}_handleRead(A,Q,w,$,B,X,Y){A=t8.join(A,"");let Z=$?`${A}:${$}`:A;if(Y=this.fsw._throttle("readdir",Z,1000),!Y)return;let H=this.fsw._getWatchedDir(w.path),W=new Set,K=this.fsw._readdirp(A,{fileFilter:(U)=>w.filterPath(U),directoryFilter:(U)=>w.filterDir(U)});if(!K)return;return K.on(TeQ,async(U)=>{if(this.fsw.closed){K=void 0;return}let G=U.path,q=t8.join(A,G);if(W.add(G),U.stats.isSymbolicLink()&&await this._handleSymlink(U,A,q,G))return;if(this.fsw.closed){K=void 0;return}if(G===$||!$&&!H.has(G))this.fsw._incrReadyCount(),q=t8.join(B,t8.relative(B,q)),this._addToNodeFs(q,Q,w,X+1)}).on(uU.ERROR,this._boundHandleError),new Promise((U,G)=>{if(!K)return G();K.once(ap0,()=>{if(this.fsw.closed){K=void 0;return}let q=Y?Y.clear():!1;if(U(void 0),H.getChildren().filter((V)=>{return V!==A&&!W.has(V)}).forEach((V)=>{this.fsw._remove(A,V)}),K=void 0,q)this._handleRead(A,!1,w,$,B,X,Y)})})}async _handleDir(A,Q,w,$,B,X,Y){let Z=this.fsw._getWatchedDir(t8.dirname(A)),H=Z.has(t8.basename(A));if(!(w&&this.fsw.options.ignoreInitial)&&!B&&!H)this.fsw._emit(uU.ADD_DIR,A,Q);Z.add(t8.basename(A)),this.fsw._getWatchedDir(A);let W,K,U=this.fsw.options.depth;if((U==null||$<=U)&&!this.fsw._symlinkPaths.has(Y)){if(!B){if(await this._handleRead(A,w,X,B,A,$,W),this.fsw.closed)return}K=this._watchWithNodeFs(A,(G,q)=>{if(q&&q.mtimeMs===0)return;this._handleRead(G,!1,X,B,A,$,W)})}return K}async _addToNodeFs(A,Q,w,$,B){let X=this.fsw._emitReady;if(this.fsw._isIgnored(A)||this.fsw.closed)return X(),!1;let Y=this.fsw._getWatchHelpers(A);if(w)Y.filterPath=(Z)=>w.filterPath(Z),Y.filterDir=(Z)=>w.filterDir(Z);try{let Z=await leQ[Y.statMethod](Y.watchPath);if(this.fsw.closed)return;if(this.fsw._isIgnored(Y.watchPath,Z))return X(),!1;let H=this.fsw.options.followSymlinks,W;if(Z.isDirectory()){let K=t8.resolve(A),U=H?await rp0(A):A;if(this.fsw.closed)return;if(W=await this._handleDir(Y.watchPath,Z,Q,$,B,Y,U),this.fsw.closed)return;if(K!==U&&U!==void 0)this.fsw._symlinkPaths.set(K,U)}else if(Z.isSymbolicLink()){let K=H?await rp0(A):A;if(this.fsw.closed)return;let U=t8.dirname(Y.watchPath);if(this.fsw._getWatchedDir(U).add(Y.watchPath),this.fsw._emit(uU.ADD,Y.watchPath,Z),W=await this._handleDir(U,Z,Q,$,A,Y,K),this.fsw.closed)return;if(K!==void 0)this.fsw._symlinkPaths.set(t8.resolve(A),K)}else W=this._handleFile(Y.watchPath,Z,Q);if(X(),W)this.fsw._addPathCloser(A,W);return!1}catch(Z){if(this.fsw._handleError(Z))return X(),A}}}/*! chokidar - MIT License (c) 2012 Paul Miller (paulmillr.com) */var Ai0="/",A0w="//",pg1=".",Q0w="..",w0w="string",$0w=/\\/g,ig1=/\/\//g,B0w=/\..*\.(sw[px])$|~$|\.subl.*\.tmp/,X0w=/^\.[/\\]/;function z40(A){return Array.isArray(A)?A:[A]}var Qi0=(A)=>typeof A==="object"&&A!==null&&!(A instanceof RegExp);function Y0w(A){if(typeof A==="function")return A;if(typeof A==="string")return(Q)=>A===Q;if(A instanceof RegExp)return(Q)=>A.test(Q);if(typeof A==="object"&&A!==null)return(Q)=>{if(A.path===Q)return!0;if(A.recursive){let w=z6.relative(A.path,Q);if(!w)return!1;return!w.startsWith("..")&&!z6.isAbsolute(w)}return!1};return()=>!1}function Z0w(A){if(typeof A!=="string")throw Error("string expected");A=z6.normalize(A),A=A.replace(/\\/g,"/");let Q=!1;if(A.startsWith("//"))Q=!0;if(A=A.replace(ig1,"/"),Q)A="/"+A;return A}function mg1(A,Q,w){let $=Z0w(Q);for(let B=0;B<A.length;B++){let X=A[B];if(X($,w))return!0}return!1}function f0w(A,Q){if(A==null)throw TypeError("anymatch: specify first argument");let $=z40(A).map((B)=>Y0w(B));if(Q==null)return(B,X)=>{return mg1($,B,X)};return mg1($,Q)}var ug1=(A)=>{let Q=z40(A).flat();if(!Q.every((w)=>typeof w===w0w))throw TypeError(`Non-string provided as watch path: ${Q}`);return Q.map(dg1)},cg1=(A)=>{let Q=A.replace($0w,Ai0),w=!1;if(Q.startsWith(A0w))w=!0;if(Q=Q.replace(ig1,Ai0),w)Q=Ai0+Q;return Q},dg1=(A)=>cg1(z6.normalize(cg1(A))),lg1=(A="")=>(Q)=>{if(typeof Q==="string")return dg1(z6.isAbsolute(Q)?Q:z6.join(A,Q));else return Q},H0w=(A,Q)=>{if(z6.isAbsolute(A))return A;return z6.join(Q,A)},W0w=Object.freeze(new Set);class ng1{path;_removeWatcher;items;constructor(A,Q){this.path=A,this._removeWatcher=Q,this.items=new Set}add(A){let{items:Q}=this;if(!Q)return;if(A!==pg1&&A!==Q0w)Q.add(A)}async remove(A){let{items:Q}=this;if(!Q)return;if(Q.delete(A),Q.size>0)return;let w=this.path;try{await teQ(w)}catch($){if(this._removeWatcher)this._removeWatcher(z6.dirname(w),z6.basename(w))}}has(A){let{items:Q}=this;if(!Q)return;return Q.has(A)}getChildren(){let{items:A}=this;if(!A)return[];return[...A.values()]}dispose(){this.items.clear(),this.path="",this._removeWatcher=D40,this.items=W0w,Object.freeze(this)}}var K0w="stat",U0w="lstat";class rg1{fsw;path;watchPath;fullWatchPath;dirParts;followSymlinks;statMethod;constructor(A,Q,w){this.fsw=w;let $=A;this.path=A=A.replace(X0w,""),this.watchPath=$,this.fullWatchPath=z6.resolve($),this.dirParts=[],this.dirParts.forEach((B)=>{if(B.length>1)B.pop()}),this.followSymlinks=Q,this.statMethod=Q?K0w:U0w}entryPath(A){return z6.join(this.watchPath,z6.relative(this.watchPath,A.fullPath))}filterPath(A){let{stats:Q}=A;if(Q&&Q.isSymbolicLink())return this.filterDir(A);let w=this.entryPath(A);return this.fsw._isntIgnored(w,Q)&&this.fsw._hasReadPermissions(Q)}filterDir(A){return this.fsw._isntIgnored(this.entryPath(A),A.stats)}}class wi0 extends seQ{closed;options;_closers;_ignoredPaths;_throttled;_streams;_symlinkPaths;_watched;_pendingWrites;_pendingUnlinks;_readyCount;_emitReady;_closePromise;_userIgnored;_readyEmitted;_emitRaw;_boundRemove;_nodeFsHandler;constructor(A={}){super();this.closed=!1,this._closers=new Map,this._ignoredPaths=new Set,this._throttled=new Map,this._streams=new Set,this._symlinkPaths=new Map,this._watched=new Map,this._pendingWrites=new Map,this._pendingUnlinks=new Map,this._readyCount=0,this._readyEmitted=!1;let Q=A.awaitWriteFinish,w={stabilityThreshold:2000,pollInterval:100},$={persistent:!0,ignoreInitial:!1,ignorePermissionErrors:!1,interval:100,binaryInterval:300,followSymlinks:!0,usePolling:!1,atomic:!0,...A,ignored:A.ignored?z40(A.ignored):z40([]),awaitWriteFinish:Q===!0?w:typeof Q==="object"?{...w,...Q}:!1};if(Tg1)$.usePolling=!0;if($.atomic===void 0)$.atomic=!$.usePolling;let B=process.env.CHOKIDAR_USEPOLLING;if(B!==void 0){let Z=B.toLowerCase();if(Z==="false"||Z==="0")$.usePolling=!1;else if(Z==="true"||Z==="1")$.usePolling=!0;else $.usePolling=!!Z}let X=process.env.CHOKIDAR_INTERVAL;if(X)$.interval=Number.parseInt(X,10);let Y=0;this._emitReady=()=>{if(Y++,Y>=this._readyCount)this._emitReady=D40,this._readyEmitted=!0,process.nextTick(()=>this.emit(M8.READY))},this._emitRaw=(...Z)=>this.emit(M8.RAW,...Z),this._boundRemove=this._remove.bind(this),this.options=$,this._nodeFsHandler=new ep0(this),Object.freeze($)}_addIgnoredPath(A){if(Qi0(A)){for(let Q of this._ignoredPaths)if(Qi0(Q)&&Q.path===A.path&&Q.recursive===A.recursive)return}this._ignoredPaths.add(A)}_removeIgnoredPath(A){if(this._ignoredPaths.delete(A),typeof A==="string"){for(let Q of this._ignoredPaths)if(Qi0(Q)&&Q.path===A)this._ignoredPaths.delete(Q)}}add(A,Q,w){let{cwd:$}=this.options;this.closed=!1,this._closePromise=void 0;let B=ug1(A);if($)B=B.map((X)=>{return H0w(X,$)});if(B.forEach((X)=>{this._removeIgnoredPath(X)}),this._userIgnored=void 0,!this._readyCount)this._readyCount=0;return this._readyCount+=B.length,Promise.all(B.map(async(X)=>{let Y=await this._nodeFsHandler._addToNodeFs(X,!w,void 0,0,Q);if(Y)this._emitReady();return Y})).then((X)=>{if(this.closed)return;X.forEach((Y)=>{if(Y)this.add(z6.dirname(Y),z6.basename(Q||Y))})}),this}unwatch(A){if(this.closed)return this;let Q=ug1(A),{cwd:w}=this.options;return Q.forEach(($)=>{if(!z6.isAbsolute($)&&!this._closers.has($)){if(w)$=z6.join(w,$);$=z6.resolve($)}if(this._closePath($),this._addIgnoredPath($),this._watched.has($))this._addIgnoredPath({path:$,recursive:!0});this._userIgnored=void 0}),this}close(){if(this._closePromise)return this._closePromise;this.closed=!0,this.removeAllListeners();let A=[];return this._closers.forEach((Q)=>Q.forEach((w)=>{let $=w();if($ instanceof Promise)A.push($)})),this._streams.forEach((Q)=>Q.destroy()),this._userIgnored=void 0,this._readyCount=0,this._readyEmitted=!1,this._watched.forEach((Q)=>Q.dispose()),this._closers.clear(),this._watched.clear(),this._streams.clear(),this._symlinkPaths.clear(),this._throttled.clear(),this._closePromise=A.length?Promise.all(A).then(()=>{return}):Promise.resolve(),this._closePromise}getWatched(){let A={};return this._watched.forEach((Q,w)=>{let B=(this.options.cwd?z6.relative(this.options.cwd,w):w)||pg1;A[B]=Q.getChildren().sort()}),A}emitWithAll(A,Q){if(this.emit(A,...Q),A!==M8.ERROR)this.emit(M8.ALL,A,...Q)}async _emit(A,Q,w){if(this.closed)return;let $=this.options;if(tp0)Q=z6.normalize(Q);if($.cwd)Q=z6.relative($.cwd,Q);let B=[Q];if(w!=null)B.push(w);let X=$.awaitWriteFinish,Y;if(X&&(Y=this._pendingWrites.get(Q)))return Y.lastChange=new Date,this;if($.atomic){if(A===M8.UNLINK)return this._pendingUnlinks.set(Q,[A,...B]),setTimeout(()=>{this._pendingUnlinks.forEach((Z,H)=>{this.emit(...Z),this.emit(M8.ALL,...Z),this._pendingUnlinks.delete(H)})},typeof $.atomic==="number"?$.atomic:100),this;if(A===M8.ADD&&this._pendingUnlinks.has(Q))A=M8.CHANGE,this._pendingUnlinks.delete(Q)}if(X&&(A===M8.ADD||A===M8.CHANGE)&&this._readyEmitted){let Z=(H,W)=>{if(H)A=M8.ERROR,B[0]=H,this.emitWithAll(A,B);else if(W){if(B.length>1)B[1]=W;else B.push(W);this.emitWithAll(A,B)}};return this._awaitWriteFinish(Q,X.stabilityThreshold,A,Z),this}if(A===M8.CHANGE){if(!this._throttle(M8.CHANGE,Q,50))return this}if($.alwaysStat&&w===void 0&&(A===M8.ADD||A===M8.ADD_DIR||A===M8.CHANGE)){let Z=$.cwd?z6.join($.cwd,Q):Q,H;try{H=await eeQ(Z)}catch(W){}if(!H||this.closed)return;B.push(H)}return this.emitWithAll(A,B),this}_handleError(A){let Q=A&&A.code;if(A&&Q!=="ENOENT"&&Q!=="ENOTDIR"&&(!this.options.ignorePermissionErrors||Q!=="EPERM"&&Q!=="EACCES"))this.emit(M8.ERROR,A);return A||this.closed}_throttle(A,Q,w){if(!this._throttled.has(A))this._throttled.set(A,new Map);let $=this._throttled.get(A);if(!$)throw Error("invalid throttle");let B=$.get(Q);if(B)return B.count++,!1;let X,Y=()=>{let H=$.get(Q),W=H?H.count:0;if($.delete(Q),clearTimeout(X),H)clearTimeout(H.timeoutObject);return W};X=setTimeout(Y,w);let Z={timeoutObject:X,clear:Y,count:0};return $.set(Q,Z),Z}_incrReadyCount(){return this._readyCount++}_awaitWriteFinish(A,Q,w,$){let B=this.options.awaitWriteFinish;if(typeof B!=="object")return;let X=B.pollInterval,Y,Z=A;if(this.options.cwd&&!z6.isAbsolute(A))Z=z6.join(this.options.cwd,A);let H=new Date,W=this._pendingWrites;function K(U){aeQ(Z,(G,q)=>{if(G||!W.has(A)){if(G&&G.code!=="ENOENT")$(G);return}let V=Number(new Date);if(U&&q.size!==U.size)W.get(A).lastChange=V;let I=W.get(A);if(V-I.lastChange>=Q)W.delete(A),$(void 0,q);else Y=setTimeout(K,X,q)})}if(!W.has(A))W.set(A,{lastChange:H,cancelWait:()=>{return W.delete(A),clearTimeout(Y),w}}),Y=setTimeout(K,X)}_isIgnored(A,Q){if(this.options.atomic&&B0w.test(A))return!0;if(!this._userIgnored){let{cwd:w}=this.options,B=(this.options.ignored||[]).map(lg1(w)),Y=[...[...this._ignoredPaths].map(lg1(w)),...B];this._userIgnored=f0w(Y,void 0)}return this._userIgnored(A,Q)}_isntIgnored(A,Q){return!this._isIgnored(A,Q)}_getWatchHelpers(A){return new rg1(A,this.options.followSymlinks,this)}_getWatchedDir(A){let Q=z6.resolve(A);if(!this._watched.has(Q))this._watched.set(Q,new ng1(Q,this._boundRemove));return this._watched.get(Q)}_hasReadPermissions(A){if(this.options.ignorePermissionErrors)return!0;return Boolean(Number(A.mode)&256)}_remove(A,Q,w){let $=z6.join(A,Q),B=z6.resolve($);if(w=w!=null?w:this._watched.has($)||this._watched.has(B),!this._throttle("remove",$,100))return;if(!w&&this._watched.size===1)this.add(A,Q,!0);this._getWatchedDir($).getChildren().forEach((U)=>this._remove($,U));let Z=this._getWatchedDir(A),H=Z.has(Q);if(Z.remove(Q),this._symlinkPaths.has(B))this._symlinkPaths.delete(B);let W=$;if(this.options.cwd)W=z6.relative(this.options.cwd,$);if(this.options.awaitWriteFinish&&this._pendingWrites.has(W)){if(this._pendingWrites.get(W).cancelWait()===M8.ADD)return}this._watched.delete($),this._watched.delete(B);let K=w?M8.UNLINK_DIR:M8.UNLINK;if(H&&!this._isIgnored($))this._emit(K,$);this._closePath($)}_closePath(A){this._closeFile(A);let Q=z6.dirname(A);this._getWatchedDir(Q).remove(z6.basename(A))}_closeFile(A){let Q=this._closers.get(A);if(!Q)return;Q.forEach((w)=>w()),this._closers.delete(A)}_addPathCloser(A,Q){if(!Q)return;let w=this._closers.get(A);if(!w)w=[],this._closers.set(A,w);w.push(Q)}_readdirp(A,Q){if(this.closed)return;let w={type:M8.ALL,alwaysStat:!0,lstat:!0,...Q,depth:0},$=hg1(A,w);return this._streams.add($),$.once(Eg1,()=>{$=void 0}),$.once(ap0,()=>{if($)this._streams.delete($),$=void 0}),$}}function G0w(A,Q={}){let w=new wi0(Q);return w.add(A),w}var og1={watch:G0w,FSWatcher:wi0};import{extname as D0w}from"path";var V40=[".png",".jpg",".jpeg",".webp",".gif",".svg"];function ZP(A){let Q=D0w(A).toLowerCase();return V40.includes(Q)}function sg1(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 $i0(A){switch(A.toLowerCase()){case"jpeg":return".jpg";case"svg+xml":return".svg";default:return`.${A.toLowerCase()}`}}import{isAbsolute as q0w,relative as z0w,sep as ag1,join as V0w}from"path";function dW(A,Q){return q0w(Q)?Q:V0w(A,Q)}function sg(A,Q){let w=dW(A,Q),$=z0w(A,w);return ag1==="/"?$:$.split(ag1).join("/")}function J0w(A,Q){if(!sg(Q,A).startsWith("image/"))return!1;return ZP(A)}function I0w(A,Q){if(sg(Q,A).split("/")[0]?.startsWith("_"))return!1;if(A.endsWith(".md"))return!0;return J0w(A,Q)}class Bi0{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=og1.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(!I0w(Q,this.syncPath))return;this.logger.debug("File change detected",{event:A,path:Q});let w=sg(this.syncPath,Q);if(this.pendingChanges.set(w,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,w]of A){let $=dW(this.syncPath,Q);try{if(this.onFileChange)await this.onFileChange(w,$)}catch(B){this.logger.error("Error processing file change",{path:Q,event:w,error:B})}}}isWatching(){return!!this.watcher}getPendingChangesCount(){return this.pendingChanges.size}}async function tg1(A,Q){if(A?.isWatching())return Q.logger.debug("Already watching directory"),A;return F0w(Q)}function eg1(A){if(A)A.stop();return}function Ay1(A,Q){if(A)A.setCallback(Q)}async function F0w(A){let{logger:Q,syncPath:w,watchInterval:$,importEntities:B,jobQueueCallback:X,fileOperations:Y,deleteOnFileRemoval:Z}=A,H=new ip0(Q,B,X,Y,Z),W=new Bi0({syncPath:w,watchInterval:$,logger:Q,onFileChange:async(K,U)=>{await H.handleFileChange(K,U)}});return await W.start(),W}async function Qy1(A){let Q=Date.now();A.logger.debug("Starting sync (import only)");let w=await A.importEntities(),$=await A.removeOrphanedEntities(),B=Date.now()-Q;return A.markSynced(new Date),A.logger.debug("Sync completed",{duration:B,imported:w.imported,orphansDeleted:$.deleted}),{export:{exported:0,failed:0,errors:[]},import:w,duration:B}}fA();class Xi0{logger;syncPath;deleteOnFileRemoval;constructor(A){this.logger=A.logger,this.syncPath=A.syncPath,this.deleteOnFileRemoval=A.deleteOnFileRemoval}prepareBatchOperations(A){let Q=[],w=this.createImportOperations(A);Q.push(...w);let $=w.length;if(this.deleteOnFileRemoval)Q.push({type:"directory-cleanup",data:{}});let B=A.length;return this.logger.debug("Prepared batch operations",{exportOperationsCount:0,importOperationsCount:$,totalFiles:B}),{operations:Q,exportOperationsCount:0,importOperationsCount:$,totalFiles:B}}async queueSyncBatch(A,Q,w,$){let B=this.prepareBatchOperations(w);if(B.operations.length===0)return this.logger.debug("No sync operations needed",{source:Q}),null;return{batchId:await A.jobs.enqueueBatch(B.operations,{source:Q,rootJobId:$?.rootJobId??v4(),metadata:{progressToken:$?.progressToken,operationType:"file_operations",operationTarget:this.syncPath,pluginId:$?.pluginId??"directory-sync",interfaceType:$?.interfaceType,channelId:$?.channelId}}),operationCount:B.operations.length,exportOperationsCount:B.exportOperationsCount,importOperationsCount:B.importOperationsCount,totalFiles:B.totalFiles}}createImportOperations(A){if(A.length===0)return[];let Q=50,w=[];for(let $=0;$<A.length;$+=Q){let B=A.slice($,$+Q);w.push({type:"directory-import",data:{batchIndex:Math.floor($/Q),paths:B,batchSize:B.length}})}return w}}class Yi0{syncInProgress=!1;logger;fileOperations;batchOperationsManager;constructor(A){this.logger=A.logger,this.fileOperations=A.fileOperations,this.batchOperationsManager=new Xi0({logger:A.logger,syncPath:A.syncPath,deleteOnFileRemoval:A.deleteOnFileRemoval})}async queueSyncBatch(A,Q,w){if(this.syncInProgress)return this.logger.debug("Sync already in progress, skipping",{source:Q}),null;this.syncInProgress=!0;try{let $=await this.fileOperations.getAllSyncFiles();return await this.batchOperationsManager.queueSyncBatch(A,Q,$,w)}finally{this.syncInProgress=!1}}}class Zi0{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 j0w,dirname as P0w,extname as M0w}from"path";import{extname as b0w}from"path";var J40=[".pdf"],wy1=".meta.json";function fP(A){let Q=b0w(A).toLowerCase();return J40.includes(Q)}function $y1(A){return A.toLowerCase().endsWith(wy1)}function fi0(A){return`${A}${wy1}`}function By1(A){switch(A.toLowerCase().replace(".","")){case"pdf":default:return"application/pdf"}}import{extname as L0w,join as I40}from"path";function F40(A,Q){let $=sg(A,Q).split("/"),B,X;if($.length===1)B="note",X=$;else if($.length>1&&$[0])B=$[0],X=$.slice(1);else B="note",X=$;let Y;if(X.length>1){let Z=X[X.length-1];if(Z)X[X.length-1]=Xy1(Z);Y=X.join(":")}else Y=Xy1(X[0]??"");return{entityType:B,id:Y}}function Yy1(A,Q,w,$=".md"){let B=Q.split(":").filter((W)=>W.length>0),X=w==="note";if(B.length===1)return X?I40(A,`${B[0]}${$}`):I40(A,w,`${B[0]}${$}`);let Y=B;if(B[0]===w)Y=B.slice(1);let Z=Y[Y.length-1],H=Y.slice(0,-1);if(X)return I40(A,...H,`${Z}${$}`);return I40(A,w,...H,`${Z}${$}`)}function Zy1(A){if(A.entityType==="document")return".pdf";if(A.entityType!=="image")return".md";let Q=A.metadata.format;if(Q)return $i0(Q);let w=A.content.match(/^data:image\/([a-z+]+);base64,/i);return w?.[1]?$i0(w[1]):".md"}function Xy1(A){let Q=L0w(A).toLowerCase();return Q===".md"||V40.includes(Q)||J40.includes(Q)?A.slice(0,-Q.length):A}C0();Xf();import{mkdir as O0w,readFile as ag,writeFile as Wi0,stat as x0w,utimes as R0w}from"fs/promises";import{join as b40}from"path";import{mkdir as fy1,readdir as _0w,stat as N0w}from"fs/promises";import{access as k0w}from"fs/promises";async function q5(A){try{return await k0w(A),!0}catch{return!1}}async function Hi0(A,Q){return Uy1(A,Q,{includeDocuments:!1,includeImages:!1})}async function Hy1(A,Q){return Uy1(A,Q,{includeDocuments:!0,includeImages:!0})}async function Wy1(A,Q){if(!await q5(A))await fy1(A,{recursive:!0});for(let w of Q)if(w!=="note")await fy1(b40(A,w),{recursive:!0})}async function Ky1(A,Q){let w=[],$={totalFiles:0,byEntityType:{}};if(!await q5(A))return{files:w,stats:$};let B=await Hi0(A,Q);for(let X of B)try{let Y=b40(A,X),Z=await N0w(Y),{entityType:H}=F40(A,X);w.push({path:X,entityType:H,modified:Z.mtime}),$.totalFiles++,$.byEntityType[H]=($.byEntityType[H]??0)+1}catch{continue}return{files:w,stats:$}}async function Uy1(A,Q,w){let $=[];if(!await q5(A))return $;let B=async(X,Y="",Z=!1,H=!1)=>{let W=await _0w(X,{withFileTypes:!0});for(let K of W){let U=Y?b40(Y,K.name):K.name;if(K.isFile()&&!K.name.endsWith(".invalid")&&!$y1(K.name)){if(K.name.endsWith(".md"))$.push(U);else if(w.includeImages&&Z&&ZP(K.name))$.push(U);else if(w.includeDocuments&&H&&fP(K.name))$.push(U)}else if(K.isDirectory()&&!K.name.startsWith(".")){if(Y===""&&!Q.hasEntityType(K.name))continue;let G=b40(X,K.name),q=K.name==="image"&&Y==="",V=K.name==="document"&&Y==="";await B(G,U,Z||q,H||V)}}};return await B(A),$}var v0w=f.record(f.string(),f.unknown());class Ki0{syncPath;entityService;constructor(A,Q){this.syncPath=A,this.entityService=Q}parseEntityFromPath(A){return F40(this.syncPath,A)}async readEntity(A){let Q=dW(this.syncPath,A),w=await x0w(Q),{entityType:$,id:B}=this.parseEntityFromPath(A),X=w.birthtime.getTime()>0?w.birthtime:w.mtime,Y=w.mtime,Z,H;if(ZP(A)||fP(A)){let U=(await ag(Q)).toString("base64"),G=M0w(A);if(Z=`data:${fP(A)?By1(G):sg1(G)};base64,${U}`,fP(A))H=await this.readDocumentSidecar(Q,A)}else Z=await ag(Q,"utf-8");let W={entityType:$,id:B,content:Z,created:X,updated:Y};if(H)W.metadata=H;return W}async readDocumentSidecar(A,Q){let w={mimeType:"application/pdf",filename:j0w(Q)},$=fi0(A);if(!await q5($))return w;try{let B=await ag($,"utf-8"),X=v0w.safeParse(JSON.parse(B));return{...w,...X.success?X.data:{}}}catch{return w}}async writeEntity(A){let Q=this.getEntityFilePath(A),w=A.entityType==="image",$=A.entityType==="document";if(w||$){let X=w?/^data:image\/[a-z+]+;base64,(.+)$/i:/^data:application\/pdf;base64,(.+)$/i,Y=A.content.match(X),Z=Y?.[1]?Buffer.from(Y[1],"base64"):Buffer.from(A.content,"base64"),H=!1;if(await q5(Q)){let W=await ag(Q),K=I6(W.toString("base64")),U=I6(Z.toString("base64"));if(K===U)H=!0}if(!H)await this.ensureEntityDirectory(A,Q),await Wi0(Q,Z);if($)await this.writeDocumentSidecar(A,Q);if(H)return}else{let X=this.entityService.serializeEntity(A);if(await q5(Q)){let Y=await ag(Q,"utf-8"),Z=I6(Y),H=I6(X);if(Z===H)return}await this.ensureEntityDirectory(A,Q),await Wi0(Q,X,"utf-8")}let B=new Date(A.updated);await R0w(Q,B,B)}async ensureEntityDirectory(A,Q){if(A.entityType!=="note")await O0w(P0w(Q),{recursive:!0})}async writeDocumentSidecar(A,Q){let w=A.metadata,$={};for(let[Y,Z]of Object.entries(w)){if(Y==="mimeType")continue;if(Z===void 0)continue;$[Y]=Z}let B=fi0(Q),X=`${JSON.stringify($,null,2)}
5734
5734
  `;if(await q5(B)){if(await ag(B,"utf-8")===X)return}await this.ensureEntityDirectory(A,B),await Wi0(B,X,"utf-8")}getFilePath(A,Q,w=".md"){return Yy1(this.syncPath,A,Q,w)}getEntityFilePath(A){return this.getFilePath(A.id,A.entityType,Zy1(A))}async getAllMarkdownFiles(){return Hi0(this.syncPath,this.entityService)}async getAllSyncFiles(){return Hy1(this.syncPath,this.entityService)}async ensureDirectoryStructure(A){await Wy1(this.syncPath,A)}shouldUpdateEntity(A,Q){let w=I6(Q.content);return A.contentHash!==w}async gatherFileStatus(){return Ky1(this.syncPath,this.entityService)}async syncDirectoryExists(){return q5(this.syncPath)}async fileExists(A){return q5(A)}}p4();C0();H7();b2();p4();async function L40(A,Q,w,$){let{sourceUrl:B}=A,X=await Q.listEntities({entityType:"image",options:{filter:{metadata:{sourceUrl:B}},limit:1}});if(X[0])return $.debug("Reusing existing image entity",{sourceUrl:B,imageId:X[0].id}),X[0].id;let Y=await w(B),{base64:Z}=iI(Y),H=a_(Z),W=dI(Z);if(!H||!W)throw Error("Could not detect image format or dimensions");let K=await Q.createEntity({entity:{id:A.id,entityType:"image",content:Y,metadata:{title:A.title,alt:A.alt,format:H,width:W.width,height:W.height,sourceUrl:B}}});return $.debug("Created image entity from URL",{sourceUrl:B,imageId:K.entityId}),K.entityId}var Gy1=f.object({title:f.string(),slug:f.string().optional(),coverImageUrl:f.url(),coverImageId:f.string().optional(),coverImageAlt:f.string().optional()});class Ui0{entityService;fetcher;logger;constructor(A,Q,w=JW){this.entityService=A,this.fetcher=w,this.logger=Q.child("FrontmatterImageConverter")}detectCoverImageUrl(A){let Q;try{Q=l6(A)}catch{return null}let{frontmatter:w}=Q,$=Gy1.safeParse(w);if(!$.success)return null;if($.data.coverImageId)return null;let{title:B,slug:X,coverImageUrl:Y,coverImageAlt:Z}=$.data;if(!s_(Y))return null;return{sourceUrl:Y,postTitle:B,postSlug:X??q1(B),customAlt:Z}}async convert(A){let Q;try{Q=l6(A)}catch(W){return this.logger.debug("Parse failed",{error:W}),{content:A,converted:!1}}let{frontmatter:w}=Q,$=Gy1.safeParse(w);if(!$.success)return{content:A,converted:!1};if($.data.coverImageId)return{content:A,converted:!1};let{title:B,slug:X,coverImageUrl:Y,coverImageAlt:Z}=$.data;if(!s_(Y))return{content:A,converted:!1};let H={postTitle:B,postSlug:X??q1(B),sourceUrl:Y,customAlt:Z};try{let W=await this.createImageEntity(H),K={...w};return delete K.coverImageUrl,delete K.coverImageAlt,K.coverImageId=W,{content:F_(K,Q.content),converted:!0,imageId:W}}catch(W){return this.logger.warn("Failed to convert coverImageUrl",{url:Y,error:dA(W)}),{content:A,converted:!1}}}async createImageEntity(A){let{postTitle:Q,postSlug:w,sourceUrl:$,customAlt:B}=A,X=`Cover image for ${Q}`;return L40({id:`${w}-cover`,title:X,alt:B??X,sourceUrl:$},this.entityService,this.fetcher,this.logger)}}p4();class Gr{entityService;fetcher;logger;constructor(A,Q,w=JW){this.entityService=A,this.fetcher=w,this.logger=Q.child("MarkdownImageConverter")}detectInlineImages(A,Q){let w=[],$=LM0(A);for(let B of $){if(!s_(B.url))continue;if(B.url.startsWith("entity://"))continue;let X=this.reconstructMarkdown(B);w.push({sourceUrl:B.url,alt:B.alt,originalMarkdown:X,postSlug:Q})}return w}reconstructMarkdown(A){if(A.title)return`![${A.alt}](${A.url} "${A.title}")`;return`![${A.alt}](${A.url})`}async convert(A,Q){let w=this.detectInlineImages(A,Q);if(w.length===0)return{content:A,converted:!1,convertedCount:0};let $=A,B=0,X=0;for(let Y of w)try{let Z=await this.createImageEntity(Y,X++),H=`![${Y.alt}](entity://image/${Z})`;$=$.replace(Y.originalMarkdown,H),B++,this.logger.debug("Converted inline image",{sourceUrl:Y.sourceUrl,imageId:Z})}catch(Z){this.logger.warn("Failed to convert inline image",{sourceUrl:Y.sourceUrl,error:dA(Z)})}return{content:$,converted:B>0,convertedCount:B}}async createImageEntity(A,Q){let{sourceUrl:w,alt:$,postSlug:B}=A;return L40({id:`${B}-inline-${Q}`,title:$||`Inline image ${Q+1} for ${B}`,alt:$||"",sourceUrl:w},this.entityService,this.fetcher,this.logger)}}class Gi0{logger;entityService;fileOperations;constructor(A,Q,w){this.logger=A,this.entityService=Q,this.fileOperations=w}async importEntitiesWithProgress(A,Q,w,$){this.logger.debug("Importing entities with progress reporting");let B={imported:0,skipped:0,failed:0,quarantined:0,quarantinedFiles:[],errors:[],jobIds:[]},X=A??await this.fileOperations.getAllSyncFiles(),Y=X.length;await Q.report({progress:0,message:`Starting import of ${Y} files`});for(let Z=0;Z<Y;Z+=w){let H=X.slice(Z,Z+w),W=await $(H);B.imported+=W.imported,B.skipped+=W.skipped,B.failed+=W.failed,B.quarantined+=W.quarantined,B.errors.push(...W.errors),B.quarantinedFiles.push(...W.quarantinedFiles),B.jobIds.push(...W.jobIds);let K=Math.min(Z+w,Y),U=Math.round(K/Y*40);await Q.report({progress:U,message:`Imported ${K}/${Y} files`})}return B}async exportEntitiesWithProgress(A,Q,w,$){this.logger.debug("Exporting entities with progress reporting");let B=A??this.entityService.getEntityTypes();await Q.report({progress:50,message:`Starting export of ${B.length} entity types`});let X=await $(A);return await Q.report({progress:100,message:`Exported ${X.exported} entities`}),this.logger.debug("Export completed",X),X}}fA();import{rename as h0w,appendFile as C0w,readFile as g0w,writeFile as y0w,access as E0w}from"fs/promises";import{join as Dy1}from"path";class Di0{logger;syncPath;constructor(A,Q){this.logger=A,this.syncPath=Q}isValidationError(A){return _20(A)}async quarantineInvalidFile(A,Q,w,$){let B=$(A),X=`${B}.invalid`;try{await h0w(B,X),w.quarantined++,w.quarantinedFiles.push(A);let Y=Dy1(this.syncPath,".import-errors.log"),Z=new Date().toISOString(),H=dA(Q),W=`${Z} - ${A}: ${H}
5735
5735
  \u2192 ${A}.invalid
@@ -5758,7 +5758,7 @@ ${hC1}</style></head><body>${Yr(A)}<main id="root" data-web-chat-root>Brain Chat
5758
5758
  *...and ${A.files.length-10} more files*`)}if(A.exists&&A.stats.totalFiles===0)Q.push(`
5759
5759
  ## Getting Started
5760
5760
  `),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(`
5761
- `)}}fA();class n40 extends D6{directorySync;constructor(A,Q,w){super(A,{schema:zd0,jobTypeName:"directory-export"});this.directorySync=w}async process(A,Q,w){this.logger.debug("Processing directory export job",{jobId:Q,data:A});let $=Date.now();try{let B=await this.directorySync.exportEntitiesWithProgress(A.entityTypes,w,A.batchSize??100);return this.logger.debug("Directory export job completed",{jobId:Q,exported:B.exported,failed:B.failed,duration:Date.now()-$}),B}catch(B){throw this.logger.error("Directory export job failed",{jobId:Q,error:B}),B}}summarizeDataForLog(A){return{entityTypes:A.entityTypes??"all",batchSize:A.batchSize}}}fA();class r40 extends D6{directorySync;constructor(A,Q,w){super(A,{schema:qd0,jobTypeName:"directory-import"});this.directorySync=w}async process(A,Q,w){this.logger.debug("Processing directory import job",{jobId:Q,data:A});let $=Date.now();try{let B=await this.directorySync.importEntitiesWithProgress(A.paths,w,A.batchSize??100);return this.logger.debug("Directory import job completed",{jobId:Q,imported:B.imported,skipped:B.skipped,failed:B.failed,quarantined:B.quarantined,duration:Date.now()-$}),B}catch(B){throw this.logger.error("Directory import job failed",{jobId:Q,error:B}),B}}summarizeDataForLog(A){return{pathCount:A.paths?.length??"all",batchSize:A.batchSize}}}fA();class o40 extends D6{directorySync;context;constructor(A,Q,w){super(A,{schema:Gd0,jobTypeName:"directory-sync"});this.context=Q,this.directorySync=w}async process(A,Q,w){let $=Date.now(),B=A.syncDirection??"both";this.logger.info("Starting directory sync job",{jobId:Q,operation:A.operation,syncDirection:B});let X={imported:0,skipped:0,failed:0,quarantined:0,quarantinedFiles:[],errors:[],jobIds:[]},Y={exported:0,failed:0,errors:[]};if(B!=="export")if(await w.report({progress:10,message:"Scanning directory for changes"}),X=await this.importWithProgress(A.paths,w),B==="import")await this.waitForImportJobs(X.jobIds,w),await w.report({progress:100,message:`Import complete: ${X.imported} imported`});else await w.report({progress:50,message:`Imported ${X.imported} entities`}),await this.waitForImportJobs(X.jobIds,w),await w.report({progress:56,message:"Processing complete, starting export"});if(B!=="import"){let H=B==="export"?10:60;await w.report({progress:H,message:"Exporting entities to directory"}),Y=await this.exportWithProgress(A.entityTypes,w),await w.report({progress:100,message:B==="export"?`Export complete: ${Y.exported} exported`:`Sync complete: ${X.imported} imported, ${Y.exported} exported`})}let Z=Date.now()-$;return this.logger.info("Directory sync job completed",{jobId:Q,duration:Z,imported:X.imported,exported:Y.exported}),{import:X,export:Y,duration:Z}}async importWithProgress(A,Q){try{return await this.directorySync.importEntitiesWithProgress(A,Q,10)}catch(w){throw this.logger.error("Import phase failed",{error:w}),w}}async exportWithProgress(A,Q){try{return await this.directorySync.exportEntitiesWithProgress(A,Q,10)}catch(w){throw this.logger.error("Export phase failed",{error:w}),w}}async waitForImportJobs(A,Q){if(A.length===0)return;this.logger.debug(`Waiting for ${A.length} import jobs to complete`);let{entityService:w}=this.context,$=300000,B=500,X=Date.now(),Y=async()=>{let H=(await Promise.all(A.map((K)=>w.getAsyncJobStatus(K)))).filter((K)=>K&&(K.status==="completed"||K.status==="failed")).length;if(H===A.length){this.logger.debug("All import jobs completed");return}if(Date.now()-X>$){this.logger.warn(`Timeout waiting for import jobs (${H}/${A.length} completed)`);return}let W=Math.round(H/A.length*100);return await Q.report({progress:50+Math.round(W*0.05),message:`Processing ${H}/${A.length} entities`}),await new Promise((K)=>setTimeout(K,B)),Y()};return Y()}summarizeDataForLog(A){return{operation:A.operation,syncDirection:A.syncDirection}}}fA();class s40 extends D6{context;directorySync;gitSync;constructor(A,Q,w,$){super(A,{schema:Dd0,jobTypeName:"sync-request"});this.context=Q,this.directorySync=w,this.gitSync=$}async process(A,Q,w){await w.report({progress:5,message:"Pulling latest content from git"});let $=await this.gitSync.withLock(async()=>{return await this.gitSync.pull(),await w.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(!$)return await w.report({progress:100,message:"Sync complete: no files to import"}),{gitPulled:!0,batchQueued:!1};return await w.report({progress:100,message:`Sync queued: ${$.importOperationsCount} import jobs for ${$.totalFiles} files`}),Qww($)}summarizeDataForLog(A){return{source:A.source,interfaceType:A.interfaceType,channelId:A.channelId}}}function Qww(A){return{gitPulled:!0,batchQueued:!0,batchId:A.batchId,importOperations:A.importOperationsCount,totalFiles:A.totalFiles}}fA();class a40 extends D6{context;constructor(A,Q,w){super(A,{schema:i40,jobTypeName:"directory-delete"});this.context=Q}async process(A,Q,w){let $=i40.parse(A);this.logger.info("Processing entity deletion for removed file",{entityId:$.entityId,entityType:$.entityType,filePath:$.filePath}),await w.report({progress:0,total:1,message:`Deleting ${$.entityType}:${$.entityId}`});try{let B=await this.context.entityService.deleteEntity({entityType:$.entityType,id:$.entityId});if(B)this.logger.info("Successfully deleted entity for removed file",{entityId:$.entityId,entityType:$.entityType});else this.logger.warn("Entity not found in database",{entityId:$.entityId,entityType:$.entityType});return await w.report({progress:1,total:1,message:`Deleted ${$.entityType}:${$.entityId}`}),{deleted:B,entityId:$.entityId,entityType:$.entityType,filePath:$.filePath}}catch(B){throw this.logger.error("Failed to delete entity",{entityId:$.entityId,entityType:$.entityType,error:B}),B}}summarizeDataForLog(A){return{entityId:A.entityId,entityType:A.entityType,filePath:A.filePath}}}fA();C0();var www=f.object({});class t40 extends D6{directorySync;constructor(A,Q){super(A,{schema:www,jobTypeName:"directory-cleanup"});this.directorySync=Q}async process(A,Q,w){await w.report({progress:0,message:"Removing orphaned entities"});let $=await this.directorySync.removeOrphanedEntities();return await w.report({progress:100,message:`Cleanup complete: ${$.deleted} orphans removed`}),$}}fA();p4();H7();e6();C0();p4();import{readFile as $ww,writeFile as Bww}from"fs/promises";var Xww=Vd0,Yww=f.record(f.string(),f.unknown());class e40 extends D6{context;fetcher;constructor(A,Q,w=JW){super(Q,{schema:Xww,jobTypeName:"cover-image-convert"});this.context=A,this.fetcher=w}async process(A,Q,w){let{filePath:$,sourceUrl:B,postTitle:X,postSlug:Y,customAlt:Z}=A;this.logger.debug("Starting image conversion job",{jobId:Q,filePath:$,sourceUrl:B,postSlug:Y});try{await this.reportProgress(w,{progress:Yw.INIT,message:`Reading file: ${$}`});let H;try{H=await $ww($,"utf-8")}catch(J){return this.logger.error("Failed to read file",{filePath:$,error:dA(J)}),k8.failure(J)}let W;try{W=l6(H)}catch(J){return this.logger.warn("Failed to parse markdown",{filePath:$,error:dA(J)}),k8.failure(J)}let K=Yww.safeParse(W.frontmatter),U=K.success?K.data:{};if(U.coverImageId)return this.logger.debug("File already has coverImageId, skipping",{filePath:$}),await this.reportProgress(w,{progress:Yw.COMPLETE,message:"Already converted"}),{success:!0,skipped:!0};await this.reportProgress(w,{progress:Yw.FETCH,message:"Checking for existing image"});let G=await this.context.entityService.listEntities({entityType:"image",options:{filter:{metadata:{sourceUrl:B}},limit:1}}),q;if(G[0])q=G[0].id,this.logger.debug("Reusing existing image entity",{sourceUrl:B,imageId:q}),await this.reportProgress(w,{progress:Yw.EXTRACT,message:`Reusing existing image: ${q}`});else{await this.reportProgress(w,{progress:Yw.PROCESS,message:`Fetching image from ${B}`});let J;try{J=await this.fetcher(B)}catch(O){return this.logger.error("Failed to fetch image",{sourceUrl:B,error:dA(O)}),k8.failure(O)}await this.reportProgress(w,{progress:Yw.GENERATE,message:"Creating image entity"});let{base64:k}=iI(J),j=a_(k),_=dI(k);if(!j||!_)return this.logger.error("Could not detect image format or dimensions",{sourceUrl:B}),k8.failure(Error("Could not detect image format or dimensions"));q=`${Y}-cover`;let x=`Cover image for ${X}`,v=Z??x;await this.context.entityService.createEntity({entity:{id:q,entityType:"image",content:J,metadata:{title:x,alt:v,format:j,width:_.width,height:_.height,sourceUrl:B}}}),this.logger.debug("Created image entity",{imageId:q,sourceUrl:B}),await this.reportProgress(w,{progress:Yw.EXTRACT,message:`Created image: ${q}`})}await this.reportProgress(w,{progress:Yw.SAVE,message:"Updating file"});let V={...U};delete V.coverImageUrl,delete V.coverImageAlt,V.coverImageId=q;let I=F_(V,W.content);try{await Bww($,I,"utf-8")}catch(J){return this.logger.error("Failed to write file",{filePath:$,error:dA(J)}),k8.failure(J)}return await this.reportProgress(w,{progress:Yw.COMPLETE,message:"Conversion complete"}),this.logger.info("Image conversion complete",{filePath:$,imageId:q,sourceUrl:B}),{success:!0,imageId:q}}catch(H){return this.logger.error("Image conversion job failed",{jobId:Q,filePath:$,error:dA(H)}),k8.failure(H)}}summarizeDataForLog(A){return{filePath:A.filePath,sourceUrl:A.sourceUrl,postSlug:A.postSlug}}}fA();p4();e6();import{readFile as Zww,writeFile as fww}from"fs/promises";class AX0 extends D6{converter;constructor(A,Q,w=JW){super(Q,{schema:Jd0,jobTypeName:"inline-image-convert"});this.converter=new Gr(A.entityService,Q,w)}async process(A,Q,w){let{filePath:$,postSlug:B}=A;this.logger.debug("Starting inline image conversion job",{jobId:Q,filePath:$,postSlug:B});try{await this.reportProgress(w,{progress:Yw.INIT,message:`Reading file: ${$}`});let X;try{X=await Zww($,"utf-8")}catch(H){let W=dA(H);return this.logger.error("Failed to read file",{filePath:$,error:W}),{success:!1,error:W}}await this.reportProgress(w,{progress:Yw.FETCH,message:"Detecting inline images"});let Y=this.converter.detectInlineImages(X,B);if(Y.length===0)return this.logger.debug("No inline images to convert",{filePath:$}),await this.reportProgress(w,{progress:Yw.COMPLETE,message:"No images to convert"}),{success:!0,skipped:!0,convertedCount:0};this.logger.debug("Found inline images to convert",{filePath:$,count:Y.length}),await this.reportProgress(w,{progress:Yw.PROCESS,message:`Converting ${Y.length} images`});let Z=await this.converter.convert(X,B);if(!Z.converted)return this.logger.debug("No images were converted",{filePath:$}),await this.reportProgress(w,{progress:Yw.COMPLETE,message:"No images converted"}),{success:!0,skipped:!0,convertedCount:0};await this.reportProgress(w,{progress:Yw.SAVE,message:"Writing updated file"});try{await fww($,Z.content,"utf-8")}catch(H){let W=dA(H);return this.logger.error("Failed to write file",{filePath:$,error:W}),{success:!1,error:W}}return await this.reportProgress(w,{progress:Yw.COMPLETE,message:"Conversion complete"}),this.logger.info("Inline image conversion complete",{filePath:$,convertedCount:Z.convertedCount}),{success:!0,convertedCount:Z.convertedCount}}catch(X){let Y=dA(X);return this.logger.error("Inline image conversion job failed",{jobId:Q,filePath:$,error:Y}),{success:!1,error:Y}}}summarizeDataForLog(A){return{filePath:A.filePath,postSlug:A.postSlug}}}function tS1(A,Q,w){let $=(B)=>w.child(B);A.jobs.registerHandler("directory-sync",new o40($("DirectorySyncJobHandler"),A,Q)),A.jobs.registerHandler("directory-export",new n40($("DirectoryExportJobHandler"),A,Q)),A.jobs.registerHandler("directory-import",new r40($("DirectoryImportJobHandler"),A,Q)),A.jobs.registerHandler("directory-delete",new a40($("DirectoryDeleteJobHandler"),A,Q)),A.jobs.registerHandler("directory-cleanup",new t40($("DirectoryCleanupJobHandler"),Q)),A.jobs.registerHandler("cover-image-convert",new e40(A,$("CoverImageConversionJobHandler"))),A.jobs.registerHandler("inline-image-convert",new AX0(A,$("InlineImageConversionJobHandler"))),w.debug("Registered async job handlers")}fA();C0();import{unlink as Hww,access as Www}from"fs/promises";var Kww=f.record(f.string(),f.unknown());function eS1(A,Q,w,$){let{subscribe:B}=A.messaging,{entityService:X}=A;B("entity:created",async(Y)=>{let{entity:Z}=Y.payload;try{await Q.fileOps.writeEntity(Z),w.debug("Auto-exported created entity",{id:Z.id,entityType:Z.entityType})}catch(H){w.error("Auto-export FAILED for created entity",{id:Z.id,entityType:Z.entityType,error:H instanceof Error?H.message:String(H),stack:H instanceof Error?H.stack:void 0})}return{success:!0}}),B("entity:updated",async(Y)=>{let{entityType:Z,entityId:H}=Y.payload;try{let W=await X.getEntity({entityType:Z,id:H});if(!W)return w.debug("Entity not found in DB, skipping export",{entityType:Z,entityId:H}),{success:!1};await Q.fileOps.writeEntity(W),w.debug("Auto-exported updated entity",{id:W.id,entityType:W.entityType})}catch(W){w.error("Auto-export FAILED for updated entity",{entityType:Z,entityId:H,error:W instanceof Error?W.message:String(W),stack:W instanceof Error?W.stack:void 0})}return{success:!0}}),B("entity:deleted",async(Y)=>{let{entityId:Z,entityType:H}=Y.payload,W=Q.fileOps.getFilePath(Z,H);if(await Www(W).then(()=>!0,()=>!1))await Hww(W),w.debug("Auto-deleted entity file",{id:Z,entityType:H,path:W});return{success:!0}}),w.debug("Setup auto-sync for entity events",{entityTypes:$})}function Am1(A,Q,w){Q.setJobQueueCallback(async($)=>{let B=[{type:$.type,data:Kww.parse($.data)}];return A.jobs.enqueueBatch(B,{priority:5,source:"directory-sync-watcher",rootJobId:v4(),metadata:{operationType:"file_operations",operationTarget:w,pluginId:"directory-sync"}})})}fA();import{readdir as $m1,mkdir as Gww,copyFile as Dww}from"fs/promises";import{join as wm1,resolve as Id0}from"path";import{join as Uww}from"path";async function Qm1(A){if(!await q5(Uww(A,".git")))return!1;try{return await cU(A).revparse(["--verify","HEAD"]),!0}catch{return!1}}async function qww(A,Q){if(!await q5(A))return!0;if((await $m1(A)).filter((B)=>!B.startsWith(".")&&!B.startsWith("_")).length>0)return!1;if(await Qm1(A))return Q.debug("Git repository with history detected - skipping seed content",{path:A}),!1;return!0}async function Bm1(A,Q){let w=await $m1(A,{withFileTypes:!0});for(let $ of w){let B=wm1(A,$.name),X=wm1(Q,$.name);if($.isDirectory()){if(!await q5(X))await Gww(X,{recursive:!0});await Bm1(B,X)}else await Dww(B,X)}}async function Xm1(A,Q,w){let $=Id0(process.cwd(),A);w=w?Id0(w):Id0(process.cwd(),"seed-content");let B=await qww($,Q);if(B&&await q5(w))Q.debug("Copying seed content to brain-data directory"),await Bm1(w,$),Q.debug("Seed content copied successfully");else if(B)Q.debug("No seed content directory found, starting with empty brain-data");else Q.debug("brain-data directory not empty, skipping seed content")}function Ym1(A,Q,w,$,B){let X=!1,Y=async()=>{if(X)return;X=!0;let Z=Q();if(w.seedContent){let H=w.syncPath??A.dataDir;await Xm1(H,$,w.seedContentPath)}try{if(B){$.debug("Git enabled \u2014 pulling before import");let W=await B.pull();if(W.files.length>0)$.info("Pulled changes from remote",{filesChanged:W.files.length})}$.debug("Starting initial sync");let H=await Z.sync();$.debug("Initial sync completed",{imported:H.import.imported,failed:H.import.failed,duration:H.duration}),await A.messaging.send({type:__.initialSyncCompleted,payload:{success:!0},...{broadcast:!0}})}catch(H){$.error("Initial sync failed",H),await A.messaging.send({type:__.initialSyncCompleted,payload:{success:!1,error:dA(H)},...{broadcast:!0}})}};A.messaging.subscribe(__.pluginsRegistered,async()=>{return $.debug("Plugins registered, starting initial sync"),await Y(),{success:!0}})}class Fd0{fn;delayMs;timeout;pending=!1;constructor(A,Q){this.fn=A,this.delayMs=Q}trigger(){if(!this.timeout){this.fn(),this.timeout=setTimeout(()=>{if(this.timeout=void 0,this.pending)this.pending=!1,this.fn()},this.delayMs);return}this.pending=!0,clearTimeout(this.timeout),this.timeout=setTimeout(()=>{if(this.timeout=void 0,this.pending)this.pending=!1,this.fn()},this.delayMs)}dispose(){if(this.timeout)clearTimeout(this.timeout),this.timeout=void 0;this.pending=!1}}class bd0{fn;delayMs;timeout;constructor(A,Q){this.fn=A,this.delayMs=Q}trigger(){if(this.timeout)clearTimeout(this.timeout);this.timeout=setTimeout(()=>{this.timeout=void 0,this.fn()},this.delayMs)}dispose(){if(this.timeout)clearTimeout(this.timeout),this.timeout=void 0}}function Zm1(A,Q,w,$){let B=new bd0(()=>{Q.withLock(async()=>{try{await Q.commit(),await Q.push()}catch(Z){$.error("Git auto-commit failed",{error:Z})}})},w),X=["entity:created","entity:updated","entity:deleted"],Y=[];for(let Z of X){let H=A.subscribe(Z,async()=>{return B.trigger(),{success:!0}});Y.push(H)}return()=>{B.dispose();for(let Z of Y)Z()}}function fm1(A,Q,w,$,B){if($<=0)return()=>{};let X=$*60*1000,Y=!1,Z=async()=>{if(Y)return;Y=!0;try{let{files:W,result:K}=await A.withLock(async()=>{let U=await A.pull();if(U.files.length===0)return{files:[],result:null};let G=await Q.queueSyncBatch(w,"periodic-sync");return{files:U.files,result:G}});if(W.length>0)B.info("Periodic sync: pulled changes",{filesChanged:W.length});if(K)B.debug("Periodic sync: queued imports",{importOperations:K.importOperationsCount,totalFiles:K.totalFiles})}catch(W){B.error("Periodic git sync failed",{error:W})}finally{Y=!1}},H=setInterval(()=>{Z()},X);return B.info("Started periodic git sync",{intervalMinutes:$}),()=>{clearInterval(H)}}import{spawnSync as Wm1}from"child_process";import{cpSync as zww,existsSync as Hm1,mkdirSync as Vww,mkdtempSync as Jww,rmSync as Iww}from"fs";import{tmpdir as Fww}from"os";import{fileURLToPath as bww}from"url";import{join as Lww,resolve as kww}from"path";function mb(A,Q){let w=Wm1("git",Q,{cwd:A,stdio:"pipe"});if(w.status!==0){let $=w.stderr.toString().trim(),B=w.stdout.toString().trim();throw Error($||B||`git ${Q.join(" ")} failed`)}}function _ww(A){return A.startsWith("file://")}function Nww(A){return bww(A)}function jww(A,Q){return Wm1("git",["--git-dir",A,"show-ref","--verify","--quiet",`refs/heads/${Q}`]).status===0}async function Km1(A){if(!A.bootstrapFromSeed)return;if(!A.gitUrl||!_ww(A.gitUrl))return;if(!A.seedContentPath)throw Error("directory-sync git.bootstrapFromSeed requires seedContentPath for local file:// remotes");let Q=A.branch??"main",w=Nww(A.gitUrl),$=kww(A.seedContentPath);if(!Hm1($))throw Error(`Seed content path not found: ${$}`);if(!Hm1(w))A.logger.debug("Creating local bare content remote",{remotePath:w,branch:Q}),Vww(w,{recursive:!0}),mb(process.cwd(),["init","--bare",`--initial-branch=${Q}`,w]);if(jww(w,Q)){A.logger.debug("Content remote already initialized",{remotePath:w,branch:Q});return}A.logger.debug("Seeding local content remote",{remotePath:w,seedPath:$,branch:Q});let B=Jww(Lww(Fww(),"directory-sync-seed-"));try{mb(B,["init",`--initial-branch=${Q}`]),mb(B,["config","user.name",A.authorName??"Brain"]),mb(B,["config","user.email",A.authorEmail??"brain@localhost"]),zww($,B,{recursive:!0}),mb(B,["add","."]),mb(B,["commit","-m","seed content remote"]),mb(B,["remote","add","origin",A.gitUrl]),mb(B,["push","-u","origin",Q])}finally{Iww(B,{recursive:!0,force:!0})}}function Um1(A,Q,w,$,B,X){let{subscribe:Y}=A.messaging;Y("entity:export:request",async(Z)=>{try{return{success:!0,data:await Q().exportEntities(Z.payload.entityTypes)}}catch(H){return{success:!1,error:H instanceof Error?H.message:"Export failed"}}}),Y("entity:import:request",async(Z)=>{try{let H=Q(),W=Z.payload.paths,K=await H.importEntities(W);if(W&&W.length>0)await H.removeOrphanedEntities();return{success:!0,data:K}}catch(H){return{success:!1,error:H instanceof Error?H.message:"Import failed"}}}),Y("sync:status:request",async()=>{try{let H=await Q().getStatus();return{success:!0,data:{syncPath:H.syncPath,isInitialized:H.exists,watchEnabled:H.watching,lastSync:H.lastSync?.toISOString()??null,totalFiles:H.stats.totalFiles,byEntityType:H.stats.byEntityType,git:await Pww(X?.(),$)}}}catch(Z){return{success:!1,error:Z instanceof Error?Z.message:"Status check failed"}}}),Y("sync:configure:request",async(Z)=>{try{return await w({syncPath:Z.payload.syncPath}),{success:!0,data:{syncPath:Z.payload.syncPath,configured:!0}}}catch(H){return{success:!1,error:H instanceof Error?H.message:"Configuration failed"}}}),Y("git-sync:get-repo-info",async()=>{if(!B?.repo)return{success:!1,error:"Git not configured"};return{success:!0,data:{repo:B.repo,branch:B.branch??"main"}}}),$.debug("Registered message handlers")}async function Pww(A,Q){if(!A)return null;try{let w=await A.getStatus();return{branch:w.branch,hasChanges:w.hasChanges,ahead:w.ahead,behind:w.behind,lastCommit:w.lastCommit??null,remote:w.remote??null}}catch(w){return Q.debug("Git status unavailable for sync:status:request",{error:w}),null}}fA();C0();fA();C0();function Gm1(A,Q){return p6(A,"history","Get version history for an entity from git. Without sha: returns commit list. With sha: returns entity content at that version.",f.object({entityType:f.string().describe("Entity type (e.g. post, note, link)"),id:f.string().describe("Entity ID"),sha:f.string().optional().describe("Commit SHA to retrieve content at. Omit to list commit history."),limit:f.number().int().positive().optional().default(10).describe("Max commits to return (list mode only)")}),async(w)=>{let $=`${w.entityType}/${w.id}.md`;try{if(w.sha){let X=await Q.show(w.sha,$);return u5({sha:w.sha,entityType:w.entityType,id:w.id,content:X},`Content at ${w.sha.slice(0,7)}`)}let B=await Q.log($,w.limit);if(B.length===0)return u5({commits:[]},`No history found for ${w.entityType}/${w.id}`);return u5({commits:B,entityType:w.entityType,id:w.id},`${B.length} version${B.length===1?"":"s"} found`)}catch(B){return d7(B instanceof Error?B.message:"History lookup failed")}},{visibility:"anchor",sideEffects:"none"})}function Dm1(A,Q,w,$){let B=[p6(w,"sync","Sync brain entities with the filesystem. Use this for refresh, pull, sync, or backup-to-git requests. Pulls from git if configured, then imports files. Git commit and push happen automatically after imports complete.",f.object({}),async(X,Y)=>{try{let Z=Y.channelId?`${Y.interfaceType}:${Y.channelId}`:`plugin:${w}`,H={interfaceType:Y.interfaceType,channelId:Y.channelId};if($){let K=await Q.jobs.enqueue({type:"sync-request",data:{source:Z,interfaceType:H.interfaceType,channelId:H.channelId},toolContext:Y});return u5({jobId:K,status:"queued",gitPulled:!0},"Sync queued: git pull and filesystem scan will run in the background")}let W=await A.queueSyncBatch(Q,Z,H);if(!W)return u5({gitPulled:!1},"No files to sync");return u5({batchId:W.batchId,importOperations:W.importOperationsCount,totalFiles:W.totalFiles,gitPulled:!1},`Sync started: ${W.importOperationsCount} import jobs queued for ${W.totalFiles} files`)}catch(Z){return d7(Z instanceof Error?Z.message:"Sync failed")}},{visibility:"anchor",sideEffects:"external",cli:{name:"sync"}}),p6(w,"status","Read directory and git sync status: last sync, watcher state, and pending git changes. Use this for every status follow-up after directory-sync_sync, even when that call returned a jobId; a sync jobId is not a system_job_status batchId.",f.object({}),async()=>{try{let X=await A.getStatus(),Y={syncPath:X.syncPath,lastSync:X.lastSync?.toISOString(),watching:X.watching};if($){let Z=await $.getStatus();Y.git={isRepo:Z.isRepo,branch:Z.branch,hasChanges:Z.hasChanges,ahead:Z.ahead,behind:Z.behind,remote:Z.remote}}return u5(Y)}catch(X){return d7(X instanceof Error?X.message:"Status check failed")}},{visibility:"anchor",sideEffects:"none"})];if($)B.push(Gm1(w,$));return B}var qm1={name:"@brains/directory-sync",version:"0.2.0-alpha.158",description:"Directory-based entity synchronization plugin for Brains",dependencies:{"@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/image":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*",chokidar:"^5.0.0","simple-git":"^3.36.0"},devDependencies:{"@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14","@types/node":"^20.19.43",typescript:"^7.0.2"},exports:{".":{types:"./src/index.ts",import:"./src/index.ts"},"./env-schema":"./src/env-schema.ts"},main:"./src/index.ts",peerDependencies:{},private:!0,scripts:{clean:"rm -rf .turbo",lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module",types:"./src/index.ts"};class Ld0 extends Kw{directorySync;gitSync;gitCleanups=[];constructor(A={}){super("directory-sync",qm1,A,jr)}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:w}=A;A.templates.register({status:{name:"status",description:"Directory synchronization status",schema:Pr,basePrompt:"",formatter:new d40,requiredPermission:"anchor"}});let $=this.config.syncPath??A.dataDir;this.directorySync=new Dr({syncPath:$,autoSync:this.config.autoSync,watchInterval:this.config.watchInterval,includeMetadata:this.config.includeMetadata,entityTypes:this.config.entityTypes,deleteOnFileRemoval:this.config.deleteOnFileRemoval,entityService:w,logger:Q});try{await this.directorySync.initializeDirectory(),this.logger.debug("Directory structure initialized",{path:$})}catch(Y){throw this.logger.error("Failed to initialize directory",Y),Y}await this.registerJobHandlers(A);let B=this.requireDirectorySync();if(eS1(A,B,this.logger,this.config.entityTypes),this.config.autoSync)Am1(A,B,this.config.syncPath??A.dataDir);let X=this.config.git!==void 0&&(this.config.git.repo!==void 0||this.config.git.gitUrl!==void 0);if(this.config.git&&!X)this.logger.debug("Git block present but no repo/gitUrl configured \u2014 git sync disabled");if(X&&this.config.git){await Km1({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 Y=this.config.syncPath??A.dataDir;if(this.gitSync=new Ud0({logger:this.logger.child("GitSync"),dataDir:Y,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 s40(this.logger.child("DirectorySyncRequestJobHandler"),A,this.requireDirectorySync(),this.gitSync)),this.gitCleanups.push(Zm1(A.messaging,this.gitSync,this.config.commitDebounce,this.logger.child("GitAutoCommit"))),this.config.autoSync)this.gitCleanups.push(fm1(this.gitSync,this.requireDirectorySync(),A,this.config.syncInterval,this.logger.child("GitPeriodicSync")))}if(this.config.initialSync)Ym1(A,()=>this.requireDirectorySync(),this.config,this.logger,this.gitSync);Um1(A,()=>this.requireDirectorySync(),(Y)=>this.configure(Y),this.logger,this.config.git,()=>this.gitSync)}async getTools(){let A=this.requireDirectorySync();return Dm1(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 Dr({...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){tS1(A,this.requireDirectorySync(),this.logger)}}function UP(A={}){return new Ld0(A)}fA();C0();var zm1={name:"@brains/email-resend",version:"0.2.0-alpha.158",description:"Generic email delivery adapter for Resend",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":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts","./env-schema":"./src/env-schema.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var xww=f.object({apiKey:f.string().min(1).optional(),from:f.string().min(1).optional()}),Rww=f.looseObject({id:f.string().optional()});class Vm1 extends Kw{fetchImpl;constructor(A={},Q={}){super("email-resend",zm1,A,xww);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(wB0,async(w)=>{let $=VcA.parse(w.payload);try{return{success:!0,data:await this.sendWithResend($)}}catch(B){if($.sensitivity==="secret")Q.warn("Email delivery failed for a secret message");else Q.warn("Email delivery failed",{to:$.to,subject:$.subject,error:B instanceof Error?B.message:String(B)});return{success:!1,error:"Email delivery failed"}}})}async sendWithResend(A){let Q=this.config.apiKey,w=this.config.from;if(!Q||!w)return{status:"failed"};let $=await this.fetchImpl("https://api.resend.com/emails",{method:"POST",headers:{Authorization:`Bearer ${Q}`,"Content-Type":"application/json"},body:JSON.stringify({from:w,to:A.to,subject:A.subject,text:A.text,...A.html?{html:A.html}:{}})});if(!$.ok)throw Error("Resend email request failed");let B=Rww.parse(await $.json());return B.id?{status:"sent",id:B.id}:{status:"sent"}}}function QX0(A={}){return new Vm1(A)}fA();import{render as $12}from"preact-render-to-string";import{h as rP}from"preact";function Jm1(A){var Q,w,$="";if(typeof A=="string"||typeof A=="number")$+=A;else if(typeof A=="object")if(Array.isArray(A)){var B=A.length;for(Q=0;Q<B;Q++)A[Q]&&(w=Jm1(A[Q]))&&($&&($+=" "),$+=w)}else for(w in A)A[w]&&($&&($+=" "),$+=w);return $}function fy(){for(var A,Q,w=0,$="",B=arguments.length;w<B;w++)(A=arguments[w])&&(Q=Jm1(A))&&($&&($+=" "),$+=Q);return $}var vww=(A,Q)=>{let w=Array(A.length+Q.length);for(let $=0;$<A.length;$++)w[$]=A[$];for(let $=0;$<Q.length;$++)w[A.length+$]=Q[$];return w},hww=(A,Q)=>({classGroupId:A,validator:Q}),jm1=(A=new Map,Q=null,w)=>({nextPart:A,validators:Q,classGroupId:w});var Im1=[];var Cww=(A)=>{let Q=yww(A),{conflictingClassGroups:w,conflictingClassGroupModifiers:$}=A;return{getClassGroupId:(Y)=>{if(Y.startsWith("[")&&Y.endsWith("]"))return gww(Y);let Z=Y.split("-"),H=Z[0]===""&&Z.length>1?1:0;return Pm1(Z,H,Q)},getConflictingClassGroupIds:(Y,Z)=>{if(Z){let H=$[Y],W=w[Y];if(H){if(W)return vww(W,H);return H}return W||Im1}return w[Y]||Im1}}},Pm1=(A,Q,w)=>{if(A.length-Q===0)return w.classGroupId;let B=A[Q],X=w.nextPart.get(B);if(X){let W=Pm1(A,Q+1,X);if(W)return W}let Y=w.validators;if(Y===null)return;let Z=Q===0?A.join("-"):A.slice(Q).join("-"),H=Y.length;for(let W=0;W<H;W++){let K=Y[W];if(K.validator(Z))return K.classGroupId}return},gww=(A)=>A.slice(1,-1).indexOf(":")===-1?void 0:(()=>{let Q=A.slice(1,-1),w=Q.indexOf(":"),$=Q.slice(0,w);return $?"arbitrary.."+$:void 0})(),yww=(A)=>{let{theme:Q,classGroups:w}=A;return Eww(w,Q)},Eww=(A,Q)=>{let w=jm1();for(let $ in A){let B=A[$];Nd0(B,w,$,Q)}return w},Nd0=(A,Q,w,$)=>{let B=A.length;for(let X=0;X<B;X++){let Y=A[X];Tww(Y,Q,w,$)}},Tww=(A,Q,w,$)=>{if(typeof A==="string"){Sww(A,Q,w);return}if(typeof A==="function"){mww(A,Q,w,$);return}uww(A,Q,w,$)},Sww=(A,Q,w)=>{let $=A===""?Q:Mm1(Q,A);$.classGroupId=w},mww=(A,Q,w,$)=>{if(cww(A)){Nd0(A($),Q,w,$);return}if(Q.validators===null)Q.validators=[];Q.validators.push(hww(w,A))},uww=(A,Q,w,$)=>{let B=Object.entries(A),X=B.length;for(let Y=0;Y<X;Y++){let[Z,H]=B[Y];Nd0(H,Mm1(Q,Z),w,$)}},Mm1=(A,Q)=>{let w=A,$=Q.split("-"),B=$.length;for(let X=0;X<B;X++){let Y=$[X],Z=w.nextPart.get(Y);if(!Z)Z=jm1(),w.nextPart.set(Y,Z);w=Z}return w},cww=(A)=>("isThemeGetter"in A)&&A.isThemeGetter===!0,lww=(A)=>{if(A<1)return{get:()=>{return},set:()=>{}};let Q=0,w=Object.create(null),$=Object.create(null),B=(X,Y)=>{if(w[X]=Y,Q++,Q>A)Q=0,$=w,w=Object.create(null)};return{get(X){let Y=w[X];if(Y!==void 0)return Y;if((Y=$[X])!==void 0)return B(X,Y),Y},set(X,Y){if(X in w)w[X]=Y;else B(X,Y)}}};var pww=[],Fm1=(A,Q,w,$,B)=>({modifiers:A,hasImportantModifier:Q,baseClassName:w,maybePostfixModifierPosition:$,isExternal:B}),iww=(A)=>{let{prefix:Q,experimentalParseClassName:w}=A,$=(B)=>{let X=[],Y=0,Z=0,H=0,W,K=B.length;for(let I=0;I<K;I++){let J=B[I];if(Y===0&&Z===0){if(J===":"){X.push(B.slice(H,I)),H=I+1;continue}if(J==="/"){W=I;continue}}if(J==="[")Y++;else if(J==="]")Y--;else if(J==="(")Z++;else if(J===")")Z--}let U=X.length===0?B:B.slice(H),G=U,q=!1;if(U.endsWith("!"))G=U.slice(0,-1),q=!0;else if(U.startsWith("!"))G=U.slice(1),q=!0;let V=W&&W>H?W-H:void 0;return Fm1(X,q,G,V)};if(Q){let B=Q+":",X=$;$=(Y)=>Y.startsWith(B)?X(Y.slice(B.length)):Fm1(pww,!1,Y,void 0,!0)}if(w){let B=$;$=(X)=>w({className:X,parseClassName:B})}return $},dww=(A)=>{let Q=new Map;return A.orderSensitiveModifiers.forEach((w,$)=>{Q.set(w,1e6+$)}),(w)=>{let $=[],B=[];for(let X=0;X<w.length;X++){let Y=w[X],Z=Y[0]==="[",H=Q.has(Y);if(Z||H){if(B.length>0)B.sort(),$.push(...B),B=[];$.push(Y)}else B.push(Y)}if(B.length>0)B.sort(),$.push(...B);return $}},nww=(A)=>({cache:lww(A.cacheSize),parseClassName:iww(A),sortModifiers:dww(A),postfixLookupClassGroupIds:rww(A),...Cww(A)}),rww=(A)=>{let Q=Object.create(null),w=A.postfixLookupClassGroups;if(w)for(let $=0;$<w.length;$++)Q[w[$]]=!0;return Q},oww=/\s+/,sww=(A,Q)=>{let{parseClassName:w,getClassGroupId:$,getConflictingClassGroupIds:B,sortModifiers:X,postfixLookupClassGroupIds:Y}=Q,Z=[],H=A.trim().split(oww),W="";for(let K=H.length-1;K>=0;K-=1){let U=H[K],{isExternal:G,modifiers:q,hasImportantModifier:V,baseClassName:I,maybePostfixModifierPosition:J}=w(U);if(G){W=U+(W.length>0?" "+W:W);continue}let k=!!J,j;if(k){let M=I.substring(0,J);j=$(M);let S=j&&Y[j]?$(I):void 0;if(S&&S!==j)j=S,k=!1}else j=$(I);if(!j){if(!k){W=U+(W.length>0?" "+W:W);continue}if(j=$(I),!j){W=U+(W.length>0?" "+W:W);continue}k=!1}let _=q.length===0?"":q.length===1?q[0]:X(q).join(":"),x=V?_+"!":_,v=x+j;if(Z.indexOf(v)>-1)continue;Z.push(v);let O=B(j,k);for(let M=0;M<O.length;++M){let S=O[M];Z.push(x+S)}W=U+(W.length>0?" "+W:W)}return W},aww=(...A)=>{let Q=0,w,$,B="";while(Q<A.length)if(w=A[Q++]){if($=Om1(w))B&&(B+=" "),B+=$}return B},Om1=(A)=>{if(typeof A==="string")return A;let Q,w="";for(let $=0;$<A.length;$++)if(A[$]){if(Q=Om1(A[$]))w&&(w+=" "),w+=Q}return w},bm1=(A,...Q)=>{let w,$,B,X,Y=(H)=>{let W=Q.reduce((K,U)=>U(K),A());return w=nww(W),$=w.cache.get,B=w.cache.set,X=Z,Z(H)},Z=(H)=>{let W=$(H);if(W)return W;let K=sww(H,w);return B(H,K),K};return X=Y,(...H)=>X(aww(...H))},tww=[],u9=(A)=>{let Q=(w)=>w[A]||tww;return Q.isThemeGetter=!0,Q},xm1=/^\[(?:(\w[\w-]*):)?(.+)\]$/i,Rm1=/^\((?:(\w[\w-]*):)?(.+)\)$/i,eww=/^\d+(?:\.\d+)?\/\d+(?:\.\d+)?$/,A6w=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,Q6w=/\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$/,w6w=/^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/,$6w=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,B6w=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,ub=(A)=>eww.test(A),sw=(A)=>!!A&&!Number.isNaN(Number(A)),Zq=(A)=>!!A&&Number.isInteger(Number(A)),kd0=(A)=>A.endsWith("%")&&sw(A.slice(0,-1)),LV=(A)=>A6w.test(A),vm1=()=>!0,X6w=(A)=>Q6w.test(A)&&!w6w.test(A),jd0=()=>!1,Y6w=(A)=>$6w.test(A),Z6w=(A)=>B6w.test(A),f6w=(A)=>!O2(A)&&!h2(A),H6w=(A)=>A.startsWith("@container")&&(A[10]==="/"&&A[11]!==void 0||A[11]==="s"&&A[16]!==void 0&&A.startsWith("-size/",10)||A[11]==="n"&&A[18]!==void 0&&A.startsWith("-normal/",10)),W6w=(A)=>cb(A,gm1,jd0),O2=(A)=>xm1.test(A),GP=(A)=>cb(A,ym1,X6w),Lm1=(A)=>cb(A,J6w,sw),K6w=(A)=>cb(A,Tm1,vm1),U6w=(A)=>cb(A,Em1,jd0),km1=(A)=>cb(A,hm1,jd0),G6w=(A)=>cb(A,Cm1,Z6w),wX0=(A)=>cb(A,Sm1,Y6w),h2=(A)=>Rm1.test(A),Mr=(A)=>DP(A,ym1),D6w=(A)=>DP(A,Em1),_m1=(A)=>DP(A,hm1),q6w=(A)=>DP(A,gm1),z6w=(A)=>DP(A,Cm1),$X0=(A)=>DP(A,Sm1,!0),V6w=(A)=>DP(A,Tm1,!0),cb=(A,Q,w)=>{let $=xm1.exec(A);if($){if($[1])return Q($[1]);return w($[2])}return!1},DP=(A,Q,w=!1)=>{let $=Rm1.exec(A);if($){if($[1])return Q($[1]);return w}return!1},hm1=(A)=>A==="position"||A==="percentage",Cm1=(A)=>A==="image"||A==="url",gm1=(A)=>A==="length"||A==="size"||A==="bg-size",ym1=(A)=>A==="length",J6w=(A)=>A==="number",Em1=(A)=>A==="family-name",Tm1=(A)=>A==="number"||A==="weight",Sm1=(A)=>A==="shadow";var Nm1=()=>{let A=u9("color"),Q=u9("font"),w=u9("text"),$=u9("font-weight"),B=u9("tracking"),X=u9("leading"),Y=u9("breakpoint"),Z=u9("container"),H=u9("spacing"),W=u9("radius"),K=u9("shadow"),U=u9("inset-shadow"),G=u9("text-shadow"),q=u9("drop-shadow"),V=u9("blur"),I=u9("perspective"),J=u9("aspect"),k=u9("ease"),j=u9("animate"),_=()=>["auto","avoid","all","avoid-page","page","left","right","column"],x=()=>["center","top","bottom","left","right","top-left","left-top","top-right","right-top","bottom-right","right-bottom","bottom-left","left-bottom"],v=()=>[...x(),h2,O2],O=()=>["auto","hidden","clip","visible","scroll"],M=()=>["auto","contain","none"],S=()=>[h2,O2,H],u=()=>[ub,"full","auto",...S()],n=()=>[Zq,"none","subgrid",h2,O2],e=()=>["auto",{span:["full",Zq,h2,O2]},Zq,h2,O2],X0=()=>[Zq,"auto",h2,O2],l=()=>["auto","min","max","fr",h2,O2],P=()=>["start","end","center","between","around","evenly","stretch","baseline","center-safe","end-safe"],y=()=>["start","end","center","stretch","center-safe","end-safe"],g=()=>["auto",...S()],s=()=>[ub,"auto","full","dvw","dvh","lvw","lvh","svw","svh","min","max","fit",...S()],a=()=>[ub,"screen","full","dvw","lvw","svw","min","max","fit",...S()],D0=()=>[ub,"screen","full","lh","dvh","lvh","svh","min","max","fit",...S()],T=()=>[A,h2,O2],f0=()=>[...x(),_m1,km1,{position:[h2,O2]}],b0=()=>["no-repeat",{repeat:["","x","y","space","round"]}],i=()=>["auto","cover","contain",q6w,W6w,{size:[h2,O2]}],u0=()=>[kd0,Mr,GP],i0=()=>["","none","full",W,h2,O2],k0=()=>["",sw,Mr,GP],_0=()=>["solid","dashed","dotted","double"],v0=()=>["normal","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity"],S0=()=>[sw,kd0,_m1,km1],j0=()=>["","none",V,h2,O2],P0=()=>["none",sw,h2,O2],E0=()=>["none",sw,h2,O2],T0=()=>[sw,h2,O2],n0=()=>[ub,"full",...S()];return{cacheSize:500,theme:{animate:["spin","ping","pulse","bounce"],aspect:["video"],blur:[LV],breakpoint:[LV],color:[vm1],container:[LV],"drop-shadow":[LV],ease:["in","out","in-out"],font:[f6w],"font-weight":["thin","extralight","light","normal","medium","semibold","bold","extrabold","black"],"inset-shadow":[LV],leading:["none","tight","snug","normal","relaxed","loose"],perspective:["dramatic","near","normal","midrange","distant","none"],radius:[LV],shadow:[LV],spacing:["px",sw],text:[LV],"text-shadow":[LV],tracking:["tighter","tight","normal","wide","wider","widest"]},classGroups:{aspect:[{aspect:["auto","square",ub,O2,h2,J]}],container:["container"],"container-type":[{"@container":["","normal","size",h2,O2]}],"container-named":[H6w],columns:[{columns:[sw,O2,h2,Z]}],"break-after":[{"break-after":_()}],"break-before":[{"break-before":_()}],"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"],sr:["sr-only","not-sr-only"],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:v()}],overflow:[{overflow:O()}],"overflow-x":[{"overflow-x":O()}],"overflow-y":[{"overflow-y":O()}],overscroll:[{overscroll:M()}],"overscroll-x":[{"overscroll-x":M()}],"overscroll-y":[{"overscroll-y":M()}],position:["static","fixed","absolute","relative","sticky"],inset:[{inset:u()}],"inset-x":[{"inset-x":u()}],"inset-y":[{"inset-y":u()}],start:[{"inset-s":u(),start:u()}],end:[{"inset-e":u(),end:u()}],"inset-bs":[{"inset-bs":u()}],"inset-be":[{"inset-be":u()}],top:[{top:u()}],right:[{right:u()}],bottom:[{bottom:u()}],left:[{left:u()}],visibility:["visible","invisible","collapse"],z:[{z:[Zq,"auto",h2,O2]}],basis:[{basis:[ub,"full","auto",Z,...S()]}],"flex-direction":[{flex:["row","row-reverse","col","col-reverse"]}],"flex-wrap":[{flex:["nowrap","wrap","wrap-reverse"]}],flex:[{flex:[sw,ub,"auto","initial","none",O2]}],grow:[{grow:["",sw,h2,O2]}],shrink:[{shrink:["",sw,h2,O2]}],order:[{order:[Zq,"first","last","none",h2,O2]}],"grid-cols":[{"grid-cols":n()}],"col-start-end":[{col:e()}],"col-start":[{"col-start":X0()}],"col-end":[{"col-end":X0()}],"grid-rows":[{"grid-rows":n()}],"row-start-end":[{row:e()}],"row-start":[{"row-start":X0()}],"row-end":[{"row-end":X0()}],"grid-flow":[{"grid-flow":["row","col","dense","row-dense","col-dense"]}],"auto-cols":[{"auto-cols":l()}],"auto-rows":[{"auto-rows":l()}],gap:[{gap:S()}],"gap-x":[{"gap-x":S()}],"gap-y":[{"gap-y":S()}],"justify-content":[{justify:[...P(),"normal"]}],"justify-items":[{"justify-items":[...y(),"normal"]}],"justify-self":[{"justify-self":["auto",...y()]}],"align-content":[{content:["normal",...P()]}],"align-items":[{items:[...y(),{baseline:["","last"]}]}],"align-self":[{self:["auto",...y(),{baseline:["","last"]}]}],"place-content":[{"place-content":P()}],"place-items":[{"place-items":[...y(),"baseline"]}],"place-self":[{"place-self":["auto",...y()]}],p:[{p:S()}],px:[{px:S()}],py:[{py:S()}],ps:[{ps:S()}],pe:[{pe:S()}],pbs:[{pbs:S()}],pbe:[{pbe:S()}],pt:[{pt:S()}],pr:[{pr:S()}],pb:[{pb:S()}],pl:[{pl:S()}],m:[{m:g()}],mx:[{mx:g()}],my:[{my:g()}],ms:[{ms:g()}],me:[{me:g()}],mbs:[{mbs:g()}],mbe:[{mbe:g()}],mt:[{mt:g()}],mr:[{mr:g()}],mb:[{mb:g()}],ml:[{ml:g()}],"space-x":[{"space-x":S()}],"space-x-reverse":["space-x-reverse"],"space-y":[{"space-y":S()}],"space-y-reverse":["space-y-reverse"],size:[{size:s()}],"inline-size":[{inline:["auto",...a()]}],"min-inline-size":[{"min-inline":["auto",...a()]}],"max-inline-size":[{"max-inline":["none",...a()]}],"block-size":[{block:["auto",...D0()]}],"min-block-size":[{"min-block":["auto",...D0()]}],"max-block-size":[{"max-block":["none",...D0()]}],w:[{w:[Z,"screen",...s()]}],"min-w":[{"min-w":[Z,"screen","none",...s()]}],"max-w":[{"max-w":[Z,"screen","none","prose",{screen:[Y]},...s()]}],h:[{h:["screen","lh",...s()]}],"min-h":[{"min-h":["screen","lh","none",...s()]}],"max-h":[{"max-h":["screen","lh",...s()]}],"font-size":[{text:["base",w,Mr,GP]}],"font-smoothing":["antialiased","subpixel-antialiased"],"font-style":["italic","not-italic"],"font-weight":[{font:[$,V6w,K6w]}],"font-stretch":[{"font-stretch":["ultra-condensed","extra-condensed","condensed","semi-condensed","normal","semi-expanded","expanded","extra-expanded","ultra-expanded",kd0,O2]}],"font-family":[{font:[D6w,U6w,Q]}],"font-features":[{"font-features":[O2]}],"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:[B,h2,O2]}],"line-clamp":[{"line-clamp":[sw,"none",h2,Lm1]}],leading:[{leading:[X,...S()]}],"list-image":[{"list-image":["none",h2,O2]}],"list-style-position":[{list:["inside","outside"]}],"list-style-type":[{list:["disc","decimal","none",h2,O2]}],"text-alignment":[{text:["left","center","right","justify","start","end"]}],"placeholder-color":[{placeholder:T()}],"text-color":[{text:T()}],"text-decoration":["underline","overline","line-through","no-underline"],"text-decoration-style":[{decoration:[..._0(),"wavy"]}],"text-decoration-thickness":[{decoration:[sw,"from-font","auto",h2,GP]}],"text-decoration-color":[{decoration:T()}],"underline-offset":[{"underline-offset":[sw,"auto",h2,O2]}],"text-transform":["uppercase","lowercase","capitalize","normal-case"],"text-overflow":["truncate","text-ellipsis","text-clip"],"text-wrap":[{text:["wrap","nowrap","balance","pretty"]}],indent:[{indent:S()}],"tab-size":[{tab:[Zq,h2,O2]}],"vertical-align":[{align:["baseline","top","middle","bottom","text-top","text-bottom","sub","super",h2,O2]}],whitespace:[{whitespace:["normal","nowrap","pre","pre-line","pre-wrap","break-spaces"]}],break:[{break:["normal","words","all","keep"]}],wrap:[{wrap:["break-word","anywhere","normal"]}],hyphens:[{hyphens:["none","manual","auto"]}],content:[{content:["none",h2,O2]}],"bg-attachment":[{bg:["fixed","local","scroll"]}],"bg-clip":[{"bg-clip":["border","padding","content","text"]}],"bg-origin":[{"bg-origin":["border","padding","content"]}],"bg-position":[{bg:f0()}],"bg-repeat":[{bg:b0()}],"bg-size":[{bg:i()}],"bg-image":[{bg:["none",{linear:[{to:["t","tr","r","br","b","bl","l","tl"]},Zq,h2,O2],radial:["",h2,O2],conic:[Zq,h2,O2]},z6w,G6w]}],"bg-color":[{bg:T()}],"gradient-from-pos":[{from:u0()}],"gradient-via-pos":[{via:u0()}],"gradient-to-pos":[{to:u0()}],"gradient-from":[{from:T()}],"gradient-via":[{via:T()}],"gradient-to":[{to:T()}],rounded:[{rounded:i0()}],"rounded-s":[{"rounded-s":i0()}],"rounded-e":[{"rounded-e":i0()}],"rounded-t":[{"rounded-t":i0()}],"rounded-r":[{"rounded-r":i0()}],"rounded-b":[{"rounded-b":i0()}],"rounded-l":[{"rounded-l":i0()}],"rounded-ss":[{"rounded-ss":i0()}],"rounded-se":[{"rounded-se":i0()}],"rounded-ee":[{"rounded-ee":i0()}],"rounded-es":[{"rounded-es":i0()}],"rounded-tl":[{"rounded-tl":i0()}],"rounded-tr":[{"rounded-tr":i0()}],"rounded-br":[{"rounded-br":i0()}],"rounded-bl":[{"rounded-bl":i0()}],"border-w":[{border:k0()}],"border-w-x":[{"border-x":k0()}],"border-w-y":[{"border-y":k0()}],"border-w-s":[{"border-s":k0()}],"border-w-e":[{"border-e":k0()}],"border-w-bs":[{"border-bs":k0()}],"border-w-be":[{"border-be":k0()}],"border-w-t":[{"border-t":k0()}],"border-w-r":[{"border-r":k0()}],"border-w-b":[{"border-b":k0()}],"border-w-l":[{"border-l":k0()}],"divide-x":[{"divide-x":k0()}],"divide-x-reverse":["divide-x-reverse"],"divide-y":[{"divide-y":k0()}],"divide-y-reverse":["divide-y-reverse"],"border-style":[{border:[..._0(),"hidden","none"]}],"divide-style":[{divide:[..._0(),"hidden","none"]}],"border-color":[{border:T()}],"border-color-x":[{"border-x":T()}],"border-color-y":[{"border-y":T()}],"border-color-s":[{"border-s":T()}],"border-color-e":[{"border-e":T()}],"border-color-bs":[{"border-bs":T()}],"border-color-be":[{"border-be":T()}],"border-color-t":[{"border-t":T()}],"border-color-r":[{"border-r":T()}],"border-color-b":[{"border-b":T()}],"border-color-l":[{"border-l":T()}],"divide-color":[{divide:T()}],"outline-style":[{outline:[..._0(),"none","hidden"]}],"outline-offset":[{"outline-offset":[sw,h2,O2]}],"outline-w":[{outline:["",sw,Mr,GP]}],"outline-color":[{outline:T()}],shadow:[{shadow:["","none",K,$X0,wX0]}],"shadow-color":[{shadow:T()}],"inset-shadow":[{"inset-shadow":["none",U,$X0,wX0]}],"inset-shadow-color":[{"inset-shadow":T()}],"ring-w":[{ring:k0()}],"ring-w-inset":["ring-inset"],"ring-color":[{ring:T()}],"ring-offset-w":[{"ring-offset":[sw,GP]}],"ring-offset-color":[{"ring-offset":T()}],"inset-ring-w":[{"inset-ring":k0()}],"inset-ring-color":[{"inset-ring":T()}],"text-shadow":[{"text-shadow":["none",G,$X0,wX0]}],"text-shadow-color":[{"text-shadow":T()}],opacity:[{opacity:[sw,h2,O2]}],"mix-blend":[{"mix-blend":[...v0(),"plus-darker","plus-lighter"]}],"bg-blend":[{"bg-blend":v0()}],"mask-clip":[{"mask-clip":["border","padding","content","fill","stroke","view"]},"mask-no-clip"],"mask-composite":[{mask:["add","subtract","intersect","exclude"]}],"mask-image-linear-pos":[{"mask-linear":[sw]}],"mask-image-linear-from-pos":[{"mask-linear-from":S0()}],"mask-image-linear-to-pos":[{"mask-linear-to":S0()}],"mask-image-linear-from-color":[{"mask-linear-from":T()}],"mask-image-linear-to-color":[{"mask-linear-to":T()}],"mask-image-t-from-pos":[{"mask-t-from":S0()}],"mask-image-t-to-pos":[{"mask-t-to":S0()}],"mask-image-t-from-color":[{"mask-t-from":T()}],"mask-image-t-to-color":[{"mask-t-to":T()}],"mask-image-r-from-pos":[{"mask-r-from":S0()}],"mask-image-r-to-pos":[{"mask-r-to":S0()}],"mask-image-r-from-color":[{"mask-r-from":T()}],"mask-image-r-to-color":[{"mask-r-to":T()}],"mask-image-b-from-pos":[{"mask-b-from":S0()}],"mask-image-b-to-pos":[{"mask-b-to":S0()}],"mask-image-b-from-color":[{"mask-b-from":T()}],"mask-image-b-to-color":[{"mask-b-to":T()}],"mask-image-l-from-pos":[{"mask-l-from":S0()}],"mask-image-l-to-pos":[{"mask-l-to":S0()}],"mask-image-l-from-color":[{"mask-l-from":T()}],"mask-image-l-to-color":[{"mask-l-to":T()}],"mask-image-x-from-pos":[{"mask-x-from":S0()}],"mask-image-x-to-pos":[{"mask-x-to":S0()}],"mask-image-x-from-color":[{"mask-x-from":T()}],"mask-image-x-to-color":[{"mask-x-to":T()}],"mask-image-y-from-pos":[{"mask-y-from":S0()}],"mask-image-y-to-pos":[{"mask-y-to":S0()}],"mask-image-y-from-color":[{"mask-y-from":T()}],"mask-image-y-to-color":[{"mask-y-to":T()}],"mask-image-radial":[{"mask-radial":[h2,O2]}],"mask-image-radial-from-pos":[{"mask-radial-from":S0()}],"mask-image-radial-to-pos":[{"mask-radial-to":S0()}],"mask-image-radial-from-color":[{"mask-radial-from":T()}],"mask-image-radial-to-color":[{"mask-radial-to":T()}],"mask-image-radial-shape":[{"mask-radial":["circle","ellipse"]}],"mask-image-radial-size":[{"mask-radial":[{closest:["side","corner"],farthest:["side","corner"]}]}],"mask-image-radial-pos":[{"mask-radial-at":x()}],"mask-image-conic-pos":[{"mask-conic":[sw]}],"mask-image-conic-from-pos":[{"mask-conic-from":S0()}],"mask-image-conic-to-pos":[{"mask-conic-to":S0()}],"mask-image-conic-from-color":[{"mask-conic-from":T()}],"mask-image-conic-to-color":[{"mask-conic-to":T()}],"mask-mode":[{mask:["alpha","luminance","match"]}],"mask-origin":[{"mask-origin":["border","padding","content","fill","stroke","view"]}],"mask-position":[{mask:f0()}],"mask-repeat":[{mask:b0()}],"mask-size":[{mask:i()}],"mask-type":[{"mask-type":["alpha","luminance"]}],"mask-image":[{mask:["none",h2,O2]}],filter:[{filter:["","none",h2,O2]}],blur:[{blur:j0()}],brightness:[{brightness:[sw,h2,O2]}],contrast:[{contrast:[sw,h2,O2]}],"drop-shadow":[{"drop-shadow":["","none",q,$X0,wX0]}],"drop-shadow-color":[{"drop-shadow":T()}],grayscale:[{grayscale:["",sw,h2,O2]}],"hue-rotate":[{"hue-rotate":[sw,h2,O2]}],invert:[{invert:["",sw,h2,O2]}],saturate:[{saturate:[sw,h2,O2]}],sepia:[{sepia:["",sw,h2,O2]}],"backdrop-filter":[{"backdrop-filter":["","none",h2,O2]}],"backdrop-blur":[{"backdrop-blur":j0()}],"backdrop-brightness":[{"backdrop-brightness":[sw,h2,O2]}],"backdrop-contrast":[{"backdrop-contrast":[sw,h2,O2]}],"backdrop-grayscale":[{"backdrop-grayscale":["",sw,h2,O2]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[sw,h2,O2]}],"backdrop-invert":[{"backdrop-invert":["",sw,h2,O2]}],"backdrop-opacity":[{"backdrop-opacity":[sw,h2,O2]}],"backdrop-saturate":[{"backdrop-saturate":[sw,h2,O2]}],"backdrop-sepia":[{"backdrop-sepia":["",sw,h2,O2]}],"border-collapse":[{border:["collapse","separate"]}],"border-spacing":[{"border-spacing":S()}],"border-spacing-x":[{"border-spacing-x":S()}],"border-spacing-y":[{"border-spacing-y":S()}],"table-layout":[{table:["auto","fixed"]}],caption:[{caption:["top","bottom"]}],transition:[{transition:["","all","colors","opacity","shadow","transform","none",h2,O2]}],"transition-behavior":[{transition:["normal","discrete"]}],duration:[{duration:[sw,"initial",h2,O2]}],ease:[{ease:["linear","initial",k,h2,O2]}],delay:[{delay:[sw,h2,O2]}],animate:[{animate:["none",j,h2,O2]}],backface:[{backface:["hidden","visible"]}],perspective:[{perspective:[I,h2,O2]}],"perspective-origin":[{"perspective-origin":v()}],rotate:[{rotate:P0()}],"rotate-x":[{"rotate-x":P0()}],"rotate-y":[{"rotate-y":P0()}],"rotate-z":[{"rotate-z":P0()}],scale:[{scale:E0()}],"scale-x":[{"scale-x":E0()}],"scale-y":[{"scale-y":E0()}],"scale-z":[{"scale-z":E0()}],"scale-3d":["scale-3d"],skew:[{skew:T0()}],"skew-x":[{"skew-x":T0()}],"skew-y":[{"skew-y":T0()}],transform:[{transform:[h2,O2,"","none","gpu","cpu"]}],"transform-origin":[{origin:v()}],"transform-style":[{transform:["3d","flat"]}],translate:[{translate:n0()}],"translate-x":[{"translate-x":n0()}],"translate-y":[{"translate-y":n0()}],"translate-z":[{"translate-z":n0()}],"translate-none":["translate-none"],zoom:[{zoom:[Zq,h2,O2]}],accent:[{accent:T()}],appearance:[{appearance:["none","auto"]}],"caret-color":[{caret:T()}],"color-scheme":[{scheme:["normal","dark","light","light-dark","only-dark","only-light"]}],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",h2,O2]}],"field-sizing":[{"field-sizing":["fixed","content"]}],"pointer-events":[{"pointer-events":["auto","none"]}],resize:[{resize:["none","","y","x"]}],"scroll-behavior":[{scroll:["auto","smooth"]}],"scrollbar-thumb-color":[{"scrollbar-thumb":T()}],"scrollbar-track-color":[{"scrollbar-track":T()}],"scrollbar-gutter":[{"scrollbar-gutter":["auto","stable","both"]}],"scrollbar-w":[{scrollbar:["auto","thin","none"]}],"scroll-m":[{"scroll-m":S()}],"scroll-mx":[{"scroll-mx":S()}],"scroll-my":[{"scroll-my":S()}],"scroll-ms":[{"scroll-ms":S()}],"scroll-me":[{"scroll-me":S()}],"scroll-mbs":[{"scroll-mbs":S()}],"scroll-mbe":[{"scroll-mbe":S()}],"scroll-mt":[{"scroll-mt":S()}],"scroll-mr":[{"scroll-mr":S()}],"scroll-mb":[{"scroll-mb":S()}],"scroll-ml":[{"scroll-ml":S()}],"scroll-p":[{"scroll-p":S()}],"scroll-px":[{"scroll-px":S()}],"scroll-py":[{"scroll-py":S()}],"scroll-ps":[{"scroll-ps":S()}],"scroll-pe":[{"scroll-pe":S()}],"scroll-pbs":[{"scroll-pbs":S()}],"scroll-pbe":[{"scroll-pbe":S()}],"scroll-pt":[{"scroll-pt":S()}],"scroll-pr":[{"scroll-pr":S()}],"scroll-pb":[{"scroll-pb":S()}],"scroll-pl":[{"scroll-pl":S()}],"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",h2,O2]}],fill:[{fill:["none",...T()]}],"stroke-w":[{stroke:[sw,Mr,GP,Lm1]}],stroke:[{stroke:["none",...T()]}],"forced-color-adjust":[{"forced-color-adjust":["auto","none"]}]},conflictingClassGroups:{"container-named":["container-type"],overflow:["overflow-x","overflow-y"],overscroll:["overscroll-x","overscroll-y"],inset:["inset-x","inset-y","inset-bs","inset-be","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","pbs","pbe","pt","pr","pb","pl"],px:["pr","pl"],py:["pt","pb"],m:["mx","my","ms","me","mbs","mbe","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-x","border-w-y","border-w-s","border-w-e","border-w-bs","border-w-be","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-x","border-color-y","border-color-s","border-color-e","border-color-bs","border-color-be","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"],translate:["translate-x","translate-y","translate-none"],"translate-none":["translate","translate-x","translate-y","translate-z"],"scroll-m":["scroll-mx","scroll-my","scroll-ms","scroll-me","scroll-mbs","scroll-mbe","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-pbs","scroll-pbe","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"]},postfixLookupClassGroups:["container-type"],orderSensitiveModifiers:["*","**","after","backdrop","before","details-content","file","first-letter","first-line","marker","placeholder","selection"]}},I6w=(A,{cacheSize:Q,prefix:w,experimentalParseClassName:$,extend:B={},override:X={}})=>{return Hy(A,"cacheSize",Q),Hy(A,"prefix",w),Hy(A,"experimentalParseClassName",$),BX0(A.theme,X.theme),BX0(A.classGroups,X.classGroups),BX0(A.conflictingClassGroups,X.conflictingClassGroups),BX0(A.conflictingClassGroupModifiers,X.conflictingClassGroupModifiers),Hy(A,"postfixLookupClassGroups",X.postfixLookupClassGroups),Hy(A,"orderSensitiveModifiers",X.orderSensitiveModifiers),XX0(A.theme,B.theme),XX0(A.classGroups,B.classGroups),XX0(A.conflictingClassGroups,B.conflictingClassGroups),XX0(A.conflictingClassGroupModifiers,B.conflictingClassGroupModifiers),_d0(A,B,"postfixLookupClassGroups"),_d0(A,B,"orderSensitiveModifiers"),A},Hy=(A,Q,w)=>{if(w!==void 0)A[Q]=w},BX0=(A,Q)=>{if(Q)for(let w in Q)Hy(A,w,Q[w])},XX0=(A,Q)=>{if(Q)for(let w in Q)_d0(A,Q,w)},_d0=(A,Q,w)=>{let $=Q[w];if($!==void 0)A[w]=A[w]?A[w].concat($):$},YX0=(A,...Q)=>typeof A==="function"?bm1(Nm1,A,...Q):bm1(()=>I6w(Nm1(),A),...Q);var F6w=YX0({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 C2(...A){return F6w(fy(A))}var mm1=(A)=>typeof A==="boolean"?`${A}`:A===0?"0":A,um1=fy,T$=(A,Q)=>(w)=>{var $;if((Q===null||Q===void 0?void 0:Q.variants)==null)return um1(A,w===null||w===void 0?void 0:w.class,w===null||w===void 0?void 0:w.className);let{variants:B,defaultVariants:X}=Q,Y=Object.keys(B).map((W)=>{let K=w===null||w===void 0?void 0:w[W],U=X===null||X===void 0?void 0:X[W];if(K===null)return null;let G=mm1(K)||mm1(U);return B[W][G]}),Z=w&&Object.entries(w).reduce((W,K)=>{let[U,G]=K;if(G===void 0)return W;return W[U]=G,W},{}),H=Q===null||Q===void 0?void 0:($=Q.compoundVariants)===null||$===void 0?void 0:$.reduce((W,K)=>{let{class:U,className:G,...q}=K;return Object.entries(q).every((V)=>{let[I,J]=V;return Array.isArray(J)?J.includes({...X,...Z}[I]):{...X,...Z}[I]===J})?[...W,U,G]:W},[]);return um1(A,Y,H,w===null||w===void 0?void 0:w.class,w===null||w===void 0?void 0:w.className)};import{jsxDEV as Pd0}from"preact/jsx-dev-runtime";var cm1=T$("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 Md0({variant:A,title:Q,children:w,className:$}){return Pd0("div",{className:C2(cm1({variant:A}),$),role:"alert",children:[Q&&Pd0("p",{className:"font-medium text-current opacity-90",children:Q},void 0,!1,void 0,this),Pd0("div",{className:C2(Q&&"mt-1","text-sm text-current opacity-75"),children:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}import{jsxDEV as b6w}from"preact/jsx-dev-runtime";var lm1=T$("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 qP({variant:A,size:Q,className:w,children:$,ssrOnClick:B,type:X="button",...Y}){return b6w("button",{type:X,className:C2(lm1({variant:A,size:Q}),w),...Y,...B&&{onclick:B},children:$},void 0,!1,void 0,this)}import{jsxDEV as L6w}from"preact/jsx-dev-runtime";var pm1=T$("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 c9({href:A,children:Q,variant:w,size:$,external:B=!1,className:X,"aria-label":Y}){let Z=B?{target:"_blank",rel:"noopener noreferrer"}:{};return L6w("a",{href:A,className:C2(pm1({variant:w,size:$}),X),"aria-label":Y,...Z,children:Q},void 0,!1,void 0,this)}import{jsxDEV as ZX0}from"preact/jsx-dev-runtime";var im1=T$("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"}}),k6w={sm:"w-4 h-4",md:"w-5 h-5",lg:"w-6 h-6"};function Wy({variant:A,size:Q,className:w}){let $=k6w[Q??"md"];return ZX0("button",{onclick:"toggleTheme()",type:"button",className:C2(im1({variant:A,size:Q}),w),"aria-label":"Toggle dark mode",children:ZX0("svg",{className:C2($,"transition-colors"),fill:"none",stroke:"currentColor",strokeWidth:1.6,viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:[ZX0("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),ZX0("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 Od0}from"preact/jsx-dev-runtime";var dm1=T$("flex flex-wrap",{variants:{orientation:{horizontal:"justify-center gap-6 items-center",vertical:"flex-col gap-2.5"}},defaultVariants:{orientation:"horizontal"}});function fX0({items:A,className:Q,linkClassName:w="hover:text-accent transition-colors",orientation:$,children:B}){if(A.length===0&&!B)return null;let X=[...A].sort((Y,Z)=>Y.priority-Z.priority);return Od0("ul",{className:C2(dm1({orientation:$}),Q),children:[X.map((Y)=>Od0("li",{children:Od0("a",{href:Y.href,className:w,children:Y.label},void 0,!1,void 0,this)},Y.href,!1,void 0,this)),B]},void 0,!0,void 0,this)}import{jsxDEV as a28}from"preact/jsx-dev-runtime";import{jsxDEV as AQ8}from"preact/jsx-dev-runtime";import{createContext as _6w,h as N6w}from"preact";import{useContext as j6w}from"preact/hooks";var xd0=_6w(null);function Ky({headCollector:A,children:Q}){return N6w(xd0.Provider,{value:A},Q)}function nm1(){return j6w(xd0)}function $w(A){let Q=nm1();if(Q)Q.setHeadProps(A);return null}import{createContext as $4w,h as B4w}from"preact";import{useContext as X4w}from"preact/hooks";vx0();var $i1=D1(wi1(),1),Q4w=new w$0({gfm:!0,breaks:!0}),w4w={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 Qr0(A,Q){let{imageRenderer:w}=Q??{},B=(w?new w$0({gfm:!0,breaks:!0}).use({renderer:{image({href:X,title:Y,text:Z}){return w(X,Y,Z)??!1}}}):Q4w).parse(A);return B=B.replace(/<\/blockquote>\s*<p>(\u2014|--|\u2013)([\s\S]*?)<\/p>/g,`</blockquote>
5761
+ `)}}fA();class n40 extends D6{directorySync;constructor(A,Q,w){super(A,{schema:zd0,jobTypeName:"directory-export"});this.directorySync=w}async process(A,Q,w){this.logger.debug("Processing directory export job",{jobId:Q,data:A});let $=Date.now();try{let B=await this.directorySync.exportEntitiesWithProgress(A.entityTypes,w,A.batchSize??100);return this.logger.debug("Directory export job completed",{jobId:Q,exported:B.exported,failed:B.failed,duration:Date.now()-$}),B}catch(B){throw this.logger.error("Directory export job failed",{jobId:Q,error:B}),B}}summarizeDataForLog(A){return{entityTypes:A.entityTypes??"all",batchSize:A.batchSize}}}fA();class r40 extends D6{directorySync;constructor(A,Q,w){super(A,{schema:qd0,jobTypeName:"directory-import"});this.directorySync=w}async process(A,Q,w){this.logger.debug("Processing directory import job",{jobId:Q,data:A});let $=Date.now();try{let B=await this.directorySync.importEntitiesWithProgress(A.paths,w,A.batchSize??100);return this.logger.debug("Directory import job completed",{jobId:Q,imported:B.imported,skipped:B.skipped,failed:B.failed,quarantined:B.quarantined,duration:Date.now()-$}),B}catch(B){throw this.logger.error("Directory import job failed",{jobId:Q,error:B}),B}}summarizeDataForLog(A){return{pathCount:A.paths?.length??"all",batchSize:A.batchSize}}}fA();class o40 extends D6{directorySync;context;constructor(A,Q,w){super(A,{schema:Gd0,jobTypeName:"directory-sync"});this.context=Q,this.directorySync=w}async process(A,Q,w){let $=Date.now(),B=A.syncDirection??"both";this.logger.info("Starting directory sync job",{jobId:Q,operation:A.operation,syncDirection:B});let X={imported:0,skipped:0,failed:0,quarantined:0,quarantinedFiles:[],errors:[],jobIds:[]},Y={exported:0,failed:0,errors:[]};if(B!=="export")if(await w.report({progress:10,message:"Scanning directory for changes"}),X=await this.importWithProgress(A.paths,w),B==="import")await this.waitForImportJobs(X.jobIds,w),await w.report({progress:100,message:`Import complete: ${X.imported} imported`});else await w.report({progress:50,message:`Imported ${X.imported} entities`}),await this.waitForImportJobs(X.jobIds,w),await w.report({progress:56,message:"Processing complete, starting export"});if(B!=="import"){let H=B==="export"?10:60;await w.report({progress:H,message:"Exporting entities to directory"}),Y=await this.exportWithProgress(A.entityTypes,w),await w.report({progress:100,message:B==="export"?`Export complete: ${Y.exported} exported`:`Sync complete: ${X.imported} imported, ${Y.exported} exported`})}let Z=Date.now()-$;return this.logger.info("Directory sync job completed",{jobId:Q,duration:Z,imported:X.imported,exported:Y.exported}),{import:X,export:Y,duration:Z}}async importWithProgress(A,Q){try{return await this.directorySync.importEntitiesWithProgress(A,Q,10)}catch(w){throw this.logger.error("Import phase failed",{error:w}),w}}async exportWithProgress(A,Q){try{return await this.directorySync.exportEntitiesWithProgress(A,Q,10)}catch(w){throw this.logger.error("Export phase failed",{error:w}),w}}async waitForImportJobs(A,Q){if(A.length===0)return;this.logger.debug(`Waiting for ${A.length} import jobs to complete`);let{entityService:w}=this.context,$=300000,B=500,X=Date.now(),Y=async()=>{let H=(await Promise.all(A.map((K)=>w.getAsyncJobStatus(K)))).filter((K)=>K&&(K.status==="completed"||K.status==="failed")).length;if(H===A.length){this.logger.debug("All import jobs completed");return}if(Date.now()-X>$){this.logger.warn(`Timeout waiting for import jobs (${H}/${A.length} completed)`);return}let W=Math.round(H/A.length*100);return await Q.report({progress:50+Math.round(W*0.05),message:`Processing ${H}/${A.length} entities`}),await new Promise((K)=>setTimeout(K,B)),Y()};return Y()}summarizeDataForLog(A){return{operation:A.operation,syncDirection:A.syncDirection}}}fA();class s40 extends D6{context;directorySync;gitSync;constructor(A,Q,w,$){super(A,{schema:Dd0,jobTypeName:"sync-request"});this.context=Q,this.directorySync=w,this.gitSync=$}async process(A,Q,w){await w.report({progress:5,message:"Pulling latest content from git"});let $=await this.gitSync.withLock(async()=>{return await this.gitSync.pull(),await w.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(!$)return await w.report({progress:100,message:"Sync complete: no files to import"}),{gitPulled:!0,batchQueued:!1};return await w.report({progress:100,message:`Sync queued: ${$.importOperationsCount} import jobs for ${$.totalFiles} files`}),Qww($)}summarizeDataForLog(A){return{source:A.source,interfaceType:A.interfaceType,channelId:A.channelId}}}function Qww(A){return{gitPulled:!0,batchQueued:!0,batchId:A.batchId,importOperations:A.importOperationsCount,totalFiles:A.totalFiles}}fA();class a40 extends D6{context;constructor(A,Q,w){super(A,{schema:i40,jobTypeName:"directory-delete"});this.context=Q}async process(A,Q,w){let $=i40.parse(A);this.logger.info("Processing entity deletion for removed file",{entityId:$.entityId,entityType:$.entityType,filePath:$.filePath}),await w.report({progress:0,total:1,message:`Deleting ${$.entityType}:${$.entityId}`});try{let B=await this.context.entityService.deleteEntity({entityType:$.entityType,id:$.entityId});if(B)this.logger.info("Successfully deleted entity for removed file",{entityId:$.entityId,entityType:$.entityType});else this.logger.warn("Entity not found in database",{entityId:$.entityId,entityType:$.entityType});return await w.report({progress:1,total:1,message:`Deleted ${$.entityType}:${$.entityId}`}),{deleted:B,entityId:$.entityId,entityType:$.entityType,filePath:$.filePath}}catch(B){throw this.logger.error("Failed to delete entity",{entityId:$.entityId,entityType:$.entityType,error:B}),B}}summarizeDataForLog(A){return{entityId:A.entityId,entityType:A.entityType,filePath:A.filePath}}}fA();C0();var www=f.object({});class t40 extends D6{directorySync;constructor(A,Q){super(A,{schema:www,jobTypeName:"directory-cleanup"});this.directorySync=Q}async process(A,Q,w){await w.report({progress:0,message:"Removing orphaned entities"});let $=await this.directorySync.removeOrphanedEntities();return await w.report({progress:100,message:`Cleanup complete: ${$.deleted} orphans removed`}),$}}fA();p4();H7();e6();C0();p4();import{readFile as $ww,writeFile as Bww}from"fs/promises";var Xww=Vd0,Yww=f.record(f.string(),f.unknown());class e40 extends D6{context;fetcher;constructor(A,Q,w=JW){super(Q,{schema:Xww,jobTypeName:"cover-image-convert"});this.context=A,this.fetcher=w}async process(A,Q,w){let{filePath:$,sourceUrl:B,postTitle:X,postSlug:Y,customAlt:Z}=A;this.logger.debug("Starting image conversion job",{jobId:Q,filePath:$,sourceUrl:B,postSlug:Y});try{await this.reportProgress(w,{progress:Yw.INIT,message:`Reading file: ${$}`});let H;try{H=await $ww($,"utf-8")}catch(J){return this.logger.error("Failed to read file",{filePath:$,error:dA(J)}),k8.failure(J)}let W;try{W=l6(H)}catch(J){return this.logger.warn("Failed to parse markdown",{filePath:$,error:dA(J)}),k8.failure(J)}let K=Yww.safeParse(W.frontmatter),U=K.success?K.data:{};if(U.coverImageId)return this.logger.debug("File already has coverImageId, skipping",{filePath:$}),await this.reportProgress(w,{progress:Yw.COMPLETE,message:"Already converted"}),{success:!0,skipped:!0};await this.reportProgress(w,{progress:Yw.FETCH,message:"Checking for existing image"});let G=await this.context.entityService.listEntities({entityType:"image",options:{filter:{metadata:{sourceUrl:B}},limit:1}}),q;if(G[0])q=G[0].id,this.logger.debug("Reusing existing image entity",{sourceUrl:B,imageId:q}),await this.reportProgress(w,{progress:Yw.EXTRACT,message:`Reusing existing image: ${q}`});else{await this.reportProgress(w,{progress:Yw.PROCESS,message:`Fetching image from ${B}`});let J;try{J=await this.fetcher(B)}catch(O){return this.logger.error("Failed to fetch image",{sourceUrl:B,error:dA(O)}),k8.failure(O)}await this.reportProgress(w,{progress:Yw.GENERATE,message:"Creating image entity"});let{base64:k}=iI(J),j=a_(k),_=dI(k);if(!j||!_)return this.logger.error("Could not detect image format or dimensions",{sourceUrl:B}),k8.failure(Error("Could not detect image format or dimensions"));q=`${Y}-cover`;let x=`Cover image for ${X}`,v=Z??x;await this.context.entityService.createEntity({entity:{id:q,entityType:"image",content:J,metadata:{title:x,alt:v,format:j,width:_.width,height:_.height,sourceUrl:B}}}),this.logger.debug("Created image entity",{imageId:q,sourceUrl:B}),await this.reportProgress(w,{progress:Yw.EXTRACT,message:`Created image: ${q}`})}await this.reportProgress(w,{progress:Yw.SAVE,message:"Updating file"});let V={...U};delete V.coverImageUrl,delete V.coverImageAlt,V.coverImageId=q;let I=F_(V,W.content);try{await Bww($,I,"utf-8")}catch(J){return this.logger.error("Failed to write file",{filePath:$,error:dA(J)}),k8.failure(J)}return await this.reportProgress(w,{progress:Yw.COMPLETE,message:"Conversion complete"}),this.logger.info("Image conversion complete",{filePath:$,imageId:q,sourceUrl:B}),{success:!0,imageId:q}}catch(H){return this.logger.error("Image conversion job failed",{jobId:Q,filePath:$,error:dA(H)}),k8.failure(H)}}summarizeDataForLog(A){return{filePath:A.filePath,sourceUrl:A.sourceUrl,postSlug:A.postSlug}}}fA();p4();e6();import{readFile as Zww,writeFile as fww}from"fs/promises";class AX0 extends D6{converter;constructor(A,Q,w=JW){super(Q,{schema:Jd0,jobTypeName:"inline-image-convert"});this.converter=new Gr(A.entityService,Q,w)}async process(A,Q,w){let{filePath:$,postSlug:B}=A;this.logger.debug("Starting inline image conversion job",{jobId:Q,filePath:$,postSlug:B});try{await this.reportProgress(w,{progress:Yw.INIT,message:`Reading file: ${$}`});let X;try{X=await Zww($,"utf-8")}catch(H){let W=dA(H);return this.logger.error("Failed to read file",{filePath:$,error:W}),{success:!1,error:W}}await this.reportProgress(w,{progress:Yw.FETCH,message:"Detecting inline images"});let Y=this.converter.detectInlineImages(X,B);if(Y.length===0)return this.logger.debug("No inline images to convert",{filePath:$}),await this.reportProgress(w,{progress:Yw.COMPLETE,message:"No images to convert"}),{success:!0,skipped:!0,convertedCount:0};this.logger.debug("Found inline images to convert",{filePath:$,count:Y.length}),await this.reportProgress(w,{progress:Yw.PROCESS,message:`Converting ${Y.length} images`});let Z=await this.converter.convert(X,B);if(!Z.converted)return this.logger.debug("No images were converted",{filePath:$}),await this.reportProgress(w,{progress:Yw.COMPLETE,message:"No images converted"}),{success:!0,skipped:!0,convertedCount:0};await this.reportProgress(w,{progress:Yw.SAVE,message:"Writing updated file"});try{await fww($,Z.content,"utf-8")}catch(H){let W=dA(H);return this.logger.error("Failed to write file",{filePath:$,error:W}),{success:!1,error:W}}return await this.reportProgress(w,{progress:Yw.COMPLETE,message:"Conversion complete"}),this.logger.info("Inline image conversion complete",{filePath:$,convertedCount:Z.convertedCount}),{success:!0,convertedCount:Z.convertedCount}}catch(X){let Y=dA(X);return this.logger.error("Inline image conversion job failed",{jobId:Q,filePath:$,error:Y}),{success:!1,error:Y}}}summarizeDataForLog(A){return{filePath:A.filePath,postSlug:A.postSlug}}}function tS1(A,Q,w){let $=(B)=>w.child(B);A.jobs.registerHandler("directory-sync",new o40($("DirectorySyncJobHandler"),A,Q)),A.jobs.registerHandler("directory-export",new n40($("DirectoryExportJobHandler"),A,Q)),A.jobs.registerHandler("directory-import",new r40($("DirectoryImportJobHandler"),A,Q)),A.jobs.registerHandler("directory-delete",new a40($("DirectoryDeleteJobHandler"),A,Q)),A.jobs.registerHandler("directory-cleanup",new t40($("DirectoryCleanupJobHandler"),Q)),A.jobs.registerHandler("cover-image-convert",new e40(A,$("CoverImageConversionJobHandler"))),A.jobs.registerHandler("inline-image-convert",new AX0(A,$("InlineImageConversionJobHandler"))),w.debug("Registered async job handlers")}fA();C0();import{unlink as Hww,access as Www}from"fs/promises";var Kww=f.record(f.string(),f.unknown());function eS1(A,Q,w,$){let{subscribe:B}=A.messaging,{entityService:X}=A;B("entity:created",async(Y)=>{let{entity:Z}=Y.payload;try{await Q.fileOps.writeEntity(Z),w.debug("Auto-exported created entity",{id:Z.id,entityType:Z.entityType})}catch(H){w.error("Auto-export FAILED for created entity",{id:Z.id,entityType:Z.entityType,error:H instanceof Error?H.message:String(H),stack:H instanceof Error?H.stack:void 0})}return{success:!0}}),B("entity:updated",async(Y)=>{let{entityType:Z,entityId:H}=Y.payload;try{let W=await X.getEntity({entityType:Z,id:H});if(!W)return w.debug("Entity not found in DB, skipping export",{entityType:Z,entityId:H}),{success:!1};await Q.fileOps.writeEntity(W),w.debug("Auto-exported updated entity",{id:W.id,entityType:W.entityType})}catch(W){w.error("Auto-export FAILED for updated entity",{entityType:Z,entityId:H,error:W instanceof Error?W.message:String(W),stack:W instanceof Error?W.stack:void 0})}return{success:!0}}),B("entity:deleted",async(Y)=>{let{entityId:Z,entityType:H}=Y.payload,W=Q.fileOps.getFilePath(Z,H);if(await Www(W).then(()=>!0,()=>!1))await Hww(W),w.debug("Auto-deleted entity file",{id:Z,entityType:H,path:W});return{success:!0}}),w.debug("Setup auto-sync for entity events",{entityTypes:$})}function Am1(A,Q,w){Q.setJobQueueCallback(async($)=>{let B=[{type:$.type,data:Kww.parse($.data)}];return A.jobs.enqueueBatch(B,{priority:5,source:"directory-sync-watcher",rootJobId:v4(),metadata:{operationType:"file_operations",operationTarget:w,pluginId:"directory-sync"}})})}fA();import{readdir as $m1,mkdir as Gww,copyFile as Dww}from"fs/promises";import{join as wm1,resolve as Id0}from"path";import{join as Uww}from"path";async function Qm1(A){if(!await q5(Uww(A,".git")))return!1;try{return await cU(A).revparse(["--verify","HEAD"]),!0}catch{return!1}}async function qww(A,Q){if(!await q5(A))return!0;if((await $m1(A)).filter((B)=>!B.startsWith(".")&&!B.startsWith("_")).length>0)return!1;if(await Qm1(A))return Q.debug("Git repository with history detected - skipping seed content",{path:A}),!1;return!0}async function Bm1(A,Q){let w=await $m1(A,{withFileTypes:!0});for(let $ of w){let B=wm1(A,$.name),X=wm1(Q,$.name);if($.isDirectory()){if(!await q5(X))await Gww(X,{recursive:!0});await Bm1(B,X)}else await Dww(B,X)}}async function Xm1(A,Q,w){let $=Id0(process.cwd(),A);w=w?Id0(w):Id0(process.cwd(),"seed-content");let B=await qww($,Q);if(B&&await q5(w))Q.debug("Copying seed content to brain-data directory"),await Bm1(w,$),Q.debug("Seed content copied successfully");else if(B)Q.debug("No seed content directory found, starting with empty brain-data");else Q.debug("brain-data directory not empty, skipping seed content")}function Ym1(A,Q,w,$,B){let X=!1,Y=async()=>{if(X)return;X=!0;let Z=Q();if(w.seedContent){let H=w.syncPath??A.dataDir;await Xm1(H,$,w.seedContentPath)}try{if(B){$.debug("Git enabled \u2014 pulling before import");let W=await B.pull();if(W.files.length>0)$.info("Pulled changes from remote",{filesChanged:W.files.length})}$.debug("Starting initial sync");let H=await Z.sync();$.debug("Initial sync completed",{imported:H.import.imported,failed:H.import.failed,duration:H.duration}),await A.messaging.send({type:__.initialSyncCompleted,payload:{success:!0},...{broadcast:!0}})}catch(H){$.error("Initial sync failed",H),await A.messaging.send({type:__.initialSyncCompleted,payload:{success:!1,error:dA(H)},...{broadcast:!0}})}};A.messaging.subscribe(__.pluginsRegistered,async()=>{return $.debug("Plugins registered, starting initial sync"),await Y(),{success:!0}})}class Fd0{fn;delayMs;timeout;pending=!1;constructor(A,Q){this.fn=A,this.delayMs=Q}trigger(){if(!this.timeout){this.fn(),this.timeout=setTimeout(()=>{if(this.timeout=void 0,this.pending)this.pending=!1,this.fn()},this.delayMs);return}this.pending=!0,clearTimeout(this.timeout),this.timeout=setTimeout(()=>{if(this.timeout=void 0,this.pending)this.pending=!1,this.fn()},this.delayMs)}dispose(){if(this.timeout)clearTimeout(this.timeout),this.timeout=void 0;this.pending=!1}}class bd0{fn;delayMs;timeout;constructor(A,Q){this.fn=A,this.delayMs=Q}trigger(){if(this.timeout)clearTimeout(this.timeout);this.timeout=setTimeout(()=>{this.timeout=void 0,this.fn()},this.delayMs)}dispose(){if(this.timeout)clearTimeout(this.timeout),this.timeout=void 0}}function Zm1(A,Q,w,$){let B=new bd0(()=>{Q.withLock(async()=>{try{await Q.commit(),await Q.push()}catch(Z){$.error("Git auto-commit failed",{error:Z})}})},w),X=["entity:created","entity:updated","entity:deleted"],Y=[];for(let Z of X){let H=A.subscribe(Z,async()=>{return B.trigger(),{success:!0}});Y.push(H)}return()=>{B.dispose();for(let Z of Y)Z()}}function fm1(A,Q,w,$,B){if($<=0)return()=>{};let X=$*60*1000,Y=!1,Z=async()=>{if(Y)return;Y=!0;try{let{files:W,result:K}=await A.withLock(async()=>{let U=await A.pull();if(U.files.length===0)return{files:[],result:null};let G=await Q.queueSyncBatch(w,"periodic-sync");return{files:U.files,result:G}});if(W.length>0)B.info("Periodic sync: pulled changes",{filesChanged:W.length});if(K)B.debug("Periodic sync: queued imports",{importOperations:K.importOperationsCount,totalFiles:K.totalFiles})}catch(W){B.error("Periodic git sync failed",{error:W})}finally{Y=!1}},H=setInterval(()=>{Z()},X);return B.info("Started periodic git sync",{intervalMinutes:$}),()=>{clearInterval(H)}}import{spawnSync as Wm1}from"child_process";import{cpSync as zww,existsSync as Hm1,mkdirSync as Vww,mkdtempSync as Jww,rmSync as Iww}from"fs";import{tmpdir as Fww}from"os";import{fileURLToPath as bww}from"url";import{join as Lww,resolve as kww}from"path";function mb(A,Q){let w=Wm1("git",Q,{cwd:A,stdio:"pipe"});if(w.status!==0){let $=w.stderr.toString().trim(),B=w.stdout.toString().trim();throw Error($||B||`git ${Q.join(" ")} failed`)}}function _ww(A){return A.startsWith("file://")}function Nww(A){return bww(A)}function jww(A,Q){return Wm1("git",["--git-dir",A,"show-ref","--verify","--quiet",`refs/heads/${Q}`]).status===0}async function Km1(A){if(!A.bootstrapFromSeed)return;if(!A.gitUrl||!_ww(A.gitUrl))return;if(!A.seedContentPath)throw Error("directory-sync git.bootstrapFromSeed requires seedContentPath for local file:// remotes");let Q=A.branch??"main",w=Nww(A.gitUrl),$=kww(A.seedContentPath);if(!Hm1($))throw Error(`Seed content path not found: ${$}`);if(!Hm1(w))A.logger.debug("Creating local bare content remote",{remotePath:w,branch:Q}),Vww(w,{recursive:!0}),mb(process.cwd(),["init","--bare",`--initial-branch=${Q}`,w]);if(jww(w,Q)){A.logger.debug("Content remote already initialized",{remotePath:w,branch:Q});return}A.logger.debug("Seeding local content remote",{remotePath:w,seedPath:$,branch:Q});let B=Jww(Lww(Fww(),"directory-sync-seed-"));try{mb(B,["init",`--initial-branch=${Q}`]),mb(B,["config","user.name",A.authorName??"Brain"]),mb(B,["config","user.email",A.authorEmail??"brain@localhost"]),zww($,B,{recursive:!0}),mb(B,["add","."]),mb(B,["commit","-m","seed content remote"]),mb(B,["remote","add","origin",A.gitUrl]),mb(B,["push","-u","origin",Q])}finally{Iww(B,{recursive:!0,force:!0})}}function Um1(A,Q,w,$,B,X){let{subscribe:Y}=A.messaging;Y("entity:export:request",async(Z)=>{try{return{success:!0,data:await Q().exportEntities(Z.payload.entityTypes)}}catch(H){return{success:!1,error:H instanceof Error?H.message:"Export failed"}}}),Y("entity:import:request",async(Z)=>{try{let H=Q(),W=Z.payload.paths,K=await H.importEntities(W);if(W&&W.length>0)await H.removeOrphanedEntities();return{success:!0,data:K}}catch(H){return{success:!1,error:H instanceof Error?H.message:"Import failed"}}}),Y("sync:status:request",async()=>{try{let H=await Q().getStatus();return{success:!0,data:{syncPath:H.syncPath,isInitialized:H.exists,watchEnabled:H.watching,lastSync:H.lastSync?.toISOString()??null,totalFiles:H.stats.totalFiles,byEntityType:H.stats.byEntityType,git:await Pww(X?.(),$)}}}catch(Z){return{success:!1,error:Z instanceof Error?Z.message:"Status check failed"}}}),Y("sync:configure:request",async(Z)=>{try{return await w({syncPath:Z.payload.syncPath}),{success:!0,data:{syncPath:Z.payload.syncPath,configured:!0}}}catch(H){return{success:!1,error:H instanceof Error?H.message:"Configuration failed"}}}),Y("git-sync:get-repo-info",async()=>{if(!B?.repo)return{success:!1,error:"Git not configured"};return{success:!0,data:{repo:B.repo,branch:B.branch??"main"}}}),$.debug("Registered message handlers")}async function Pww(A,Q){if(!A)return null;try{let w=await A.getStatus();return{branch:w.branch,hasChanges:w.hasChanges,ahead:w.ahead,behind:w.behind,lastCommit:w.lastCommit??null,remote:w.remote??null}}catch(w){return Q.debug("Git status unavailable for sync:status:request",{error:w}),null}}fA();C0();fA();C0();function Gm1(A,Q){return p6(A,"history","Get version history for an entity from git. Without sha: returns commit list. With sha: returns entity content at that version.",f.object({entityType:f.string().describe("Entity type (e.g. post, note, link)"),id:f.string().describe("Entity ID"),sha:f.string().optional().describe("Commit SHA to retrieve content at. Omit to list commit history."),limit:f.number().int().positive().optional().default(10).describe("Max commits to return (list mode only)")}),async(w)=>{let $=`${w.entityType}/${w.id}.md`;try{if(w.sha){let X=await Q.show(w.sha,$);return u5({sha:w.sha,entityType:w.entityType,id:w.id,content:X},`Content at ${w.sha.slice(0,7)}`)}let B=await Q.log($,w.limit);if(B.length===0)return u5({commits:[]},`No history found for ${w.entityType}/${w.id}`);return u5({commits:B,entityType:w.entityType,id:w.id},`${B.length} version${B.length===1?"":"s"} found`)}catch(B){return d7(B instanceof Error?B.message:"History lookup failed")}},{visibility:"anchor",sideEffects:"none"})}function Dm1(A,Q,w,$){let B=[p6(w,"sync","Sync brain entities with the filesystem. Use this for refresh, pull, sync, or backup-to-git requests. Pulls from git if configured, then imports files. Git commit and push happen automatically after imports complete.",f.object({}),async(X,Y)=>{try{let Z=Y.channelId?`${Y.interfaceType}:${Y.channelId}`:`plugin:${w}`,H={interfaceType:Y.interfaceType,channelId:Y.channelId};if($){let K=await Q.jobs.enqueue({type:"sync-request",data:{source:Z,interfaceType:H.interfaceType,channelId:H.channelId},toolContext:Y});return u5({jobId:K,status:"queued",gitPulled:!0},"Sync queued: git pull and filesystem scan will run in the background")}let W=await A.queueSyncBatch(Q,Z,H);if(!W)return u5({gitPulled:!1},"No files to sync");return u5({batchId:W.batchId,importOperations:W.importOperationsCount,totalFiles:W.totalFiles,gitPulled:!1},`Sync started: ${W.importOperationsCount} import jobs queued for ${W.totalFiles} files`)}catch(Z){return d7(Z instanceof Error?Z.message:"Sync failed")}},{visibility:"anchor",sideEffects:"external",cli:{name:"sync"}}),p6(w,"status","Read directory and git sync status: last sync, watcher state, and pending git changes. Use this for every status follow-up after directory-sync_sync, even when that call returned a jobId; a sync jobId is not a system_job_status batchId.",f.object({}),async()=>{try{let X=await A.getStatus(),Y={syncPath:X.syncPath,lastSync:X.lastSync?.toISOString(),watching:X.watching};if($){let Z=await $.getStatus();Y.git={isRepo:Z.isRepo,branch:Z.branch,hasChanges:Z.hasChanges,ahead:Z.ahead,behind:Z.behind,remote:Z.remote}}return u5(Y)}catch(X){return d7(X instanceof Error?X.message:"Status check failed")}},{visibility:"anchor",sideEffects:"none"})];if($)B.push(Gm1(w,$));return B}var qm1={name:"@brains/directory-sync",version:"0.2.0-alpha.159",description:"Directory-based entity synchronization plugin for Brains",dependencies:{"@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/image":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*",chokidar:"^5.0.0","simple-git":"^3.36.0"},devDependencies:{"@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14","@types/node":"^20.19.43",typescript:"^7.0.2"},exports:{".":{types:"./src/index.ts",import:"./src/index.ts"},"./env-schema":"./src/env-schema.ts"},main:"./src/index.ts",peerDependencies:{},private:!0,scripts:{clean:"rm -rf .turbo",lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module",types:"./src/index.ts"};class Ld0 extends Kw{directorySync;gitSync;gitCleanups=[];constructor(A={}){super("directory-sync",qm1,A,jr)}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:w}=A;A.templates.register({status:{name:"status",description:"Directory synchronization status",schema:Pr,basePrompt:"",formatter:new d40,requiredPermission:"anchor"}});let $=this.config.syncPath??A.dataDir;this.directorySync=new Dr({syncPath:$,autoSync:this.config.autoSync,watchInterval:this.config.watchInterval,includeMetadata:this.config.includeMetadata,entityTypes:this.config.entityTypes,deleteOnFileRemoval:this.config.deleteOnFileRemoval,entityService:w,logger:Q});try{await this.directorySync.initializeDirectory(),this.logger.debug("Directory structure initialized",{path:$})}catch(Y){throw this.logger.error("Failed to initialize directory",Y),Y}await this.registerJobHandlers(A);let B=this.requireDirectorySync();if(eS1(A,B,this.logger,this.config.entityTypes),this.config.autoSync)Am1(A,B,this.config.syncPath??A.dataDir);let X=this.config.git!==void 0&&(this.config.git.repo!==void 0||this.config.git.gitUrl!==void 0);if(this.config.git&&!X)this.logger.debug("Git block present but no repo/gitUrl configured \u2014 git sync disabled");if(X&&this.config.git){await Km1({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 Y=this.config.syncPath??A.dataDir;if(this.gitSync=new Ud0({logger:this.logger.child("GitSync"),dataDir:Y,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 s40(this.logger.child("DirectorySyncRequestJobHandler"),A,this.requireDirectorySync(),this.gitSync)),this.gitCleanups.push(Zm1(A.messaging,this.gitSync,this.config.commitDebounce,this.logger.child("GitAutoCommit"))),this.config.autoSync)this.gitCleanups.push(fm1(this.gitSync,this.requireDirectorySync(),A,this.config.syncInterval,this.logger.child("GitPeriodicSync")))}if(this.config.initialSync)Ym1(A,()=>this.requireDirectorySync(),this.config,this.logger,this.gitSync);Um1(A,()=>this.requireDirectorySync(),(Y)=>this.configure(Y),this.logger,this.config.git,()=>this.gitSync)}async getTools(){let A=this.requireDirectorySync();return Dm1(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 Dr({...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){tS1(A,this.requireDirectorySync(),this.logger)}}function UP(A={}){return new Ld0(A)}fA();C0();var zm1={name:"@brains/email-resend",version:"0.2.0-alpha.159",description:"Generic email delivery adapter for Resend",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":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts","./env-schema":"./src/env-schema.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var xww=f.object({apiKey:f.string().min(1).optional(),from:f.string().min(1).optional()}),Rww=f.looseObject({id:f.string().optional()});class Vm1 extends Kw{fetchImpl;constructor(A={},Q={}){super("email-resend",zm1,A,xww);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(wB0,async(w)=>{let $=VcA.parse(w.payload);try{return{success:!0,data:await this.sendWithResend($)}}catch(B){if($.sensitivity==="secret")Q.warn("Email delivery failed for a secret message");else Q.warn("Email delivery failed",{to:$.to,subject:$.subject,error:B instanceof Error?B.message:String(B)});return{success:!1,error:"Email delivery failed"}}})}async sendWithResend(A){let Q=this.config.apiKey,w=this.config.from;if(!Q||!w)return{status:"failed"};let $=await this.fetchImpl("https://api.resend.com/emails",{method:"POST",headers:{Authorization:`Bearer ${Q}`,"Content-Type":"application/json"},body:JSON.stringify({from:w,to:A.to,subject:A.subject,text:A.text,...A.html?{html:A.html}:{}})});if(!$.ok)throw Error("Resend email request failed");let B=Rww.parse(await $.json());return B.id?{status:"sent",id:B.id}:{status:"sent"}}}function QX0(A={}){return new Vm1(A)}fA();import{render as $12}from"preact-render-to-string";import{h as rP}from"preact";function Jm1(A){var Q,w,$="";if(typeof A=="string"||typeof A=="number")$+=A;else if(typeof A=="object")if(Array.isArray(A)){var B=A.length;for(Q=0;Q<B;Q++)A[Q]&&(w=Jm1(A[Q]))&&($&&($+=" "),$+=w)}else for(w in A)A[w]&&($&&($+=" "),$+=w);return $}function fy(){for(var A,Q,w=0,$="",B=arguments.length;w<B;w++)(A=arguments[w])&&(Q=Jm1(A))&&($&&($+=" "),$+=Q);return $}var vww=(A,Q)=>{let w=Array(A.length+Q.length);for(let $=0;$<A.length;$++)w[$]=A[$];for(let $=0;$<Q.length;$++)w[A.length+$]=Q[$];return w},hww=(A,Q)=>({classGroupId:A,validator:Q}),jm1=(A=new Map,Q=null,w)=>({nextPart:A,validators:Q,classGroupId:w});var Im1=[];var Cww=(A)=>{let Q=yww(A),{conflictingClassGroups:w,conflictingClassGroupModifiers:$}=A;return{getClassGroupId:(Y)=>{if(Y.startsWith("[")&&Y.endsWith("]"))return gww(Y);let Z=Y.split("-"),H=Z[0]===""&&Z.length>1?1:0;return Pm1(Z,H,Q)},getConflictingClassGroupIds:(Y,Z)=>{if(Z){let H=$[Y],W=w[Y];if(H){if(W)return vww(W,H);return H}return W||Im1}return w[Y]||Im1}}},Pm1=(A,Q,w)=>{if(A.length-Q===0)return w.classGroupId;let B=A[Q],X=w.nextPart.get(B);if(X){let W=Pm1(A,Q+1,X);if(W)return W}let Y=w.validators;if(Y===null)return;let Z=Q===0?A.join("-"):A.slice(Q).join("-"),H=Y.length;for(let W=0;W<H;W++){let K=Y[W];if(K.validator(Z))return K.classGroupId}return},gww=(A)=>A.slice(1,-1).indexOf(":")===-1?void 0:(()=>{let Q=A.slice(1,-1),w=Q.indexOf(":"),$=Q.slice(0,w);return $?"arbitrary.."+$:void 0})(),yww=(A)=>{let{theme:Q,classGroups:w}=A;return Eww(w,Q)},Eww=(A,Q)=>{let w=jm1();for(let $ in A){let B=A[$];Nd0(B,w,$,Q)}return w},Nd0=(A,Q,w,$)=>{let B=A.length;for(let X=0;X<B;X++){let Y=A[X];Tww(Y,Q,w,$)}},Tww=(A,Q,w,$)=>{if(typeof A==="string"){Sww(A,Q,w);return}if(typeof A==="function"){mww(A,Q,w,$);return}uww(A,Q,w,$)},Sww=(A,Q,w)=>{let $=A===""?Q:Mm1(Q,A);$.classGroupId=w},mww=(A,Q,w,$)=>{if(cww(A)){Nd0(A($),Q,w,$);return}if(Q.validators===null)Q.validators=[];Q.validators.push(hww(w,A))},uww=(A,Q,w,$)=>{let B=Object.entries(A),X=B.length;for(let Y=0;Y<X;Y++){let[Z,H]=B[Y];Nd0(H,Mm1(Q,Z),w,$)}},Mm1=(A,Q)=>{let w=A,$=Q.split("-"),B=$.length;for(let X=0;X<B;X++){let Y=$[X],Z=w.nextPart.get(Y);if(!Z)Z=jm1(),w.nextPart.set(Y,Z);w=Z}return w},cww=(A)=>("isThemeGetter"in A)&&A.isThemeGetter===!0,lww=(A)=>{if(A<1)return{get:()=>{return},set:()=>{}};let Q=0,w=Object.create(null),$=Object.create(null),B=(X,Y)=>{if(w[X]=Y,Q++,Q>A)Q=0,$=w,w=Object.create(null)};return{get(X){let Y=w[X];if(Y!==void 0)return Y;if((Y=$[X])!==void 0)return B(X,Y),Y},set(X,Y){if(X in w)w[X]=Y;else B(X,Y)}}};var pww=[],Fm1=(A,Q,w,$,B)=>({modifiers:A,hasImportantModifier:Q,baseClassName:w,maybePostfixModifierPosition:$,isExternal:B}),iww=(A)=>{let{prefix:Q,experimentalParseClassName:w}=A,$=(B)=>{let X=[],Y=0,Z=0,H=0,W,K=B.length;for(let I=0;I<K;I++){let J=B[I];if(Y===0&&Z===0){if(J===":"){X.push(B.slice(H,I)),H=I+1;continue}if(J==="/"){W=I;continue}}if(J==="[")Y++;else if(J==="]")Y--;else if(J==="(")Z++;else if(J===")")Z--}let U=X.length===0?B:B.slice(H),G=U,q=!1;if(U.endsWith("!"))G=U.slice(0,-1),q=!0;else if(U.startsWith("!"))G=U.slice(1),q=!0;let V=W&&W>H?W-H:void 0;return Fm1(X,q,G,V)};if(Q){let B=Q+":",X=$;$=(Y)=>Y.startsWith(B)?X(Y.slice(B.length)):Fm1(pww,!1,Y,void 0,!0)}if(w){let B=$;$=(X)=>w({className:X,parseClassName:B})}return $},dww=(A)=>{let Q=new Map;return A.orderSensitiveModifiers.forEach((w,$)=>{Q.set(w,1e6+$)}),(w)=>{let $=[],B=[];for(let X=0;X<w.length;X++){let Y=w[X],Z=Y[0]==="[",H=Q.has(Y);if(Z||H){if(B.length>0)B.sort(),$.push(...B),B=[];$.push(Y)}else B.push(Y)}if(B.length>0)B.sort(),$.push(...B);return $}},nww=(A)=>({cache:lww(A.cacheSize),parseClassName:iww(A),sortModifiers:dww(A),postfixLookupClassGroupIds:rww(A),...Cww(A)}),rww=(A)=>{let Q=Object.create(null),w=A.postfixLookupClassGroups;if(w)for(let $=0;$<w.length;$++)Q[w[$]]=!0;return Q},oww=/\s+/,sww=(A,Q)=>{let{parseClassName:w,getClassGroupId:$,getConflictingClassGroupIds:B,sortModifiers:X,postfixLookupClassGroupIds:Y}=Q,Z=[],H=A.trim().split(oww),W="";for(let K=H.length-1;K>=0;K-=1){let U=H[K],{isExternal:G,modifiers:q,hasImportantModifier:V,baseClassName:I,maybePostfixModifierPosition:J}=w(U);if(G){W=U+(W.length>0?" "+W:W);continue}let k=!!J,j;if(k){let M=I.substring(0,J);j=$(M);let S=j&&Y[j]?$(I):void 0;if(S&&S!==j)j=S,k=!1}else j=$(I);if(!j){if(!k){W=U+(W.length>0?" "+W:W);continue}if(j=$(I),!j){W=U+(W.length>0?" "+W:W);continue}k=!1}let _=q.length===0?"":q.length===1?q[0]:X(q).join(":"),x=V?_+"!":_,v=x+j;if(Z.indexOf(v)>-1)continue;Z.push(v);let O=B(j,k);for(let M=0;M<O.length;++M){let S=O[M];Z.push(x+S)}W=U+(W.length>0?" "+W:W)}return W},aww=(...A)=>{let Q=0,w,$,B="";while(Q<A.length)if(w=A[Q++]){if($=Om1(w))B&&(B+=" "),B+=$}return B},Om1=(A)=>{if(typeof A==="string")return A;let Q,w="";for(let $=0;$<A.length;$++)if(A[$]){if(Q=Om1(A[$]))w&&(w+=" "),w+=Q}return w},bm1=(A,...Q)=>{let w,$,B,X,Y=(H)=>{let W=Q.reduce((K,U)=>U(K),A());return w=nww(W),$=w.cache.get,B=w.cache.set,X=Z,Z(H)},Z=(H)=>{let W=$(H);if(W)return W;let K=sww(H,w);return B(H,K),K};return X=Y,(...H)=>X(aww(...H))},tww=[],u9=(A)=>{let Q=(w)=>w[A]||tww;return Q.isThemeGetter=!0,Q},xm1=/^\[(?:(\w[\w-]*):)?(.+)\]$/i,Rm1=/^\((?:(\w[\w-]*):)?(.+)\)$/i,eww=/^\d+(?:\.\d+)?\/\d+(?:\.\d+)?$/,A6w=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,Q6w=/\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$/,w6w=/^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/,$6w=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,B6w=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,ub=(A)=>eww.test(A),sw=(A)=>!!A&&!Number.isNaN(Number(A)),Zq=(A)=>!!A&&Number.isInteger(Number(A)),kd0=(A)=>A.endsWith("%")&&sw(A.slice(0,-1)),LV=(A)=>A6w.test(A),vm1=()=>!0,X6w=(A)=>Q6w.test(A)&&!w6w.test(A),jd0=()=>!1,Y6w=(A)=>$6w.test(A),Z6w=(A)=>B6w.test(A),f6w=(A)=>!O2(A)&&!h2(A),H6w=(A)=>A.startsWith("@container")&&(A[10]==="/"&&A[11]!==void 0||A[11]==="s"&&A[16]!==void 0&&A.startsWith("-size/",10)||A[11]==="n"&&A[18]!==void 0&&A.startsWith("-normal/",10)),W6w=(A)=>cb(A,gm1,jd0),O2=(A)=>xm1.test(A),GP=(A)=>cb(A,ym1,X6w),Lm1=(A)=>cb(A,J6w,sw),K6w=(A)=>cb(A,Tm1,vm1),U6w=(A)=>cb(A,Em1,jd0),km1=(A)=>cb(A,hm1,jd0),G6w=(A)=>cb(A,Cm1,Z6w),wX0=(A)=>cb(A,Sm1,Y6w),h2=(A)=>Rm1.test(A),Mr=(A)=>DP(A,ym1),D6w=(A)=>DP(A,Em1),_m1=(A)=>DP(A,hm1),q6w=(A)=>DP(A,gm1),z6w=(A)=>DP(A,Cm1),$X0=(A)=>DP(A,Sm1,!0),V6w=(A)=>DP(A,Tm1,!0),cb=(A,Q,w)=>{let $=xm1.exec(A);if($){if($[1])return Q($[1]);return w($[2])}return!1},DP=(A,Q,w=!1)=>{let $=Rm1.exec(A);if($){if($[1])return Q($[1]);return w}return!1},hm1=(A)=>A==="position"||A==="percentage",Cm1=(A)=>A==="image"||A==="url",gm1=(A)=>A==="length"||A==="size"||A==="bg-size",ym1=(A)=>A==="length",J6w=(A)=>A==="number",Em1=(A)=>A==="family-name",Tm1=(A)=>A==="number"||A==="weight",Sm1=(A)=>A==="shadow";var Nm1=()=>{let A=u9("color"),Q=u9("font"),w=u9("text"),$=u9("font-weight"),B=u9("tracking"),X=u9("leading"),Y=u9("breakpoint"),Z=u9("container"),H=u9("spacing"),W=u9("radius"),K=u9("shadow"),U=u9("inset-shadow"),G=u9("text-shadow"),q=u9("drop-shadow"),V=u9("blur"),I=u9("perspective"),J=u9("aspect"),k=u9("ease"),j=u9("animate"),_=()=>["auto","avoid","all","avoid-page","page","left","right","column"],x=()=>["center","top","bottom","left","right","top-left","left-top","top-right","right-top","bottom-right","right-bottom","bottom-left","left-bottom"],v=()=>[...x(),h2,O2],O=()=>["auto","hidden","clip","visible","scroll"],M=()=>["auto","contain","none"],S=()=>[h2,O2,H],u=()=>[ub,"full","auto",...S()],n=()=>[Zq,"none","subgrid",h2,O2],e=()=>["auto",{span:["full",Zq,h2,O2]},Zq,h2,O2],X0=()=>[Zq,"auto",h2,O2],l=()=>["auto","min","max","fr",h2,O2],P=()=>["start","end","center","between","around","evenly","stretch","baseline","center-safe","end-safe"],y=()=>["start","end","center","stretch","center-safe","end-safe"],g=()=>["auto",...S()],s=()=>[ub,"auto","full","dvw","dvh","lvw","lvh","svw","svh","min","max","fit",...S()],a=()=>[ub,"screen","full","dvw","lvw","svw","min","max","fit",...S()],D0=()=>[ub,"screen","full","lh","dvh","lvh","svh","min","max","fit",...S()],T=()=>[A,h2,O2],f0=()=>[...x(),_m1,km1,{position:[h2,O2]}],b0=()=>["no-repeat",{repeat:["","x","y","space","round"]}],i=()=>["auto","cover","contain",q6w,W6w,{size:[h2,O2]}],u0=()=>[kd0,Mr,GP],i0=()=>["","none","full",W,h2,O2],k0=()=>["",sw,Mr,GP],_0=()=>["solid","dashed","dotted","double"],v0=()=>["normal","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity"],S0=()=>[sw,kd0,_m1,km1],j0=()=>["","none",V,h2,O2],P0=()=>["none",sw,h2,O2],E0=()=>["none",sw,h2,O2],T0=()=>[sw,h2,O2],n0=()=>[ub,"full",...S()];return{cacheSize:500,theme:{animate:["spin","ping","pulse","bounce"],aspect:["video"],blur:[LV],breakpoint:[LV],color:[vm1],container:[LV],"drop-shadow":[LV],ease:["in","out","in-out"],font:[f6w],"font-weight":["thin","extralight","light","normal","medium","semibold","bold","extrabold","black"],"inset-shadow":[LV],leading:["none","tight","snug","normal","relaxed","loose"],perspective:["dramatic","near","normal","midrange","distant","none"],radius:[LV],shadow:[LV],spacing:["px",sw],text:[LV],"text-shadow":[LV],tracking:["tighter","tight","normal","wide","wider","widest"]},classGroups:{aspect:[{aspect:["auto","square",ub,O2,h2,J]}],container:["container"],"container-type":[{"@container":["","normal","size",h2,O2]}],"container-named":[H6w],columns:[{columns:[sw,O2,h2,Z]}],"break-after":[{"break-after":_()}],"break-before":[{"break-before":_()}],"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"],sr:["sr-only","not-sr-only"],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:v()}],overflow:[{overflow:O()}],"overflow-x":[{"overflow-x":O()}],"overflow-y":[{"overflow-y":O()}],overscroll:[{overscroll:M()}],"overscroll-x":[{"overscroll-x":M()}],"overscroll-y":[{"overscroll-y":M()}],position:["static","fixed","absolute","relative","sticky"],inset:[{inset:u()}],"inset-x":[{"inset-x":u()}],"inset-y":[{"inset-y":u()}],start:[{"inset-s":u(),start:u()}],end:[{"inset-e":u(),end:u()}],"inset-bs":[{"inset-bs":u()}],"inset-be":[{"inset-be":u()}],top:[{top:u()}],right:[{right:u()}],bottom:[{bottom:u()}],left:[{left:u()}],visibility:["visible","invisible","collapse"],z:[{z:[Zq,"auto",h2,O2]}],basis:[{basis:[ub,"full","auto",Z,...S()]}],"flex-direction":[{flex:["row","row-reverse","col","col-reverse"]}],"flex-wrap":[{flex:["nowrap","wrap","wrap-reverse"]}],flex:[{flex:[sw,ub,"auto","initial","none",O2]}],grow:[{grow:["",sw,h2,O2]}],shrink:[{shrink:["",sw,h2,O2]}],order:[{order:[Zq,"first","last","none",h2,O2]}],"grid-cols":[{"grid-cols":n()}],"col-start-end":[{col:e()}],"col-start":[{"col-start":X0()}],"col-end":[{"col-end":X0()}],"grid-rows":[{"grid-rows":n()}],"row-start-end":[{row:e()}],"row-start":[{"row-start":X0()}],"row-end":[{"row-end":X0()}],"grid-flow":[{"grid-flow":["row","col","dense","row-dense","col-dense"]}],"auto-cols":[{"auto-cols":l()}],"auto-rows":[{"auto-rows":l()}],gap:[{gap:S()}],"gap-x":[{"gap-x":S()}],"gap-y":[{"gap-y":S()}],"justify-content":[{justify:[...P(),"normal"]}],"justify-items":[{"justify-items":[...y(),"normal"]}],"justify-self":[{"justify-self":["auto",...y()]}],"align-content":[{content:["normal",...P()]}],"align-items":[{items:[...y(),{baseline:["","last"]}]}],"align-self":[{self:["auto",...y(),{baseline:["","last"]}]}],"place-content":[{"place-content":P()}],"place-items":[{"place-items":[...y(),"baseline"]}],"place-self":[{"place-self":["auto",...y()]}],p:[{p:S()}],px:[{px:S()}],py:[{py:S()}],ps:[{ps:S()}],pe:[{pe:S()}],pbs:[{pbs:S()}],pbe:[{pbe:S()}],pt:[{pt:S()}],pr:[{pr:S()}],pb:[{pb:S()}],pl:[{pl:S()}],m:[{m:g()}],mx:[{mx:g()}],my:[{my:g()}],ms:[{ms:g()}],me:[{me:g()}],mbs:[{mbs:g()}],mbe:[{mbe:g()}],mt:[{mt:g()}],mr:[{mr:g()}],mb:[{mb:g()}],ml:[{ml:g()}],"space-x":[{"space-x":S()}],"space-x-reverse":["space-x-reverse"],"space-y":[{"space-y":S()}],"space-y-reverse":["space-y-reverse"],size:[{size:s()}],"inline-size":[{inline:["auto",...a()]}],"min-inline-size":[{"min-inline":["auto",...a()]}],"max-inline-size":[{"max-inline":["none",...a()]}],"block-size":[{block:["auto",...D0()]}],"min-block-size":[{"min-block":["auto",...D0()]}],"max-block-size":[{"max-block":["none",...D0()]}],w:[{w:[Z,"screen",...s()]}],"min-w":[{"min-w":[Z,"screen","none",...s()]}],"max-w":[{"max-w":[Z,"screen","none","prose",{screen:[Y]},...s()]}],h:[{h:["screen","lh",...s()]}],"min-h":[{"min-h":["screen","lh","none",...s()]}],"max-h":[{"max-h":["screen","lh",...s()]}],"font-size":[{text:["base",w,Mr,GP]}],"font-smoothing":["antialiased","subpixel-antialiased"],"font-style":["italic","not-italic"],"font-weight":[{font:[$,V6w,K6w]}],"font-stretch":[{"font-stretch":["ultra-condensed","extra-condensed","condensed","semi-condensed","normal","semi-expanded","expanded","extra-expanded","ultra-expanded",kd0,O2]}],"font-family":[{font:[D6w,U6w,Q]}],"font-features":[{"font-features":[O2]}],"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:[B,h2,O2]}],"line-clamp":[{"line-clamp":[sw,"none",h2,Lm1]}],leading:[{leading:[X,...S()]}],"list-image":[{"list-image":["none",h2,O2]}],"list-style-position":[{list:["inside","outside"]}],"list-style-type":[{list:["disc","decimal","none",h2,O2]}],"text-alignment":[{text:["left","center","right","justify","start","end"]}],"placeholder-color":[{placeholder:T()}],"text-color":[{text:T()}],"text-decoration":["underline","overline","line-through","no-underline"],"text-decoration-style":[{decoration:[..._0(),"wavy"]}],"text-decoration-thickness":[{decoration:[sw,"from-font","auto",h2,GP]}],"text-decoration-color":[{decoration:T()}],"underline-offset":[{"underline-offset":[sw,"auto",h2,O2]}],"text-transform":["uppercase","lowercase","capitalize","normal-case"],"text-overflow":["truncate","text-ellipsis","text-clip"],"text-wrap":[{text:["wrap","nowrap","balance","pretty"]}],indent:[{indent:S()}],"tab-size":[{tab:[Zq,h2,O2]}],"vertical-align":[{align:["baseline","top","middle","bottom","text-top","text-bottom","sub","super",h2,O2]}],whitespace:[{whitespace:["normal","nowrap","pre","pre-line","pre-wrap","break-spaces"]}],break:[{break:["normal","words","all","keep"]}],wrap:[{wrap:["break-word","anywhere","normal"]}],hyphens:[{hyphens:["none","manual","auto"]}],content:[{content:["none",h2,O2]}],"bg-attachment":[{bg:["fixed","local","scroll"]}],"bg-clip":[{"bg-clip":["border","padding","content","text"]}],"bg-origin":[{"bg-origin":["border","padding","content"]}],"bg-position":[{bg:f0()}],"bg-repeat":[{bg:b0()}],"bg-size":[{bg:i()}],"bg-image":[{bg:["none",{linear:[{to:["t","tr","r","br","b","bl","l","tl"]},Zq,h2,O2],radial:["",h2,O2],conic:[Zq,h2,O2]},z6w,G6w]}],"bg-color":[{bg:T()}],"gradient-from-pos":[{from:u0()}],"gradient-via-pos":[{via:u0()}],"gradient-to-pos":[{to:u0()}],"gradient-from":[{from:T()}],"gradient-via":[{via:T()}],"gradient-to":[{to:T()}],rounded:[{rounded:i0()}],"rounded-s":[{"rounded-s":i0()}],"rounded-e":[{"rounded-e":i0()}],"rounded-t":[{"rounded-t":i0()}],"rounded-r":[{"rounded-r":i0()}],"rounded-b":[{"rounded-b":i0()}],"rounded-l":[{"rounded-l":i0()}],"rounded-ss":[{"rounded-ss":i0()}],"rounded-se":[{"rounded-se":i0()}],"rounded-ee":[{"rounded-ee":i0()}],"rounded-es":[{"rounded-es":i0()}],"rounded-tl":[{"rounded-tl":i0()}],"rounded-tr":[{"rounded-tr":i0()}],"rounded-br":[{"rounded-br":i0()}],"rounded-bl":[{"rounded-bl":i0()}],"border-w":[{border:k0()}],"border-w-x":[{"border-x":k0()}],"border-w-y":[{"border-y":k0()}],"border-w-s":[{"border-s":k0()}],"border-w-e":[{"border-e":k0()}],"border-w-bs":[{"border-bs":k0()}],"border-w-be":[{"border-be":k0()}],"border-w-t":[{"border-t":k0()}],"border-w-r":[{"border-r":k0()}],"border-w-b":[{"border-b":k0()}],"border-w-l":[{"border-l":k0()}],"divide-x":[{"divide-x":k0()}],"divide-x-reverse":["divide-x-reverse"],"divide-y":[{"divide-y":k0()}],"divide-y-reverse":["divide-y-reverse"],"border-style":[{border:[..._0(),"hidden","none"]}],"divide-style":[{divide:[..._0(),"hidden","none"]}],"border-color":[{border:T()}],"border-color-x":[{"border-x":T()}],"border-color-y":[{"border-y":T()}],"border-color-s":[{"border-s":T()}],"border-color-e":[{"border-e":T()}],"border-color-bs":[{"border-bs":T()}],"border-color-be":[{"border-be":T()}],"border-color-t":[{"border-t":T()}],"border-color-r":[{"border-r":T()}],"border-color-b":[{"border-b":T()}],"border-color-l":[{"border-l":T()}],"divide-color":[{divide:T()}],"outline-style":[{outline:[..._0(),"none","hidden"]}],"outline-offset":[{"outline-offset":[sw,h2,O2]}],"outline-w":[{outline:["",sw,Mr,GP]}],"outline-color":[{outline:T()}],shadow:[{shadow:["","none",K,$X0,wX0]}],"shadow-color":[{shadow:T()}],"inset-shadow":[{"inset-shadow":["none",U,$X0,wX0]}],"inset-shadow-color":[{"inset-shadow":T()}],"ring-w":[{ring:k0()}],"ring-w-inset":["ring-inset"],"ring-color":[{ring:T()}],"ring-offset-w":[{"ring-offset":[sw,GP]}],"ring-offset-color":[{"ring-offset":T()}],"inset-ring-w":[{"inset-ring":k0()}],"inset-ring-color":[{"inset-ring":T()}],"text-shadow":[{"text-shadow":["none",G,$X0,wX0]}],"text-shadow-color":[{"text-shadow":T()}],opacity:[{opacity:[sw,h2,O2]}],"mix-blend":[{"mix-blend":[...v0(),"plus-darker","plus-lighter"]}],"bg-blend":[{"bg-blend":v0()}],"mask-clip":[{"mask-clip":["border","padding","content","fill","stroke","view"]},"mask-no-clip"],"mask-composite":[{mask:["add","subtract","intersect","exclude"]}],"mask-image-linear-pos":[{"mask-linear":[sw]}],"mask-image-linear-from-pos":[{"mask-linear-from":S0()}],"mask-image-linear-to-pos":[{"mask-linear-to":S0()}],"mask-image-linear-from-color":[{"mask-linear-from":T()}],"mask-image-linear-to-color":[{"mask-linear-to":T()}],"mask-image-t-from-pos":[{"mask-t-from":S0()}],"mask-image-t-to-pos":[{"mask-t-to":S0()}],"mask-image-t-from-color":[{"mask-t-from":T()}],"mask-image-t-to-color":[{"mask-t-to":T()}],"mask-image-r-from-pos":[{"mask-r-from":S0()}],"mask-image-r-to-pos":[{"mask-r-to":S0()}],"mask-image-r-from-color":[{"mask-r-from":T()}],"mask-image-r-to-color":[{"mask-r-to":T()}],"mask-image-b-from-pos":[{"mask-b-from":S0()}],"mask-image-b-to-pos":[{"mask-b-to":S0()}],"mask-image-b-from-color":[{"mask-b-from":T()}],"mask-image-b-to-color":[{"mask-b-to":T()}],"mask-image-l-from-pos":[{"mask-l-from":S0()}],"mask-image-l-to-pos":[{"mask-l-to":S0()}],"mask-image-l-from-color":[{"mask-l-from":T()}],"mask-image-l-to-color":[{"mask-l-to":T()}],"mask-image-x-from-pos":[{"mask-x-from":S0()}],"mask-image-x-to-pos":[{"mask-x-to":S0()}],"mask-image-x-from-color":[{"mask-x-from":T()}],"mask-image-x-to-color":[{"mask-x-to":T()}],"mask-image-y-from-pos":[{"mask-y-from":S0()}],"mask-image-y-to-pos":[{"mask-y-to":S0()}],"mask-image-y-from-color":[{"mask-y-from":T()}],"mask-image-y-to-color":[{"mask-y-to":T()}],"mask-image-radial":[{"mask-radial":[h2,O2]}],"mask-image-radial-from-pos":[{"mask-radial-from":S0()}],"mask-image-radial-to-pos":[{"mask-radial-to":S0()}],"mask-image-radial-from-color":[{"mask-radial-from":T()}],"mask-image-radial-to-color":[{"mask-radial-to":T()}],"mask-image-radial-shape":[{"mask-radial":["circle","ellipse"]}],"mask-image-radial-size":[{"mask-radial":[{closest:["side","corner"],farthest:["side","corner"]}]}],"mask-image-radial-pos":[{"mask-radial-at":x()}],"mask-image-conic-pos":[{"mask-conic":[sw]}],"mask-image-conic-from-pos":[{"mask-conic-from":S0()}],"mask-image-conic-to-pos":[{"mask-conic-to":S0()}],"mask-image-conic-from-color":[{"mask-conic-from":T()}],"mask-image-conic-to-color":[{"mask-conic-to":T()}],"mask-mode":[{mask:["alpha","luminance","match"]}],"mask-origin":[{"mask-origin":["border","padding","content","fill","stroke","view"]}],"mask-position":[{mask:f0()}],"mask-repeat":[{mask:b0()}],"mask-size":[{mask:i()}],"mask-type":[{"mask-type":["alpha","luminance"]}],"mask-image":[{mask:["none",h2,O2]}],filter:[{filter:["","none",h2,O2]}],blur:[{blur:j0()}],brightness:[{brightness:[sw,h2,O2]}],contrast:[{contrast:[sw,h2,O2]}],"drop-shadow":[{"drop-shadow":["","none",q,$X0,wX0]}],"drop-shadow-color":[{"drop-shadow":T()}],grayscale:[{grayscale:["",sw,h2,O2]}],"hue-rotate":[{"hue-rotate":[sw,h2,O2]}],invert:[{invert:["",sw,h2,O2]}],saturate:[{saturate:[sw,h2,O2]}],sepia:[{sepia:["",sw,h2,O2]}],"backdrop-filter":[{"backdrop-filter":["","none",h2,O2]}],"backdrop-blur":[{"backdrop-blur":j0()}],"backdrop-brightness":[{"backdrop-brightness":[sw,h2,O2]}],"backdrop-contrast":[{"backdrop-contrast":[sw,h2,O2]}],"backdrop-grayscale":[{"backdrop-grayscale":["",sw,h2,O2]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[sw,h2,O2]}],"backdrop-invert":[{"backdrop-invert":["",sw,h2,O2]}],"backdrop-opacity":[{"backdrop-opacity":[sw,h2,O2]}],"backdrop-saturate":[{"backdrop-saturate":[sw,h2,O2]}],"backdrop-sepia":[{"backdrop-sepia":["",sw,h2,O2]}],"border-collapse":[{border:["collapse","separate"]}],"border-spacing":[{"border-spacing":S()}],"border-spacing-x":[{"border-spacing-x":S()}],"border-spacing-y":[{"border-spacing-y":S()}],"table-layout":[{table:["auto","fixed"]}],caption:[{caption:["top","bottom"]}],transition:[{transition:["","all","colors","opacity","shadow","transform","none",h2,O2]}],"transition-behavior":[{transition:["normal","discrete"]}],duration:[{duration:[sw,"initial",h2,O2]}],ease:[{ease:["linear","initial",k,h2,O2]}],delay:[{delay:[sw,h2,O2]}],animate:[{animate:["none",j,h2,O2]}],backface:[{backface:["hidden","visible"]}],perspective:[{perspective:[I,h2,O2]}],"perspective-origin":[{"perspective-origin":v()}],rotate:[{rotate:P0()}],"rotate-x":[{"rotate-x":P0()}],"rotate-y":[{"rotate-y":P0()}],"rotate-z":[{"rotate-z":P0()}],scale:[{scale:E0()}],"scale-x":[{"scale-x":E0()}],"scale-y":[{"scale-y":E0()}],"scale-z":[{"scale-z":E0()}],"scale-3d":["scale-3d"],skew:[{skew:T0()}],"skew-x":[{"skew-x":T0()}],"skew-y":[{"skew-y":T0()}],transform:[{transform:[h2,O2,"","none","gpu","cpu"]}],"transform-origin":[{origin:v()}],"transform-style":[{transform:["3d","flat"]}],translate:[{translate:n0()}],"translate-x":[{"translate-x":n0()}],"translate-y":[{"translate-y":n0()}],"translate-z":[{"translate-z":n0()}],"translate-none":["translate-none"],zoom:[{zoom:[Zq,h2,O2]}],accent:[{accent:T()}],appearance:[{appearance:["none","auto"]}],"caret-color":[{caret:T()}],"color-scheme":[{scheme:["normal","dark","light","light-dark","only-dark","only-light"]}],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",h2,O2]}],"field-sizing":[{"field-sizing":["fixed","content"]}],"pointer-events":[{"pointer-events":["auto","none"]}],resize:[{resize:["none","","y","x"]}],"scroll-behavior":[{scroll:["auto","smooth"]}],"scrollbar-thumb-color":[{"scrollbar-thumb":T()}],"scrollbar-track-color":[{"scrollbar-track":T()}],"scrollbar-gutter":[{"scrollbar-gutter":["auto","stable","both"]}],"scrollbar-w":[{scrollbar:["auto","thin","none"]}],"scroll-m":[{"scroll-m":S()}],"scroll-mx":[{"scroll-mx":S()}],"scroll-my":[{"scroll-my":S()}],"scroll-ms":[{"scroll-ms":S()}],"scroll-me":[{"scroll-me":S()}],"scroll-mbs":[{"scroll-mbs":S()}],"scroll-mbe":[{"scroll-mbe":S()}],"scroll-mt":[{"scroll-mt":S()}],"scroll-mr":[{"scroll-mr":S()}],"scroll-mb":[{"scroll-mb":S()}],"scroll-ml":[{"scroll-ml":S()}],"scroll-p":[{"scroll-p":S()}],"scroll-px":[{"scroll-px":S()}],"scroll-py":[{"scroll-py":S()}],"scroll-ps":[{"scroll-ps":S()}],"scroll-pe":[{"scroll-pe":S()}],"scroll-pbs":[{"scroll-pbs":S()}],"scroll-pbe":[{"scroll-pbe":S()}],"scroll-pt":[{"scroll-pt":S()}],"scroll-pr":[{"scroll-pr":S()}],"scroll-pb":[{"scroll-pb":S()}],"scroll-pl":[{"scroll-pl":S()}],"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",h2,O2]}],fill:[{fill:["none",...T()]}],"stroke-w":[{stroke:[sw,Mr,GP,Lm1]}],stroke:[{stroke:["none",...T()]}],"forced-color-adjust":[{"forced-color-adjust":["auto","none"]}]},conflictingClassGroups:{"container-named":["container-type"],overflow:["overflow-x","overflow-y"],overscroll:["overscroll-x","overscroll-y"],inset:["inset-x","inset-y","inset-bs","inset-be","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","pbs","pbe","pt","pr","pb","pl"],px:["pr","pl"],py:["pt","pb"],m:["mx","my","ms","me","mbs","mbe","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-x","border-w-y","border-w-s","border-w-e","border-w-bs","border-w-be","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-x","border-color-y","border-color-s","border-color-e","border-color-bs","border-color-be","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"],translate:["translate-x","translate-y","translate-none"],"translate-none":["translate","translate-x","translate-y","translate-z"],"scroll-m":["scroll-mx","scroll-my","scroll-ms","scroll-me","scroll-mbs","scroll-mbe","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-pbs","scroll-pbe","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"]},postfixLookupClassGroups:["container-type"],orderSensitiveModifiers:["*","**","after","backdrop","before","details-content","file","first-letter","first-line","marker","placeholder","selection"]}},I6w=(A,{cacheSize:Q,prefix:w,experimentalParseClassName:$,extend:B={},override:X={}})=>{return Hy(A,"cacheSize",Q),Hy(A,"prefix",w),Hy(A,"experimentalParseClassName",$),BX0(A.theme,X.theme),BX0(A.classGroups,X.classGroups),BX0(A.conflictingClassGroups,X.conflictingClassGroups),BX0(A.conflictingClassGroupModifiers,X.conflictingClassGroupModifiers),Hy(A,"postfixLookupClassGroups",X.postfixLookupClassGroups),Hy(A,"orderSensitiveModifiers",X.orderSensitiveModifiers),XX0(A.theme,B.theme),XX0(A.classGroups,B.classGroups),XX0(A.conflictingClassGroups,B.conflictingClassGroups),XX0(A.conflictingClassGroupModifiers,B.conflictingClassGroupModifiers),_d0(A,B,"postfixLookupClassGroups"),_d0(A,B,"orderSensitiveModifiers"),A},Hy=(A,Q,w)=>{if(w!==void 0)A[Q]=w},BX0=(A,Q)=>{if(Q)for(let w in Q)Hy(A,w,Q[w])},XX0=(A,Q)=>{if(Q)for(let w in Q)_d0(A,Q,w)},_d0=(A,Q,w)=>{let $=Q[w];if($!==void 0)A[w]=A[w]?A[w].concat($):$},YX0=(A,...Q)=>typeof A==="function"?bm1(Nm1,A,...Q):bm1(()=>I6w(Nm1(),A),...Q);var F6w=YX0({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 C2(...A){return F6w(fy(A))}var mm1=(A)=>typeof A==="boolean"?`${A}`:A===0?"0":A,um1=fy,T$=(A,Q)=>(w)=>{var $;if((Q===null||Q===void 0?void 0:Q.variants)==null)return um1(A,w===null||w===void 0?void 0:w.class,w===null||w===void 0?void 0:w.className);let{variants:B,defaultVariants:X}=Q,Y=Object.keys(B).map((W)=>{let K=w===null||w===void 0?void 0:w[W],U=X===null||X===void 0?void 0:X[W];if(K===null)return null;let G=mm1(K)||mm1(U);return B[W][G]}),Z=w&&Object.entries(w).reduce((W,K)=>{let[U,G]=K;if(G===void 0)return W;return W[U]=G,W},{}),H=Q===null||Q===void 0?void 0:($=Q.compoundVariants)===null||$===void 0?void 0:$.reduce((W,K)=>{let{class:U,className:G,...q}=K;return Object.entries(q).every((V)=>{let[I,J]=V;return Array.isArray(J)?J.includes({...X,...Z}[I]):{...X,...Z}[I]===J})?[...W,U,G]:W},[]);return um1(A,Y,H,w===null||w===void 0?void 0:w.class,w===null||w===void 0?void 0:w.className)};import{jsxDEV as Pd0}from"preact/jsx-dev-runtime";var cm1=T$("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 Md0({variant:A,title:Q,children:w,className:$}){return Pd0("div",{className:C2(cm1({variant:A}),$),role:"alert",children:[Q&&Pd0("p",{className:"font-medium text-current opacity-90",children:Q},void 0,!1,void 0,this),Pd0("div",{className:C2(Q&&"mt-1","text-sm text-current opacity-75"),children:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}import{jsxDEV as b6w}from"preact/jsx-dev-runtime";var lm1=T$("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 qP({variant:A,size:Q,className:w,children:$,ssrOnClick:B,type:X="button",...Y}){return b6w("button",{type:X,className:C2(lm1({variant:A,size:Q}),w),...Y,...B&&{onclick:B},children:$},void 0,!1,void 0,this)}import{jsxDEV as L6w}from"preact/jsx-dev-runtime";var pm1=T$("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 c9({href:A,children:Q,variant:w,size:$,external:B=!1,className:X,"aria-label":Y}){let Z=B?{target:"_blank",rel:"noopener noreferrer"}:{};return L6w("a",{href:A,className:C2(pm1({variant:w,size:$}),X),"aria-label":Y,...Z,children:Q},void 0,!1,void 0,this)}import{jsxDEV as ZX0}from"preact/jsx-dev-runtime";var im1=T$("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"}}),k6w={sm:"w-4 h-4",md:"w-5 h-5",lg:"w-6 h-6"};function Wy({variant:A,size:Q,className:w}){let $=k6w[Q??"md"];return ZX0("button",{onclick:"toggleTheme()",type:"button",className:C2(im1({variant:A,size:Q}),w),"aria-label":"Toggle dark mode",children:ZX0("svg",{className:C2($,"transition-colors"),fill:"none",stroke:"currentColor",strokeWidth:1.6,viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:[ZX0("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),ZX0("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 Od0}from"preact/jsx-dev-runtime";var dm1=T$("flex flex-wrap",{variants:{orientation:{horizontal:"justify-center gap-6 items-center",vertical:"flex-col gap-2.5"}},defaultVariants:{orientation:"horizontal"}});function fX0({items:A,className:Q,linkClassName:w="hover:text-accent transition-colors",orientation:$,children:B}){if(A.length===0&&!B)return null;let X=[...A].sort((Y,Z)=>Y.priority-Z.priority);return Od0("ul",{className:C2(dm1({orientation:$}),Q),children:[X.map((Y)=>Od0("li",{children:Od0("a",{href:Y.href,className:w,children:Y.label},void 0,!1,void 0,this)},Y.href,!1,void 0,this)),B]},void 0,!0,void 0,this)}import{jsxDEV as a28}from"preact/jsx-dev-runtime";import{jsxDEV as AQ8}from"preact/jsx-dev-runtime";import{createContext as _6w,h as N6w}from"preact";import{useContext as j6w}from"preact/hooks";var xd0=_6w(null);function Ky({headCollector:A,children:Q}){return N6w(xd0.Provider,{value:A},Q)}function nm1(){return j6w(xd0)}function $w(A){let Q=nm1();if(Q)Q.setHeadProps(A);return null}import{createContext as $4w,h as B4w}from"preact";import{useContext as X4w}from"preact/hooks";vx0();var $i1=D1(wi1(),1),Q4w=new w$0({gfm:!0,breaks:!0}),w4w={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 Qr0(A,Q){let{imageRenderer:w}=Q??{},B=(w?new w$0({gfm:!0,breaks:!0}).use({renderer:{image({href:X,title:Y,text:Z}){return w(X,Y,Z)??!1}}}):Q4w).parse(A);return B=B.replace(/<\/blockquote>\s*<p>(\u2014|--|\u2013)([\s\S]*?)<\/p>/g,`</blockquote>
5762
5762
  <cite class="block-attribution"><span class="emdash">$1</span>$2</cite>`),$i1.default(B,w4w)}var Bi1=$4w(null);function My({imageRenderer:A,children:Q}){return B4w(Bi1.Provider,{value:A??null},Q)}function Xi1(){return X4w(Bi1)}function xV(){let A=Xi1();return(Q)=>Qr0(Q,A?{imageRenderer:A}:void 0)}var Y4w=/<pre><code class="language-mermaid">([\s\S]*?)<\/code><\/pre>/g,Z4w={"&amp;":"&","&lt;":"<","&gt;":">","&quot;":'"',"&#39;":"'"},f4w=/&(?:amp|lt|gt|quot|#39);/g;function H4w(A){return A.replace(f4w,(Q)=>Z4w[Q]??Q)}function wr0(A){return A.replace(Y4w,(Q,w)=>{return`<div class="mermaid">${H4w(w)}</div>`})}var Yi1=/<!--\s*\.slide:\s*(.*?)\s*-->/g;function Zi1(A){let Q={};for(let $ of A.matchAll(Yi1)){let B=$[1]??"";for(let Y of B.matchAll(/([\w-]+)=["']([^"']*?)["']/g)){let Z=Y[1],H=Y[2];if(Z&&H!==void 0)Q[Z]=H}let X=B.replace(/([\w-]+)=["']([^"']*?)["']/g,"").trim();if(X)for(let Y of X.matchAll(/(?:^|\s)([\w-]+)(?=\s|$)/g)){let Z=Y[1];if(Z)Q[Z]="true"}}let w=A.replace(Yi1,"").replace(/^\n+/,"").replace(/\n{3,}/g,`
5763
5763
 
5764
5764
  `).trim();return{attributes:Q,markdown:w}}var W4w=/<!--\s*\.break\s*-->/;function fi1(A){let Q=A.split(W4w);return Q.length>1?Q:null}import{jsxDEV as Dq}from"preact/jsx-dev-runtime";var $r0=({markdown:A,deck:Q})=>{let w=xV(),B=A.split(/^---$/gm).map((K)=>K.trim()).map((K)=>{let{attributes:U,markdown:G}=Zi1(K),q=fi1(G),V;if(q)V=`<div class="slide-columns">${q.map((J)=>`<div class="slide-column">${wr0(w(J.trim()))}</div>`).join("")}</div>`;else V=wr0(w(G));return{attributes:U,htmlContent:V}}),X=B.some((K)=>K.htmlContent.includes('class="mermaid"')),Y=Q?.frontmatter?.title??Q?.metadata?.title,Z=Q?.frontmatter?.description??Q?.metadata?.description,H=Q?.ogImageUrl??Q?.coverImageUrl,W=B.map(({attributes:K,htmlContent:U},G)=>Dq("section",{...K,dangerouslySetInnerHTML:{__html:U}},G,!1,void 0,this));return Dq("section",{className:"presentation-section",children:[Y&&Dq($w,{title:Y,...Z?{description:Z}:{},...H?{ogImage:H}:{},ogType:"article"},void 0,!1,void 0,this),Dq("link",{rel:"stylesheet",href:"https://cdn.jsdelivr.net/npm/reveal.js@5.1.0/dist/reveal.min.css"},void 0,!1,void 0,this),Dq("div",{className:"reveal",children:Dq("div",{className:"slides",children:W},void 0,!1,void 0,this)},void 0,!1,void 0,this),Dq("script",{src:"https://cdn.jsdelivr.net/npm/reveal.js@5.1.0/dist/reveal.min.js",defer:!0},void 0,!1,void 0,this),X&&Dq("script",{src:"https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js",defer:!0},void 0,!1,void 0,this),Dq("script",{dangerouslySetInnerHTML:{__html:`
@@ -6745,13 +6745,13 @@ ${A.map((X)=>({url:`${Q}${X.path}`,lastmod:w,changefreq:X.path==="/"?"daily":"we
6745
6745
  `+B:w,Y=jq(this.outputDir,"styles","main.css");await this.cssProcessor.process(X,Y,this.workingDir,this.outputDir,this.logger);let Z=await W4.readFile(Y,"utf-8"),H=$.length>0?$:Q;if(H.length>0){let W=H.join(`
6746
6746
  `)+`
6747
6747
 
6748
- `+Z;await W4.writeFile(Y,W,"utf-8")}this.logger.debug("CSS processed successfully with font imports")}async copyStaticAssets(){this.logger.debug("Copying static assets from public/ directory");let A=jq(process.cwd(),"public");try{await W4.access(A)}catch{this.logger.debug("No public/ directory found, skipping static assets");return}let Q=await W4.readdir(A,{withFileTypes:!0});for(let w of Q){let $=jq(A,w.name),B=jq(this.outputDir,w.name);if(w.isDirectory())await this.copyDirectory($,B);else await W4.copyFile($,B),this.logger.debug(`Copied static asset: ${w.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([w,$])=>{let B=w.startsWith("/")?w.slice(1):w,X=jq(this.outputDir,B);await W4.mkdir(pFw(X),{recursive:!0}),await W4.writeFile(X,$,"utf-8"),this.logger.debug(`Wrote inline static asset: ${B}`)}))}async copyDirectory(A,Q){await W4.mkdir(Q,{recursive:!0});let w=await W4.readdir(A,{withFileTypes:!0});for(let $ of w){let B=jq(A,$.name),X=jq(Q,$.name);if($.isDirectory())await this.copyDirectory(B,X);else await W4.copyFile(B,X)}}}function Qa0(A){return new X12(A)}Y7();C0();C0();var iFw=f.object({heading:f.string(),buttonText:f.string(),buttonLink:f.string()}),dFw=f.object({blurb:f.string().optional()}),fE=f.object({title:f.string(),description:f.string(),url:f.string().optional(),copyright:f.string().optional(),logo:f.boolean().optional(),themeMode:f.enum(["light","dark"]).optional(),analyticsScript:f.string().optional(),cta:iFw.optional(),sections:f.record(f.string(),dFw).optional()});var Y12=f.object({environment:f.enum(["preview","production"]),outputDir:f.string(),workingDir:f.string().optional(),sharedImagesDir:f.string().default("./dist/images"),enableContentGeneration:f.boolean().default(!1),cleanBeforeBuild:f.boolean().default(!0),siteConfig:fE,layouts:f.record(f.string(),f.any()),themeCSS:f.string().optional()}),mZ8=f.object({success:f.boolean(),outputDir:f.string(),filesGenerated:f.number(),routesBuilt:f.number(),errors:f.array(f.string()).optional(),warnings:f.array(f.string()).optional()});function Z12(A){let Q=A.list(),w=Q.length===0?["No routes registered for site build"]:[];return{routes:Q,warnings:w}}function f12(A,Q,w){let $=Q.getProfile(),B=w.getNavigationItems("primary"),X=w.getNavigationItems("secondary");return{...A,...$.socialLinks!==void 0&&{socialLinks:$.socialLinks},navigation:{primary:B,secondary:X},copyright:A.copyright??"Powered by Rizom"}}Y7();p4();Y7();b2();C0();var nFw=f.looseObject({id:f.string(),entityType:f.string(),content:f.string(),metadata:f.looseObject({slug:f.string()})}),rFw=f.looseObject({content:f.string(),metadata:f.looseObject({width:f.number().optional(),height:f.number().optional()})});async function TZ0(A,Q){let w=Q.urlGenerator??R4.getInstance();if(A===null||A===void 0)return A;if(Array.isArray(A))return Promise.all(A.map((x)=>TZ0(x,{...Q,urlGenerator:w})));if(typeof A!=="object")return A;let $={},B=Object.entries(A),X=await Promise.all(B.map(([,x])=>TZ0(x,{...Q,urlGenerator:w})));for(let x=0;x<B.length;x++){let v=B[x];if(v)$[v[0]]=X[x]}let Y=nFw.safeParse(A);if(!Y.success)return $;let Z=Y.data,H=Z.entityType,W=Z.metadata.slug,K=Q.pipelineContext.entityDisplay?.[H],U=K?K.label:H.charAt(0).toUpperCase()+H.slice(1),G=K?K.pluralName??K.label.toLowerCase()+"s":yK(H),q=`/${G}`,V=G.charAt(0).toUpperCase()+G.slice(1),I=$l(Z),J=await oFw(I,Q),k=xw0(Z)??I,j=await sFw(k,Q);return{...$,...Z,url:w.generateUrl(H,W),typeLabel:U,listUrl:q,listLabel:V,...J,...j&&{ogImageUrl:j}}}async function oFw(A,Q){let w=A?Q.imageBuildService?.get(A):void 0;if(w)return{coverImageUrl:w.src,coverImageWidth:w.width,coverImageHeight:w.height,...w.srcset&&{coverImageSrcset:w.srcset,coverImageSizes:w.sizes}};let $=await W12(A,Q.pipelineContext.services.entityService);if(!$)return{};return{coverImageUrl:$.url,...$.width&&{coverImageWidth:$.width},...$.height&&{coverImageHeight:$.height}}}async function sFw(A,Q){if(!A)return;let w=Q.imageBuildService?.get(A);if(w)return H12(w.src,Q.siteUrl);let $=await W12(A,Q.pipelineContext.services.entityService);if(!$)return;if($.url.startsWith("data:"))return;return H12($.url,Q.siteUrl)}function H12(A,Q){if(/^https?:\/\//i.test(A)||A.startsWith("data:"))return A;if(!Q)return A;return`${Q.replace(/\/$/,"")}/${A.replace(/^\//,"")}`}async function W12(A,Q){if(!A)return;let w=await Q.getEntity({entityType:"image",id:A}),$=rFw.safeParse(w);if(!$.success)return;return{url:$.data.content,...$.data.metadata.width&&{width:$.data.metadata.width},...$.data.metadata.height&&{height:$.data.metadata.height}}}async function K12(A,Q){let w=new Set;try{let $=A.getEntityTypes();for(let B of $){if(B==="image")continue;let X=await A.listEntities({entityType:B});for(let Y of X){let Z=$l(Y);if(Z)w.add(Z);let H=xw0(Y);if(H)w.add(H)}}}catch($){Q.warn("Failed to collect image IDs for pre-resolution",{error:dA($)})}return[...w]}async function U12(A,Q,w,$,B){if(!A.template)return A.content??null;let X=A.template,Y=A.dataQuery?{dataParams:A.dataQuery,fallback:A.content,publishedOnly:w,visibilityScope:$}:{savedContent:{entityType:"site-content",entityId:`${Q.id}:${A.id}`},fallback:A.content,visibilityScope:$},Z=await B.pipelineContext.services.resolveTemplateContent(X,Y);if(!Z)return null;return TZ0(Z,{pipelineContext:B.pipelineContext,imageBuildService:B.imageBuildService,siteUrl:B.siteUrl,urlGenerator:R4.getInstance()})}function G12(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,w)=>{let $=A.parsedOptions.environment==="production";return U12(w,Q,$,"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 f12(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 aFw}from"path";async function D12(A){let Q=A.parsedOptions.workingDir??aFw(A.parsedOptions.outputDir,".preact-work"),w=A.staticSiteBuilderFactory({logger:A.logger.child("StaticSiteBuilder"),workingDir:Q,outputDir:A.parsedOptions.outputDir});if(A.parsedOptions.cleanBeforeBuild)await w.clean();return w}async function q12(A){await new yZ0({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 z12(A){let Q=new gZ0(A.pipelineContext.services.entityService,A.pipelineContext.logger,A.sharedImagesDir),w=await K12(A.pipelineContext.services.entityService,A.pipelineContext.logger);if(w.length>0)await Q.resolveAll(w);return Q}async function V12(A){let Q=A.reporter?.createSub({scale:{start:85,end:95}});await A.staticSiteBuilder.build(A.buildContext,(w)=>{Q?.report(w).catch(()=>{})})}function J12(A){return{success:!0,outputDir:A.outputDir,filesGenerated:A.routesBuilt+1,routesBuilt:A.routesBuilt,...A.warnings.length>0&&{warnings:A.warnings}}}function I12(A){return{success:!1,outputDir:A.outputDir,filesGenerated:0,routesBuilt:0,errors:[A.errorMessage]}}async function F12(A){let Q=Y12.parse(A.buildOptions),w=hX.from(A.progress),$=[];try{await w?.report({message:"Starting site build",progress:0,total:100}),await w?.report({message:"Generating dynamic routes",progress:10,total:100}),await q12({pipelineContext:A.pipelineContext,publishedOnly:Q.environment==="production"});let B=await D12({logger:A.pipelineContext.logger,parsedOptions:Q,staticSiteBuilderFactory:A.staticSiteBuilderFactory}),X=Z12(A.pipelineContext.routeRegistry);$.push(...X.warnings);let{routes:Y}=X;await w?.report({message:`Building ${Y.length} routes`,progress:20,total:100}),await w?.report({message:"Resolving images",progress:25,total:100});let Z=await z12({pipelineContext:A.pipelineContext,sharedImagesDir:Q.sharedImagesDir}),H=G12({routes:Y,parsedOptions:Q,buildOptions:A.buildOptions,pipelineContext:A.pipelineContext,imageBuildService:Z,siteMetadata:Q.siteConfig});return await V12({staticSiteBuilder:B,buildContext:H,reporter:w}),await w?.report({message:"Site build complete",progress:100,total:100}),J12({outputDir:Q.outputDir,routesBuilt:Y.length,warnings:$})}catch(B){let X=Error("Site build process failed");return A.pipelineContext.logger.error("Site build failed",{error:X,originalError:B}),I12({outputDir:Q.outputDir,errorMessage:X.message})}}class YH{static instance=null;static defaultStaticSiteBuilderFactory=Qa0;pipelineContext;staticSiteBuilderFactory;static setDefaultStaticSiteBuilderFactory(A){YH.defaultStaticSiteBuilderFactory=A}static getInstance(A,Q,w,$,B=void 0){return YH.instance??=new YH(A,YH.defaultStaticSiteBuilderFactory,Q,w,$,B),YH.instance}static resetInstance(){YH.instance=null}static createFresh(A,Q,w,$,B,X=void 0){return new YH(A,B??YH.defaultStaticSiteBuilderFactory,Q,w,$,X)}constructor(A,Q,w,$,B,X){this.pipelineContext={logger:A,services:w,routeRegistry:$,profileService:B,entityDisplay:X},this.staticSiteBuilderFactory=Q,R4.getInstance().configure(X)}async build(A,Q){return F12({buildOptions:A,progress:Q,pipelineContext:this.pipelineContext,staticSiteBuilderFactory:this.staticSiteBuilderFactory})}}class wa0{config;context;pluginId;logger;debounces=new Map;unsubscribeFunctions=[];constructor(A,Q,w,$){this.config=A,this.context=Q,this.pluginId=w,this.logger=$}requestBuild(A){let Q=A??(this.config.previewOutputDir?"preview":"production"),w=this.debounces.get(Q);if(!w)w=new Fd0(()=>{this.enqueueBuild(Q)},this.config.rebuildDebounce),this.debounces.set(Q,w);w.trigger()}setupAutoRebuild(){let A=new Set(["note"]),Q=async($)=>{let{entityType:B}=$.payload;if(!A.has(B))this.logger.debug(`Entity type ${B} will trigger rebuild`),this.requestBuild();return{success:!0}},w=["entity:created","entity:updated","entity:deleted"];for(let $ of w)this.unsubscribeFunctions.push(this.context.messaging.subscribe($,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(w){this.logger.error("Failed to enqueue site rebuild",{error:w})}}}Y7();function tFw(A,Q){return A.map((w)=>({...w,template:w.template.includes(":")?w.template:`${Q}:${w.template}`}))}function SZ0(A,Q,w){for(let $ of A)w.register({...$,pluginId:Q,sections:$.sections?tFw($.sections,Q):[]})}function b12(A,Q,w){A.messaging.subscribe("plugin:site-builder:route:register",async($)=>{try{let B=FA0.parse($.payload),{routes:X,pluginId:Y}=B;return SZ0(X,Y,Q),{success:!0}}catch(B){return w.error("Failed to register routes",{error:B}),{success:!1,error:"Failed to register routes"}}}),A.messaging.subscribe("plugin:site-builder:route:unregister",async($)=>{try{let B=bA0.parse($.payload),{paths:X,pluginId:Y}=B;if(X)for(let Z of X)Q.unregister(Z);else if(Y)Q.unregisterByPlugin(Y);return{success:!0}}catch(B){return w.error("Failed to unregister routes",{error:B}),{success:!1,error:"Failed to unregister routes"}}}),A.messaging.subscribe("plugin:site-builder:route:list",async($)=>{try{let B=LA0.parse($.payload);return{success:!0,data:{routes:Q.list(B.pluginId?B:void 0)}}}catch(B){return w.error("Failed to list routes",{error:B}),{success:!1,error:"Failed to list routes"}}}),A.messaging.subscribe("plugin:site-builder:route:get",async($)=>{try{let B=kA0.parse($.payload);return{success:!0,data:{route:Q.get(B.path)}}}catch(B){return w.error("Failed to get route",{error:B}),{success:!1,error:"Failed to get route"}}}),A.messaging.subscribe("site-builder:routes:list",async()=>{return{success:!0,data:Q.list()}})}import{promises as L12}from"fs";import{join as k12}from"path";async function eFw(A,Q,w){let $=A.siteConfig.url??"https://example.com",B=Q.list(),X=es0($,A.environment);await L12.writeFile(k12(A.outputDir,"robots.txt"),X,"utf-8"),w.info(`Generated robots.txt for ${A.environment} environment`);let Y=Aa0(B,$);await L12.writeFile(k12(A.outputDir,"sitemap.xml"),Y,"utf-8"),w.info(`Generated sitemap.xml with ${B.length} URLs`)}function _12(A){let{context:Q,routeRegistry:w,logger:$}=A;Q.messaging.subscribe("site:build:completed",async(B)=>{try{let X=B.payload;return $.info(`Received site:build:completed event for ${X.environment} environment - generating SEO files`),await eFw(X,w,$),{success:!0}}catch(X){return $.error("Failed to generate SEO files",X),{success:!1}}})}fA();C0();var N12=f.object({environment:f.enum(["preview","production"]).optional(),outputDir:f.string(),workingDir:f.string().optional(),enableContentGeneration:f.boolean().optional(),siteConfig:fE.optional()});Y7();Y7();C0();var Abw=f.object({heading:f.string(),buttonText:f.string(),buttonLink:f.string()}),Qbw=f.object({blurb:f.string().optional()}),j12=f.object({title:f.string(),description:f.string(),url:f.string().optional(),copyright:f.string().optional(),logo:f.boolean().optional(),themeMode:f.enum(["light","dark"]).optional(),analyticsScript:f.string().optional(),cta:Abw.optional(),sections:f.record(f.string(),Qbw).optional()});async function Qs(A,Q){try{let w=await A({type:Jm,payload:void 0});if("success"in w&&w.success&&w.data){let $=j12.safeParse(w.data);if($.success)return j12.parse({...Q,...$.data})}}catch{}return Q}class $a0 extends D6{sendMessage;cfg;constructor(A,Q,w){super(A,{schema:N12,jobTypeName:"site-build"});this.sendMessage=Q,this.cfg=w}async process(A,Q,w){let $=A.environment??"preview",B=A.enableContentGeneration??!1;try{this.logger.debug("Starting site build job",{jobId:Q,environment:$,outputDir:A.outputDir}),await w.report({progress:0,total:100,message:`Starting site build for ${$} environment`});let X=w.createSub({scale:{start:10,end:90}}),Y=await Qs(this.sendMessage,A.siteConfig??this.cfg.defaultSiteConfig),Z=await this.cfg.siteBuilder.build({outputDir:A.outputDir,workingDir:A.workingDir,sharedImagesDir:this.cfg.sharedImagesDir,enableContentGeneration:B,environment:$,cleanBeforeBuild:!0,siteConfig:Y,layouts:this.cfg.layouts,themeCSS:this.cfg.themeCSS,slots:this.cfg.slots,headScripts:this.cfg.getHeadScripts?.(),...this.cfg.staticAssets&&{staticAssets:this.cfg.staticAssets}},X.toCallback());if(await w.report({progress:100,total:100,message:`Site build completed: ${Z.routesBuilt} routes built`}),this.logger.debug("Site build job completed",{jobId:Q,environment:$,routesBuilt:Z.routesBuilt,success:Z.success}),Z.success){this.logger.info(`Emitting site:build:completed event for ${$} environment`);let H=$==="preview"?this.cfg.previewUrl??this.cfg.siteUrl:this.cfg.siteUrl;await this.sendMessage({type:"site:build:completed",payload:{outputDir:A.outputDir,environment:$,routesBuilt:Z.routesBuilt,siteConfig:{...Y,url:H},generateEntityUrl:(W,K)=>R4.getInstance().generateUrl(W,K)},broadcast:!0})}return{success:Z.success,routesBuilt:Z.routesBuilt,outputDir:A.outputDir,environment:$,...Z.errors&&{errors:Z.errors},...Z.warnings&&{warnings:Z.warnings}}}catch(X){throw this.logger.error("Site build job failed",X),X}}summarizeDataForLog(A){return{environment:A.environment,outputDir:A.outputDir}}}C0();Y7();var wbw=f.object({slot:f.enum($I).optional().default("primary"),limit:f.number().optional()});class Ba0{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,w){let $=wbw.parse(A??{});this.logger.debug("NavigationDataSource fetch called",{params:$});let B=this.routeRegistry.getNavigationItems($.slot),X=$.limit?B.slice(0,$.limit):B,Y=X.map((H)=>({label:H.label,href:H.href}));this.logger.debug("NavigationDataSource returning",{slot:$.slot,itemCount:X.length,items:Y});let Z={navigation:Y};return Q.parse(Z)}}Y7();fA();C0();var $bw=f.object({environment:f.enum(["preview","production"]).optional().describe("Build environment (defaults to production, or preview if configured)")});function P12(A,Q){return[p6(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'.",$bw,async(w)=>{return Q(w.environment),{success:!0,message:`Site build requested${w.environment?` for ${w.environment}`:""} (debounced)`,data:{}}},{sideEffects:"external",cli:{name:"build"}})]}C0();Y7();var Bbw=f.object({id:f.string(),template:f.string(),content:f.unknown().optional(),dataQuery:f.looseObject({entityType:f.string().optional(),template:f.string().optional(),query:f.looseObject({id:f.string().optional(),limit:f.number().optional(),offset:f.number().optional()}).optional()}).optional(),order:f.number().optional()}),Xbw=f.object({show:f.boolean().default(!1),label:f.string().optional(),slot:f.enum($I).default("primary"),priority:f.number().min(0).max(100).default(50)}).optional(),Ybw=f.object({id:f.string(),path:f.string(),title:f.string().default(""),pageLabel:f.string().optional(),description:f.string().default(""),sections:f.array(Bbw).default([]),layout:f.string().default("default"),fullscreen:f.boolean().optional(),pluginId:f.string().optional(),sourceEntityType:f.string().optional(),external:f.boolean().optional(),navigation:Xbw}),M12=f.object({previewOutputDir:f.string().describe("Output directory for preview builds").default("./dist/site-preview"),productionOutputDir:f.string().describe("Output directory for production builds").default("./dist/site-production"),sharedImagesDir:f.string().describe("Shared directory for optimized images (used by both preview and production)").default("./dist/images"),workingDir:f.string().optional().describe("Working directory for builds").default("./.preact-work"),siteInfo:fE.default({title:"Brain",description:"A knowledge management system"}),themeCSS:f.string().describe("Custom CSS theme overrides to inject into builds").optional(),analyticsScript:f.string().describe("Analytics tracking script to inject into page head (e.g., Cloudflare Web Analytics)").optional(),templates:f.any().optional().describe("Template definitions to register"),routes:f.array(Ybw).optional().describe("Routes to register"),layouts:f.record(f.string(),f.any()).optional().describe("Layout components (at least 'default' required)"),autoRebuild:f.boolean().default(!0).describe("Automatically rebuild site when content changes"),rebuildDebounce:f.number().min(100).describe("Debounce time in ms before triggering site rebuild after content changes").default(5000),entityDisplay:f.record(f.string(),f.object({label:f.string().describe("Display label for entity type (e.g., 'Essay')"),pluralName:f.string().optional().describe("URL path segment (defaults to label.toLowerCase() + 's')"),layout:f.string().optional().describe("Layout name for this entity type's generated routes (defaults to 'default')"),paginate:f.boolean().optional().describe("Enable pagination for list pages"),pageSize:f.number().optional().describe("Items per page (default: 10)"),navigation:f.object({show:f.boolean().optional().describe("Show in navigation"),slot:f.enum($I).optional().describe("Navigation slot (primary or secondary)"),priority:f.number().min(0).max(100).optional().describe("Navigation priority (0-100)")}).optional().describe("Navigation settings for this entity type")})).optional().describe("Display metadata per entity type \u2014 label, plural name, layout, pagination, navigation slot. Consulted when auto-generating routes for active entity plugins."),staticAssets:f.record(f.string(),f.string()).optional().describe("Static files to write to the output directory at build time. Keys are output paths (e.g. '/canvases/tree.js'), values are file contents as strings. Typically supplied by a SitePackage via text imports.")});var O12={name:"@brains/site-builder-plugin",version:"0.2.0-alpha.158",description:"Static site generation plugin for Brain system",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.20",preact:"^10.27.2","preact-render-to-string":"^6.7.0"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{clean:"rm -rf dist",lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};class Xa0 extends Kw{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",O12,{...A,layouts:Q},M12);this.layouts=Q}async onRegister(A){if(this.pluginContext=A,this._routeRegistry=new EZ0(A.logger),this._slotRegistry=new KZ0,A.messaging.subscribe("plugin:site-builder:slot:register",async(w)=>{let{slotName:$,pluginId:B,render:X,priority:Y}=w.payload;return this._slotRegistry?.register($,{pluginId:B,render:X,...Y!==void 0&&{priority:Y}}),{success:!0}}),A.messaging.subscribe("plugin:site-builder:head-script:register",async(w)=>{let{pluginId:$,script:B}=w.payload;return this.headScripts.set($,B),{success:!0}}),A.entities.registerDataSource(new Ba0(this._routeRegistry,A.logger.child("NavigationDataSource"))),this.profileService=iX.getInstance(A.entityService,A.logger),b12(A,this._routeRegistry,this.logger),this.config.templates)A.templates.register(this.config.templates);if(this.config.routes)SZ0(this.config.routes,this.id,this.routeRegistry);let Q={entityService:A.entityService,sendMessage:A.messaging.send,resolveTemplateContent:(w,$)=>A.templates.resolve(w,$),getViewTemplate:(w)=>A.views.get(w),listViewTemplateNames:()=>A.views.list().map((w)=>w.name)};if(this.siteBuilder=YH.getInstance(A.logger.child("SiteBuilder"),Q,this.routeRegistry,this.profileService,this.config.entityDisplay),A.jobs.registerHandler("site-build",new $a0(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 wa0(this.config,A,this.id,this.logger),this.config.autoRebuild)this.logger.debug("Auto-rebuild enabled"),this.rebuildManager.setupAutoRebuild();A.messaging.subscribe(Im,async()=>{let w=await this.getInstructions();if(w)A.registerInstructions(w);return{success:!0}}),_12({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 P12(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 Qs(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((w)=>({id:w.id,path:w.path,title:w.title,description:w.description,sections:w.sections.map(($)=>({id:$.id,template:$.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((w)=>({name:w.name,description:w.description,hasWebRenderer:!!w.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.",w=await Qs(A.messaging.send,this.config.siteInfo);return`## Your Site
6748
+ `+Z;await W4.writeFile(Y,W,"utf-8")}this.logger.debug("CSS processed successfully with font imports")}async copyStaticAssets(){this.logger.debug("Copying static assets from public/ directory");let A=jq(process.cwd(),"public");try{await W4.access(A)}catch{this.logger.debug("No public/ directory found, skipping static assets");return}let Q=await W4.readdir(A,{withFileTypes:!0});for(let w of Q){let $=jq(A,w.name),B=jq(this.outputDir,w.name);if(w.isDirectory())await this.copyDirectory($,B);else await W4.copyFile($,B),this.logger.debug(`Copied static asset: ${w.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([w,$])=>{let B=w.startsWith("/")?w.slice(1):w,X=jq(this.outputDir,B);await W4.mkdir(pFw(X),{recursive:!0}),await W4.writeFile(X,$,"utf-8"),this.logger.debug(`Wrote inline static asset: ${B}`)}))}async copyDirectory(A,Q){await W4.mkdir(Q,{recursive:!0});let w=await W4.readdir(A,{withFileTypes:!0});for(let $ of w){let B=jq(A,$.name),X=jq(Q,$.name);if($.isDirectory())await this.copyDirectory(B,X);else await W4.copyFile(B,X)}}}function Qa0(A){return new X12(A)}Y7();C0();C0();var iFw=f.object({heading:f.string(),buttonText:f.string(),buttonLink:f.string()}),dFw=f.object({blurb:f.string().optional()}),fE=f.object({title:f.string(),description:f.string(),url:f.string().optional(),copyright:f.string().optional(),logo:f.boolean().optional(),themeMode:f.enum(["light","dark"]).optional(),analyticsScript:f.string().optional(),cta:iFw.optional(),sections:f.record(f.string(),dFw).optional()});var Y12=f.object({environment:f.enum(["preview","production"]),outputDir:f.string(),workingDir:f.string().optional(),sharedImagesDir:f.string().default("./dist/images"),enableContentGeneration:f.boolean().default(!1),cleanBeforeBuild:f.boolean().default(!0),siteConfig:fE,layouts:f.record(f.string(),f.any()),themeCSS:f.string().optional()}),mZ8=f.object({success:f.boolean(),outputDir:f.string(),filesGenerated:f.number(),routesBuilt:f.number(),errors:f.array(f.string()).optional(),warnings:f.array(f.string()).optional()});function Z12(A){let Q=A.list(),w=Q.length===0?["No routes registered for site build"]:[];return{routes:Q,warnings:w}}function f12(A,Q,w){let $=Q.getProfile(),B=w.getNavigationItems("primary"),X=w.getNavigationItems("secondary");return{...A,...$.socialLinks!==void 0&&{socialLinks:$.socialLinks},navigation:{primary:B,secondary:X},copyright:A.copyright??"Powered by Rizom"}}Y7();p4();Y7();b2();C0();var nFw=f.looseObject({id:f.string(),entityType:f.string(),content:f.string(),metadata:f.looseObject({slug:f.string()})}),rFw=f.looseObject({content:f.string(),metadata:f.looseObject({width:f.number().optional(),height:f.number().optional()})});async function TZ0(A,Q){let w=Q.urlGenerator??R4.getInstance();if(A===null||A===void 0)return A;if(Array.isArray(A))return Promise.all(A.map((x)=>TZ0(x,{...Q,urlGenerator:w})));if(typeof A!=="object")return A;let $={},B=Object.entries(A),X=await Promise.all(B.map(([,x])=>TZ0(x,{...Q,urlGenerator:w})));for(let x=0;x<B.length;x++){let v=B[x];if(v)$[v[0]]=X[x]}let Y=nFw.safeParse(A);if(!Y.success)return $;let Z=Y.data,H=Z.entityType,W=Z.metadata.slug,K=Q.pipelineContext.entityDisplay?.[H],U=K?K.label:H.charAt(0).toUpperCase()+H.slice(1),G=K?K.pluralName??K.label.toLowerCase()+"s":yK(H),q=`/${G}`,V=G.charAt(0).toUpperCase()+G.slice(1),I=$l(Z),J=await oFw(I,Q),k=xw0(Z)??I,j=await sFw(k,Q);return{...$,...Z,url:w.generateUrl(H,W),typeLabel:U,listUrl:q,listLabel:V,...J,...j&&{ogImageUrl:j}}}async function oFw(A,Q){let w=A?Q.imageBuildService?.get(A):void 0;if(w)return{coverImageUrl:w.src,coverImageWidth:w.width,coverImageHeight:w.height,...w.srcset&&{coverImageSrcset:w.srcset,coverImageSizes:w.sizes}};let $=await W12(A,Q.pipelineContext.services.entityService);if(!$)return{};return{coverImageUrl:$.url,...$.width&&{coverImageWidth:$.width},...$.height&&{coverImageHeight:$.height}}}async function sFw(A,Q){if(!A)return;let w=Q.imageBuildService?.get(A);if(w)return H12(w.src,Q.siteUrl);let $=await W12(A,Q.pipelineContext.services.entityService);if(!$)return;if($.url.startsWith("data:"))return;return H12($.url,Q.siteUrl)}function H12(A,Q){if(/^https?:\/\//i.test(A)||A.startsWith("data:"))return A;if(!Q)return A;return`${Q.replace(/\/$/,"")}/${A.replace(/^\//,"")}`}async function W12(A,Q){if(!A)return;let w=await Q.getEntity({entityType:"image",id:A}),$=rFw.safeParse(w);if(!$.success)return;return{url:$.data.content,...$.data.metadata.width&&{width:$.data.metadata.width},...$.data.metadata.height&&{height:$.data.metadata.height}}}async function K12(A,Q){let w=new Set;try{let $=A.getEntityTypes();for(let B of $){if(B==="image")continue;let X=await A.listEntities({entityType:B});for(let Y of X){let Z=$l(Y);if(Z)w.add(Z);let H=xw0(Y);if(H)w.add(H)}}}catch($){Q.warn("Failed to collect image IDs for pre-resolution",{error:dA($)})}return[...w]}async function U12(A,Q,w,$,B){if(!A.template)return A.content??null;let X=A.template,Y=A.dataQuery?{dataParams:A.dataQuery,fallback:A.content,publishedOnly:w,visibilityScope:$}:{savedContent:{entityType:"site-content",entityId:`${Q.id}:${A.id}`},fallback:A.content,visibilityScope:$},Z=await B.pipelineContext.services.resolveTemplateContent(X,Y);if(!Z)return null;return TZ0(Z,{pipelineContext:B.pipelineContext,imageBuildService:B.imageBuildService,siteUrl:B.siteUrl,urlGenerator:R4.getInstance()})}function G12(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,w)=>{let $=A.parsedOptions.environment==="production";return U12(w,Q,$,"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 f12(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 aFw}from"path";async function D12(A){let Q=A.parsedOptions.workingDir??aFw(A.parsedOptions.outputDir,".preact-work"),w=A.staticSiteBuilderFactory({logger:A.logger.child("StaticSiteBuilder"),workingDir:Q,outputDir:A.parsedOptions.outputDir});if(A.parsedOptions.cleanBeforeBuild)await w.clean();return w}async function q12(A){await new yZ0({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 z12(A){let Q=new gZ0(A.pipelineContext.services.entityService,A.pipelineContext.logger,A.sharedImagesDir),w=await K12(A.pipelineContext.services.entityService,A.pipelineContext.logger);if(w.length>0)await Q.resolveAll(w);return Q}async function V12(A){let Q=A.reporter?.createSub({scale:{start:85,end:95}});await A.staticSiteBuilder.build(A.buildContext,(w)=>{Q?.report(w).catch(()=>{})})}function J12(A){return{success:!0,outputDir:A.outputDir,filesGenerated:A.routesBuilt+1,routesBuilt:A.routesBuilt,...A.warnings.length>0&&{warnings:A.warnings}}}function I12(A){return{success:!1,outputDir:A.outputDir,filesGenerated:0,routesBuilt:0,errors:[A.errorMessage]}}async function F12(A){let Q=Y12.parse(A.buildOptions),w=hX.from(A.progress),$=[];try{await w?.report({message:"Starting site build",progress:0,total:100}),await w?.report({message:"Generating dynamic routes",progress:10,total:100}),await q12({pipelineContext:A.pipelineContext,publishedOnly:Q.environment==="production"});let B=await D12({logger:A.pipelineContext.logger,parsedOptions:Q,staticSiteBuilderFactory:A.staticSiteBuilderFactory}),X=Z12(A.pipelineContext.routeRegistry);$.push(...X.warnings);let{routes:Y}=X;await w?.report({message:`Building ${Y.length} routes`,progress:20,total:100}),await w?.report({message:"Resolving images",progress:25,total:100});let Z=await z12({pipelineContext:A.pipelineContext,sharedImagesDir:Q.sharedImagesDir}),H=G12({routes:Y,parsedOptions:Q,buildOptions:A.buildOptions,pipelineContext:A.pipelineContext,imageBuildService:Z,siteMetadata:Q.siteConfig});return await V12({staticSiteBuilder:B,buildContext:H,reporter:w}),await w?.report({message:"Site build complete",progress:100,total:100}),J12({outputDir:Q.outputDir,routesBuilt:Y.length,warnings:$})}catch(B){let X=Error("Site build process failed");return A.pipelineContext.logger.error("Site build failed",{error:X,originalError:B}),I12({outputDir:Q.outputDir,errorMessage:X.message})}}class YH{static instance=null;static defaultStaticSiteBuilderFactory=Qa0;pipelineContext;staticSiteBuilderFactory;static setDefaultStaticSiteBuilderFactory(A){YH.defaultStaticSiteBuilderFactory=A}static getInstance(A,Q,w,$,B=void 0){return YH.instance??=new YH(A,YH.defaultStaticSiteBuilderFactory,Q,w,$,B),YH.instance}static resetInstance(){YH.instance=null}static createFresh(A,Q,w,$,B,X=void 0){return new YH(A,B??YH.defaultStaticSiteBuilderFactory,Q,w,$,X)}constructor(A,Q,w,$,B,X){this.pipelineContext={logger:A,services:w,routeRegistry:$,profileService:B,entityDisplay:X},this.staticSiteBuilderFactory=Q,R4.getInstance().configure(X)}async build(A,Q){return F12({buildOptions:A,progress:Q,pipelineContext:this.pipelineContext,staticSiteBuilderFactory:this.staticSiteBuilderFactory})}}class wa0{config;context;pluginId;logger;debounces=new Map;unsubscribeFunctions=[];constructor(A,Q,w,$){this.config=A,this.context=Q,this.pluginId=w,this.logger=$}requestBuild(A){let Q=A??(this.config.previewOutputDir?"preview":"production"),w=this.debounces.get(Q);if(!w)w=new Fd0(()=>{this.enqueueBuild(Q)},this.config.rebuildDebounce),this.debounces.set(Q,w);w.trigger()}setupAutoRebuild(){let A=new Set(["note"]),Q=async($)=>{let{entityType:B}=$.payload;if(!A.has(B))this.logger.debug(`Entity type ${B} will trigger rebuild`),this.requestBuild();return{success:!0}},w=["entity:created","entity:updated","entity:deleted"];for(let $ of w)this.unsubscribeFunctions.push(this.context.messaging.subscribe($,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(w){this.logger.error("Failed to enqueue site rebuild",{error:w})}}}Y7();function tFw(A,Q){return A.map((w)=>({...w,template:w.template.includes(":")?w.template:`${Q}:${w.template}`}))}function SZ0(A,Q,w){for(let $ of A)w.register({...$,pluginId:Q,sections:$.sections?tFw($.sections,Q):[]})}function b12(A,Q,w){A.messaging.subscribe("plugin:site-builder:route:register",async($)=>{try{let B=FA0.parse($.payload),{routes:X,pluginId:Y}=B;return SZ0(X,Y,Q),{success:!0}}catch(B){return w.error("Failed to register routes",{error:B}),{success:!1,error:"Failed to register routes"}}}),A.messaging.subscribe("plugin:site-builder:route:unregister",async($)=>{try{let B=bA0.parse($.payload),{paths:X,pluginId:Y}=B;if(X)for(let Z of X)Q.unregister(Z);else if(Y)Q.unregisterByPlugin(Y);return{success:!0}}catch(B){return w.error("Failed to unregister routes",{error:B}),{success:!1,error:"Failed to unregister routes"}}}),A.messaging.subscribe("plugin:site-builder:route:list",async($)=>{try{let B=LA0.parse($.payload);return{success:!0,data:{routes:Q.list(B.pluginId?B:void 0)}}}catch(B){return w.error("Failed to list routes",{error:B}),{success:!1,error:"Failed to list routes"}}}),A.messaging.subscribe("plugin:site-builder:route:get",async($)=>{try{let B=kA0.parse($.payload);return{success:!0,data:{route:Q.get(B.path)}}}catch(B){return w.error("Failed to get route",{error:B}),{success:!1,error:"Failed to get route"}}}),A.messaging.subscribe("site-builder:routes:list",async()=>{return{success:!0,data:Q.list()}})}import{promises as L12}from"fs";import{join as k12}from"path";async function eFw(A,Q,w){let $=A.siteConfig.url??"https://example.com",B=Q.list(),X=es0($,A.environment);await L12.writeFile(k12(A.outputDir,"robots.txt"),X,"utf-8"),w.info(`Generated robots.txt for ${A.environment} environment`);let Y=Aa0(B,$);await L12.writeFile(k12(A.outputDir,"sitemap.xml"),Y,"utf-8"),w.info(`Generated sitemap.xml with ${B.length} URLs`)}function _12(A){let{context:Q,routeRegistry:w,logger:$}=A;Q.messaging.subscribe("site:build:completed",async(B)=>{try{let X=B.payload;return $.info(`Received site:build:completed event for ${X.environment} environment - generating SEO files`),await eFw(X,w,$),{success:!0}}catch(X){return $.error("Failed to generate SEO files",X),{success:!1}}})}fA();C0();var N12=f.object({environment:f.enum(["preview","production"]).optional(),outputDir:f.string(),workingDir:f.string().optional(),enableContentGeneration:f.boolean().optional(),siteConfig:fE.optional()});Y7();Y7();C0();var Abw=f.object({heading:f.string(),buttonText:f.string(),buttonLink:f.string()}),Qbw=f.object({blurb:f.string().optional()}),j12=f.object({title:f.string(),description:f.string(),url:f.string().optional(),copyright:f.string().optional(),logo:f.boolean().optional(),themeMode:f.enum(["light","dark"]).optional(),analyticsScript:f.string().optional(),cta:Abw.optional(),sections:f.record(f.string(),Qbw).optional()});async function Qs(A,Q){try{let w=await A({type:Jm,payload:void 0});if("success"in w&&w.success&&w.data){let $=j12.safeParse(w.data);if($.success)return j12.parse({...Q,...$.data})}}catch{}return Q}class $a0 extends D6{sendMessage;cfg;constructor(A,Q,w){super(A,{schema:N12,jobTypeName:"site-build"});this.sendMessage=Q,this.cfg=w}async process(A,Q,w){let $=A.environment??"preview",B=A.enableContentGeneration??!1;try{this.logger.debug("Starting site build job",{jobId:Q,environment:$,outputDir:A.outputDir}),await w.report({progress:0,total:100,message:`Starting site build for ${$} environment`});let X=w.createSub({scale:{start:10,end:90}}),Y=await Qs(this.sendMessage,A.siteConfig??this.cfg.defaultSiteConfig),Z=await this.cfg.siteBuilder.build({outputDir:A.outputDir,workingDir:A.workingDir,sharedImagesDir:this.cfg.sharedImagesDir,enableContentGeneration:B,environment:$,cleanBeforeBuild:!0,siteConfig:Y,layouts:this.cfg.layouts,themeCSS:this.cfg.themeCSS,slots:this.cfg.slots,headScripts:this.cfg.getHeadScripts?.(),...this.cfg.staticAssets&&{staticAssets:this.cfg.staticAssets}},X.toCallback());if(await w.report({progress:100,total:100,message:`Site build completed: ${Z.routesBuilt} routes built`}),this.logger.debug("Site build job completed",{jobId:Q,environment:$,routesBuilt:Z.routesBuilt,success:Z.success}),Z.success){this.logger.info(`Emitting site:build:completed event for ${$} environment`);let H=$==="preview"?this.cfg.previewUrl??this.cfg.siteUrl:this.cfg.siteUrl;await this.sendMessage({type:"site:build:completed",payload:{outputDir:A.outputDir,environment:$,routesBuilt:Z.routesBuilt,siteConfig:{...Y,url:H},generateEntityUrl:(W,K)=>R4.getInstance().generateUrl(W,K)},broadcast:!0})}return{success:Z.success,routesBuilt:Z.routesBuilt,outputDir:A.outputDir,environment:$,...Z.errors&&{errors:Z.errors},...Z.warnings&&{warnings:Z.warnings}}}catch(X){throw this.logger.error("Site build job failed",X),X}}summarizeDataForLog(A){return{environment:A.environment,outputDir:A.outputDir}}}C0();Y7();var wbw=f.object({slot:f.enum($I).optional().default("primary"),limit:f.number().optional()});class Ba0{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,w){let $=wbw.parse(A??{});this.logger.debug("NavigationDataSource fetch called",{params:$});let B=this.routeRegistry.getNavigationItems($.slot),X=$.limit?B.slice(0,$.limit):B,Y=X.map((H)=>({label:H.label,href:H.href}));this.logger.debug("NavigationDataSource returning",{slot:$.slot,itemCount:X.length,items:Y});let Z={navigation:Y};return Q.parse(Z)}}Y7();fA();C0();var $bw=f.object({environment:f.enum(["preview","production"]).optional().describe("Build environment (defaults to production, or preview if configured)")});function P12(A,Q){return[p6(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'.",$bw,async(w)=>{return Q(w.environment),{success:!0,message:`Site build requested${w.environment?` for ${w.environment}`:""} (debounced)`,data:{}}},{sideEffects:"external",cli:{name:"build"}})]}C0();Y7();var Bbw=f.object({id:f.string(),template:f.string(),content:f.unknown().optional(),dataQuery:f.looseObject({entityType:f.string().optional(),template:f.string().optional(),query:f.looseObject({id:f.string().optional(),limit:f.number().optional(),offset:f.number().optional()}).optional()}).optional(),order:f.number().optional()}),Xbw=f.object({show:f.boolean().default(!1),label:f.string().optional(),slot:f.enum($I).default("primary"),priority:f.number().min(0).max(100).default(50)}).optional(),Ybw=f.object({id:f.string(),path:f.string(),title:f.string().default(""),pageLabel:f.string().optional(),description:f.string().default(""),sections:f.array(Bbw).default([]),layout:f.string().default("default"),fullscreen:f.boolean().optional(),pluginId:f.string().optional(),sourceEntityType:f.string().optional(),external:f.boolean().optional(),navigation:Xbw}),M12=f.object({previewOutputDir:f.string().describe("Output directory for preview builds").default("./dist/site-preview"),productionOutputDir:f.string().describe("Output directory for production builds").default("./dist/site-production"),sharedImagesDir:f.string().describe("Shared directory for optimized images (used by both preview and production)").default("./dist/images"),workingDir:f.string().optional().describe("Working directory for builds").default("./.preact-work"),siteInfo:fE.default({title:"Brain",description:"A knowledge management system"}),themeCSS:f.string().describe("Custom CSS theme overrides to inject into builds").optional(),analyticsScript:f.string().describe("Analytics tracking script to inject into page head (e.g., Cloudflare Web Analytics)").optional(),templates:f.any().optional().describe("Template definitions to register"),routes:f.array(Ybw).optional().describe("Routes to register"),layouts:f.record(f.string(),f.any()).optional().describe("Layout components (at least 'default' required)"),autoRebuild:f.boolean().default(!0).describe("Automatically rebuild site when content changes"),rebuildDebounce:f.number().min(100).describe("Debounce time in ms before triggering site rebuild after content changes").default(5000),entityDisplay:f.record(f.string(),f.object({label:f.string().describe("Display label for entity type (e.g., 'Essay')"),pluralName:f.string().optional().describe("URL path segment (defaults to label.toLowerCase() + 's')"),layout:f.string().optional().describe("Layout name for this entity type's generated routes (defaults to 'default')"),paginate:f.boolean().optional().describe("Enable pagination for list pages"),pageSize:f.number().optional().describe("Items per page (default: 10)"),navigation:f.object({show:f.boolean().optional().describe("Show in navigation"),slot:f.enum($I).optional().describe("Navigation slot (primary or secondary)"),priority:f.number().min(0).max(100).optional().describe("Navigation priority (0-100)")}).optional().describe("Navigation settings for this entity type")})).optional().describe("Display metadata per entity type \u2014 label, plural name, layout, pagination, navigation slot. Consulted when auto-generating routes for active entity plugins."),staticAssets:f.record(f.string(),f.string()).optional().describe("Static files to write to the output directory at build time. Keys are output paths (e.g. '/canvases/tree.js'), values are file contents as strings. Typically supplied by a SitePackage via text imports.")});var O12={name:"@brains/site-builder-plugin",version:"0.2.0-alpha.159",description:"Static site generation plugin for Brain system",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.20",preact:"^10.27.2","preact-render-to-string":"^6.7.0"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{clean:"rm -rf dist",lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};class Xa0 extends Kw{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",O12,{...A,layouts:Q},M12);this.layouts=Q}async onRegister(A){if(this.pluginContext=A,this._routeRegistry=new EZ0(A.logger),this._slotRegistry=new KZ0,A.messaging.subscribe("plugin:site-builder:slot:register",async(w)=>{let{slotName:$,pluginId:B,render:X,priority:Y}=w.payload;return this._slotRegistry?.register($,{pluginId:B,render:X,...Y!==void 0&&{priority:Y}}),{success:!0}}),A.messaging.subscribe("plugin:site-builder:head-script:register",async(w)=>{let{pluginId:$,script:B}=w.payload;return this.headScripts.set($,B),{success:!0}}),A.entities.registerDataSource(new Ba0(this._routeRegistry,A.logger.child("NavigationDataSource"))),this.profileService=iX.getInstance(A.entityService,A.logger),b12(A,this._routeRegistry,this.logger),this.config.templates)A.templates.register(this.config.templates);if(this.config.routes)SZ0(this.config.routes,this.id,this.routeRegistry);let Q={entityService:A.entityService,sendMessage:A.messaging.send,resolveTemplateContent:(w,$)=>A.templates.resolve(w,$),getViewTemplate:(w)=>A.views.get(w),listViewTemplateNames:()=>A.views.list().map((w)=>w.name)};if(this.siteBuilder=YH.getInstance(A.logger.child("SiteBuilder"),Q,this.routeRegistry,this.profileService,this.config.entityDisplay),A.jobs.registerHandler("site-build",new $a0(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 wa0(this.config,A,this.id,this.logger),this.config.autoRebuild)this.logger.debug("Auto-rebuild enabled"),this.rebuildManager.setupAutoRebuild();A.messaging.subscribe(Im,async()=>{let w=await this.getInstructions();if(w)A.registerInstructions(w);return{success:!0}}),_12({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 P12(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 Qs(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((w)=>({id:w.id,path:w.path,title:w.title,description:w.description,sections:w.sections.map(($)=>({id:$.id,template:$.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((w)=>({name:w.name,description:w.description,hasWebRenderer:!!w.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.",w=await Qs(A.messaging.send,this.config.siteInfo);return`## Your Site
6749
6749
  ${[`**Title:** ${w.title}`,`**Description:** ${w.description}`,A.domain&&`**Domain:** ${A.domain}`,A.siteUrl&&`**URL:** ${A.siteUrl}`].filter(Boolean).join(`
6750
6750
  `)}
6751
6751
 
6752
6752
  ## Site Builder Actions
6753
6753
  - When the user asks to build, rebuild, publish, or build the website/site again, call \`site-builder_build-site\` immediately.
6754
- - 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(),YH.resetInstance(),this.logger.debug("Cleaned up all event subscriptions")}}function oP(A={}){return new Xa0(A)}fA();fA();C0();var Ya0=f.object({routeId:f.string(),sectionId:f.string()}),fbw=f.object({routeId:f.string(),sectionId:f.string()}),ws=EQ.extend({entityType:f.literal("site-content"),template:f.string().optional(),content:f.string(),metadata:fbw});fA();class x12 extends d2{constructor(){super({entityType:"site-content",purpose:"A content section bound to a route on the published site.",schema:ws,frontmatterSchema:Ya0})}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 Za0=new x12;C0();var mZ0=f.object({routeId:f.string().optional().describe("Optional: specific route filter"),sectionId:f.string().optional().describe("Optional: specific section filter"),dryRun:f.boolean().optional().default(!1).describe("Optional: preview changes without executing"),force:f.boolean().optional().default(!1).describe("Force regeneration even if content exists")}),OH8=f.object({jobs:f.array(f.object({jobId:f.string(),routeId:f.string(),sectionId:f.string()})),totalSections:f.number(),queuedSections:f.number(),skippedSections:f.number().optional(),batchId:f.string().optional()});C0();var Hbw=f.looseObject({id:f.string(),template:f.string().optional(),content:f.unknown().optional()}),Wbw=f.looseObject({id:f.string(),title:f.string().optional(),description:f.string().optional(),sections:f.array(Hbw)}),Kbw=f.array(Wbw);class fa0{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");let Q=Kbw.safeParse(A.data);if(!Q.success)throw Error("Failed to parse routes from site-builder");return Q.data}async generate(A,Q,w){let $=this.context.logger.child("SiteContentOperations"),B=await this.fetchRoutes(),X=B;if(A.routeId){if(X=B.filter((K)=>K.id===A.routeId),X.length===0)throw Error(`Route not found: ${A.routeId}`)}let Y=[];for(let K of X)for(let U of K.sections){if(A.sectionId&&U.id!==A.sectionId)continue;if(U.content){$.debug("Section has static content, skipping",{routeId:K.id,sectionId:U.id});continue}if(U.template){let G=this.context.templates.getCapabilities(U.template);if(!G){$.warn("Template not found, skipping section",{routeId:K.id,sectionId:U.id,templateName:U.template});continue}if(!G.canGenerate){$.debug("Template doesn't support generation, skipping",{routeId:K.id,sectionId:U.id,templateName:U.template,capabilities:G});continue}}else{$.debug("Section has no template, skipping",{routeId:K.id,sectionId:U.id});continue}if(!A.force&&!A.dryRun){let G=`${K.id}:${U.id}`;if(await this.context.entityService.getEntity({entityType:"site-content",id:G})){$.debug("Content already exists, skipping",{routeId:K.id,sectionId:U.id});continue}}Y.push({route:K,section:U})}let Z=Y.length;if(A.dryRun)return{jobs:[],totalSections:Z,queuedSections:Z,batchId:`dry-run-${Date.now()}`};let H=[],W=[];for(let{route:K,section:U}of Y){let G=`${K.id}:${U.id}`,q=U.template,V={routeId:K.id,sectionId:U.id,entityId:G,entityType:"site-content",templateName:q,context:{prompt:typeof U.content==="string"?U.content:void 0,data:{routeId:K.id,sectionId:U.id,routeTitle:K.title,routeDescription:K.description,sectionContent:U.content},conversationId:"system"},siteConfig:Q};W.push({type:"shell:content-generation",data:V})}if(W.length>0){let K=this.createJobOptions(w,"site:content-generation"),U=await this.context.jobs.enqueueBatch(W,K);for(let G=0;G<Y.length;G++){let q=Y[G];if(q)H.push({jobId:`${U}-${G}`,routeId:q.route.id,sectionId:q.section.id})}return{jobs:H,totalSections:Z,queuedSections:H.length,batchId:U}}return{jobs:[],totalSections:Z,queuedSections:0,batchId:`empty-${Date.now()}`}}}class Ha0{siteConfig;operations;constructor(A,Q){this.siteConfig=Q,this.operations=new fa0(A)}async generateContent(A,Q){let w=mZ0.parse(A);return this.operations.generate(w,this.siteConfig,Q)}}Y7();C0();var Ubw=f.object({namespace:f.string(),sections:f.record(f.string(),f.any())}),R12=f.custom((A)=>Ubw.safeParse(A).success),Wa0=f.object({definitions:f.union([R12,f.array(R12)]).optional()});fA();function v12(A,Q){return[p6(Q,"generate","Generate content for all routes, a specific route, or a specific section",mZ0,async(w,$)=>{let B=A();if(!B)return{success:!1,error:"Site content service not initialized"};if(w.sectionId&&!w.routeId)return{success:!1,error:"sectionId requires routeId to be specified"};let X={rootJobId:`generate-${Date.now()}`,progressToken:$.progressToken,pluginId:Q,operationType:"content_operations",interfaceType:$.interfaceType,channelId:$.channelId},Y=await B.generateContent(w,X);return{success:!0,message:`Generated ${Y.queuedSections} of ${Y.totalSections} sections. ${Y.queuedSections>0?"Jobs are running in the background.":"No new content to generate."}`,data:{batchId:Y.batchId,jobsQueued:Y.queuedSections,totalSections:Y.totalSections,jobs:Y.jobs}}})]}var h12={name:"@brains/site-content",version:"0.2.0-alpha.158",description:"Site content entity and generation orchestration",dependencies:{"@brains/content-formatters":"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":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};class Ka0 extends Kw{siteContentService;constructor(A={}){super("site-content",h12,A,Wa0)}async onRegister(A){A.entities.register("site-content",ws,Za0);for(let Q of ZF(this.config.definitions))A.templates.register(UI(Q),Q.namespace);this.siteContentService=new Ha0(A)}async getTools(){return v12(()=>this.siteContentService,this.id)}}function sP(A={}){return new Ka0(A)}fA();Y7();fA();C0();Y7();var Dbw=f.object({}),qbw=f.object({}),$s=EQ.extend({id:f.literal("site-info"),entityType:f.literal("site-info"),metadata:qbw});var HE=zI0.omit({url:!0,analyticsScript:!0});fA();C0();var zbw=f.record(f.string(),f.unknown());class Pq extends d2{constructor(){super({entityType:"site-info",purpose:"Singleton configuration describing the published site.",schema:$s,frontmatterSchema:HE,isSingleton:!0,hasBody:!1})}createSiteInfoContent(A){let Q=HE.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("",zbw.parse(Q))}}class Mq{static instance=null;logger;entityService;adapter;defaultSiteInfo;static getDefaultSiteInfo(){return{title:"Brain",description:"A knowledge management system"}}static getInstance(A,Q,w){return Mq.instance??=new Mq(A,Q,w),Mq.instance}static resetInstance(){Mq.instance=null}static createFresh(A,Q,w){return new Mq(A,Q,w)}constructor(A,Q,w){this.entityService=A,this.logger=Q.child("SiteInfoService"),this.adapter=new Pq;let $=Mq.getDefaultSiteInfo();this.defaultSiteInfo={...$,...w}}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 w=this.adapter.createSiteInfoContent(this.defaultSiteInfo);await this.entityService.createEntity({entity:{id:"site-info",entityType:"site-info",content:w,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}}C0();var Vbw=new Pq,Jbw=f.looseObject({platform:f.string(),url:f.string(),label:f.string().optional()}).transform((A)=>({platform:A.platform,url:A.url,...A.label!==void 0?{label:A.label}:{}})),Ibw=f.looseObject({socialLinks:f.array(Jbw).optional()});class uZ0{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,w){let{entityService:$}=w,B;try{let Z=await $.getEntity({entityType:"site-info",id:"site-info"});B=Z?Vbw.parseSiteInfoBody(Z.content):{title:"Brain",description:"A knowledge management system"}}catch{B={title:"Brain",description:"A knowledge management system"}}let X;try{let Z=await $.getEntity({entityType:"anchor-profile",id:"anchor-profile"});if(Z){let H=Ibw.safeParse(Z.metadata);X=H.success?H.data.socialLinks:void 0}}catch{}let Y={...B,socialLinks:X,copyright:B.copyright??"Powered by Rizom"};return this.logger.debug("SiteInfoDataSource returning",{title:Y.title,hasSocialLinks:!!Y.socialLinks}),Q.parse(Y)}}var C12={name:"@brains/site-info",version:"0.2.0-alpha.158",description:"Site info entity \u2014 site metadata, title, description, CTA",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":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var bbw=new Pq,Lbw="site-info";class Ua0 extends Zw{entityType=Lbw;schema=$s;adapter=bbw;defaultSiteInfo;constructor(A){super("site-info",C12,{},i7);this.defaultSiteInfo=A?.siteInfo??{}}getEntityTypeConfig(){return{embeddable:!1}}getDataSources(){return[new uZ0(this.logger.child("SiteInfoDataSource"))]}async onRegister(A){let Q=Mq.createFresh(A.entityService,this.logger,this.defaultSiteInfo);A.messaging.subscribe(Jm,async()=>{return{success:!0,data:await Q.getSiteInfo()}}),A.messaging.subscribe("entity:updated",async(w)=>{if(w.payload.entityType==="site-info"){let B=await Q.getSiteInfo();await A.messaging.send({type:Im,payload:B,broadcast:!0})}return{success:!0}}),A.messaging.subscribe("sync:initial:completed",async()=>{return await Q.initialize(),{success:!0}})}}function aP(A){return new Ua0(A)}var kbw=new Pq;async function Bs(A){let w=(await A.listEntities({entityType:"site-info",options:{limit:1}}))[0];if(!w)throw Error("Site info not found \u2014 create a site-info entity");return kbw.parseSiteInfoBody(w.content)}function g12(A,Q){let w=A.metadata.publishedAt??A.created,$=Q.metadata.publishedAt??Q.created;return new Date($).getTime()-new Date(w).getTime()}async function cZ0(A,Q){return(await A.listEntities({entityType:Q.entityType,options:{limit:20}})).sort(g12).slice(0,Q.count).map(Q.parse)}function Ga0(A){if(!A)throw Error("CTA not configured in site-info");return A}C0();var y12=f.object({label:f.string(),href:f.string(),priority:f.number()}),_bw=f.object({primary:f.array(y12),secondary:f.array(y12)}),Nbw=f.object({platform:f.enum(["github","instagram","linkedin","email","website"]).describe("Social media platform"),url:f.string().describe("Profile or contact URL"),label:f.string().optional().describe("Optional display label")}),jbw=HE.extend({navigation:_bw,copyright:f.string(),socialLinks:f.array(Nbw).optional().describe("Social media links from profile entity")});fA();ZH();UE();C0();var Da0=f.object({defaultPrompt:f.string().default("Write a blog post about my recent work and insights"),paginate:f.boolean().default(!0),pageSize:f.number().default(10)});fA();e6();b2();C0();var xbw=f.object({prompt:f.string().optional(),title:f.string().optional(),content:f.string().optional(),excerpt:f.string().optional(),coverImageId:f.string().optional(),seriesName:f.string().optional(),seriesIndex:f.number().optional(),skipAi:f.boolean().optional()}),XK8=aZ.extend({title:f.string().optional(),slug:f.string().optional()});class qa0 extends S4{constructor(A,Q){super(A,Q,{schema:xbw,jobTypeName:"blog-generation",entityType:"post"})}async generate(A,Q){let{prompt:w,coverImageId:$,seriesName:B,seriesIndex:X,skipAi:Y}=A,{title:Z,content:H,excerpt:W}=A;if(Y){if(!Z)this.failEarly("Title is required when skipAi is true");H=H??`## Introduction
6754
+ - 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(),YH.resetInstance(),this.logger.debug("Cleaned up all event subscriptions")}}function oP(A={}){return new Xa0(A)}fA();fA();C0();var Ya0=f.object({routeId:f.string(),sectionId:f.string()}),fbw=f.object({routeId:f.string(),sectionId:f.string()}),ws=EQ.extend({entityType:f.literal("site-content"),template:f.string().optional(),content:f.string(),metadata:fbw});fA();class x12 extends d2{constructor(){super({entityType:"site-content",purpose:"A content section bound to a route on the published site.",schema:ws,frontmatterSchema:Ya0})}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 Za0=new x12;C0();var mZ0=f.object({routeId:f.string().optional().describe("Optional: specific route filter"),sectionId:f.string().optional().describe("Optional: specific section filter"),dryRun:f.boolean().optional().default(!1).describe("Optional: preview changes without executing"),force:f.boolean().optional().default(!1).describe("Force regeneration even if content exists")}),OH8=f.object({jobs:f.array(f.object({jobId:f.string(),routeId:f.string(),sectionId:f.string()})),totalSections:f.number(),queuedSections:f.number(),skippedSections:f.number().optional(),batchId:f.string().optional()});C0();var Hbw=f.looseObject({id:f.string(),template:f.string().optional(),content:f.unknown().optional()}),Wbw=f.looseObject({id:f.string(),title:f.string().optional(),description:f.string().optional(),sections:f.array(Hbw)}),Kbw=f.array(Wbw);class fa0{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");let Q=Kbw.safeParse(A.data);if(!Q.success)throw Error("Failed to parse routes from site-builder");return Q.data}async generate(A,Q,w){let $=this.context.logger.child("SiteContentOperations"),B=await this.fetchRoutes(),X=B;if(A.routeId){if(X=B.filter((K)=>K.id===A.routeId),X.length===0)throw Error(`Route not found: ${A.routeId}`)}let Y=[];for(let K of X)for(let U of K.sections){if(A.sectionId&&U.id!==A.sectionId)continue;if(U.content){$.debug("Section has static content, skipping",{routeId:K.id,sectionId:U.id});continue}if(U.template){let G=this.context.templates.getCapabilities(U.template);if(!G){$.warn("Template not found, skipping section",{routeId:K.id,sectionId:U.id,templateName:U.template});continue}if(!G.canGenerate){$.debug("Template doesn't support generation, skipping",{routeId:K.id,sectionId:U.id,templateName:U.template,capabilities:G});continue}}else{$.debug("Section has no template, skipping",{routeId:K.id,sectionId:U.id});continue}if(!A.force&&!A.dryRun){let G=`${K.id}:${U.id}`;if(await this.context.entityService.getEntity({entityType:"site-content",id:G})){$.debug("Content already exists, skipping",{routeId:K.id,sectionId:U.id});continue}}Y.push({route:K,section:U})}let Z=Y.length;if(A.dryRun)return{jobs:[],totalSections:Z,queuedSections:Z,batchId:`dry-run-${Date.now()}`};let H=[],W=[];for(let{route:K,section:U}of Y){let G=`${K.id}:${U.id}`,q=U.template,V={routeId:K.id,sectionId:U.id,entityId:G,entityType:"site-content",templateName:q,context:{prompt:typeof U.content==="string"?U.content:void 0,data:{routeId:K.id,sectionId:U.id,routeTitle:K.title,routeDescription:K.description,sectionContent:U.content},conversationId:"system"},siteConfig:Q};W.push({type:"shell:content-generation",data:V})}if(W.length>0){let K=this.createJobOptions(w,"site:content-generation"),U=await this.context.jobs.enqueueBatch(W,K);for(let G=0;G<Y.length;G++){let q=Y[G];if(q)H.push({jobId:`${U}-${G}`,routeId:q.route.id,sectionId:q.section.id})}return{jobs:H,totalSections:Z,queuedSections:H.length,batchId:U}}return{jobs:[],totalSections:Z,queuedSections:0,batchId:`empty-${Date.now()}`}}}class Ha0{siteConfig;operations;constructor(A,Q){this.siteConfig=Q,this.operations=new fa0(A)}async generateContent(A,Q){let w=mZ0.parse(A);return this.operations.generate(w,this.siteConfig,Q)}}Y7();C0();var Ubw=f.object({namespace:f.string(),sections:f.record(f.string(),f.any())}),R12=f.custom((A)=>Ubw.safeParse(A).success),Wa0=f.object({definitions:f.union([R12,f.array(R12)]).optional()});fA();function v12(A,Q){return[p6(Q,"generate","Generate content for all routes, a specific route, or a specific section",mZ0,async(w,$)=>{let B=A();if(!B)return{success:!1,error:"Site content service not initialized"};if(w.sectionId&&!w.routeId)return{success:!1,error:"sectionId requires routeId to be specified"};let X={rootJobId:`generate-${Date.now()}`,progressToken:$.progressToken,pluginId:Q,operationType:"content_operations",interfaceType:$.interfaceType,channelId:$.channelId},Y=await B.generateContent(w,X);return{success:!0,message:`Generated ${Y.queuedSections} of ${Y.totalSections} sections. ${Y.queuedSections>0?"Jobs are running in the background.":"No new content to generate."}`,data:{batchId:Y.batchId,jobsQueued:Y.queuedSections,totalSections:Y.totalSections,jobs:Y.jobs}}})]}var h12={name:"@brains/site-content",version:"0.2.0-alpha.159",description:"Site content entity and generation orchestration",dependencies:{"@brains/content-formatters":"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":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};class Ka0 extends Kw{siteContentService;constructor(A={}){super("site-content",h12,A,Wa0)}async onRegister(A){A.entities.register("site-content",ws,Za0);for(let Q of ZF(this.config.definitions))A.templates.register(UI(Q),Q.namespace);this.siteContentService=new Ha0(A)}async getTools(){return v12(()=>this.siteContentService,this.id)}}function sP(A={}){return new Ka0(A)}fA();Y7();fA();C0();Y7();var Dbw=f.object({}),qbw=f.object({}),$s=EQ.extend({id:f.literal("site-info"),entityType:f.literal("site-info"),metadata:qbw});var HE=zI0.omit({url:!0,analyticsScript:!0});fA();C0();var zbw=f.record(f.string(),f.unknown());class Pq extends d2{constructor(){super({entityType:"site-info",purpose:"Singleton configuration describing the published site.",schema:$s,frontmatterSchema:HE,isSingleton:!0,hasBody:!1})}createSiteInfoContent(A){let Q=HE.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("",zbw.parse(Q))}}class Mq{static instance=null;logger;entityService;adapter;defaultSiteInfo;static getDefaultSiteInfo(){return{title:"Brain",description:"A knowledge management system"}}static getInstance(A,Q,w){return Mq.instance??=new Mq(A,Q,w),Mq.instance}static resetInstance(){Mq.instance=null}static createFresh(A,Q,w){return new Mq(A,Q,w)}constructor(A,Q,w){this.entityService=A,this.logger=Q.child("SiteInfoService"),this.adapter=new Pq;let $=Mq.getDefaultSiteInfo();this.defaultSiteInfo={...$,...w}}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 w=this.adapter.createSiteInfoContent(this.defaultSiteInfo);await this.entityService.createEntity({entity:{id:"site-info",entityType:"site-info",content:w,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}}C0();var Vbw=new Pq,Jbw=f.looseObject({platform:f.string(),url:f.string(),label:f.string().optional()}).transform((A)=>({platform:A.platform,url:A.url,...A.label!==void 0?{label:A.label}:{}})),Ibw=f.looseObject({socialLinks:f.array(Jbw).optional()});class uZ0{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,w){let{entityService:$}=w,B;try{let Z=await $.getEntity({entityType:"site-info",id:"site-info"});B=Z?Vbw.parseSiteInfoBody(Z.content):{title:"Brain",description:"A knowledge management system"}}catch{B={title:"Brain",description:"A knowledge management system"}}let X;try{let Z=await $.getEntity({entityType:"anchor-profile",id:"anchor-profile"});if(Z){let H=Ibw.safeParse(Z.metadata);X=H.success?H.data.socialLinks:void 0}}catch{}let Y={...B,socialLinks:X,copyright:B.copyright??"Powered by Rizom"};return this.logger.debug("SiteInfoDataSource returning",{title:Y.title,hasSocialLinks:!!Y.socialLinks}),Q.parse(Y)}}var C12={name:"@brains/site-info",version:"0.2.0-alpha.159",description:"Site info entity \u2014 site metadata, title, description, CTA",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":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var bbw=new Pq,Lbw="site-info";class Ua0 extends Zw{entityType=Lbw;schema=$s;adapter=bbw;defaultSiteInfo;constructor(A){super("site-info",C12,{},i7);this.defaultSiteInfo=A?.siteInfo??{}}getEntityTypeConfig(){return{embeddable:!1}}getDataSources(){return[new uZ0(this.logger.child("SiteInfoDataSource"))]}async onRegister(A){let Q=Mq.createFresh(A.entityService,this.logger,this.defaultSiteInfo);A.messaging.subscribe(Jm,async()=>{return{success:!0,data:await Q.getSiteInfo()}}),A.messaging.subscribe("entity:updated",async(w)=>{if(w.payload.entityType==="site-info"){let B=await Q.getSiteInfo();await A.messaging.send({type:Im,payload:B,broadcast:!0})}return{success:!0}}),A.messaging.subscribe("sync:initial:completed",async()=>{return await Q.initialize(),{success:!0}})}}function aP(A){return new Ua0(A)}var kbw=new Pq;async function Bs(A){let w=(await A.listEntities({entityType:"site-info",options:{limit:1}}))[0];if(!w)throw Error("Site info not found \u2014 create a site-info entity");return kbw.parseSiteInfoBody(w.content)}function g12(A,Q){let w=A.metadata.publishedAt??A.created,$=Q.metadata.publishedAt??Q.created;return new Date($).getTime()-new Date(w).getTime()}async function cZ0(A,Q){return(await A.listEntities({entityType:Q.entityType,options:{limit:20}})).sort(g12).slice(0,Q.count).map(Q.parse)}function Ga0(A){if(!A)throw Error("CTA not configured in site-info");return A}C0();var y12=f.object({label:f.string(),href:f.string(),priority:f.number()}),_bw=f.object({primary:f.array(y12),secondary:f.array(y12)}),Nbw=f.object({platform:f.enum(["github","instagram","linkedin","email","website"]).describe("Social media platform"),url:f.string().describe("Profile or contact URL"),label:f.string().optional().describe("Optional display label")}),jbw=HE.extend({navigation:_bw,copyright:f.string(),socialLinks:f.array(Nbw).optional().describe("Social media links from profile entity")});fA();ZH();UE();C0();var Da0=f.object({defaultPrompt:f.string().default("Write a blog post about my recent work and insights"),paginate:f.boolean().default(!0),pageSize:f.number().default(10)});fA();e6();b2();C0();var xbw=f.object({prompt:f.string().optional(),title:f.string().optional(),content:f.string().optional(),excerpt:f.string().optional(),coverImageId:f.string().optional(),seriesName:f.string().optional(),seriesIndex:f.number().optional(),skipAi:f.boolean().optional()}),XK8=aZ.extend({title:f.string().optional(),slug:f.string().optional()});class qa0 extends S4{constructor(A,Q){super(A,Q,{schema:xbw,jobTypeName:"blog-generation",entityType:"post"})}async generate(A,Q){let{prompt:w,coverImageId:$,seriesName:B,seriesIndex:X,skipAi:Y}=A,{title:Z,content:H,excerpt:W}=A;if(Y){if(!Z)this.failEarly("Title is required when skipAi is true");H=H??`## Introduction
6755
6755
 
6756
6756
  Add your introduction here.
6757
6757
 
@@ -6971,7 +6971,7 @@ ${w.content}`,templateName:"blog:excerpt"})})}fA();UE();ZH();function ALw(A){let
6971
6971
  letter-spacing: 0.02em;
6972
6972
  }
6973
6973
  .printable-footer a { color: inherit; text-decoration: none; overflow-wrap: anywhere; }
6974
- `}},void 0,!1,void 0,this),K4("header",{className:"printable-hero",children:[K4("div",{className:"printable-masthead",children:Q.brandLabel&&K4("p",{className:"printable-kicker",children:Q.brandLabel},void 0,!1,void 0,this)},void 0,!1,void 0,this),K4("div",{children:[K4("h1",{className:"printable-title",children:Q.title},void 0,!1,void 0,this),Q.excerpt&&K4("p",{className:"printable-excerpt",children:Q.excerpt},void 0,!1,void 0,this),K4("div",{className:"printable-meta",children:[Q.author&&K4("span",{children:["By ",Q.author]},void 0,!0,void 0,this),w&&K4("span",{children: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),Q.coverImageUrl&&K4("figure",{className:"printable-cover-wrap",children:K4("img",{className:"printable-cover",src:Q.coverImageUrl,alt:""},void 0,!1,void 0,this)},void 0,!1,void 0,this),K4(l9,{markdown:Q.body,className:"printable-body"},void 0,!1,void 0,this),(Boolean(Q.canonicalUrl)||Boolean(Q.brandLabel))&&K4("footer",{className:"printable-footer",children:[K4("span",{children:Q.brandLabel??"Printable PDF"},void 0,!1,void 0,this),Q.canonicalUrl&&K4("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 yLw=26214400,ELw=60000;class ja0{metadata={outputEntityType:"document"};context;renderPdf;constructor(A,Q={}){this.context=A,this.renderPdf=Q.renderPdf??XG}async resolve(A){if(A.sourceEntityType!=="post"||A.attachmentType!==dZ0)return;let Q=await this.context.entityService.getEntity({entityType:"post",id:A.sourceEntityId});if(!Q)return;let w=TLw(Q,{brandLabel:this.resolveBrandLabel(),coverImageUrl:await this.resolveCoverImageUrl(Q)}),$=await vLw(gLw(CLw(),"brain-blog-printable-"));try{let B=await HH({outputDir:$,mediaPath:`/_media/printable/post/${Q.id}`,template:$22,format:"pdf",content:w,siteConfig:{title:w.title,themeMode:"light"},themeCSS:this.context.themeCSS}),X=await WH({rootDir:$});try{return{type:"document",data:await this.renderPdf(X.urlFor(B.urlPath),{maxBytes:yLw,timeoutMs:ELw,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${SLw(Q)}-printable.pdf`}}finally{await X.close()}}finally{await hLw($,{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}=l6(A.content),w=v8.parse(Q);if(!w.coverImageId)return;let $=await this.context.entityService.getEntity({entityType:"image",id:w.coverImageId});return $?.content.startsWith("data:image/")?$.content:void 0}}function TLw(A,Q={}){let{frontmatter:w,content:$}=l6(A.content),B=v8.parse(w);return{title:B.title,body:$,...B.excerpt?{excerpt:B.excerpt}:{},...B.author?{author:B.author}:{},...B.publishedAt?{publishedAt:B.publishedAt}:{},...B.canonicalUrl?{canonicalUrl:B.canonicalUrl}:{},...Q.coverImageUrl?{coverImageUrl:Q.coverImageUrl}:{},...Q.brandLabel?{brandLabel:Q.brandLabel}:{}}}function SLw(A){let Q=A.metadata.slug;return Q.length>0?Q:q1(A.metadata.title)}import{mkdtemp as pLw,rm as iLw}from"fs/promises";import{tmpdir as dLw}from"os";import{join as nLw}from"path";H7();b2();ZH();C0();import{jsxDEV as lLw}from"preact/jsx-dev-runtime";var Ws="og-image",mLw="blog:og-image",B22=f.object({title:f.string().min(1),excerpt:f.string().optional(),author:f.string().optional(),publishedAt:f.string().optional(),brandLabel:f.string().optional(),coverImageUrl:f.string().optional()}),X22={name:mLw,pluginId:"blog",schema:B22,renderers:{image:cLw}};function uLw(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 cLw(A){let Q=B22.parse(A);return lLw(RV,{brandLabel:Q.brandLabel??Q.title,eyebrow:"Journal",title:Q.title,subtitle:Q.excerpt,meta:[Q.author],tag:uLw(Q.publishedAt)},void 0,!1,void 0,this)}var rLw={width:1200,height:630},oLw=60000;class Pa0{metadata={outputEntityType:"image",targetField:"ogImageId"};context;screenshotPng;constructor(A,Q={}){this.context=A,this.screenshotPng=Q.screenshotPng??Hs}async resolve(A){if(A.sourceEntityType!=="post"||A.attachmentType!==Ws)return;let Q=await this.context.entityService.getEntity({entityType:"post",id:A.sourceEntityId});if(!Q)return;let w=sLw(Q,{brandLabel:this.resolveBrandLabel(),coverImageUrl:await this.resolveCoverImageUrl(Q)}),$=await pLw(nLw(dLw(),"brain-blog-og-image-"));try{let B=await HH({outputDir:$,mediaPath:`/_media/og/post/${Q.id}`,template:X22,format:"image",content:w,siteConfig:{title:w.title,themeMode:"light"},themeCSS:this.context.themeCSS}),X=await WH({rootDir:$});try{return{type:"image",data:await this.screenshotPng(X.urlFor(B.urlPath),rLw,{timeoutMs:oLw,fullPage:!1,omitBackground:!1}),mimeType:"image/png",filename:`${aLw(Q)}-og.png`}}finally{await X.close()}}finally{await iLw($,{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}=l6(A.content),w=v8.parse(Q);if(!w.coverImageId)return;let $=await this.context.entityService.getEntity({entityType:"image",id:w.coverImageId});return $?.content.startsWith("data:image/")?$.content:void 0}}function sLw(A,Q={}){let{frontmatter:w}=l6(A.content),$=v8.parse(w);return{title:$.title,...$.excerpt?{excerpt:$.excerpt}:{},...$.author?{author:$.author}:{},...$.publishedAt?{publishedAt:$.publishedAt}:{},...Q.coverImageUrl?{coverImageUrl:Q.coverImageUrl}:{},...Q.brandLabel?{brandLabel:Q.brandLabel}:{}}}function aLw(A){let Q=A.metadata.slug;return Q.length>0?Q:q1(A.metadata.title)}var Y22={name:"@brains/blog",version:"0.2.0-alpha.158",description:"AI-powered blog post generation from existing brain content",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":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{eval:"cd evals && bun run brain-eval",lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};class Ma0 extends Zw{entityType=nV.entityType;schema=WE;adapter=nV;unregisterAtprotoProjection;unregisterPrintableAttachmentProvider;unregisterOgImageAttachmentProvider;constructor(A={}){super("blog",Y22,A,Da0)}getEntityTypeConfig(){return{weight:2,publish:{publishStatuses:["queued","published"]}}}createGenerationHandler(A){return new qa0(this.logger.child("BlogGenerationJobHandler"),A)}getTemplates(){return c12()}getDataSources(){return[new Va0(this.logger.child("BlogDataSource"))]}async onRegister(A){let{RSSDataSource:Q}=await Promise.resolve().then(() => (H22(),f22));A.entities.registerDataSource(new Q(this.logger.child("RSSDataSource"))),l12(A,this.logger),p12(A,this.logger),d12(A,this.logger),n12(A),this.unregisterPrintableAttachmentProvider=A.attachments.register("post",dZ0,new ja0(A)),this.unregisterOgImageAttachmentProvider=A.attachments.register("post",Ws,new Pa0(A)),this.deferPublishAssetRegistration(A),this.unregisterAtprotoProjection=kB.getInstance().register(Fa0()),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:Ws,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 Oa0(A={}){return new Ma0(A)}ZH();UE();fA();C0();b9();fA();C0();var YG=f.object({title:f.string(),slug:f.string(),coverImageId:f.string().optional()}),Akw=f.object({title:f.string(),slug:f.string()}),Qkw=f.object({title:f.string(),slug:f.string()}),GL=EQ.extend({entityType:f.literal("series"),metadata:Qkw}),nZ0=GL.extend({frontmatter:YG}),wkw=nZ0.extend({description:f.string().optional(),postCount:f.number(),coverImageUrl:f.string().optional(),coverImageWidth:f.number().optional(),coverImageHeight:f.number().optional()}),W22=f.object({description:f.string().optional()});function QM(A){return new R6(W22,{title:A,mappings:[{key:"description",label:"Description",type:"string"}]})}fA();class xa0 extends d2{constructor(){super({entityType:"series",purpose:"A series grouping related posts or content under one theme.",schema:GL,frontmatterSchema:YG,supportsCoverImage:!0,bodyFormatter:QM("")})}toMarkdown(A){let Q,w={};try{Q=this.parseFrontMatter(A.content,YG).coverImageId,w=QM(A.metadata.title).parse(this.extractBody(A.content))}catch{}let $={title:A.metadata.title,slug:A.metadata.slug,...Q&&{coverImageId:Q}},X=QM(A.metadata.title).format(w);return this.buildMarkdown(X,$)}fromMarkdown(A){let Q=this.parseFrontMatter(A,YG);return{content:A,entityType:"series",metadata:{title:Q.title,slug:Q.slug}}}parseBody(A){try{let Q=this.parseFrontMatter(A,YG);return QM(Q.title).parse(this.extractBody(A))}catch{return{}}}generateFrontMatter(){return""}}var DL=new xa0;fA();b2();Xf();C0();var $kw=f.object({seriesName:f.string().optional(),seriesIndex:f.number().optional()});function rZ0(A){let Q=$kw.safeParse(A);return Q.success?Q.data:{}}function wM(A){return rZ0(A.metadata).seriesName}function K22(A){return rZ0(A.metadata).seriesIndex}function U22(A,Q){let w=K22(A)??Number.MAX_SAFE_INTEGER,$=K22(Q)??Number.MAX_SAFE_INTEGER;return w-$}class Ra0{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"}),w=new Map(Q.map((B)=>[B.id,B])),$=new Set;for(let B of A){let X=q1(B);$.add(X);let Y=w.get(X),Z=Y?.content??this.createSeriesContent(B),H=I6(Z);if(Y?.contentHash===H)continue;let W={id:X,entityType:"series",content:Z,contentHash:H,created:Y?.created??new Date().toISOString(),updated:new Date().toISOString(),visibility:"public",metadata:{title:B,slug:q1(B)}};await this.entityService.upsertEntity({entity:W}),this.logger.debug(`Upserted series: ${B}`)}for(let B of Q)if(!$.has(B.id))await this.entityService.deleteEntity({entityType:"series",id:B.id}),this.logger.debug(`Deleted orphaned series: ${B.id}`)}async handleEntityChange(A,Q){let w=wM(A);if(w)await this.ensureSeriesExists(w);if(Q&&Q!==w)await this.cleanupOrphanedSeries(Q)}async handleEntityDeleted(){await this.syncAllSeries()}async ensureSeriesExists(A){let Q=q1(A);if(await this.entityService.getEntity({entityType:"series",id:Q}))return;let $=this.createSeriesContent(A),B={id:Q,entityType:"series",content:$,contentHash:I6($),created:new Date().toISOString(),updated:new Date().toISOString(),visibility:"public",metadata:{title:A,slug:q1(A)}};await this.entityService.upsertEntity({entity:B}),this.logger.debug(`Created series: ${A}`)}async cleanupOrphanedSeries(A){let Q=q1(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 w of Q){if(w==="series")continue;if((await this.entityService.listEntities({entityType:w,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 w of Q){if(w==="series")continue;let $=await this.entityService.listEntities({entityType:w});for(let B of $){let X=wM(B);if(X)A.add(X)}}return A}createSeriesContent(A){let Q={title:A,slug:q1(A)};return m5("",Q)}}fA();C0();var Bkw=f.object({entityType:f.literal("series"),query:f.looseObject({id:f.string().optional(),limit:f.number().optional(),page:f.number().optional(),pageSize:f.number().optional()})}),Xkw=f.object({type:f.enum(["list","detail"]),seriesName:f.string().optional()});function Ykw(A){let Q=Xkw.safeParse(A);if(Q.success)return{type:Q.data.type,seriesName:Q.data.seriesName};let w=Bkw.safeParse(A);if(w.success){let{query:$}=w.data;if($.id)return{type:"detail",seriesSlug:$.id};return{type:"list"}}throw Error('Invalid series query format. Expected { type: "list"|"detail" } or { entityType: "series", query: { id?: string } }')}function G22(A){let Q=$Q(A.content,YG);return nZ0.parse({...A,frontmatter:Q.metadata})}class va0{logger;id="series:entities";name="Series DataSource";description="Fetches series list and detail data";constructor(A){this.logger=A}async fetch(A,Q,w){let $=Ykw(A),B=w.entityService;if($.type==="list")return this.fetchSeriesList(Q,B);if($.seriesName)return this.fetchSeriesDetail($.seriesName,Q,B);if($.seriesSlug)return this.fetchSeriesDetailBySlug($.seriesSlug,Q,B);throw Error("Invalid series query: must specify seriesName or slug for detail")}async fetchSeriesList(A,Q){let w=await Q.listEntities({entityType:"series"}),$=await this.countEntitiesPerSeries(Q),B=w.map((X)=>{let Y=G22(X),Z=DL.parseBody(X.content);return{...Y,description:Z.description,postCount:$.get(X.metadata.title)??0}});return this.logger.debug(`Found ${B.length} series entities`),A.parse({series:B})}async fetchSeriesDetail(A,Q,w,$){if(!$)$=(await w.listEntities({entityType:"series",options:{filter:{metadata:{title:A}}}}))[0];if(!$)throw Error(`Series not found: ${A}`);let B=G22($),X=DL.parseBody($.content),Y=await this.getSeriesMembers(A,w);return this.logger.debug(`Found ${Y.length} entities in series "${A}"`),Q.parse({seriesName:A,posts:Y,series:{...B,description:X.description,postCount:Y.length},description:X.description})}async fetchSeriesDetailBySlug(A,Q,w){let B=(await w.listEntities({entityType:"series",options:{filter:{metadata:{slug:A}}}}))[0];if(!B)throw Error(`Series not found with slug: ${A}`);return this.fetchSeriesDetail(B.metadata.title,Q,w,B)}async countEntitiesPerSeries(A){let Q=new Map,w=A.getEntityTypes();for(let $ of w){if($==="series")continue;let B=await A.listEntities({entityType:$});for(let X of B){let Y=wM(X);if(Y)Q.set(Y,(Q.get(Y)??0)+1)}}return Q}async getSeriesMembers(A,Q){let w=[],$=Q.getEntityTypes();for(let B of $){if(B==="series")continue;let X=await Q.listEntities({entityType:B,options:{filter:{metadata:{seriesName:A}}}});w.push(...X)}return w.sort(U22),w}}fA();C0();Xf();var Zkw=f.object({prompt:f.string().optional(),title:f.string().optional(),seriesId:f.string().optional()}),fkw=f.object({title:f.string().optional(),excerpt:f.string().optional()});class oZ0{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 w=await this.context.entityService.getEntity({entityType:"series",id:Q});if(!w)return{success:!1,error:`Series not found: ${Q}`};let $=await this.gatherMemberSummaries(w.metadata.title);if($.length===0)return{success:!1,error:`No members found in series: ${w.metadata.title}`};let B=A.prompt??`Series name: ${w.metadata.title}
6974
+ `}},void 0,!1,void 0,this),K4("header",{className:"printable-hero",children:[K4("div",{className:"printable-masthead",children:Q.brandLabel&&K4("p",{className:"printable-kicker",children:Q.brandLabel},void 0,!1,void 0,this)},void 0,!1,void 0,this),K4("div",{children:[K4("h1",{className:"printable-title",children:Q.title},void 0,!1,void 0,this),Q.excerpt&&K4("p",{className:"printable-excerpt",children:Q.excerpt},void 0,!1,void 0,this),K4("div",{className:"printable-meta",children:[Q.author&&K4("span",{children:["By ",Q.author]},void 0,!0,void 0,this),w&&K4("span",{children: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),Q.coverImageUrl&&K4("figure",{className:"printable-cover-wrap",children:K4("img",{className:"printable-cover",src:Q.coverImageUrl,alt:""},void 0,!1,void 0,this)},void 0,!1,void 0,this),K4(l9,{markdown:Q.body,className:"printable-body"},void 0,!1,void 0,this),(Boolean(Q.canonicalUrl)||Boolean(Q.brandLabel))&&K4("footer",{className:"printable-footer",children:[K4("span",{children:Q.brandLabel??"Printable PDF"},void 0,!1,void 0,this),Q.canonicalUrl&&K4("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 yLw=26214400,ELw=60000;class ja0{metadata={outputEntityType:"document"};context;renderPdf;constructor(A,Q={}){this.context=A,this.renderPdf=Q.renderPdf??XG}async resolve(A){if(A.sourceEntityType!=="post"||A.attachmentType!==dZ0)return;let Q=await this.context.entityService.getEntity({entityType:"post",id:A.sourceEntityId});if(!Q)return;let w=TLw(Q,{brandLabel:this.resolveBrandLabel(),coverImageUrl:await this.resolveCoverImageUrl(Q)}),$=await vLw(gLw(CLw(),"brain-blog-printable-"));try{let B=await HH({outputDir:$,mediaPath:`/_media/printable/post/${Q.id}`,template:$22,format:"pdf",content:w,siteConfig:{title:w.title,themeMode:"light"},themeCSS:this.context.themeCSS}),X=await WH({rootDir:$});try{return{type:"document",data:await this.renderPdf(X.urlFor(B.urlPath),{maxBytes:yLw,timeoutMs:ELw,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${SLw(Q)}-printable.pdf`}}finally{await X.close()}}finally{await hLw($,{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}=l6(A.content),w=v8.parse(Q);if(!w.coverImageId)return;let $=await this.context.entityService.getEntity({entityType:"image",id:w.coverImageId});return $?.content.startsWith("data:image/")?$.content:void 0}}function TLw(A,Q={}){let{frontmatter:w,content:$}=l6(A.content),B=v8.parse(w);return{title:B.title,body:$,...B.excerpt?{excerpt:B.excerpt}:{},...B.author?{author:B.author}:{},...B.publishedAt?{publishedAt:B.publishedAt}:{},...B.canonicalUrl?{canonicalUrl:B.canonicalUrl}:{},...Q.coverImageUrl?{coverImageUrl:Q.coverImageUrl}:{},...Q.brandLabel?{brandLabel:Q.brandLabel}:{}}}function SLw(A){let Q=A.metadata.slug;return Q.length>0?Q:q1(A.metadata.title)}import{mkdtemp as pLw,rm as iLw}from"fs/promises";import{tmpdir as dLw}from"os";import{join as nLw}from"path";H7();b2();ZH();C0();import{jsxDEV as lLw}from"preact/jsx-dev-runtime";var Ws="og-image",mLw="blog:og-image",B22=f.object({title:f.string().min(1),excerpt:f.string().optional(),author:f.string().optional(),publishedAt:f.string().optional(),brandLabel:f.string().optional(),coverImageUrl:f.string().optional()}),X22={name:mLw,pluginId:"blog",schema:B22,renderers:{image:cLw}};function uLw(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 cLw(A){let Q=B22.parse(A);return lLw(RV,{brandLabel:Q.brandLabel??Q.title,eyebrow:"Journal",title:Q.title,subtitle:Q.excerpt,meta:[Q.author],tag:uLw(Q.publishedAt)},void 0,!1,void 0,this)}var rLw={width:1200,height:630},oLw=60000;class Pa0{metadata={outputEntityType:"image",targetField:"ogImageId"};context;screenshotPng;constructor(A,Q={}){this.context=A,this.screenshotPng=Q.screenshotPng??Hs}async resolve(A){if(A.sourceEntityType!=="post"||A.attachmentType!==Ws)return;let Q=await this.context.entityService.getEntity({entityType:"post",id:A.sourceEntityId});if(!Q)return;let w=sLw(Q,{brandLabel:this.resolveBrandLabel(),coverImageUrl:await this.resolveCoverImageUrl(Q)}),$=await pLw(nLw(dLw(),"brain-blog-og-image-"));try{let B=await HH({outputDir:$,mediaPath:`/_media/og/post/${Q.id}`,template:X22,format:"image",content:w,siteConfig:{title:w.title,themeMode:"light"},themeCSS:this.context.themeCSS}),X=await WH({rootDir:$});try{return{type:"image",data:await this.screenshotPng(X.urlFor(B.urlPath),rLw,{timeoutMs:oLw,fullPage:!1,omitBackground:!1}),mimeType:"image/png",filename:`${aLw(Q)}-og.png`}}finally{await X.close()}}finally{await iLw($,{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}=l6(A.content),w=v8.parse(Q);if(!w.coverImageId)return;let $=await this.context.entityService.getEntity({entityType:"image",id:w.coverImageId});return $?.content.startsWith("data:image/")?$.content:void 0}}function sLw(A,Q={}){let{frontmatter:w}=l6(A.content),$=v8.parse(w);return{title:$.title,...$.excerpt?{excerpt:$.excerpt}:{},...$.author?{author:$.author}:{},...$.publishedAt?{publishedAt:$.publishedAt}:{},...Q.coverImageUrl?{coverImageUrl:Q.coverImageUrl}:{},...Q.brandLabel?{brandLabel:Q.brandLabel}:{}}}function aLw(A){let Q=A.metadata.slug;return Q.length>0?Q:q1(A.metadata.title)}var Y22={name:"@brains/blog",version:"0.2.0-alpha.159",description:"AI-powered blog post generation from existing brain content",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":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{eval:"cd evals && bun run brain-eval",lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};class Ma0 extends Zw{entityType=nV.entityType;schema=WE;adapter=nV;unregisterAtprotoProjection;unregisterPrintableAttachmentProvider;unregisterOgImageAttachmentProvider;constructor(A={}){super("blog",Y22,A,Da0)}getEntityTypeConfig(){return{weight:2,publish:{publishStatuses:["queued","published"]}}}createGenerationHandler(A){return new qa0(this.logger.child("BlogGenerationJobHandler"),A)}getTemplates(){return c12()}getDataSources(){return[new Va0(this.logger.child("BlogDataSource"))]}async onRegister(A){let{RSSDataSource:Q}=await Promise.resolve().then(() => (H22(),f22));A.entities.registerDataSource(new Q(this.logger.child("RSSDataSource"))),l12(A,this.logger),p12(A,this.logger),d12(A,this.logger),n12(A),this.unregisterPrintableAttachmentProvider=A.attachments.register("post",dZ0,new ja0(A)),this.unregisterOgImageAttachmentProvider=A.attachments.register("post",Ws,new Pa0(A)),this.deferPublishAssetRegistration(A),this.unregisterAtprotoProjection=kB.getInstance().register(Fa0()),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:Ws,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 Oa0(A={}){return new Ma0(A)}ZH();UE();fA();C0();b9();fA();C0();var YG=f.object({title:f.string(),slug:f.string(),coverImageId:f.string().optional()}),Akw=f.object({title:f.string(),slug:f.string()}),Qkw=f.object({title:f.string(),slug:f.string()}),GL=EQ.extend({entityType:f.literal("series"),metadata:Qkw}),nZ0=GL.extend({frontmatter:YG}),wkw=nZ0.extend({description:f.string().optional(),postCount:f.number(),coverImageUrl:f.string().optional(),coverImageWidth:f.number().optional(),coverImageHeight:f.number().optional()}),W22=f.object({description:f.string().optional()});function QM(A){return new R6(W22,{title:A,mappings:[{key:"description",label:"Description",type:"string"}]})}fA();class xa0 extends d2{constructor(){super({entityType:"series",purpose:"A series grouping related posts or content under one theme.",schema:GL,frontmatterSchema:YG,supportsCoverImage:!0,bodyFormatter:QM("")})}toMarkdown(A){let Q,w={};try{Q=this.parseFrontMatter(A.content,YG).coverImageId,w=QM(A.metadata.title).parse(this.extractBody(A.content))}catch{}let $={title:A.metadata.title,slug:A.metadata.slug,...Q&&{coverImageId:Q}},X=QM(A.metadata.title).format(w);return this.buildMarkdown(X,$)}fromMarkdown(A){let Q=this.parseFrontMatter(A,YG);return{content:A,entityType:"series",metadata:{title:Q.title,slug:Q.slug}}}parseBody(A){try{let Q=this.parseFrontMatter(A,YG);return QM(Q.title).parse(this.extractBody(A))}catch{return{}}}generateFrontMatter(){return""}}var DL=new xa0;fA();b2();Xf();C0();var $kw=f.object({seriesName:f.string().optional(),seriesIndex:f.number().optional()});function rZ0(A){let Q=$kw.safeParse(A);return Q.success?Q.data:{}}function wM(A){return rZ0(A.metadata).seriesName}function K22(A){return rZ0(A.metadata).seriesIndex}function U22(A,Q){let w=K22(A)??Number.MAX_SAFE_INTEGER,$=K22(Q)??Number.MAX_SAFE_INTEGER;return w-$}class Ra0{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"}),w=new Map(Q.map((B)=>[B.id,B])),$=new Set;for(let B of A){let X=q1(B);$.add(X);let Y=w.get(X),Z=Y?.content??this.createSeriesContent(B),H=I6(Z);if(Y?.contentHash===H)continue;let W={id:X,entityType:"series",content:Z,contentHash:H,created:Y?.created??new Date().toISOString(),updated:new Date().toISOString(),visibility:"public",metadata:{title:B,slug:q1(B)}};await this.entityService.upsertEntity({entity:W}),this.logger.debug(`Upserted series: ${B}`)}for(let B of Q)if(!$.has(B.id))await this.entityService.deleteEntity({entityType:"series",id:B.id}),this.logger.debug(`Deleted orphaned series: ${B.id}`)}async handleEntityChange(A,Q){let w=wM(A);if(w)await this.ensureSeriesExists(w);if(Q&&Q!==w)await this.cleanupOrphanedSeries(Q)}async handleEntityDeleted(){await this.syncAllSeries()}async ensureSeriesExists(A){let Q=q1(A);if(await this.entityService.getEntity({entityType:"series",id:Q}))return;let $=this.createSeriesContent(A),B={id:Q,entityType:"series",content:$,contentHash:I6($),created:new Date().toISOString(),updated:new Date().toISOString(),visibility:"public",metadata:{title:A,slug:q1(A)}};await this.entityService.upsertEntity({entity:B}),this.logger.debug(`Created series: ${A}`)}async cleanupOrphanedSeries(A){let Q=q1(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 w of Q){if(w==="series")continue;if((await this.entityService.listEntities({entityType:w,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 w of Q){if(w==="series")continue;let $=await this.entityService.listEntities({entityType:w});for(let B of $){let X=wM(B);if(X)A.add(X)}}return A}createSeriesContent(A){let Q={title:A,slug:q1(A)};return m5("",Q)}}fA();C0();var Bkw=f.object({entityType:f.literal("series"),query:f.looseObject({id:f.string().optional(),limit:f.number().optional(),page:f.number().optional(),pageSize:f.number().optional()})}),Xkw=f.object({type:f.enum(["list","detail"]),seriesName:f.string().optional()});function Ykw(A){let Q=Xkw.safeParse(A);if(Q.success)return{type:Q.data.type,seriesName:Q.data.seriesName};let w=Bkw.safeParse(A);if(w.success){let{query:$}=w.data;if($.id)return{type:"detail",seriesSlug:$.id};return{type:"list"}}throw Error('Invalid series query format. Expected { type: "list"|"detail" } or { entityType: "series", query: { id?: string } }')}function G22(A){let Q=$Q(A.content,YG);return nZ0.parse({...A,frontmatter:Q.metadata})}class va0{logger;id="series:entities";name="Series DataSource";description="Fetches series list and detail data";constructor(A){this.logger=A}async fetch(A,Q,w){let $=Ykw(A),B=w.entityService;if($.type==="list")return this.fetchSeriesList(Q,B);if($.seriesName)return this.fetchSeriesDetail($.seriesName,Q,B);if($.seriesSlug)return this.fetchSeriesDetailBySlug($.seriesSlug,Q,B);throw Error("Invalid series query: must specify seriesName or slug for detail")}async fetchSeriesList(A,Q){let w=await Q.listEntities({entityType:"series"}),$=await this.countEntitiesPerSeries(Q),B=w.map((X)=>{let Y=G22(X),Z=DL.parseBody(X.content);return{...Y,description:Z.description,postCount:$.get(X.metadata.title)??0}});return this.logger.debug(`Found ${B.length} series entities`),A.parse({series:B})}async fetchSeriesDetail(A,Q,w,$){if(!$)$=(await w.listEntities({entityType:"series",options:{filter:{metadata:{title:A}}}}))[0];if(!$)throw Error(`Series not found: ${A}`);let B=G22($),X=DL.parseBody($.content),Y=await this.getSeriesMembers(A,w);return this.logger.debug(`Found ${Y.length} entities in series "${A}"`),Q.parse({seriesName:A,posts:Y,series:{...B,description:X.description,postCount:Y.length},description:X.description})}async fetchSeriesDetailBySlug(A,Q,w){let B=(await w.listEntities({entityType:"series",options:{filter:{metadata:{slug:A}}}}))[0];if(!B)throw Error(`Series not found with slug: ${A}`);return this.fetchSeriesDetail(B.metadata.title,Q,w,B)}async countEntitiesPerSeries(A){let Q=new Map,w=A.getEntityTypes();for(let $ of w){if($==="series")continue;let B=await A.listEntities({entityType:$});for(let X of B){let Y=wM(X);if(Y)Q.set(Y,(Q.get(Y)??0)+1)}}return Q}async getSeriesMembers(A,Q){let w=[],$=Q.getEntityTypes();for(let B of $){if(B==="series")continue;let X=await Q.listEntities({entityType:B,options:{filter:{metadata:{seriesName:A}}}});w.push(...X)}return w.sort(U22),w}}fA();C0();Xf();var Zkw=f.object({prompt:f.string().optional(),title:f.string().optional(),seriesId:f.string().optional()}),fkw=f.object({title:f.string().optional(),excerpt:f.string().optional()});class oZ0{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 w=await this.context.entityService.getEntity({entityType:"series",id:Q});if(!w)return{success:!1,error:`Series not found: ${Q}`};let $=await this.gatherMemberSummaries(w.metadata.title);if($.length===0)return{success:!1,error:`No members found in series: ${w.metadata.title}`};let B=A.prompt??`Series name: ${w.metadata.title}
6975
6975
 
6976
6976
  Content in this series:
6977
6977
  ${$.join(`
@@ -6983,7 +6983,7 @@ Your task is to write a series description (2-3 sentences) that:
6983
6983
  3. Is engaging and makes readers want to explore the content
6984
6984
  4. Works well as a series overview on a website
6985
6985
 
6986
- Be concise and focus on what makes this series unique and valuable.`});async function b22({entity:A,config:Q}){let w=GL.parse(A),$=DL.parseBody(w.content);return{$type:"ai.rizom.brain.series",title:w.metadata.title,slug:w.metadata.slug,...$.description&&{description:$.description},...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"series",sourceEntityId:w.id,createdAt:w.created,...w.updated&&{updatedAt:w.updated}}}function ha0(){return{entityType:"series",collection:"ai.rizom.brain.series",lexicon:S6["ai.rizom.brain.series"],validate:!1,buildRecord:b22}}var L22={name:"@brains/series",version:"0.2.0-alpha.158",description:"Cross-content series \u2014 auto-derived from entities with seriesName metadata",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":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var k22=f.discriminatedUnion("mode",[f.object({mode:f.literal("derive"),reason:f.string().optional()}),f.object({mode:f.literal("source"),entityId:f.string(),entityType:f.string(),seriesName:f.string().optional(),previousSeriesName:f.string().optional()})]);class Ca0 extends Zw{entityType="series";schema=GL;adapter=DL;manager;unregisterAtprotoProjection;constructor(){super("series",L22,{},i7)}getEntityTypeConfig(){return{weight:0.5}}createGenerationHandler(A){return new oZ0(this.logger.child("SeriesGenerationHandler"),A)}getTemplates(){return{...I22(),description:F22}}getDataSources(){return[new va0(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 w=wM(Q.entity),$=rZ0(Q.previousMetadata).seriesName;if(!w&&!$)return null;return{mode:"source",entityId:Q.entity.id,entityType:Q.entity.entityType,...w?{seriesName:w}:{},...$&&$!==w?{previousSeriesName:$}:{}}},jobOptions:(Q)=>{if(!Q.entity)return;return this.getSourceProjectionJobOptions(Q.entity)}}}]}async onRegister(A){this.manager=new Ra0(A.entityService,this.logger.child("SeriesManager")),this.unregisterAtprotoProjection=kB.getInstance().register(ha0())}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}createSeriesProjectionHandler(A){return{process:async(Q)=>{let w=k22.parse(Q);if(w.mode==="derive")return await this.projectAll(A),{success:!0};let $=await A.entityService.getEntity({entityType:w.entityType,id:w.entityId});if($)await this.projectSource($,w.previousSeriesName);else{let B=this.requireManager();for(let X of[w.seriesName,w.previousSeriesName])if(X)await B.cleanupOrphanedSeries(X)}return{success:!0}},validateAndParse:(Q)=>{let w=k22.safeParse(Q??{});return w.success?w.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 oZ0(this.logger.child("SeriesGenerationHandler"),A),w=await A.entityService.listEntities({entityType:"series"});for(let $ of w)try{if(!this.adapter.parseBody($.content).description)this.logger.info(`Generating description for series: ${$.metadata.title}`),await Q.process({seriesId:$.id})}catch(B){this.logger.error(`Failed to generate description for series: ${$.id}`,{error:B})}}}function ga0(){return new Ca0}fA();C0();fA();b2();C0();fA();var _22=f.enum(["generating","draft","queued","published","failed"]),N22=f.enum(["generating","draft","queued","published","failed"]),ya0="publishedAt is required when deck status is published",Ea0=(A)=>A.status==="published"&&!A.publishedAt,Ta0=(A)=>{if(Ea0(A))throw Error(ya0)},Oq=f.object({title:f.string(),slug:f.string().optional(),description:f.string().optional(),author:f.string().optional(),status:_22,publishedAt:f.string().datetime().optional(),event:f.string().optional(),coverImageId:f.string().optional(),ogImageId:f.string().optional()}),tD8=f.object({title:f.string(),description:f.string().optional(),status:_22,publishedAt:f.string().datetime().optional(),coverImageId:f.string().optional(),slug:f.string(),error:f.string().optional()}).superRefine((A,Q)=>{if(!Ea0(A))return;Q.addIssue({code:f.ZodIssueCode.custom,path:["publishedAt"],message:ya0})}),Vkw=f.object({title:f.string(),description:f.string().optional(),status:N22,publishedAt:f.string().datetime().optional(),coverImageId:f.string().optional(),slug:f.string(),error:f.string().optional()}).superRefine((A,Q)=>{if(!Ea0(A))return;Q.addIssue({code:"custom",path:["publishedAt"],message:ya0})}),Jkw=f.object({title:f.string(),slug:f.string().optional(),description:f.string().optional(),author:f.string().optional(),status:N22,publishedAt:f.string().datetime().optional(),event:f.string().optional(),coverImageId:f.string().optional(),ogImageId:f.string().optional()}),DE=EQ.extend({entityType:f.literal("deck"),metadata:Vkw}),sZ0=DE.extend({frontmatter:Jkw,body:f.string(),ogImageUrl:f.string().optional()}),Ks=sZ0.extend({url:f.string().optional(),typeLabel:f.string().optional(),listUrl:f.string().optional(),listLabel:f.string().optional(),coverImageUrl:f.string().optional(),ogImageUrl:f.string().optional(),coverImageWidth:f.number().optional(),coverImageHeight:f.number().optional()});class Sa0 extends d2{constructor(){super({entityType:"deck",purpose:"A slide-deck presentation.",schema:DE,frontmatterSchema:Oq,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 w=this.parseFrontMatter(A.content,Oq);Ta0(w);let $={...w,slug:w.slug??A.metadata.slug};return this.buildMarkdown(Q,$)}fromMarkdown(A){let Q=this.parseFrontmatter(A),w=this.extractBody(A);Ta0(Q),this.validateSlideStructure(w);let $=Q.slug??q1(Q.title),B=Q.status;return{entityType:"deck",content:A,metadata:{slug:$,title:Q.title,description:Q.description,status:B,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(`---
6986
+ Be concise and focus on what makes this series unique and valuable.`});async function b22({entity:A,config:Q}){let w=GL.parse(A),$=DL.parseBody(w.content);return{$type:"ai.rizom.brain.series",title:w.metadata.title,slug:w.metadata.slug,...$.description&&{description:$.description},...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"series",sourceEntityId:w.id,createdAt:w.created,...w.updated&&{updatedAt:w.updated}}}function ha0(){return{entityType:"series",collection:"ai.rizom.brain.series",lexicon:S6["ai.rizom.brain.series"],validate:!1,buildRecord:b22}}var L22={name:"@brains/series",version:"0.2.0-alpha.159",description:"Cross-content series \u2014 auto-derived from entities with seriesName metadata",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":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var k22=f.discriminatedUnion("mode",[f.object({mode:f.literal("derive"),reason:f.string().optional()}),f.object({mode:f.literal("source"),entityId:f.string(),entityType:f.string(),seriesName:f.string().optional(),previousSeriesName:f.string().optional()})]);class Ca0 extends Zw{entityType="series";schema=GL;adapter=DL;manager;unregisterAtprotoProjection;constructor(){super("series",L22,{},i7)}getEntityTypeConfig(){return{weight:0.5}}createGenerationHandler(A){return new oZ0(this.logger.child("SeriesGenerationHandler"),A)}getTemplates(){return{...I22(),description:F22}}getDataSources(){return[new va0(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 w=wM(Q.entity),$=rZ0(Q.previousMetadata).seriesName;if(!w&&!$)return null;return{mode:"source",entityId:Q.entity.id,entityType:Q.entity.entityType,...w?{seriesName:w}:{},...$&&$!==w?{previousSeriesName:$}:{}}},jobOptions:(Q)=>{if(!Q.entity)return;return this.getSourceProjectionJobOptions(Q.entity)}}}]}async onRegister(A){this.manager=new Ra0(A.entityService,this.logger.child("SeriesManager")),this.unregisterAtprotoProjection=kB.getInstance().register(ha0())}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}createSeriesProjectionHandler(A){return{process:async(Q)=>{let w=k22.parse(Q);if(w.mode==="derive")return await this.projectAll(A),{success:!0};let $=await A.entityService.getEntity({entityType:w.entityType,id:w.entityId});if($)await this.projectSource($,w.previousSeriesName);else{let B=this.requireManager();for(let X of[w.seriesName,w.previousSeriesName])if(X)await B.cleanupOrphanedSeries(X)}return{success:!0}},validateAndParse:(Q)=>{let w=k22.safeParse(Q??{});return w.success?w.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 oZ0(this.logger.child("SeriesGenerationHandler"),A),w=await A.entityService.listEntities({entityType:"series"});for(let $ of w)try{if(!this.adapter.parseBody($.content).description)this.logger.info(`Generating description for series: ${$.metadata.title}`),await Q.process({seriesId:$.id})}catch(B){this.logger.error(`Failed to generate description for series: ${$.id}`,{error:B})}}}function ga0(){return new Ca0}fA();C0();fA();b2();C0();fA();var _22=f.enum(["generating","draft","queued","published","failed"]),N22=f.enum(["generating","draft","queued","published","failed"]),ya0="publishedAt is required when deck status is published",Ea0=(A)=>A.status==="published"&&!A.publishedAt,Ta0=(A)=>{if(Ea0(A))throw Error(ya0)},Oq=f.object({title:f.string(),slug:f.string().optional(),description:f.string().optional(),author:f.string().optional(),status:_22,publishedAt:f.string().datetime().optional(),event:f.string().optional(),coverImageId:f.string().optional(),ogImageId:f.string().optional()}),tD8=f.object({title:f.string(),description:f.string().optional(),status:_22,publishedAt:f.string().datetime().optional(),coverImageId:f.string().optional(),slug:f.string(),error:f.string().optional()}).superRefine((A,Q)=>{if(!Ea0(A))return;Q.addIssue({code:f.ZodIssueCode.custom,path:["publishedAt"],message:ya0})}),Vkw=f.object({title:f.string(),description:f.string().optional(),status:N22,publishedAt:f.string().datetime().optional(),coverImageId:f.string().optional(),slug:f.string(),error:f.string().optional()}).superRefine((A,Q)=>{if(!Ea0(A))return;Q.addIssue({code:"custom",path:["publishedAt"],message:ya0})}),Jkw=f.object({title:f.string(),slug:f.string().optional(),description:f.string().optional(),author:f.string().optional(),status:N22,publishedAt:f.string().datetime().optional(),event:f.string().optional(),coverImageId:f.string().optional(),ogImageId:f.string().optional()}),DE=EQ.extend({entityType:f.literal("deck"),metadata:Vkw}),sZ0=DE.extend({frontmatter:Jkw,body:f.string(),ogImageUrl:f.string().optional()}),Ks=sZ0.extend({url:f.string().optional(),typeLabel:f.string().optional(),listUrl:f.string().optional(),listLabel:f.string().optional(),coverImageUrl:f.string().optional(),ogImageUrl:f.string().optional(),coverImageWidth:f.number().optional(),coverImageHeight:f.number().optional()});class Sa0 extends d2{constructor(){super({entityType:"deck",purpose:"A slide-deck presentation.",schema:DE,frontmatterSchema:Oq,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 w=this.parseFrontMatter(A.content,Oq);Ta0(w);let $={...w,slug:w.slug??A.metadata.slug};return this.buildMarkdown(Q,$)}fromMarkdown(A){let Q=this.parseFrontmatter(A),w=this.extractBody(A);Ta0(Q),this.validateSlideStructure(w);let $=Q.slug??q1(Q.title),B=Q.status;return{entityType:"deck",content:A,metadata:{slug:$,title:Q.title,description:Q.description,status:B,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(`---
6987
6987
  `,Q),metadata:{title:A.title,slug:A.id,status:"generating"}}}}var Us=new Sa0;C0();p$();var Ikw=f.object({markdown:f.string().describe("Markdown content with slide separators (---)"),deck:Ks.optional()}),ma0=e1({name:"deck-detail",description:"Render a presentation deck as Reveal.js slides",schema:Ikw,dataSourceId:"decks:entities",requiredPermission:"public",layout:{component:$r0,fullscreen:!0}});p$();C0();var ua0=f.object({decks:f.array(sZ0)}),ca0=f.object({decks:f.array(Ks),pageTitle:f.string().optional(),pageLabel:f.string().optional()});import{jsxDEV as la0}from"preact/jsx-dev-runtime";var Fkw="Presentations",pa0=({decks:A,pageLabel:Q})=>{let w=A.map((B)=>({id:B.id,url:B.url,title:B.frontmatter.title,date:B.frontmatter.publishedAt??B.created,description:B.frontmatter.description}));return la0("div",{className:"deck-list bg-theme",children:la0("div",{className:"container mx-auto max-w-[1100px] px-6 py-16 md:px-12 md:py-24",children:la0(Qo,{label:Q&&Q!=="Decks"?Q:Fkw,items:w},void 0,!1,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)};b9();class aZ0 extends R6{constructor(){super(ua0,{title:"Deck List",mappings:[{key:"decks",label:"Decks",type:"array",itemType:"object"}]})}}var ia0=e1({name:"deck-list",description:"List view of all presentation decks",schema:ca0,dataSourceId:"decks:entities",requiredPermission:"public",formatter:new aZ0,layout:{component:pa0}});C0();fA();var bkw=f.object({title:f.string().max(80).describe("A short, punchy title (2-5 words) that's memorable and evocative"),content:f.string().describe("Full slide deck content in markdown format with slide separators (---). Each slide should have a header and focused content."),description:f.string().describe("A concise 1-2 sentence summary that captures the essence of the talk")}),j22=e1({name:"decks:generation",description:"Template for AI to generate complete slide decks from prompts",schema:bkw,dataSourceId:"shell:ai-content",requiredPermission:"public",useKnowledgeContext:!0,basePrompt:`You are creating slide decks in a distinctive voice that blends philosophy, technology, and culture.
6988
6988
 
6989
6989
  Your task is to generate a complete slide deck based on the user's prompt.
@@ -7291,7 +7291,7 @@ ${Z}`,templateName:"decks:description"})).description,await this.reportProgress(
7291
7291
  color: var(--carousel-accent);
7292
7292
  font-weight: 600;
7293
7293
  }
7294
- `}},void 0,!1,void 0,this),B.map((W,K)=>GX("section",{className:`deck-carousel-slide${K===0?" is-cover":""}`,children:[GX("header",{className:"deck-carousel-header",children:GX("span",{className:"deck-carousel-wordmark","aria-label":w??Q,children:[GX("span",{className:"wm-primary",children:X.primary},void 0,!1,void 0,this),X.secondary!==void 0&&GX(Pkw,{children:[GX("span",{className:"wm-dot",children:"."},void 0,!1,void 0,this),GX("span",{className:"wm-secondary",children:X.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),GX("div",{className:"deck-carousel-body",children:GX("div",{className:"deck-carousel-content",dangerouslySetInnerHTML:{__html:H(W.markdown)}},void 0,!1,void 0,this)},void 0,!1,void 0,this),GX("footer",{className:"deck-carousel-footer",children:[GX("span",{className:"deck-carousel-footer-meta",children:$??Q},void 0,!1,void 0,this),GX("span",{className:"deck-carousel-counter","aria-label":`Slide ${K+1} of ${Y}`,children:[GX("span",{className:"deck-carousel-counter-current",children:String(K+1).padStart(2,"0")},void 0,!1,void 0,this)," / ",GX("span",{children:Z},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},K,!0,void 0,this))]},void 0,!0,void 0,this)}import{mkdtemp as Mkw,rm as Okw}from"fs/promises";import{tmpdir as xkw}from"os";import{join as Rkw}from"path";H7();b2();var vkw=26214400,hkw=60000,R22=20;class ra0{metadata={outputEntityType:"document"};context;renderPdf;getThemeMode;constructor(A,Q={}){this.context=A,this.renderPdf=Q.renderPdf??XG,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 w=Ckw(Q,{brandLabel:this.resolveBrandLabel()});if(w.slides.length>R22)throw Error(`Refusing to render carousel with ${w.slides.length} slides; maxSlides=${R22}`);let $=await this.getThemeMode(),B=await Mkw(Rkw(xkw(),"brain-deck-carousel-"));try{let X=await HH({outputDir:B,mediaPath:`/_media/carousel/${Q.id}`,template:x22,format:"pdf",content:w,siteConfig:{title:w.title,themeMode:$},themeCSS:this.context.themeCSS}),Y=await WH({rootDir:B});try{return{type:"document",data:await this.renderPdf(Y.urlFor(X.urlPath),{maxBytes:vkw,timeoutMs:hkw,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${gkw(Q)}-carousel.pdf`}}finally{await Y.close()}}finally{await Okw(B,{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 Ckw(A,Q={}){let{frontmatter:w,content:$}=l6(A.content),B=typeof w.title==="string"?w.title:A.metadata.title,X=typeof w.event==="string"&&w.event.length>0?w.event:void 0,Y=$.split(/^---$/gm).map((Z)=>Z.trim()).filter((Z)=>Z.length>0).map((Z)=>({markdown:Z}));return{title:B,slides:Y,...Q.brandLabel?{brandLabel:Q.brandLabel}:{},...X?{eyebrow:X}:{}}}function gkw(A){let Q=A.metadata.slug;return Q.length>0?Q:q1(A.metadata.title)}C0();import{jsxDEV as Tkw}from"preact/jsx-dev-runtime";var tZ0="og-image",ykw="decks:og-image",v22=f.object({title:f.string().min(1),description:f.string().optional(),event:f.string().optional(),brandLabel:f.string().optional(),slideCount:f.number().int().positive().optional(),coverImageUrl:f.string().optional()}),h22={name:ykw,pluginId:"decks",schema:v22,renderers:{image:Ekw}};function Ekw(A){let Q=v22.parse(A),w=Q.slideCount?`${Q.slideCount} slide${Q.slideCount===1?"":"s"}`:void 0;return Tkw(RV,{brandLabel:Q.brandLabel??Q.title,eyebrow:"Deck",title:Q.title,subtitle:Q.description,meta:[Q.event],tag:w},void 0,!1,void 0,this)}H7();b2();class oa0{metadata={outputEntityType:"image",targetField:"ogImageId"};context;deps;constructor(A,Q={}){this.context=A,this.deps=Q}async resolve(A){if(A.sourceEntityType!=="deck"||A.attachmentType!==tZ0)return;let Q=await this.context.entityService.getEntity({entityType:"deck",id:A.sourceEntityId});if(!Q)return;let{frontmatter:w,content:$}=l6(Q.content),B=Oq.parse(w),X=Skw($),Y=this.resolveBrandLabel(),Z=await this.resolveCoverImageUrl(B.coverImageId),H={title:B.title,...B.description?{description:B.description}:{},...B.event?{event:B.event}:{},...X?{slideCount:X}:{},...Z?{coverImageUrl:Z}:{},...Y?{brandLabel:Y}:{}};return{type:"image",data:await AM({mediaPath:`/_media/og/deck/${Q.id}`,template:h22,content:H,title:H.title,themeMode:"dark",themeCSS:this.context.themeCSS,tmpPrefix:"brain-deck-og-image-",...this.deps.screenshotPng&&{screenshotPng:this.deps.screenshotPng}}),mimeType:"image/png",filename:`${mkw(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 Skw(A){return A.split(/^---$/gm).map((Q)=>Q.trim()).filter((Q)=>Q.length>0).length}function mkw(A){let Q=A.metadata.slug;return Q.length>0?Q:q1(A.metadata.title)}fA();async function C22({entity:A,config:Q}){let w=DE.parse(A),$=$Q(w.content,Oq),B=$.metadata;return{$type:"ai.rizom.brain.deck",title:B.title,...B.slug&&{slug:B.slug},...B.description&&{description:B.description},body:$.content,format:"text/markdown",...B.author&&{author:B.author},...B.event&&{event:B.event},...B.publishedAt&&{publishedAt:B.publishedAt},...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"deck",sourceEntityId:w.id,createdAt:w.created,...w.updated&&{updatedAt:w.updated}}}function sa0(){return{entityType:"deck",collection:"ai.rizom.brain.deck",lexicon:S6["ai.rizom.brain.deck"],validate:!1,buildRecord:C22}}var g22={name:"@brains/decks",version:"0.2.0-alpha.158",description:"Presentation decks plugin for creating and viewing slide presentations",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":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{eval:"cd evals && bun run brain-eval",lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var ckw=f.object({prompt:f.string(),event:f.string().optional()}),lkw=f.object({title:f.string(),content:f.string()});class aa0 extends Zw{deps;entityType=Us.entityType;schema=Us.schema;adapter=Us;unregisterCarouselAttachmentProvider;unregisterOgImageAttachmentProvider;unregisterAtprotoProjection;constructor(A={}){super("decks",g22,{},i7);this.deps=A}createGenerationHandler(A){return new na0(this.logger.child("DeckGenerationJobHandler"),A)}getTemplates(){return{"deck-detail":ma0,"deck-list":ia0,generation:j22,description:P22}}getDataSources(){return[new da0(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=kB.getInstance().register(sa0()),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:w,entityId:$}=Q.payload;if(w!=="deck")return{success:!0};try{let B=await A.entityService.getEntity({entityType:"deck",id:$});if(!B)return await A.messaging.send({type:"publish:report:failure",payload:{entityType:w,entityId:$,error:`Deck not found: ${$}`}}),{success:!0};if(B.metadata.status==="published")return{success:!0};let X=new Date().toISOString(),Y={...B,metadata:{...B.metadata,status:"published",publishedAt:X}};await A.entityService.updateEntity({entity:{...Y,content:this.adapter.toMarkdown(Y)}}),await A.messaging.send({type:"publish:report:success",payload:{entityType:w,entityId:$,result:{id:$}}})}catch(B){await A.messaging.send({type:"publish:report:failure",payload:{entityType:w,entityId:$,error:dA(B)}})}return{success:!0}})}registerCarouselAttachmentProvider(A){let Q={...this.deps,getThemeMode:this.deps.getThemeMode??(async()=>{try{return(await Bs(A.entityService)).themeMode??"dark"}catch{return"dark"}})};this.unregisterCarouselAttachmentProvider=A.attachments.register("deck",M22,new ra0(A,Q))}registerOgImageAttachmentProvider(A){this.unregisterOgImageAttachmentProvider=A.attachments.register("deck",tZ0,new oa0(A))}registerEvalHandlers(A){A.eval.registerHandler("generateDeck",async(Q)=>{let w=ckw.parse(Q);return A.ai.generate({prompt:`${w.prompt}${w.event?`
7294
+ `}},void 0,!1,void 0,this),B.map((W,K)=>GX("section",{className:`deck-carousel-slide${K===0?" is-cover":""}`,children:[GX("header",{className:"deck-carousel-header",children:GX("span",{className:"deck-carousel-wordmark","aria-label":w??Q,children:[GX("span",{className:"wm-primary",children:X.primary},void 0,!1,void 0,this),X.secondary!==void 0&&GX(Pkw,{children:[GX("span",{className:"wm-dot",children:"."},void 0,!1,void 0,this),GX("span",{className:"wm-secondary",children:X.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),GX("div",{className:"deck-carousel-body",children:GX("div",{className:"deck-carousel-content",dangerouslySetInnerHTML:{__html:H(W.markdown)}},void 0,!1,void 0,this)},void 0,!1,void 0,this),GX("footer",{className:"deck-carousel-footer",children:[GX("span",{className:"deck-carousel-footer-meta",children:$??Q},void 0,!1,void 0,this),GX("span",{className:"deck-carousel-counter","aria-label":`Slide ${K+1} of ${Y}`,children:[GX("span",{className:"deck-carousel-counter-current",children:String(K+1).padStart(2,"0")},void 0,!1,void 0,this)," / ",GX("span",{children:Z},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},K,!0,void 0,this))]},void 0,!0,void 0,this)}import{mkdtemp as Mkw,rm as Okw}from"fs/promises";import{tmpdir as xkw}from"os";import{join as Rkw}from"path";H7();b2();var vkw=26214400,hkw=60000,R22=20;class ra0{metadata={outputEntityType:"document"};context;renderPdf;getThemeMode;constructor(A,Q={}){this.context=A,this.renderPdf=Q.renderPdf??XG,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 w=Ckw(Q,{brandLabel:this.resolveBrandLabel()});if(w.slides.length>R22)throw Error(`Refusing to render carousel with ${w.slides.length} slides; maxSlides=${R22}`);let $=await this.getThemeMode(),B=await Mkw(Rkw(xkw(),"brain-deck-carousel-"));try{let X=await HH({outputDir:B,mediaPath:`/_media/carousel/${Q.id}`,template:x22,format:"pdf",content:w,siteConfig:{title:w.title,themeMode:$},themeCSS:this.context.themeCSS}),Y=await WH({rootDir:B});try{return{type:"document",data:await this.renderPdf(Y.urlFor(X.urlPath),{maxBytes:vkw,timeoutMs:hkw,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${gkw(Q)}-carousel.pdf`}}finally{await Y.close()}}finally{await Okw(B,{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 Ckw(A,Q={}){let{frontmatter:w,content:$}=l6(A.content),B=typeof w.title==="string"?w.title:A.metadata.title,X=typeof w.event==="string"&&w.event.length>0?w.event:void 0,Y=$.split(/^---$/gm).map((Z)=>Z.trim()).filter((Z)=>Z.length>0).map((Z)=>({markdown:Z}));return{title:B,slides:Y,...Q.brandLabel?{brandLabel:Q.brandLabel}:{},...X?{eyebrow:X}:{}}}function gkw(A){let Q=A.metadata.slug;return Q.length>0?Q:q1(A.metadata.title)}C0();import{jsxDEV as Tkw}from"preact/jsx-dev-runtime";var tZ0="og-image",ykw="decks:og-image",v22=f.object({title:f.string().min(1),description:f.string().optional(),event:f.string().optional(),brandLabel:f.string().optional(),slideCount:f.number().int().positive().optional(),coverImageUrl:f.string().optional()}),h22={name:ykw,pluginId:"decks",schema:v22,renderers:{image:Ekw}};function Ekw(A){let Q=v22.parse(A),w=Q.slideCount?`${Q.slideCount} slide${Q.slideCount===1?"":"s"}`:void 0;return Tkw(RV,{brandLabel:Q.brandLabel??Q.title,eyebrow:"Deck",title:Q.title,subtitle:Q.description,meta:[Q.event],tag:w},void 0,!1,void 0,this)}H7();b2();class oa0{metadata={outputEntityType:"image",targetField:"ogImageId"};context;deps;constructor(A,Q={}){this.context=A,this.deps=Q}async resolve(A){if(A.sourceEntityType!=="deck"||A.attachmentType!==tZ0)return;let Q=await this.context.entityService.getEntity({entityType:"deck",id:A.sourceEntityId});if(!Q)return;let{frontmatter:w,content:$}=l6(Q.content),B=Oq.parse(w),X=Skw($),Y=this.resolveBrandLabel(),Z=await this.resolveCoverImageUrl(B.coverImageId),H={title:B.title,...B.description?{description:B.description}:{},...B.event?{event:B.event}:{},...X?{slideCount:X}:{},...Z?{coverImageUrl:Z}:{},...Y?{brandLabel:Y}:{}};return{type:"image",data:await AM({mediaPath:`/_media/og/deck/${Q.id}`,template:h22,content:H,title:H.title,themeMode:"dark",themeCSS:this.context.themeCSS,tmpPrefix:"brain-deck-og-image-",...this.deps.screenshotPng&&{screenshotPng:this.deps.screenshotPng}}),mimeType:"image/png",filename:`${mkw(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 Skw(A){return A.split(/^---$/gm).map((Q)=>Q.trim()).filter((Q)=>Q.length>0).length}function mkw(A){let Q=A.metadata.slug;return Q.length>0?Q:q1(A.metadata.title)}fA();async function C22({entity:A,config:Q}){let w=DE.parse(A),$=$Q(w.content,Oq),B=$.metadata;return{$type:"ai.rizom.brain.deck",title:B.title,...B.slug&&{slug:B.slug},...B.description&&{description:B.description},body:$.content,format:"text/markdown",...B.author&&{author:B.author},...B.event&&{event:B.event},...B.publishedAt&&{publishedAt:B.publishedAt},...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"deck",sourceEntityId:w.id,createdAt:w.created,...w.updated&&{updatedAt:w.updated}}}function sa0(){return{entityType:"deck",collection:"ai.rizom.brain.deck",lexicon:S6["ai.rizom.brain.deck"],validate:!1,buildRecord:C22}}var g22={name:"@brains/decks",version:"0.2.0-alpha.159",description:"Presentation decks plugin for creating and viewing slide presentations",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":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{eval:"cd evals && bun run brain-eval",lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var ckw=f.object({prompt:f.string(),event:f.string().optional()}),lkw=f.object({title:f.string(),content:f.string()});class aa0 extends Zw{deps;entityType=Us.entityType;schema=Us.schema;adapter=Us;unregisterCarouselAttachmentProvider;unregisterOgImageAttachmentProvider;unregisterAtprotoProjection;constructor(A={}){super("decks",g22,{},i7);this.deps=A}createGenerationHandler(A){return new na0(this.logger.child("DeckGenerationJobHandler"),A)}getTemplates(){return{"deck-detail":ma0,"deck-list":ia0,generation:j22,description:P22}}getDataSources(){return[new da0(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=kB.getInstance().register(sa0()),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:w,entityId:$}=Q.payload;if(w!=="deck")return{success:!0};try{let B=await A.entityService.getEntity({entityType:"deck",id:$});if(!B)return await A.messaging.send({type:"publish:report:failure",payload:{entityType:w,entityId:$,error:`Deck not found: ${$}`}}),{success:!0};if(B.metadata.status==="published")return{success:!0};let X=new Date().toISOString(),Y={...B,metadata:{...B.metadata,status:"published",publishedAt:X}};await A.entityService.updateEntity({entity:{...Y,content:this.adapter.toMarkdown(Y)}}),await A.messaging.send({type:"publish:report:success",payload:{entityType:w,entityId:$,result:{id:$}}})}catch(B){await A.messaging.send({type:"publish:report:failure",payload:{entityType:w,entityId:$,error:dA(B)}})}return{success:!0}})}registerCarouselAttachmentProvider(A){let Q={...this.deps,getThemeMode:this.deps.getThemeMode??(async()=>{try{return(await Bs(A.entityService)).themeMode??"dark"}catch{return"dark"}})};this.unregisterCarouselAttachmentProvider=A.attachments.register("deck",M22,new ra0(A,Q))}registerOgImageAttachmentProvider(A){this.unregisterOgImageAttachmentProvider=A.attachments.register("deck",tZ0,new oa0(A))}registerEvalHandlers(A){A.eval.registerHandler("generateDeck",async(Q)=>{let w=ckw.parse(Q);return A.ai.generate({prompt:`${w.prompt}${w.event?`
7295
7295
 
7296
7296
  Note: This presentation is for "${w.event}".`:""}`,templateName:"decks:generation"})}),A.eval.registerHandler("generateDescription",async(Q)=>{let w=lkw.parse(Q);return A.ai.generate({prompt:`Title: ${w.title}
7297
7297
 
@@ -7448,9 +7448,9 @@ ${w.content}`,templateName:"decks:description"})})}}function Ds(){return new aa0
7448
7448
  background: transparent;
7449
7449
  }
7450
7450
 
7451
- `,i22=()=>W9("style",{children:okw},void 0,!1,void 0,this);import{jsxDEV as l2,Fragment as skw}from"preact/jsx-dev-runtime";var $f0=({title:A,description:Q,children:w,detail:$=!1,footer:B=!1,contentClassName:X=""})=>l2(skw,{children:[l2($w,{title:A,description:Q},void 0,!1,void 0,this),l2(i22,{},void 0,!1,void 0,this),l2("div",{className:`docs-handbook${$?" docs-handbook--detail":""}`,children:[l2(l22,{},void 0,!1,void 0,this),l2("div",{className:`${xq.wrap} ${X}`.trim(),children:[w,B&&l2(p22,{},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),d22=({docsCount:A,sectionsCount:Q,startDoc:w})=>l2("section",{className:"border-b border-[var(--docs-text)] py-14 md:py-24 md:pb-[72px]",children:[l2("p",{className:`${xq.label} mb-8`,children:"Handbook \xB7 Brains docs"},void 0,!1,void 0,this),l2("h1",{className:`${xq.display} m-0 max-w-[16ch] text-5xl leading-[1.05] tracking-[-0.02em] md:text-7xl`,children:["Build, run, and publish"," ",l2("em",{className:"text-[var(--docs-accent)]",children:"brains."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),l2("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),l2("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:[l2("div",{children:[l2("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),l2("div",{children:[l2("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),l2("div",{children:[l2("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),l2("div",{className:"mt-9 flex flex-wrap gap-3.5",children:[w&&l2("a",{className:xq.primaryButton,href:zE(w),children:"Start reading"},void 0,!1,void 0,this),l2("a",{className:xq.button,href:"#sections",children:"Browse sections"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),n22=({groups:A})=>l2("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:[l2("p",{className:"m-0 mb-3.5 font-medium text-[var(--docs-text)]",children:"Sections"},void 0,!1,void 0,this),l2("ol",{className:"m-0 list-none p-0",children:A.map((Q,w)=>l2("li",{className:"grid grid-cols-[32px_1fr] gap-2 py-1.5",children:[l2("span",{className:"docs-font-display text-[var(--docs-text-light)] italic",children:[VE(w),"."]},void 0,!0,void 0,this),l2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:`#${wf0(w)}`,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),r22=({group:A,index:Q})=>l2("article",{className:"mb-16 last:mb-0",id:wf0(Q),children:[l2("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:[l2("span",{className:"text-right docs-font-display text-3xl leading-[1.1] text-[var(--docs-accent)] italic md:text-4xl",children:[VE(Q),"."]},void 0,!0,void 0,this),l2("h2",{className:`${xq.display} m-0 text-3xl leading-[1.1] tracking-[-0.015em] md:text-4xl`,children:A.section},void 0,!1,void 0,this),l2("span",{className:"docs-chapter__leader"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),l2("ol",{className:"m-0 list-none p-0",children:A.docs.map((w)=>l2("li",{className:"border-b border-[var(--docs-border-light)] last:border-b-0",children:l2("a",{className:"group block py-[18px] pl-12 md:pl-[68px]",href:zE(w),children:[l2("p",{className:"m-0 text-[22px] leading-[1.2] tracking-[-0.005em] transition-colors duration-150 group-hover:text-[var(--docs-accent)]",children:w.metadata.title},void 0,!1,void 0,this),w.metadata.description&&l2("p",{className:"mt-1.5 mb-0 max-w-[70ch] text-sm leading-[1.55] text-[var(--docs-text-muted)]",children:w.metadata.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},w.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),o22=({title:A})=>l2("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:[l2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/",children:"Home"},void 0,!1,void 0,this),l2("span",{children:"/"},void 0,!1,void 0,this),l2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/docs",children:"Docs"},void 0,!1,void 0,this),l2("span",{children:"/"},void 0,!1,void 0,this),l2("span",{children:A},void 0,!1,void 0,this)]},void 0,!0,void 0,this),s22=({groups:A,activeGroupIndex:Q,activeSlug:w})=>l2("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:l2("nav",{className:"docs-font-label text-xs tracking-[0.06em] text-[var(--docs-text-light)]",children:[l2("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),l2("ol",{className:"m-0 list-none p-0",children:A.map(($,B)=>{let X=B===Q;return l2("li",{className:X?"mb-[22px]":"mb-3.5",children:[l2("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)] ${X?"text-[var(--docs-text)]":"text-[var(--docs-text-muted)]"}`,href:`/docs#${wf0(B)}`,children:[l2("span",{className:"docs-font-display text-sm text-[var(--docs-accent)] italic",children:[VE(B),"."]},void 0,!0,void 0,this)," ",$.section]},void 0,!0,void 0,this),X&&l2("ol",{className:"mt-0.5 list-none p-0",children:$.docs.map((Y)=>{let Z=Y.metadata.slug===w;return l2("li",{children:l2("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)] ${Z?"pl-3.5 font-medium text-[var(--docs-accent)]":"text-[var(--docs-text-muted)]"}`,href:zE(Y),"aria-current":Z?"page":void 0,children:Y.metadata.title},void 0,!1,void 0,this)},Y.id,!1,void 0,this)})},void 0,!1,void 0,this)]},$.section,!0,void 0,this)})},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),a22=({prevDoc:A,nextDoc:Q})=>{if(!A&&!Q)return null;return l2("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?l2("a",{className:"group border-t border-[var(--docs-border-light)] pt-[18px] transition-colors duration-150 hover:border-[var(--docs-accent)]",href:zE(A),children:[l2("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),l2("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):l2("span",{},void 0,!1,void 0,this),Q&&l2("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:zE(Q),children:[l2("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),l2("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 JE}from"preact/jsx-dev-runtime";var Qt0=({docs:A})=>{let Q=qs(A),w=Qf0(Q),B=Q.filter((X)=>X.metadata.slug!=="index")[0]??Q[0];return JE($f0,{title:"Documentation",description:"Brains documentation",children:[JE(d22,{docsCount:A.length,sectionsCount:w.length,startDoc:B},void 0,!1,void 0,this),JE("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:[JE(n22,{groups:w},void 0,!1,void 0,this),JE("div",{children:w.map((X,Y)=>JE(r22,{group:X,index:Y},X.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 KH}from"preact/jsx-dev-runtime";var wt0=({doc:A,docs:Q,prevDoc:w,nextDoc:$})=>{let B=Qf0(Q.length>0?Q:[A]),X=qs(Q.length>0?Q:[A]),Y=X.findIndex((H)=>H.metadata.slug===A.metadata.slug),Z=Math.max(B.findIndex((H)=>H.docs.some((W)=>W.metadata.slug===A.metadata.slug)),0);return KH($f0,{title:A.metadata.title,description:A.metadata.description??A.metadata.section,detail:!0,footer:!0,contentClassName:"pt-16",children:[KH(o22,{title:A.metadata.title},void 0,!1,void 0,this),KH("div",{className:"grid items-start gap-10 py-8 pb-24 md:grid-cols-[240px_minmax(0,1fr)] md:gap-20",children:[KH(s22,{groups:B,activeGroupIndex:Z,activeSlug:A.metadata.slug},void 0,!1,void 0,this),KH("article",{className:"min-w-0",children:[KH("header",{className:"mb-10 border-b border-[var(--docs-border)] pb-8",children:[KH("p",{className:`${xq.label} m-0 mb-6 flex items-baseline gap-3`,children:[KH("span",{className:"docs-font-display text-lg leading-none tracking-normal normal-case text-[var(--docs-accent)] italic",children:[VE(Z),"."]},void 0,!0,void 0,this)," ",A.metadata.section,Y>=0?` \xB7 ${Y+1}/${X.length}`:""]},void 0,!0,void 0,this),KH("h1",{className:`${xq.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&&KH("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),KH("div",{className:"docs-article__body",children:KH(l9,{markdown:A.body},void 0,!1,void 0,this)},void 0,!1,void 0,this),KH(a22,{prevDoc:w,nextDoc:$},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 akw=f.object({currentPage:f.number(),totalPages:f.number(),totalItems:f.number(),pageSize:f.number(),hasNextPage:f.boolean(),hasPrevPage:f.boolean()}),tkw=f.union([f.enum(["public","shared","restricted"]),f.literal("private")]).optional().transform((A)=>{if(A===void 0)return"public";if(A==="private")return"restricted";return A}),ekw=f.object({title:f.string(),section:f.string(),order:f.number().int(),sourcePath:f.string(),description:f.string().optional(),slug:f.string().optional()}),A_w=f.object({title:f.string(),section:f.string(),order:f.number().int(),description:f.string().optional(),slug:f.string()}),zs=f.object({id:f.string(),entityType:f.literal("doc"),content:f.string(),created:f.string(),updated:f.string(),visibility:tkw,metadata:A_w,contentHash:f.string(),frontmatter:ekw,body:f.string()}),Q_w=f.object({docs:f.array(zs),pagination:akw.nullable(),baseUrl:f.string().optional()}),w_w=f.object({doc:zs,docs:f.array(zs),prevDoc:zs.nullable(),nextDoc:zs.nullable()});function t22(){return{"doc-list":e1({name:"doc-list",description:"Documentation index template",schema:Q_w,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:Qt0}}),"doc-detail":e1({name:"doc-detail",description:"Documentation page template",schema:w_w,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:wt0}})}}var e22={name:"@brains/doc",version:"0.2.0-alpha.158",description:"Documentation entity type \u2014 markdown docs as first-class brain content",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":"^1.3.14",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};class $t0 extends Zw{entityType=eZ0.entityType;schema=qE;adapter=eZ0;constructor(){super("docs",e22,{},i7)}getTemplates(){return t22()}getDataSources(){return[new Af0(this.logger.child("DocDataSource"))]}}function Vs(){return new $t0}fA();b2();C0();Q8();C0();var Bt0=f.literal("application/pdf"),AQ2=f.enum(["pending","draft","failed"]),Xt0=f.object({title:f.string().optional(),mimeType:Bt0,filename:f.string().min(1),pageCount:f.number().int().min(0).optional(),status:AQ2.optional(),processingJobId:f.string().optional(),processingError:f.string().optional(),sourceEntityType:f.string().min(1).optional(),sourceEntityId:f.string().min(1).optional(),sourceUploadId:f.string().optional(),sourceFilename:f.string().optional(),sourceMediaType:f.string().optional(),attachmentType:f.string().min(1).optional(),dedupKey:f.string().min(1).optional()}),IE=EQ.extend({entityType:f.literal("document"),content:f.string().regex(/^data:application\/pdf;base64,.+$/),metadata:Xt0});function Js(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 Bf0(A){return`data:application/pdf;base64,${Buffer.from(A).toString("base64")}`}function Yt0(A){let Q=Buffer.from(A).toString("latin1"),w=0,$=/\/Type\s*\/Pages\b[^]*?\/Count\s+(\d+)|\/Count\s+(\d+)[^]*?\/Type\s*\/Pages\b/g;for(let X of Q.matchAll($)){let Y=parseInt(X[1]??X[2]??"0",10);if(Y>w)w=Y}if(w>0)return w;return Q.match(/\/Type\s*\/Page(?!\w)/g)?.length??0}class Xf0{entityType="document";purpose="A durable rendered file artifact such as a printable or carousel PDF.";schema=IE;toMarkdown(A){return A.content}fromMarkdown(A){return Js(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,...w}=A,{mimeType:$}=Js(Q);return{entityType:"document",content:Q,metadata:{mimeType:$,...w}}}}var rV=new Xf0;async function dt0(A,Q={}){let w=Q.maxBytes??5000000;if(A.byteLength>w)throw Error(`Uploaded PDF is too large for synchronous markdown extraction (${A.byteLength} bytes; max ${w} bytes)`);let B=(await Promise.resolve().then(() => (H62(),f62))).getDocument({data:new Uint8Array(A),disableFontFace:!1,useSystemFonts:!0,useWorkerFetch:!1}),X=await B.promise;try{let Y=Q.maxPages??50;if(X.numPages>Y)throw Error(`Uploaded PDF has ${X.numPages} pages; maximum supported for synchronous markdown extraction is ${Y}`);let Z=[];for(let W=1;W<=X.numPages;W+=1){let G=(await(await X.getPage(W)).getTextContent()).items.flatMap((q)=>("str"in q)?[q.str]:[]).join(" ").replace(/\s+/g," ").trim();if(G.length>0)Z.push(G)}let H=Z.join(`
7451
+ `,i22=()=>W9("style",{children:okw},void 0,!1,void 0,this);import{jsxDEV as l2,Fragment as skw}from"preact/jsx-dev-runtime";var $f0=({title:A,description:Q,children:w,detail:$=!1,footer:B=!1,contentClassName:X=""})=>l2(skw,{children:[l2($w,{title:A,description:Q},void 0,!1,void 0,this),l2(i22,{},void 0,!1,void 0,this),l2("div",{className:`docs-handbook${$?" docs-handbook--detail":""}`,children:[l2(l22,{},void 0,!1,void 0,this),l2("div",{className:`${xq.wrap} ${X}`.trim(),children:[w,B&&l2(p22,{},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),d22=({docsCount:A,sectionsCount:Q,startDoc:w})=>l2("section",{className:"border-b border-[var(--docs-text)] py-14 md:py-24 md:pb-[72px]",children:[l2("p",{className:`${xq.label} mb-8`,children:"Handbook \xB7 Brains docs"},void 0,!1,void 0,this),l2("h1",{className:`${xq.display} m-0 max-w-[16ch] text-5xl leading-[1.05] tracking-[-0.02em] md:text-7xl`,children:["Build, run, and publish"," ",l2("em",{className:"text-[var(--docs-accent)]",children:"brains."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),l2("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),l2("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:[l2("div",{children:[l2("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),l2("div",{children:[l2("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),l2("div",{children:[l2("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),l2("div",{className:"mt-9 flex flex-wrap gap-3.5",children:[w&&l2("a",{className:xq.primaryButton,href:zE(w),children:"Start reading"},void 0,!1,void 0,this),l2("a",{className:xq.button,href:"#sections",children:"Browse sections"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),n22=({groups:A})=>l2("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:[l2("p",{className:"m-0 mb-3.5 font-medium text-[var(--docs-text)]",children:"Sections"},void 0,!1,void 0,this),l2("ol",{className:"m-0 list-none p-0",children:A.map((Q,w)=>l2("li",{className:"grid grid-cols-[32px_1fr] gap-2 py-1.5",children:[l2("span",{className:"docs-font-display text-[var(--docs-text-light)] italic",children:[VE(w),"."]},void 0,!0,void 0,this),l2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:`#${wf0(w)}`,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),r22=({group:A,index:Q})=>l2("article",{className:"mb-16 last:mb-0",id:wf0(Q),children:[l2("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:[l2("span",{className:"text-right docs-font-display text-3xl leading-[1.1] text-[var(--docs-accent)] italic md:text-4xl",children:[VE(Q),"."]},void 0,!0,void 0,this),l2("h2",{className:`${xq.display} m-0 text-3xl leading-[1.1] tracking-[-0.015em] md:text-4xl`,children:A.section},void 0,!1,void 0,this),l2("span",{className:"docs-chapter__leader"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),l2("ol",{className:"m-0 list-none p-0",children:A.docs.map((w)=>l2("li",{className:"border-b border-[var(--docs-border-light)] last:border-b-0",children:l2("a",{className:"group block py-[18px] pl-12 md:pl-[68px]",href:zE(w),children:[l2("p",{className:"m-0 text-[22px] leading-[1.2] tracking-[-0.005em] transition-colors duration-150 group-hover:text-[var(--docs-accent)]",children:w.metadata.title},void 0,!1,void 0,this),w.metadata.description&&l2("p",{className:"mt-1.5 mb-0 max-w-[70ch] text-sm leading-[1.55] text-[var(--docs-text-muted)]",children:w.metadata.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},w.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),o22=({title:A})=>l2("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:[l2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/",children:"Home"},void 0,!1,void 0,this),l2("span",{children:"/"},void 0,!1,void 0,this),l2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/docs",children:"Docs"},void 0,!1,void 0,this),l2("span",{children:"/"},void 0,!1,void 0,this),l2("span",{children:A},void 0,!1,void 0,this)]},void 0,!0,void 0,this),s22=({groups:A,activeGroupIndex:Q,activeSlug:w})=>l2("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:l2("nav",{className:"docs-font-label text-xs tracking-[0.06em] text-[var(--docs-text-light)]",children:[l2("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),l2("ol",{className:"m-0 list-none p-0",children:A.map(($,B)=>{let X=B===Q;return l2("li",{className:X?"mb-[22px]":"mb-3.5",children:[l2("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)] ${X?"text-[var(--docs-text)]":"text-[var(--docs-text-muted)]"}`,href:`/docs#${wf0(B)}`,children:[l2("span",{className:"docs-font-display text-sm text-[var(--docs-accent)] italic",children:[VE(B),"."]},void 0,!0,void 0,this)," ",$.section]},void 0,!0,void 0,this),X&&l2("ol",{className:"mt-0.5 list-none p-0",children:$.docs.map((Y)=>{let Z=Y.metadata.slug===w;return l2("li",{children:l2("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)] ${Z?"pl-3.5 font-medium text-[var(--docs-accent)]":"text-[var(--docs-text-muted)]"}`,href:zE(Y),"aria-current":Z?"page":void 0,children:Y.metadata.title},void 0,!1,void 0,this)},Y.id,!1,void 0,this)})},void 0,!1,void 0,this)]},$.section,!0,void 0,this)})},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),a22=({prevDoc:A,nextDoc:Q})=>{if(!A&&!Q)return null;return l2("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?l2("a",{className:"group border-t border-[var(--docs-border-light)] pt-[18px] transition-colors duration-150 hover:border-[var(--docs-accent)]",href:zE(A),children:[l2("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),l2("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):l2("span",{},void 0,!1,void 0,this),Q&&l2("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:zE(Q),children:[l2("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),l2("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 JE}from"preact/jsx-dev-runtime";var Qt0=({docs:A})=>{let Q=qs(A),w=Qf0(Q),B=Q.filter((X)=>X.metadata.slug!=="index")[0]??Q[0];return JE($f0,{title:"Documentation",description:"Brains documentation",children:[JE(d22,{docsCount:A.length,sectionsCount:w.length,startDoc:B},void 0,!1,void 0,this),JE("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:[JE(n22,{groups:w},void 0,!1,void 0,this),JE("div",{children:w.map((X,Y)=>JE(r22,{group:X,index:Y},X.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 KH}from"preact/jsx-dev-runtime";var wt0=({doc:A,docs:Q,prevDoc:w,nextDoc:$})=>{let B=Qf0(Q.length>0?Q:[A]),X=qs(Q.length>0?Q:[A]),Y=X.findIndex((H)=>H.metadata.slug===A.metadata.slug),Z=Math.max(B.findIndex((H)=>H.docs.some((W)=>W.metadata.slug===A.metadata.slug)),0);return KH($f0,{title:A.metadata.title,description:A.metadata.description??A.metadata.section,detail:!0,footer:!0,contentClassName:"pt-16",children:[KH(o22,{title:A.metadata.title},void 0,!1,void 0,this),KH("div",{className:"grid items-start gap-10 py-8 pb-24 md:grid-cols-[240px_minmax(0,1fr)] md:gap-20",children:[KH(s22,{groups:B,activeGroupIndex:Z,activeSlug:A.metadata.slug},void 0,!1,void 0,this),KH("article",{className:"min-w-0",children:[KH("header",{className:"mb-10 border-b border-[var(--docs-border)] pb-8",children:[KH("p",{className:`${xq.label} m-0 mb-6 flex items-baseline gap-3`,children:[KH("span",{className:"docs-font-display text-lg leading-none tracking-normal normal-case text-[var(--docs-accent)] italic",children:[VE(Z),"."]},void 0,!0,void 0,this)," ",A.metadata.section,Y>=0?` \xB7 ${Y+1}/${X.length}`:""]},void 0,!0,void 0,this),KH("h1",{className:`${xq.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&&KH("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),KH("div",{className:"docs-article__body",children:KH(l9,{markdown:A.body},void 0,!1,void 0,this)},void 0,!1,void 0,this),KH(a22,{prevDoc:w,nextDoc:$},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 akw=f.object({currentPage:f.number(),totalPages:f.number(),totalItems:f.number(),pageSize:f.number(),hasNextPage:f.boolean(),hasPrevPage:f.boolean()}),tkw=f.union([f.enum(["public","shared","restricted"]),f.literal("private")]).optional().transform((A)=>{if(A===void 0)return"public";if(A==="private")return"restricted";return A}),ekw=f.object({title:f.string(),section:f.string(),order:f.number().int(),sourcePath:f.string(),description:f.string().optional(),slug:f.string().optional()}),A_w=f.object({title:f.string(),section:f.string(),order:f.number().int(),description:f.string().optional(),slug:f.string()}),zs=f.object({id:f.string(),entityType:f.literal("doc"),content:f.string(),created:f.string(),updated:f.string(),visibility:tkw,metadata:A_w,contentHash:f.string(),frontmatter:ekw,body:f.string()}),Q_w=f.object({docs:f.array(zs),pagination:akw.nullable(),baseUrl:f.string().optional()}),w_w=f.object({doc:zs,docs:f.array(zs),prevDoc:zs.nullable(),nextDoc:zs.nullable()});function t22(){return{"doc-list":e1({name:"doc-list",description:"Documentation index template",schema:Q_w,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:Qt0}}),"doc-detail":e1({name:"doc-detail",description:"Documentation page template",schema:w_w,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:wt0}})}}var e22={name:"@brains/doc",version:"0.2.0-alpha.159",description:"Documentation entity type \u2014 markdown docs as first-class brain content",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":"^1.3.14",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};class $t0 extends Zw{entityType=eZ0.entityType;schema=qE;adapter=eZ0;constructor(){super("docs",e22,{},i7)}getTemplates(){return t22()}getDataSources(){return[new Af0(this.logger.child("DocDataSource"))]}}function Vs(){return new $t0}fA();b2();C0();Q8();C0();var Bt0=f.literal("application/pdf"),AQ2=f.enum(["pending","draft","failed"]),Xt0=f.object({title:f.string().optional(),mimeType:Bt0,filename:f.string().min(1),pageCount:f.number().int().min(0).optional(),status:AQ2.optional(),processingJobId:f.string().optional(),processingError:f.string().optional(),sourceEntityType:f.string().min(1).optional(),sourceEntityId:f.string().min(1).optional(),sourceUploadId:f.string().optional(),sourceFilename:f.string().optional(),sourceMediaType:f.string().optional(),attachmentType:f.string().min(1).optional(),dedupKey:f.string().min(1).optional()}),IE=EQ.extend({entityType:f.literal("document"),content:f.string().regex(/^data:application\/pdf;base64,.+$/),metadata:Xt0});function Js(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 Bf0(A){return`data:application/pdf;base64,${Buffer.from(A).toString("base64")}`}function Yt0(A){let Q=Buffer.from(A).toString("latin1"),w=0,$=/\/Type\s*\/Pages\b[^]*?\/Count\s+(\d+)|\/Count\s+(\d+)[^]*?\/Type\s*\/Pages\b/g;for(let X of Q.matchAll($)){let Y=parseInt(X[1]??X[2]??"0",10);if(Y>w)w=Y}if(w>0)return w;return Q.match(/\/Type\s*\/Page(?!\w)/g)?.length??0}class Xf0{entityType="document";purpose="A durable rendered file artifact such as a printable or carousel PDF.";schema=IE;toMarkdown(A){return A.content}fromMarkdown(A){return Js(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,...w}=A,{mimeType:$}=Js(Q);return{entityType:"document",content:Q,metadata:{mimeType:$,...w}}}}var rV=new Xf0;async function dt0(A,Q={}){let w=Q.maxBytes??5000000;if(A.byteLength>w)throw Error(`Uploaded PDF is too large for synchronous markdown extraction (${A.byteLength} bytes; max ${w} bytes)`);let B=(await Promise.resolve().then(() => (H62(),f62))).getDocument({data:new Uint8Array(A),disableFontFace:!1,useSystemFonts:!0,useWorkerFetch:!1}),X=await B.promise;try{let Y=Q.maxPages??50;if(X.numPages>Y)throw Error(`Uploaded PDF has ${X.numPages} pages; maximum supported for synchronous markdown extraction is ${Y}`);let Z=[];for(let W=1;W<=X.numPages;W+=1){let G=(await(await X.getPage(W)).getTextContent()).items.flatMap((q)=>("str"in q)?[q.str]:[]).join(" ").replace(/\s+/g," ").trim();if(G.length>0)Z.push(G)}let H=Z.join(`
7452
7452
 
7453
- `).trim();if(!H)throw Error("Could not extract text from the uploaded PDF");return H}finally{await B.destroy()}}fA();H7();b2();C0();import{createHash as l_w}from"crypto";var p_w=26214400,i_w=20,d_w=60000,W62=80,n_w=10,r_w={renderUrl:f.url().optional(),sourceEntityType:f.string().min(1),sourceEntityId:f.string().min(1),attachmentType:f.string().min(1),documentId:f.string().min(1).optional(),title:f.string().min(1).optional(),filename:f.string().min(1).optional(),dedupKey:f.string().min(1).optional(),replace:f.boolean().optional(),pageCount:f.number().int().min(0).optional(),maxPageCount:f.number().int().positive().optional(),maxBytes:f.number().int().positive().optional(),timeoutMs:f.number().int().positive().optional(),width:f.union([f.string(),f.number()]).optional(),height:f.union([f.string(),f.number()]).optional(),format:f.string().optional(),targetEntityType:f.string().min(1).optional(),targetEntityId:f.string().min(1).optional()},U62=f.object(r_w),if0=U62.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 df0 extends D6{context;renderPdf;constructor(A,Q,w={}){super(A,{schema:if0,jobTypeName:"document-generate"});this.context=Q,this.renderPdf=w.renderPdf??XG}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`,w=await this.context.entityService.getEntity({entityType:A.sourceEntityType,id:A.sourceEntityId});return w?`${Q}:${w.contentHash}`:Q}async process(A,Q,w){this.logger.debug("Starting document generation job",{jobId:Q,sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType});let $=A.maxPageCount??i_w,B=A.maxBytes??p_w,X=A.timeoutMs??d_w;if(A.pageCount!==void 0&&A.pageCount>$)throw Error(`Refusing to render ${A.pageCount} page PDF; maxPageCount=${$}`);let Y=await this.getDedupKey(A),Z=nt0(A,Y),H=A.documentId!==void 0||A.filename!==void 0;if(A.replace!==!0){let W=await this.findDocumentByDedupKey(Y,H?Z:void 0);if(W&&(!H||W.id===Z)){if(A.targetEntityType&&A.targetEntityId)await this.attachDocumentToTarget(A.targetEntityType,A.targetEntityId,W.id,A);return await this.reportProgress(w,{progress:100,message:"Reusing existing generated document"}),{success:!0,documentId:W.id,reused:!0}}}await this.reportProgress(w,{progress:20,message:"Rendering PDF document"});try{let W=await this.resolveDocumentAttachment(A,Z,{timeoutMs:X,maxBytes:B}),K=W.data;if(K.byteLength>B)throw Error(`Rendered PDF exceeds maxBytes=${B}: ${K.byteLength} bytes`);let U=Yt0(K);if(U>$)throw Error(`Rendered PDF has ${U} pages, exceeding maxPageCount=${$}`);let G=U>0?U:A.pageCount;await this.reportProgress(w,{progress:70,message:"Storing PDF document"});let q=A.filename??(A.renderUrl===void 0?W.filename:`${Z}.pdf`),V=rV.createDocumentEntity({dataUrl:Bf0(K),filename:q,...A.title&&{title:A.title},...G!==void 0&&{pageCount:G},status:"draft",sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType,dedupKey:Y});if(await pX({entityService:this.context.entityService,entity:{...V,id:Z}}),A.targetEntityType&&A.targetEntityId)await this.attachDocumentToTarget(A.targetEntityType,A.targetEntityId,Z,A);return await this.reportProgress(w,{progress:100,message:"PDF document generation complete"}),{success:!0,documentId:Z,reused:!1}}catch(W){let K=dA(W);throw this.logger.error("Document generation failed",{jobId:Q,error:K}),await YD({entityService:this.context.entityService,entityType:"document",id:Z,error:K}),W}}async resolveDocumentAttachment(A,Q,w){if(A.renderUrl!==void 0)return{type:"document",data:await this.renderPdf(A.renderUrl,{timeoutMs:w.timeoutMs,maxBytes:w.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 $=await this.context.attachments.resolve({sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType});if(!$)throw Error(`No attachment provider found for ${A.sourceEntityType}/${A.attachmentType}`);if($.type!=="document")throw Error(`Attachment provider returned ${$.type}; expected document`);return $}async findDocumentByDedupKey(A,Q){let w=await this.context.entityService.listEntities({entityType:"document",options:{filter:{metadata:{dedupKey:A}}}});if(w.length>1)this.logger.warn("Multiple documents share dedupKey; using first",{dedupKey:A,count:w.length,ids:w.map((B)=>B.id),preferredDocumentId:Q});let $=w.filter((B)=>B.metadata.status!=="pending"&&B.metadata.status!=="failed");return $.find((B)=>B.id===Q)??$[0]}async attachDocumentToTarget(A,Q,w,$){let B=await this.context.entityService.getEntity({entityType:A,id:Q});if(!B)throw Error(`Target entity not found: ${A}/${Q}`);let{frontmatter:X}=l6(B.content),Y=Array.isArray(X.documents)?X.documents.filter(s_w):[],Z=$.replace?await this.removeReferencesForSameSourceAttachment(Y,w,$):Y,H=Z.some((W)=>W.id===w)?Z:[...Z,{id:w}];await this.context.entityService.updateEntity({entity:{...B,content:E4(B.content,"documents",H)}})}async removeReferencesForSameSourceAttachment(A,Q,w){let $=[];for(let B of A){if(B.id===Q){$.push(B);continue}let X=await this.context.entityService.getEntity({entityType:"document",id:B.id});if(!X||!a_w(X,w))$.push(B)}return $}}function nt0(A,Q){let w=`${A.attachmentType}:${A.sourceEntityType}:${A.sourceEntityId}:${A.renderUrl??"resolved-attachment"}`,$=A.documentId??A.filename?.replace(/\.pdf$/i,"")??Q??w,B=A.replace===!0&&A.documentId===void 0?`${$}-${Date.now()}`:$;return o_w(B)}function o_w(A){let Q=q1(A.replace(/[/:]+/g," "))||`document-${K62(A)}`;if(Q.length<=W62)return Q;let w=`-${K62(A)}`;return`${Q.slice(0,W62-w.length).replace(/-+$/g,"")}${w}`}function K62(A){return l_w("sha256").update(A).digest("hex").slice(0,n_w)}function s_w(A){return typeof A==="object"&&A!==null&&"id"in A&&typeof A.id==="string"&&A.id.length>0}function a_w(A,Q){return A.metadata.sourceEntityType===Q.sourceEntityType&&A.metadata.sourceEntityId===Q.sourceEntityId&&A.metadata.attachmentType===Q.attachmentType}var G62={name:"@brains/document-plugin",version:"0.2.0-alpha.158",description:"Document entity type for generated PDFs and publishable document attachments",dependencies:{"@brains/contracts":"workspace:*","@brains/document":"workspace:*","@brains/media-renderer":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/typescript-config":"workspace:*","bun-types":"^1.3.14",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var e_w=`data:application/pdf;base64,${Buffer.from(`%PDF-1.4
7453
+ `).trim();if(!H)throw Error("Could not extract text from the uploaded PDF");return H}finally{await B.destroy()}}fA();H7();b2();C0();import{createHash as l_w}from"crypto";var p_w=26214400,i_w=20,d_w=60000,W62=80,n_w=10,r_w={renderUrl:f.url().optional(),sourceEntityType:f.string().min(1),sourceEntityId:f.string().min(1),attachmentType:f.string().min(1),documentId:f.string().min(1).optional(),title:f.string().min(1).optional(),filename:f.string().min(1).optional(),dedupKey:f.string().min(1).optional(),replace:f.boolean().optional(),pageCount:f.number().int().min(0).optional(),maxPageCount:f.number().int().positive().optional(),maxBytes:f.number().int().positive().optional(),timeoutMs:f.number().int().positive().optional(),width:f.union([f.string(),f.number()]).optional(),height:f.union([f.string(),f.number()]).optional(),format:f.string().optional(),targetEntityType:f.string().min(1).optional(),targetEntityId:f.string().min(1).optional()},U62=f.object(r_w),if0=U62.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 df0 extends D6{context;renderPdf;constructor(A,Q,w={}){super(A,{schema:if0,jobTypeName:"document-generate"});this.context=Q,this.renderPdf=w.renderPdf??XG}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`,w=await this.context.entityService.getEntity({entityType:A.sourceEntityType,id:A.sourceEntityId});return w?`${Q}:${w.contentHash}`:Q}async process(A,Q,w){this.logger.debug("Starting document generation job",{jobId:Q,sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType});let $=A.maxPageCount??i_w,B=A.maxBytes??p_w,X=A.timeoutMs??d_w;if(A.pageCount!==void 0&&A.pageCount>$)throw Error(`Refusing to render ${A.pageCount} page PDF; maxPageCount=${$}`);let Y=await this.getDedupKey(A),Z=nt0(A,Y),H=A.documentId!==void 0||A.filename!==void 0;if(A.replace!==!0){let W=await this.findDocumentByDedupKey(Y,H?Z:void 0);if(W&&(!H||W.id===Z)){if(A.targetEntityType&&A.targetEntityId)await this.attachDocumentToTarget(A.targetEntityType,A.targetEntityId,W.id,A);return await this.reportProgress(w,{progress:100,message:"Reusing existing generated document"}),{success:!0,documentId:W.id,reused:!0}}}await this.reportProgress(w,{progress:20,message:"Rendering PDF document"});try{let W=await this.resolveDocumentAttachment(A,Z,{timeoutMs:X,maxBytes:B}),K=W.data;if(K.byteLength>B)throw Error(`Rendered PDF exceeds maxBytes=${B}: ${K.byteLength} bytes`);let U=Yt0(K);if(U>$)throw Error(`Rendered PDF has ${U} pages, exceeding maxPageCount=${$}`);let G=U>0?U:A.pageCount;await this.reportProgress(w,{progress:70,message:"Storing PDF document"});let q=A.filename??(A.renderUrl===void 0?W.filename:`${Z}.pdf`),V=rV.createDocumentEntity({dataUrl:Bf0(K),filename:q,...A.title&&{title:A.title},...G!==void 0&&{pageCount:G},status:"draft",sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType,dedupKey:Y});if(await pX({entityService:this.context.entityService,entity:{...V,id:Z}}),A.targetEntityType&&A.targetEntityId)await this.attachDocumentToTarget(A.targetEntityType,A.targetEntityId,Z,A);return await this.reportProgress(w,{progress:100,message:"PDF document generation complete"}),{success:!0,documentId:Z,reused:!1}}catch(W){let K=dA(W);throw this.logger.error("Document generation failed",{jobId:Q,error:K}),await YD({entityService:this.context.entityService,entityType:"document",id:Z,error:K}),W}}async resolveDocumentAttachment(A,Q,w){if(A.renderUrl!==void 0)return{type:"document",data:await this.renderPdf(A.renderUrl,{timeoutMs:w.timeoutMs,maxBytes:w.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 $=await this.context.attachments.resolve({sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType});if(!$)throw Error(`No attachment provider found for ${A.sourceEntityType}/${A.attachmentType}`);if($.type!=="document")throw Error(`Attachment provider returned ${$.type}; expected document`);return $}async findDocumentByDedupKey(A,Q){let w=await this.context.entityService.listEntities({entityType:"document",options:{filter:{metadata:{dedupKey:A}}}});if(w.length>1)this.logger.warn("Multiple documents share dedupKey; using first",{dedupKey:A,count:w.length,ids:w.map((B)=>B.id),preferredDocumentId:Q});let $=w.filter((B)=>B.metadata.status!=="pending"&&B.metadata.status!=="failed");return $.find((B)=>B.id===Q)??$[0]}async attachDocumentToTarget(A,Q,w,$){let B=await this.context.entityService.getEntity({entityType:A,id:Q});if(!B)throw Error(`Target entity not found: ${A}/${Q}`);let{frontmatter:X}=l6(B.content),Y=Array.isArray(X.documents)?X.documents.filter(s_w):[],Z=$.replace?await this.removeReferencesForSameSourceAttachment(Y,w,$):Y,H=Z.some((W)=>W.id===w)?Z:[...Z,{id:w}];await this.context.entityService.updateEntity({entity:{...B,content:E4(B.content,"documents",H)}})}async removeReferencesForSameSourceAttachment(A,Q,w){let $=[];for(let B of A){if(B.id===Q){$.push(B);continue}let X=await this.context.entityService.getEntity({entityType:"document",id:B.id});if(!X||!a_w(X,w))$.push(B)}return $}}function nt0(A,Q){let w=`${A.attachmentType}:${A.sourceEntityType}:${A.sourceEntityId}:${A.renderUrl??"resolved-attachment"}`,$=A.documentId??A.filename?.replace(/\.pdf$/i,"")??Q??w,B=A.replace===!0&&A.documentId===void 0?`${$}-${Date.now()}`:$;return o_w(B)}function o_w(A){let Q=q1(A.replace(/[/:]+/g," "))||`document-${K62(A)}`;if(Q.length<=W62)return Q;let w=`-${K62(A)}`;return`${Q.slice(0,W62-w.length).replace(/-+$/g,"")}${w}`}function K62(A){return l_w("sha256").update(A).digest("hex").slice(0,n_w)}function s_w(A){return typeof A==="object"&&A!==null&&"id"in A&&typeof A.id==="string"&&A.id.length>0}function a_w(A,Q){return A.metadata.sourceEntityType===Q.sourceEntityType&&A.metadata.sourceEntityId===Q.sourceEntityId&&A.metadata.attachmentType===Q.attachmentType}var G62={name:"@brains/document-plugin",version:"0.2.0-alpha.159",description:"Document entity type for generated PDFs and publishable document attachments",dependencies:{"@brains/contracts":"workspace:*","@brains/document":"workspace:*","@brains/media-renderer":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/typescript-config":"workspace:*","bun-types":"^1.3.14",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var e_w=`data:application/pdf;base64,${Buffer.from(`%PDF-1.4
7454
7454
  % Pending document placeholder
7455
7455
  %%EOF
7456
7456
  `).toString("base64")}`,ANw=f.object({}).catchall(f.unknown()).transform(()=>({})),rt0={namespace:"upload",refKind:"upload",routePath:"/api/chat/uploads"};function QNw(A,Q){let w=A.title?.trim();if(w)return w;return Q.replace(/\.[^.]+$/,"").trim()||Q}function wNw(A,Q){return`data:${A};base64,${Q.toString("base64")}`}function $Nw(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 ot0 extends Kw{entityType=rV.entityType;schema=IE;adapter=rV;pluginContext;constructor(){super("document",G62,{},ANw)}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.entities.registerUploadSaveHandler({entityType:this.entityType,mediaTypes:["application/pdf"],handler:async(Q)=>{let w=await this.promoteUpload({entityType:this.entityType,...Q.title!==void 0?{title:Q.title}:{},from:Q.upload},A);return w.kind==="handled"?w.result:{success:!1,error:"Document upload save was not handled"}}}),A.jobs.registerHandler("generate",new df0(this.logger.child("DocumentGenerationJobHandler"),A))}async interceptCreate(A){let Q=this.pluginContext;if(A.from?.kind===rt0.refKind){if(!Q)return{kind:"handled",result:{success:!1,error:"Plugin context not initialized"}};return this.promoteUpload(A,Q)}if(A.from?.kind!=="entity-attachment")return{kind:"continue",input:A};if(!Q)return{kind:"handled",result:{success:!1,error:"Plugin context not initialized"}};let w=if0.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}}),$=await this.getDedupKey(w,Q),B=w.replace===!0?void 0:await this.findExistingDocument($,Q),X=B?.id??nt0(w,$);if(!B)await this.createPendingDocument(Q,{id:X,title:w.title??X,filename:`${X}.pdf`,sourceEntityType:w.sourceEntityType,sourceEntityId:w.sourceEntityId,attachmentType:w.attachmentType,dedupKey:$});let Y=await Q.jobs.enqueue({type:"generate",data:{...w,dedupKey:$,documentId:X}}),Z=`${X}.pdf`;return{kind:"handled",result:{success:!0,data:{entityId:X,jobId:Y,status:"generating",attachment:{mediaType:"application/pdf",url:`/api/chat/attachments/document?id=${encodeURIComponent(X)}`,downloadUrl:`/api/chat/attachments/document?id=${encodeURIComponent(X)}&download=1`,filename:Z,source:{entityType:"document",entityId:X,attachmentType:w.attachmentType}}}}}}async promoteUpload(A,Q){let w=A.from;if(w?.kind!==rt0.refKind)return{kind:"handled",result:{success:!1,error:"Unsupported upload ref kind"}};let $;try{$=await Q.uploads.scoped(rt0).read(w.id)}catch{return{kind:"handled",result:{success:!1,error:"Upload ref not found"}}}if($.record.mediaType!=="application/pdf")return{kind:"handled",result:{success:!1,error:"Only PDF uploads can be promoted to document entities"}};let B=QNw(A,$.record.filename),X=q1(B);if(!X)return{kind:"handled",result:{success:!1,error:"Could not derive a document id from the uploaded filename. Provide a title."}};let Y=new Date().toISOString(),Z=rV.createDocumentEntity({dataUrl:wNw($.record.mediaType,$.content),filename:$.record.filename,title:B,status:"draft",sourceUploadId:w.id,sourceFilename:$.record.filename,sourceMediaType:$.record.mediaType,attachmentType:"uploaded",dedupKey:`upload:${w.kind}:${w.id}`}),H=await Q.entityService.createEntity({entity:{id:X,...Z,created:Y,updated:Y},options:{deduplicateId:!0}});return{kind:"handled",result:{success:!0,data:{entityId:H.entityId,status:"created",attachment:$Nw({entityId:H.entityId,filename:$.record.filename})}}}}async createPendingDocument(A,Q){let w=new Date().toISOString(),$=rV.createDocumentEntity({dataUrl:e_w,filename:Q.filename,title:Q.title,status:"pending",sourceEntityType:Q.sourceEntityType,sourceEntityId:Q.sourceEntityId,attachmentType:Q.attachmentType,dedupKey:Q.dedupKey});await k_({entityService:A.entityService,entity:{id:Q.id,...$,created:w,updated:w}})}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 w=`${A.attachmentType}:${A.sourceEntityType}:${A.sourceEntityId}:resolved-attachment`,$=await Q.entityService.getEntity({entityType:A.sourceEntityType,id:A.sourceEntityId});return $?`${w}:${$.contentHash}`:w}async findExistingDocument(A,Q){return(await Q.entityService.listEntities({entityType:"document",options:{filter:{metadata:{dedupKey:A}}}}))[0]}async getInstructions(){return"Document entities store durable file artifacts such as PDFs. Uploaded PDFs are raw document files, not decks. Source-derived document artifacts are durable documents backed by registered attachment providers such as carousel or printable. Generate saved PDF artifacts through system_generate with source.kind attachment; preserve raw uploaded PDFs with system_create source.kind upload and transform preserve."}async getTools(){return[]}}function st0(){return new ot0}fA();C0();fA();C0();var D62=f.enum(["generating","failed"]),BNw=f.enum(["generating","failed"]),bL=f.object({title:f.string().optional(),status:D62.optional(),error:f.string().optional()}),XNw=f.object({title:f.string(),status:D62.optional(),error:f.string().optional()}),YNw=f.object({title:f.string(),status:BNw.optional(),error:f.string().optional()}),LL=EQ.extend({entityType:f.literal("note"),metadata:YNw}),ZNw=LL.extend({frontmatter:bL,body:f.string()});fA();C0();var fNw=f.record(f.string(),f.unknown());class at0 extends d2{constructor(){super({entityType:"note",purpose:"A short, free-form captured thought, reference, or snippet the user wants to keep.",schema:LL,frontmatterSchema:bL})}toMarkdown(A){let Q=this.extractBody(A.content);try{let w=this.parseFrontMatter(A.content,bL);if(Object.values(w).some(($)=>$!==void 0))return this.buildMarkdown(Q,w)}catch{}return Q}fromMarkdown(A){let Q=this.parseMarkdownFrontmatter(A),w=Q.title??this.extractH1(A)??"Untitled";return{content:A,entityType:"note",metadata:{title:w,...Q.status&&{status:Q.status},...Q.error&&{error:Q.error}}}}parseNoteFrontmatter(A){return this.parseMarkdownFrontmatter(A.content)}parseMarkdownFrontmatter(A){try{return this.parseFrontMatter(A,bL)}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 w=this.parseFrontMatter(Q,fNw);if(Object.keys(w).length===0)return Q;let $={...w,title:w.title??A},B=this.extractBody(Q);return this.buildMarkdown(B,$)}catch{return Q}}extractH1(A){return A.match(/^#\s+(.+)$/m)?.[1]?.trim()??null}}var tV=new at0;C0();var tt0=f.object({defaultPrompt:f.string().default("Create a note summarizing key concepts from my knowledge base")});C0();fA();var q62=f.object({title:f.string().max(80).describe("A clear, descriptive title for the note (3-8 words)"),body:f.string().describe("Note content in markdown format with clear organization and structure")}),et0=e1({name:"note:generation",description:"Template for AI to generate notes from prompts",schema:q62,dataSourceId:"shell:ai-content",requiredPermission:"public",useKnowledgeContext:!0,basePrompt:`You are helping to create personal knowledge notes for research and reference.
@@ -7468,7 +7468,7 @@ title: ${JSON.stringify(A)}
7468
7468
  ---
7469
7469
 
7470
7470
  ${Q.trim()}
7471
- `}var GNw={namespace:"upload",refKind:"upload",routePath:"/api/chat/uploads"},DNw=f.object({uploadId:f.string().min(1),entityId:f.string().min(1),title:f.string().optional()});class Qe0 extends D6{context;constructor(A,Q){super(A,{schema:DNw,jobTypeName:"upload-import"});this.context=Q}async process(A,Q,w){try{await this.reportProgress(w,{progress:10,message:"Reading uploaded file"});let $=await this.context.uploads.scoped(GNw).read(A.uploadId);await this.reportProgress(w,{progress:35,message:"Extracting markdown from upload"});let B=await I62({upload:$,...A.title!==void 0?{title:A.title}:{}});await this.reportProgress(w,{progress:80,message:"Saving imported note"});let X=new Date().toISOString(),Y=tV.fromMarkdown(B.content),Z=await pX({entityService:this.context.entityService,entity:{id:A.entityId,entityType:"note",content:B.content,metadata:{title:B.title,...Y.metadata},created:X,updated:X}});return await this.reportProgress(w,{progress:100,message:"Upload imported as markdown note"}),{entityId:Z.entityId,status:"created"}}catch($){return await this.markStubFailed(A.entityId,dA($)),k8.failure($)}}async markStubFailed(A,Q){try{let w=await this.context.entityService.getEntity({entityType:"note",id:A});if(!w)return;await this.context.entityService.updateEntity({entity:{...w,content:E4(E4(w.content,"status","failed"),"error",Q),metadata:{...w.metadata,status:"failed",error:Q}}})}catch(w){this.logger.warn("Failed to mark import stub as failed",{error:w,entityId:A})}}summarizeDataForLog(A){return{uploadId:A.uploadId,entityId:A.entityId,hasTitle:A.title!==void 0}}}fA();async function F62({entity:A,config:Q}){let w=LL.parse(A),$=$Q(w.content,bL);return{$type:"ai.rizom.brain.note",title:w.metadata.title,body:$.content,format:"text/markdown",...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"note",sourceEntityId:w.id,createdAt:w.created,...w.updated&&{updatedAt:w.updated}}}function we0(){return{entityType:"note",collection:"ai.rizom.brain.note",lexicon:S6["ai.rizom.brain.note"],validate:!1,buildRecord:F62}}var b62={name:"@brains/note",version:"0.2.0-alpha.158",description:"Personal knowledge capture with markdown-first workflow",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":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{eval:"cd evals && bun run brain-eval",lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var L62={namespace:"upload",refKind:"upload",routePath:"/api/chat/uploads"},zNw=f.object({prompt:f.string()});class $e0 extends Zw{entityType=tV.entityType;schema=LL;adapter=tV;unregisterAtprotoProjection;constructor(A={}){super("note",b62,A,tt0)}async interceptCreate(A,Q,w){if(A.from?.kind!==L62.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 $=A.from.id,B;try{B=await w.uploads.scoped(L62).readRecord($)}catch{return{kind:"handled",result:{success:!1,error:"Upload ref not found"}}}try{if(!J62(B.mediaType))return{kind:"handled",result:{success:!1,error:"Only text, JSON, and PDF uploads can be imported as markdown notes"}};let X=Ae0({filename:B.filename,...A.title!==void 0?{title:A.title}:{}}),Y=tV.buildStub({id:X.id,title:X.title}),Z=new Date().toISOString(),H=await w.entityService.createEntity({entity:{id:X.id,entityType:"note",content:Y.content,metadata:Y.metadata,created:Z,updated:Z},options:{deduplicateId:!0}}),W=await w.jobs.enqueue({type:"upload-import",data:{uploadId:$,entityId:H.entityId,...A.title!==void 0?{title:A.title}:{}}});return{kind:"handled",result:{success:!0,data:{entityId:H.entityId,status:"generating",jobId:W}}}}catch(X){return{kind:"handled",result:{success:!1,error:X instanceof Error?X.message:"Failed to import upload as markdown"}}}}createGenerationHandler(A){return new nf0(this.logger.child("NoteGenerationJobHandler"),A)}getTemplates(){return{generation:et0}}async onRegister(A){A.jobs.registerHandler("upload-import",new Qe0(this.logger.child("UploadMarkdownImportJobHandler"),A)),A.eval.registerHandler("generateNote",async(Q)=>{let w=zNw.parse(Q);return A.ai.generate({prompt:w.prompt,templateName:"note:generation"})}),this.unregisterAtprotoProjection=kB.getInstance().register(we0())}async getInstructions(){return"Note entities are editable markdown notes. Use them for durable text captures, summaries, and imported markdown; raw files remain document or image entities instead of notes."}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}}function WM(A={}){return new $e0(A)}fA();C0();fA();var k62=f.object({ref:f.string(),label:f.string()}),_62=f.enum(["pending","draft","published"]),VNw=f.enum(["pending","draft","published"]),ps=f.object({status:_62,title:f.string(),url:f.string().url(),description:f.string().optional(),domain:f.string(),capturedAt:f.string().datetime(),source:k62}),JNw=ps.pick({title:!0,status:!0}),INw=f.object({title:f.string(),status:VNw}),KM=EQ.extend({entityType:f.literal("link"),metadata:INw});b2();C0();C0();var Be0=f.object({enableSummarization:f.boolean().default(!0).describe("Generate AI summaries for captured links"),jinaApiKey:f.string().optional().describe("Jina Reader API key for higher rate limits (500 RPM vs 20 RPM without key)")});fA();class kL extends d2{constructor(){super({entityType:"link",purpose:"A saved external URL or web resource captured for later reference.",schema:KM,frontmatterSchema:ps})}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},w=A.summary??"";return this.buildMarkdown(w,Q)}parseLinkContent(A){return{frontmatter:this.parseFrontMatter(A,ps),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 hE=new kL;fA();C0();var FNw=f.object({success:f.boolean().describe("Set to true if you can extract meaningful content. Set to false only if the provided content is empty, just an error message, or otherwise unusable."),error:f.string().describe("If success is false, explain why content could not be extracted. Use an empty string when success is true."),title:f.string().max(80).describe("The page title - extract from the content or create a descriptive one. Leave empty string if success is false."),description:f.string().describe("A one-sentence description of what the page is about. Leave empty string if success is false."),summary:f.string().describe("A 1-2 paragraph summary of the main content. Leave empty string if success is false.")}),N62=e1({name:"link:extraction",description:"Extract structured content from webpage markdown",dataSourceId:"shell:ai-content",schema:FNw,basePrompt:`You are an expert at extracting key information from webpage content.
7471
+ `}var GNw={namespace:"upload",refKind:"upload",routePath:"/api/chat/uploads"},DNw=f.object({uploadId:f.string().min(1),entityId:f.string().min(1),title:f.string().optional()});class Qe0 extends D6{context;constructor(A,Q){super(A,{schema:DNw,jobTypeName:"upload-import"});this.context=Q}async process(A,Q,w){try{await this.reportProgress(w,{progress:10,message:"Reading uploaded file"});let $=await this.context.uploads.scoped(GNw).read(A.uploadId);await this.reportProgress(w,{progress:35,message:"Extracting markdown from upload"});let B=await I62({upload:$,...A.title!==void 0?{title:A.title}:{}});await this.reportProgress(w,{progress:80,message:"Saving imported note"});let X=new Date().toISOString(),Y=tV.fromMarkdown(B.content),Z=await pX({entityService:this.context.entityService,entity:{id:A.entityId,entityType:"note",content:B.content,metadata:{title:B.title,...Y.metadata},created:X,updated:X}});return await this.reportProgress(w,{progress:100,message:"Upload imported as markdown note"}),{entityId:Z.entityId,status:"created"}}catch($){return await this.markStubFailed(A.entityId,dA($)),k8.failure($)}}async markStubFailed(A,Q){try{let w=await this.context.entityService.getEntity({entityType:"note",id:A});if(!w)return;await this.context.entityService.updateEntity({entity:{...w,content:E4(E4(w.content,"status","failed"),"error",Q),metadata:{...w.metadata,status:"failed",error:Q}}})}catch(w){this.logger.warn("Failed to mark import stub as failed",{error:w,entityId:A})}}summarizeDataForLog(A){return{uploadId:A.uploadId,entityId:A.entityId,hasTitle:A.title!==void 0}}}fA();async function F62({entity:A,config:Q}){let w=LL.parse(A),$=$Q(w.content,bL);return{$type:"ai.rizom.brain.note",title:w.metadata.title,body:$.content,format:"text/markdown",...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"note",sourceEntityId:w.id,createdAt:w.created,...w.updated&&{updatedAt:w.updated}}}function we0(){return{entityType:"note",collection:"ai.rizom.brain.note",lexicon:S6["ai.rizom.brain.note"],validate:!1,buildRecord:F62}}var b62={name:"@brains/note",version:"0.2.0-alpha.159",description:"Personal knowledge capture with markdown-first workflow",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":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{eval:"cd evals && bun run brain-eval",lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var L62={namespace:"upload",refKind:"upload",routePath:"/api/chat/uploads"},zNw=f.object({prompt:f.string()});class $e0 extends Zw{entityType=tV.entityType;schema=LL;adapter=tV;unregisterAtprotoProjection;constructor(A={}){super("note",b62,A,tt0)}async interceptCreate(A,Q,w){if(A.from?.kind!==L62.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 $=A.from.id,B;try{B=await w.uploads.scoped(L62).readRecord($)}catch{return{kind:"handled",result:{success:!1,error:"Upload ref not found"}}}try{if(!J62(B.mediaType))return{kind:"handled",result:{success:!1,error:"Only text, JSON, and PDF uploads can be imported as markdown notes"}};let X=Ae0({filename:B.filename,...A.title!==void 0?{title:A.title}:{}}),Y=tV.buildStub({id:X.id,title:X.title}),Z=new Date().toISOString(),H=await w.entityService.createEntity({entity:{id:X.id,entityType:"note",content:Y.content,metadata:Y.metadata,created:Z,updated:Z},options:{deduplicateId:!0}}),W=await w.jobs.enqueue({type:"upload-import",data:{uploadId:$,entityId:H.entityId,...A.title!==void 0?{title:A.title}:{}}});return{kind:"handled",result:{success:!0,data:{entityId:H.entityId,status:"generating",jobId:W}}}}catch(X){return{kind:"handled",result:{success:!1,error:X instanceof Error?X.message:"Failed to import upload as markdown"}}}}createGenerationHandler(A){return new nf0(this.logger.child("NoteGenerationJobHandler"),A)}getTemplates(){return{generation:et0}}async onRegister(A){A.jobs.registerHandler("upload-import",new Qe0(this.logger.child("UploadMarkdownImportJobHandler"),A)),A.eval.registerHandler("generateNote",async(Q)=>{let w=zNw.parse(Q);return A.ai.generate({prompt:w.prompt,templateName:"note:generation"})}),this.unregisterAtprotoProjection=kB.getInstance().register(we0())}async getInstructions(){return"Note entities are editable markdown notes. Use them for durable text captures, summaries, and imported markdown; raw files remain document or image entities instead of notes."}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}}function WM(A={}){return new $e0(A)}fA();C0();fA();var k62=f.object({ref:f.string(),label:f.string()}),_62=f.enum(["pending","draft","published"]),VNw=f.enum(["pending","draft","published"]),ps=f.object({status:_62,title:f.string(),url:f.string().url(),description:f.string().optional(),domain:f.string(),capturedAt:f.string().datetime(),source:k62}),JNw=ps.pick({title:!0,status:!0}),INw=f.object({title:f.string(),status:VNw}),KM=EQ.extend({entityType:f.literal("link"),metadata:INw});b2();C0();C0();var Be0=f.object({enableSummarization:f.boolean().default(!0).describe("Generate AI summaries for captured links"),jinaApiKey:f.string().optional().describe("Jina Reader API key for higher rate limits (500 RPM vs 20 RPM without key)")});fA();class kL extends d2{constructor(){super({entityType:"link",purpose:"A saved external URL or web resource captured for later reference.",schema:KM,frontmatterSchema:ps})}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},w=A.summary??"";return this.buildMarkdown(w,Q)}parseLinkContent(A){return{frontmatter:this.parseFrontMatter(A,ps),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 hE=new kL;fA();C0();var FNw=f.object({success:f.boolean().describe("Set to true if you can extract meaningful content. Set to false only if the provided content is empty, just an error message, or otherwise unusable."),error:f.string().describe("If success is false, explain why content could not be extracted. Use an empty string when success is true."),title:f.string().max(80).describe("The page title - extract from the content or create a descriptive one. Leave empty string if success is false."),description:f.string().describe("A one-sentence description of what the page is about. Leave empty string if success is false."),summary:f.string().describe("A 1-2 paragraph summary of the main content. Leave empty string if success is false.")}),N62=e1({name:"link:extraction",description:"Extract structured content from webpage markdown",dataSourceId:"shell:ai-content",schema:FNw,basePrompt:`You are an expert at extracting key information from webpage content.
7472
7472
 
7473
7473
  You will receive webpage content in markdown format. Your job is to extract structured information from it.
7474
7474
 
@@ -7490,7 +7490,7 @@ Accuracy rules:
7490
7490
 
7491
7491
  `))return{success:!1,error:Y.trim(),errorType:"fetch_failed"};return{success:!0,content:Y}}catch(w){return this.handleFetchError(w,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 jNw}from"crypto";class _L{static URL_PATTERN=/https?:\/\/[^\s<>"{}|\\^`[\]]+?(?=[,;:\s]|$)/gi;static extractUrls(A){let Q=A.match(_L.URL_PATTERN)??[];return[...new Set(Q)]}static normalizeUrl(A){try{let Q=new URL(A),w=Q.pathname.replace(/\/$/,"")||"/";return`${Q.protocol}//${Q.host}${w}`}catch{return A}}static generateEntityId(A){let Q=this.normalizeUrl(A),w=jNw("sha256").update(Q).digest("hex");try{return`${new URL(Q).hostname.replace(/\./g,"-")}-${w.substring(0,6)}`}catch{return w.substring(0,12)}}static isValidUrl(A){try{let Q=new URL(A);return["http:","https:"].includes(Q.protocol)}catch{return!1}}}fA();C0();e6();var PNw=f.object({interfaceId:f.string().optional(),userId:f.string().optional(),channelId:f.string().optional(),channelName:f.string().optional(),timestamp:f.string().optional()}),MNw=f.object({url:f.url(),metadata:PNw.optional()}),AF8=f.object({success:f.boolean(),entityId:f.string().optional(),title:f.string().optional(),url:f.string().optional(),status:f.enum(["pending","draft","published"]).optional(),error:f.string().optional()});class of0 extends D6{context;linkAdapter;urlFetcher;constructor(A,Q,w){super(A,{schema:MNw,jobTypeName:"link-capture"});this.context=Q,this.linkAdapter=new kL,this.urlFetcher=new CE(w?.jinaApiKey?{jinaApiKey:w.jinaApiKey}:void 0)}async process(A,Q,w){let{url:$,metadata:B}=A;try{await w.report({progress:Yw.START,total:100,message:"Starting link capture"});let X=_L.generateEntityId($);await w.report({progress:Yw.INIT,total:100,message:"Checking for existing link"});let Y=await this.context.entityService.getEntity({entityType:"link",id:X});if(Y){let{frontmatter:q}=this.linkAdapter.parseLinkContent(Y.content),V=Y.metadata.status;if(V!=="pending")return this.logger.info("Link already captured, returning existing",{url:$,entityId:X}),{success:!0,entityId:Y.id,title:q.title,url:$,status:V};this.logger.info("Pending link exists, completing extraction",{url:$,entityId:X})}let Z=this.resolveSource(B),H=new Date().toISOString();await w.report({progress:Yw.FETCH,total:100,message:"Fetching webpage content"});let W=await this.urlFetcher.fetch($);if(!W.success){if(W.errorType==="url_not_found"||W.errorType==="url_unreachable"){this.logger.warn("Link URL not accessible",{url:$,errorType:W.errorType,error:W.error});let q=new URL($).hostname,V=`Could not capture link: ${W.error}`,I=this.linkAdapter.createLinkContent({status:"pending",title:q,url:$,description:V,summary:V,domain:q,capturedAt:H,source:Z});return await pX({entityService:this.context.entityService,entity:{id:X,entityType:"link",content:I,metadata:{status:"pending",title:q}}}),{success:!1,entityId:X,title:q,url:$,status:"pending",error:V}}}await w.report({progress:Yw.PROCESS,total:100,message:"Extracting content with AI"});let K=await this.context.ai.generate({templateName:"link:extraction",prompt:W.success?`Extract structured information from this webpage content:
7492
7492
 
7493
- ${W.content}`:`The URL ${$} could not be fetched. Return success: false with error: "${W.error}"`,data:{url:$,hasContent:W.success},interfacePermissionGrant:"public"});if(this.logger.debug("AI extraction result",{result:K}),await w.report({progress:Yw.EXTRACT,total:100,message:"Processing extraction results"}),K.success===!1||!K.title||!K.description||!K.summary){let q=K.title||new URL($).hostname;this.logger.info("Incomplete extraction, saving as pending",{url:$}),await w.report({progress:Yw.SAVE,total:100,message:"Saving link as pending"});let V=this.linkAdapter.createLinkContent({status:"pending",title:q,url:$,description:K.description,summary:K.summary,domain:new URL($).hostname,capturedAt:H,source:Z}),I=await pX({entityService:this.context.entityService,entity:{id:X,entityType:"link",content:V,metadata:{status:"pending",title:q}}});return await w.report({progress:Yw.COMPLETE,total:100,message:"Link saved (pending)"}),{success:!0,entityId:I.entityId,title:q,url:$,status:"pending"}}await w.report({progress:Yw.SAVE,total:100,message:`Saving link: "${K.title}"`});let U=this.linkAdapter.createLinkContent({status:"draft",title:K.title,url:$,description:K.description,summary:K.summary,domain:new URL($).hostname,capturedAt:H,source:Z}),G=await pX({entityService:this.context.entityService,entity:{id:X,entityType:"link",content:U,metadata:{status:"draft",title:K.title}}});return await w.report({progress:Yw.COMPLETE,total:100,message:`Link captured: "${K.title}"`}),{success:!0,entityId:G.entityId,title:K.title,url:$,status:"draft"}}catch(X){return this.logger.error("Link capture job failed",{error:X,jobId:Q,data:A}),k8.failure(X)}}resolveSource(A){let Q=A?.channelId,w=A?.channelName;if(Q)return{ref:`matrix:${Q}`,label:w??Q};let $=A?.interfaceId??"cli";return{ref:`${$}:local`,label:$.toUpperCase()}}summarizeDataForLog(A){return{url:A.url,interfaceId:A.metadata?.interfaceId}}}async function M62({entity:A,config:Q}){let w=KM.parse(A),{frontmatter:$,summary:B}=hE.parseLinkContent(w.content);return{$type:"ai.rizom.brain.link",title:$.title,url:$.url,...$.description&&{description:$.description},...B&&{summary:B},domain:$.domain,capturedAt:$.capturedAt,source:$.source,...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"link",sourceEntityId:w.id,createdAt:w.created,...w.updated&&{updatedAt:w.updated}}}function We0(){return{entityType:"link",collection:"ai.rizom.brain.link",lexicon:S6["ai.rizom.brain.link"],validate:!1,buildRecord:M62}}var O62={name:"@brains/link",version:"0.2.0-alpha.158",description:"Web content capture plugin with AI-powered extraction and structured storage",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":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{eval:"cd evals && bun run brain-eval",lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var xNw=f.object({url:f.url()});class Ke0 extends Zw{entityType=hE.entityType;schema=KM;adapter=hE;shell;unregisterAtprotoProjection;constructor(A={}){super("link",O62,A,Be0)}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 of0(this.logger.child("LinkCaptureJobHandler"),this.context,this.config.jinaApiKey?{jinaApiKey:this.config.jinaApiKey}:void 0),this.id),Q}async interceptCreate(A,Q,w){if(A.content)try{let X=this.adapter.fromMarkdown(A.content).metadata,Y=typeof X?.title==="string"?X.title:void 0,Z=typeof X?.status==="string"?X.status:void 0,H=this.extractFirstUrl(A.content);if(Y&&Z&&H){let W=q1(H)||q1(Y)||`${A.entityType}-${Date.now()}`,K=new Date().toISOString();return{kind:"handled",result:{success:!0,data:{entityId:(await w.entityService.createEntity({entity:{id:W,entityType:A.entityType,content:A.content,metadata:{title:Y,status:Z},created:K,updated:K}})).entityId,status:"created"}}}}}catch{}let $=A.url??this.extractFirstUrl(A.content,A.prompt,A.title);if($){if(!this.shell)throw Error("LinkPlugin shell was not initialized during register()");try{let B=await this.createPendingLink($,A.title,Q,w),X=await this.shell.getJobQueueService().enqueue({type:"link-capture",data:{url:$,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}:{}}}});return{kind:"handled",result:{success:!0,data:{entityId:B,status:"generating",jobId:X}}}}catch(B){return{kind:"handled",result:{success:!1,error:B instanceof Error?B.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 of0(this.logger.child("LinkCaptureJobHandler"),A,this.config.jinaApiKey?{jinaApiKey:this.config.jinaApiKey}:void 0)}getTemplates(){return{extraction:N62,"link-list":j62,"link-detail":P62}}getDataSources(){return[new He0(this.logger.child("LinksDataSource"))]}async onRegister(A){this.unregisterAtprotoProjection=kB.getInstance().register(We0()),A.eval.registerHandler("extractContent",async(Q)=>{let{url:w}=xNw.parse(Q),B=await new CE(this.config.jinaApiKey?{jinaApiKey:this.config.jinaApiKey}:void 0).fetch(w);if(!B.success)return{success:!1,error:B.error,errorType:B.errorType};return A.ai.generate({templateName:"link:extraction",prompt:`Extract structured information from this webpage content:
7493
+ ${W.content}`:`The URL ${$} could not be fetched. Return success: false with error: "${W.error}"`,data:{url:$,hasContent:W.success},interfacePermissionGrant:"public"});if(this.logger.debug("AI extraction result",{result:K}),await w.report({progress:Yw.EXTRACT,total:100,message:"Processing extraction results"}),K.success===!1||!K.title||!K.description||!K.summary){let q=K.title||new URL($).hostname;this.logger.info("Incomplete extraction, saving as pending",{url:$}),await w.report({progress:Yw.SAVE,total:100,message:"Saving link as pending"});let V=this.linkAdapter.createLinkContent({status:"pending",title:q,url:$,description:K.description,summary:K.summary,domain:new URL($).hostname,capturedAt:H,source:Z}),I=await pX({entityService:this.context.entityService,entity:{id:X,entityType:"link",content:V,metadata:{status:"pending",title:q}}});return await w.report({progress:Yw.COMPLETE,total:100,message:"Link saved (pending)"}),{success:!0,entityId:I.entityId,title:q,url:$,status:"pending"}}await w.report({progress:Yw.SAVE,total:100,message:`Saving link: "${K.title}"`});let U=this.linkAdapter.createLinkContent({status:"draft",title:K.title,url:$,description:K.description,summary:K.summary,domain:new URL($).hostname,capturedAt:H,source:Z}),G=await pX({entityService:this.context.entityService,entity:{id:X,entityType:"link",content:U,metadata:{status:"draft",title:K.title}}});return await w.report({progress:Yw.COMPLETE,total:100,message:`Link captured: "${K.title}"`}),{success:!0,entityId:G.entityId,title:K.title,url:$,status:"draft"}}catch(X){return this.logger.error("Link capture job failed",{error:X,jobId:Q,data:A}),k8.failure(X)}}resolveSource(A){let Q=A?.channelId,w=A?.channelName;if(Q)return{ref:`matrix:${Q}`,label:w??Q};let $=A?.interfaceId??"cli";return{ref:`${$}:local`,label:$.toUpperCase()}}summarizeDataForLog(A){return{url:A.url,interfaceId:A.metadata?.interfaceId}}}async function M62({entity:A,config:Q}){let w=KM.parse(A),{frontmatter:$,summary:B}=hE.parseLinkContent(w.content);return{$type:"ai.rizom.brain.link",title:$.title,url:$.url,...$.description&&{description:$.description},...B&&{summary:B},domain:$.domain,capturedAt:$.capturedAt,source:$.source,...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"link",sourceEntityId:w.id,createdAt:w.created,...w.updated&&{updatedAt:w.updated}}}function We0(){return{entityType:"link",collection:"ai.rizom.brain.link",lexicon:S6["ai.rizom.brain.link"],validate:!1,buildRecord:M62}}var O62={name:"@brains/link",version:"0.2.0-alpha.159",description:"Web content capture plugin with AI-powered extraction and structured storage",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":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{eval:"cd evals && bun run brain-eval",lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var xNw=f.object({url:f.url()});class Ke0 extends Zw{entityType=hE.entityType;schema=KM;adapter=hE;shell;unregisterAtprotoProjection;constructor(A={}){super("link",O62,A,Be0)}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 of0(this.logger.child("LinkCaptureJobHandler"),this.context,this.config.jinaApiKey?{jinaApiKey:this.config.jinaApiKey}:void 0),this.id),Q}async interceptCreate(A,Q,w){if(A.content)try{let X=this.adapter.fromMarkdown(A.content).metadata,Y=typeof X?.title==="string"?X.title:void 0,Z=typeof X?.status==="string"?X.status:void 0,H=this.extractFirstUrl(A.content);if(Y&&Z&&H){let W=q1(H)||q1(Y)||`${A.entityType}-${Date.now()}`,K=new Date().toISOString();return{kind:"handled",result:{success:!0,data:{entityId:(await w.entityService.createEntity({entity:{id:W,entityType:A.entityType,content:A.content,metadata:{title:Y,status:Z},created:K,updated:K}})).entityId,status:"created"}}}}}catch{}let $=A.url??this.extractFirstUrl(A.content,A.prompt,A.title);if($){if(!this.shell)throw Error("LinkPlugin shell was not initialized during register()");try{let B=await this.createPendingLink($,A.title,Q,w),X=await this.shell.getJobQueueService().enqueue({type:"link-capture",data:{url:$,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}:{}}}});return{kind:"handled",result:{success:!0,data:{entityId:B,status:"generating",jobId:X}}}}catch(B){return{kind:"handled",result:{success:!1,error:B instanceof Error?B.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 of0(this.logger.child("LinkCaptureJobHandler"),A,this.config.jinaApiKey?{jinaApiKey:this.config.jinaApiKey}:void 0)}getTemplates(){return{extraction:N62,"link-list":j62,"link-detail":P62}}getDataSources(){return[new He0(this.logger.child("LinksDataSource"))]}async onRegister(A){this.unregisterAtprotoProjection=kB.getInstance().register(We0()),A.eval.registerHandler("extractContent",async(Q)=>{let{url:w}=xNw.parse(Q),B=await new CE(this.config.jinaApiKey?{jinaApiKey:this.config.jinaApiKey}:void 0).fetch(w);if(!B.success)return{success:!1,error:B.error,errorType:B.errorType};return A.ai.generate({templateName:"link:extraction",prompt:`Extract structured information from this webpage content:
7494
7494
 
7495
7495
  ${B.content}`,data:{url:w,hasContent:!0},interfacePermissionGrant:"public"})})}async createPendingLink(A,Q,w,$){let B=_L.generateEntityId(A),X=new URL(A),Y=new Date().toISOString(),Z=Q?.trim()?Q.trim():X.hostname,H=this.adapter.createLinkContent({status:"pending",title:Z,url:A,description:"Link capture is in progress.",summary:`Pending link capture for ${A}.`,domain:X.hostname,capturedAt:Y,source:this.resolveSource(w)});return(await k_({entityService:$.entityService,entity:{id:B,entityType:"link",content:H,metadata:{status:"pending",title:Z},created:Y,updated:Y}})).entityId}resolveSource(A){if(A.channelId)return{ref:`matrix:${A.channelId}`,label:A.channelName??A.channelId};return{ref:`${A.interfaceType}:local`,label:A.interfaceType.toUpperCase()}}extractFirstUrl(...A){for(let Q of A){if(!Q)continue;let[w]=_L.extractUrls(Q);if(w)return w}return}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}}function x62(A={}){return new Ke0(A)}var UM=x62;C0();var RNw=f.object({conversationId:f.string().optional(),interfaceId:f.string().optional(),userId:f.string().optional(),messageId:f.string().optional(),timestamp:f.string().optional()}),MF8=f.object({id:f.string().optional(),metadata:RNw.optional()});fA();C0();p$();C0();fA();var R62=f.enum(["generating","draft","published","failed"]),v62=f.enum(["generating","draft","published","failed"]),h7=f.object({title:f.string(),slug:f.string().optional(),status:R62,publishedAt:f.string().datetime().optional(),description:f.string(),year:f.number(),coverImageId:f.string().optional(),ogImageId:f.string().optional(),url:f.string().url().optional()}),vNw=h7.pick({title:!0,status:!0,publishedAt:!0,year:!0}).extend({slug:f.string(),error:f.string().optional()}),hNw=f.object({title:f.string(),status:v62,publishedAt:f.string().datetime().optional(),year:f.number(),slug:f.string(),error:f.string().optional()}),CNw=f.object({title:f.string(),slug:f.string().optional(),status:v62,publishedAt:f.string().datetime().optional(),description:f.string(),year:f.number(),coverImageId:f.string().optional(),ogImageId:f.string().optional(),url:f.string().url().optional()}),NL=EQ.extend({entityType:f.literal("project"),metadata:hNw}),sf0=f.object({context:f.string(),problem:f.string(),solution:f.string(),outcome:f.string()}),ds=NL.extend({frontmatter:CNw,body:f.string(),structuredContent:sf0.optional(),coverImageUrl:f.string().optional(),ogImageUrl:f.string().optional()}),gNw=ds.extend({url:f.string().optional(),typeLabel:f.string().optional(),coverImageUrl:f.string().optional(),ogImageUrl:f.string().optional(),coverImageWidth:f.number().optional(),coverImageHeight:f.number().optional()}),yNw=ds.extend({url:f.string(),typeLabel:f.string(),coverImageUrl:f.string().optional(),ogImageUrl:f.string().optional(),coverImageWidth:f.number().optional(),coverImageHeight:f.number().optional()});fA();b2();b9();class Ue0 extends R6{constructor(){super(sf0,{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 Ge0=new Ue0;class De0 extends d2{constructor(){super({entityType:"project",purpose:"A project record in the user's portfolio.",schema:NL,frontmatterSchema:h7,supportsCoverImage:!0,bodyFormatter:Ge0})}toMarkdown(A){let Q=this.extractBody(A.content);try{let w=this.parseFrontMatter(A.content,h7),$={...w,slug:w.slug??A.metadata.slug};return this.buildMarkdown(Q,$)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,h7),w=Q.slug??q1(Q.title);return{content:A,entityType:"project",metadata:{title:Q.title,slug:w,status:Q.status,publishedAt:Q.publishedAt,year:Q.year}}}parseProjectFrontmatter(A){return this.parseFrontMatter(A.content,h7)}parseStructuredContent(A){return Ge0.parse(this.extractBody(A.content))}createProjectContent(A,Q){let w=Ge0.format(Q);return this.buildMarkdown(w,A)}buildStub(A){let Q=new Date().getUTCFullYear(),w={title:A.title,slug:A.id,status:"generating",description:"",year:Q};return{content:this.buildMarkdown("",w),metadata:{title:A.title,slug:A.id,status:"generating",year:Q}}}}var GM=new De0;C0();var qe0=f.looseObject({});import{jsxDEV as IH,Fragment as TNw}from"preact/jsx-dev-runtime";var ENw=({project:A})=>{let{frontmatter:Q,url:w,coverImageUrl:$}=A;return IH(O6,{href:w,children:[$&&IH("img",{src:$,alt:Q.title,className:"w-full h-56 object-cover rounded-md mb-4"},void 0,!1,void 0,this),IH(M7,{children:Q.title},void 0,!1,void 0,this),IH("p",{className:"text-theme leading-relaxed",children:Q.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},ze0=({projects:A,pageTitle:Q,pagination:w,baseUrl:$="/projects"})=>{let B=Q??"Projects",X=w?.totalItems??A.length,Y=`Browse all ${X} ${X===1?"project":"projects"}`;return IH(TNw,{children:[IH($w,{title:B,description:Y},void 0,!1,void 0,this),IH("div",{className:"project-list bg-theme",children:IH("div",{className:"container mx-auto px-6 md:px-12 max-w-5xl py-16 md:py-24",children:[IH("h1",{className:"text-4xl font-bold text-heading mb-12",children:B},void 0,!1,void 0,this),IH("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-8",children:A.map((Z)=>IH(ENw,{project:Z},Z.id,!1,void 0,this))},void 0,!1,void 0,this),w&&w.totalPages>1&&IH("div",{className:"mt-12",children:IH(CV,{currentPage:w.currentPage,totalPages:w.totalPages,baseUrl:$},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 Z$,Fragment as h62}from"preact/jsx-dev-runtime";var SNw=({prevProject:A,nextProject:Q})=>{if(!A&&!Q)return null;return Z$("nav",{className:"pt-12 mt-12 border-t border-theme-muted",children:Z$("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[A?Z$(O6,{href:A.url,variant:"compact",children:[Z$("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Previous"},void 0,!1,void 0,this),Z$("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):Z$("div",{},void 0,!1,void 0,this),Q&&Z$(O6,{href:Q.url,variant:"compact",className:"md:text-right",children:[Z$("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Next"},void 0,!1,void 0,this),Z$("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)},af0=({title:A,content:Q})=>{if(!Q)return null;return Z$("section",{className:"mb-12",children:[Z$("h2",{className:"text-2xl font-bold text-heading mb-4",children:A},void 0,!1,void 0,this),Z$(l9,{markdown:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},Ve0=({project:A,prevProject:Q,nextProject:w})=>{let{frontmatter:$,structuredContent:B,metadata:X,coverImageUrl:Y}=A,Z=A.ogImageUrl??Y;return Z$(h62,{children:[Z$($w,{title:$.title,description:$.description,...Z?{ogImage:Z}:{},ogType:"article"},void 0,!1,void 0,this),Z$("article",{className:"project-detail",children:Z$("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:Z$("div",{className:"max-w-3xl mx-auto",children:[Y&&A.coverImageWidth&&A.coverImageHeight&&Z$(vV,{src:Y,alt:$.title,width:A.coverImageWidth,height:A.coverImageHeight,className:"mb-8 shadow-lg"},void 0,!1,void 0,this),Z$("h1",{className:"text-4xl md:text-5xl font-bold text-heading leading-tight tracking-tight mb-4",children:$.title},void 0,!1,void 0,this),Z$("div",{className:"flex flex-wrap items-center gap-4 text-theme-muted mb-8",children:[Z$("span",{className:"text-sm",children:X.year},void 0,!1,void 0,this),$.url&&Z$(h62,{children:[Z$("span",{className:"text-theme-muted",children:"|"},void 0,!1,void 0,this),Z$("a",{href:$.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),Z$("p",{className:"text-lg text-theme mb-12 leading-relaxed",children:$.description},void 0,!1,void 0,this),B&&Z$("div",{className:"case-study",children:[Z$(af0,{title:"Context",content:B.context},void 0,!1,void 0,this),Z$(af0,{title:"Problem",content:B.problem},void 0,!1,void 0,this),Z$(af0,{title:"Solution",content:B.solution},void 0,!1,void 0,this),Z$(af0,{title:"Outcome",content:B.outcome},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Z$(SNw,{prevProject:Q,nextProject: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)]},void 0,!0,void 0,this)};C0();fA();var mNw=f.object({title:f.string().max(80).describe("A clear, compelling project title (3-8 words). Should capture the essence of the project."),description:f.string().describe("A 1-2 sentence summary of the project for portfolio cards. Focus on the core value delivered."),context:f.string().describe("Background information: Who was the client/user? What was the situation? What constraints existed? (2-4 paragraphs)"),problem:f.string().describe("The challenge: What specific problem needed solving? What were the pain points? (2-3 paragraphs)"),solution:f.string().describe("The approach: What was built? What technologies/methods were used? How did it work? (3-5 paragraphs)"),outcome:f.string().describe("The results: What impact did this have? What metrics improved? What was learned? (2-3 paragraphs)")}),Je0=e1({name:"portfolio:generation",description:"Template for AI to generate portfolio project case studies",schema:mNw,dataSourceId:"shell:ai-content",requiredPermission:"public",useKnowledgeContext:!0,basePrompt:`You are helping to create a professional portfolio case study based on REAL project information.
7496
7496
 
@@ -7666,7 +7666,7 @@ Use the project request as the primary source of truth. If retrieved knowledge c
7666
7666
  font: 10px/1.45 var(--font-mono, "JetBrains Mono", ui-monospace, monospace);
7667
7667
  }
7668
7668
  .printable-footer a { color: inherit; text-decoration: none; overflow-wrap: anywhere; }
7669
- `}},void 0,!1,void 0,this),o9("section",{className:"project-shell",children:[o9("header",{className:"project-hero",children:[o9("div",{className:"project-index",children:[Q.brandLabel&&o9("p",{className:"printable-kicker",children:Q.brandLabel},void 0,!1,void 0,this),Q.year&&o9("span",{className:"project-year",children:Q.year},void 0,!1,void 0,this)]},void 0,!0,void 0,this),o9("div",{className:"project-title-panel",children:[o9("span",{className:"printable-kind",children:"Case study dossier"},void 0,!1,void 0,this),o9("h1",{className:"printable-title",children:Q.title},void 0,!1,void 0,this),Q.description&&o9("p",{className:"printable-description",children:Q.description},void 0,!1,void 0,this),o9("div",{className:"printable-meta",children:[Q.year&&o9("span",{children:Q.year},void 0,!1,void 0,this),Q.url&&o9("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&&o9("img",{className:"printable-cover",src:Q.coverImageUrl,alt:""},void 0,!1,void 0,this),o9(l9,{markdown:Q.body,className:"printable-body"},void 0,!1,void 0,this),(Boolean(Q.canonicalUrl)||Boolean(Q.url)||Boolean(Q.brandLabel))&&o9("footer",{className:"printable-footer",children:[o9("span",{children:Q.brandLabel??"Project printable"},void 0,!1,void 0,this),Q.canonicalUrl||Q.url?o9("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 oNw=26214400,sNw=60000;class be0{metadata={outputEntityType:"document"};context;renderPdf;constructor(A,Q={}){this.context=A,this.renderPdf=Q.renderPdf??XG}async resolve(A){if(A.sourceEntityType!=="project"||A.attachmentType!==AH0)return;let Q=await this.context.entityService.getEntity({entityType:"project",id:A.sourceEntityId});if(!Q)return;let w=aNw(Q,{brandLabel:this.resolveBrandLabel(),coverImageUrl:await this.resolveCoverImageUrl(Q)}),$=await iNw(rNw(nNw(),"brain-project-printable-"));try{let B=await HH({outputDir:$,mediaPath:`/_media/printable/project/${Q.id}`,template:y62,format:"pdf",content:w,siteConfig:{title:w.title,themeMode:"light"},themeCSS:this.context.themeCSS}),X=await WH({rootDir:$});try{return{type:"document",data:await this.renderPdf(X.urlFor(B.urlPath),{maxBytes:oNw,timeoutMs:sNw,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${tNw(Q)}-printable.pdf`}}finally{await X.close()}}finally{await dNw($,{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}=l6(A.content),w=h7.parse(Q);if(!w.coverImageId)return;let $=await this.context.entityService.getEntity({entityType:"image",id:w.coverImageId});return $?.content.startsWith("data:image/")?$.content:void 0}}function aNw(A,Q={}){let{frontmatter:w,content:$}=l6(A.content),B=h7.parse(w);return{title:B.title,body:$,...B.description?{description:B.description}:{},year:B.year,...B.publishedAt?{publishedAt:B.publishedAt}:{},...B.url?{url:B.url,canonicalUrl:B.url}:{},...Q.coverImageUrl?{coverImageUrl:Q.coverImageUrl}:{},...Q.brandLabel?{brandLabel:Q.brandLabel}:{}}}function tNw(A){let Q=A.metadata.slug;return Q.length>0?Q:q1(A.metadata.title)}H7();b2();C0();import{jsxDEV as Qjw}from"preact/jsx-dev-runtime";var QH0="og-image",eNw="portfolio:og-image",E62=f.object({title:f.string().min(1),description:f.string().optional(),year:f.number().optional(),brandLabel:f.string().optional(),coverImageUrl:f.string().optional()}),T62={name:eNw,pluginId:"portfolio",schema:E62,renderers:{image:Ajw}};function Ajw(A){let Q=E62.parse(A);return Qjw(RV,{brandLabel:Q.brandLabel??Q.title,eyebrow:"Project",title:Q.title,subtitle:Q.description,tag:Q.year},void 0,!1,void 0,this)}class Le0{metadata={outputEntityType:"image",targetField:"ogImageId"};context;deps;constructor(A,Q={}){this.context=A,this.deps=Q}async resolve(A){if(A.sourceEntityType!=="project"||A.attachmentType!==QH0)return;let Q=await this.context.entityService.getEntity({entityType:"project",id:A.sourceEntityId});if(!Q)return;let{frontmatter:w}=l6(Q.content),$=h7.parse(w),B=this.resolveBrandLabel(),X=await this.resolveCoverImageUrl($.coverImageId),Y={title:$.title,...$.description?{description:$.description}:{},year:$.year,...X?{coverImageUrl:X}:{},...B?{brandLabel:B}:{}};return{type:"image",data:await AM({mediaPath:`/_media/og/project/${Q.id}`,template:T62,content:Y,title:Y.title,themeMode:"light",themeCSS:this.context.themeCSS,tmpPrefix:"brain-project-og-image-",...this.deps.screenshotPng&&{screenshotPng:this.deps.screenshotPng}}),mimeType:"image/png",filename:`${wjw(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 wjw(A){let Q=A.metadata.slug;return Q.length>0?Q:q1(A.metadata.title)}var S62={name:"@brains/portfolio",version:"0.2.0-alpha.158",description:"Portfolio showcase for projects and case studies",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":"^1.3.14",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{eval:"cd evals && bun run brain-eval",lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var Bjw=f.object({currentPage:f.number(),totalPages:f.number(),totalItems:f.number(),pageSize:f.number(),hasNextPage:f.boolean(),hasPrevPage:f.boolean()}),Xjw=f.union([f.enum(["public","shared","restricted"]),f.literal("private")]).optional().transform((A)=>{if(A===void 0)return"public";if(A==="private")return"restricted";return A}),m62=f.enum(["generating","draft","published","failed"]),Yjw=f.object({title:f.string(),slug:f.string().optional(),status:m62,publishedAt:f.string().optional(),description:f.string(),year:f.number(),coverImageId:f.string().optional(),ogImageId:f.string().optional(),url:f.url().optional()}),Zjw=f.object({title:f.string(),status:m62,publishedAt:f.string().optional(),year:f.number(),slug:f.string(),error:f.string().optional()}),fjw=f.object({context:f.string(),problem:f.string(),solution:f.string(),outcome:f.string()}),wH0=f.object({id:f.string(),entityType:f.literal("project"),content:f.string(),created:f.string(),updated:f.string(),visibility:Xjw,metadata:Zjw,contentHash:f.string(),frontmatter:Yjw,body:f.string(),structuredContent:fjw.optional(),url:f.string().optional(),typeLabel:f.string().optional(),coverImageUrl:f.string().optional(),ogImageUrl:f.string().optional(),coverImageWidth:f.number().optional(),coverImageHeight:f.number().optional()}),Hjw=f.object({projects:f.array(wH0),pageTitle:f.string().optional(),pagination:Bjw.nullable(),baseUrl:f.string().optional()}),Wjw=f.object({prompt:f.string(),year:f.number()});function Kjw(A,Q){for(let w of[A,Q]){let $=w?.match(/\b(19\d{2}|20\d{2})\b/);if($?.[1])return Number($[1])}return null}class ke0 extends Zw{entityType="project";schema=NL;adapter=GM;unregisterAtprotoProjection;unregisterPrintableAttachmentProvider;unregisterOgImageAttachmentProvider;constructor(A={}){super("portfolio",S62,A,qe0)}async interceptCreate(A,Q,w){if(!A.prompt||A.content)return{kind:"continue",input:A};let $=Kjw(A.title,A.prompt);if(!$)return{kind:"continue",input:A};return{kind:"handled",result:{success:!0,data:{status:"generating",jobId:await w.jobs.enqueue({type:"project:generation",data:{prompt:A.prompt,...A.title?{title:A.title}:{},year:$},toolContext:Q,options:{source:this.id,metadata:{operationType:"content_operations"}}})}}}}createGenerationHandler(A){return new tf0(this.logger.child("ProjectGenerationJobHandler"),A)}getTemplates(){return{"project-list":e1({name:"project-list",description:"Portfolio project list page template",schema:Hjw,dataSourceId:"portfolio:entities",requiredPermission:"public",layout:{component:ze0}}),"project-detail":e1({name:"project-detail",description:"Individual project case study template",schema:f.object({project:wH0,prevProject:wH0.nullable(),nextProject:wH0.nullable()}),dataSourceId:"portfolio:entities",requiredPermission:"public",layout:{component:Ve0}}),generation:Je0}}getDataSources(){return[new ef0(this.logger.child("ProjectDataSource"))]}async onRegister(A){this.registerEvalHandlers(A),this.unregisterPrintableAttachmentProvider=A.attachments.register("project",AH0,new be0(A)),this.unregisterOgImageAttachmentProvider=A.attachments.register("project",QH0,new Le0(A)),this.deferPublishRegistration(A),this.subscribeToPublishExecute(A),this.unregisterAtprotoProjection=kB.getInstance().register(Fe0())}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 w=Wjw.parse(Q);return A.ai.generate({prompt:Ie0(w),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:w,entityId:$}=Q.payload;if(w!=="project")return{success:!0};try{let B=await A.entityService.getEntity({entityType:"project",id:$});if(!B)return await A.messaging.send({type:"publish:report:failure",payload:{entityType:w,entityId:$,error:`Project not found: ${$}`}}),{success:!0};if(B.metadata.status==="published")return{success:!0};let X=$Q(B.content,h7),Y=new Date().toISOString(),Z=m5(X.content,{...X.metadata,status:"published",publishedAt:Y});await A.entityService.updateEntity({entity:{...B,content:Z,metadata:{...B.metadata,status:"published",publishedAt:Y}}}),await A.messaging.send({type:"publish:report:success",payload:{entityType:w,entityId:$,publishedAt:Y}})}catch(B){await A.messaging.send({type:"publish:report:failure",payload:{entityType:w,entityId:$,error:dA(B)}})}return{success:!0}})}}function _e0(A={}){return new ke0(A)}fA();C0();C0();var Ujw=f.enum(["public","shared","restricted"]),u62=f.object({includeEntityTypes:f.array(f.string()).default([]),minRelevanceScore:f.number().min(0).max(1).default(0.5),mergeSimilarityThreshold:f.number().min(0).max(1).default(0.85),autoMerge:f.boolean().default(!0),extractableStatuses:f.array(f.string()).default(["published"]),enableAutoExtraction:f.boolean().default(!0),extractionVisibility:Ujw.default("public"),sourceChangeBatchDelayMs:f.number().int().min(0).default(1000)});fA();C0();fA();var ML8=f.object({}),Gjw=f.record(f.string(),f.unknown()).transform(()=>({})),gE=EQ.extend({entityType:f.literal("topic"),metadata:Gjw}),OL8=f.object({content:f.string()}),c62=f.object({title:f.string().describe("Topic title")});var DM="topics",f$="topic",Ne0="topics-projection",l62="topic:project",$H0="topics-plugin",p62="topics:batch-completed",i62="topics-source-batch";class HG extends d2{constructor(){super({entityType:f$,purpose:"A recurring theme or subject derived from the user's content.",schema:gE,frontmatterSchema:c62})}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:f$}}extractMetadata(A){return{}}generateFrontMatter(A){let Q=this.parseTopicBody(A.content),$=this.buildMarkdown("",this.buildFrontmatter(Q.title)).match(/^---\n[\s\S]*?\n---/);return $?$[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))}}fA();C0();C0();var Djw=f.object({title:f.string().max(100),content:f.string(),relevanceScore:f.number().min(0).max(1)}),d62=f.array(Djw);var qjw=f.object({topics:d62}),n62=e1({name:"topics:extraction",description:"Extract topics from conversation text",dataSourceId:"shell:ai-content",schema:qjw,basePrompt:`You are an expert at analyzing content and extracting key topics.
7669
+ `}},void 0,!1,void 0,this),o9("section",{className:"project-shell",children:[o9("header",{className:"project-hero",children:[o9("div",{className:"project-index",children:[Q.brandLabel&&o9("p",{className:"printable-kicker",children:Q.brandLabel},void 0,!1,void 0,this),Q.year&&o9("span",{className:"project-year",children:Q.year},void 0,!1,void 0,this)]},void 0,!0,void 0,this),o9("div",{className:"project-title-panel",children:[o9("span",{className:"printable-kind",children:"Case study dossier"},void 0,!1,void 0,this),o9("h1",{className:"printable-title",children:Q.title},void 0,!1,void 0,this),Q.description&&o9("p",{className:"printable-description",children:Q.description},void 0,!1,void 0,this),o9("div",{className:"printable-meta",children:[Q.year&&o9("span",{children:Q.year},void 0,!1,void 0,this),Q.url&&o9("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&&o9("img",{className:"printable-cover",src:Q.coverImageUrl,alt:""},void 0,!1,void 0,this),o9(l9,{markdown:Q.body,className:"printable-body"},void 0,!1,void 0,this),(Boolean(Q.canonicalUrl)||Boolean(Q.url)||Boolean(Q.brandLabel))&&o9("footer",{className:"printable-footer",children:[o9("span",{children:Q.brandLabel??"Project printable"},void 0,!1,void 0,this),Q.canonicalUrl||Q.url?o9("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 oNw=26214400,sNw=60000;class be0{metadata={outputEntityType:"document"};context;renderPdf;constructor(A,Q={}){this.context=A,this.renderPdf=Q.renderPdf??XG}async resolve(A){if(A.sourceEntityType!=="project"||A.attachmentType!==AH0)return;let Q=await this.context.entityService.getEntity({entityType:"project",id:A.sourceEntityId});if(!Q)return;let w=aNw(Q,{brandLabel:this.resolveBrandLabel(),coverImageUrl:await this.resolveCoverImageUrl(Q)}),$=await iNw(rNw(nNw(),"brain-project-printable-"));try{let B=await HH({outputDir:$,mediaPath:`/_media/printable/project/${Q.id}`,template:y62,format:"pdf",content:w,siteConfig:{title:w.title,themeMode:"light"},themeCSS:this.context.themeCSS}),X=await WH({rootDir:$});try{return{type:"document",data:await this.renderPdf(X.urlFor(B.urlPath),{maxBytes:oNw,timeoutMs:sNw,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${tNw(Q)}-printable.pdf`}}finally{await X.close()}}finally{await dNw($,{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}=l6(A.content),w=h7.parse(Q);if(!w.coverImageId)return;let $=await this.context.entityService.getEntity({entityType:"image",id:w.coverImageId});return $?.content.startsWith("data:image/")?$.content:void 0}}function aNw(A,Q={}){let{frontmatter:w,content:$}=l6(A.content),B=h7.parse(w);return{title:B.title,body:$,...B.description?{description:B.description}:{},year:B.year,...B.publishedAt?{publishedAt:B.publishedAt}:{},...B.url?{url:B.url,canonicalUrl:B.url}:{},...Q.coverImageUrl?{coverImageUrl:Q.coverImageUrl}:{},...Q.brandLabel?{brandLabel:Q.brandLabel}:{}}}function tNw(A){let Q=A.metadata.slug;return Q.length>0?Q:q1(A.metadata.title)}H7();b2();C0();import{jsxDEV as Qjw}from"preact/jsx-dev-runtime";var QH0="og-image",eNw="portfolio:og-image",E62=f.object({title:f.string().min(1),description:f.string().optional(),year:f.number().optional(),brandLabel:f.string().optional(),coverImageUrl:f.string().optional()}),T62={name:eNw,pluginId:"portfolio",schema:E62,renderers:{image:Ajw}};function Ajw(A){let Q=E62.parse(A);return Qjw(RV,{brandLabel:Q.brandLabel??Q.title,eyebrow:"Project",title:Q.title,subtitle:Q.description,tag:Q.year},void 0,!1,void 0,this)}class Le0{metadata={outputEntityType:"image",targetField:"ogImageId"};context;deps;constructor(A,Q={}){this.context=A,this.deps=Q}async resolve(A){if(A.sourceEntityType!=="project"||A.attachmentType!==QH0)return;let Q=await this.context.entityService.getEntity({entityType:"project",id:A.sourceEntityId});if(!Q)return;let{frontmatter:w}=l6(Q.content),$=h7.parse(w),B=this.resolveBrandLabel(),X=await this.resolveCoverImageUrl($.coverImageId),Y={title:$.title,...$.description?{description:$.description}:{},year:$.year,...X?{coverImageUrl:X}:{},...B?{brandLabel:B}:{}};return{type:"image",data:await AM({mediaPath:`/_media/og/project/${Q.id}`,template:T62,content:Y,title:Y.title,themeMode:"light",themeCSS:this.context.themeCSS,tmpPrefix:"brain-project-og-image-",...this.deps.screenshotPng&&{screenshotPng:this.deps.screenshotPng}}),mimeType:"image/png",filename:`${wjw(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 wjw(A){let Q=A.metadata.slug;return Q.length>0?Q:q1(A.metadata.title)}var S62={name:"@brains/portfolio",version:"0.2.0-alpha.159",description:"Portfolio showcase for projects and case studies",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":"^1.3.14",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{eval:"cd evals && bun run brain-eval",lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var Bjw=f.object({currentPage:f.number(),totalPages:f.number(),totalItems:f.number(),pageSize:f.number(),hasNextPage:f.boolean(),hasPrevPage:f.boolean()}),Xjw=f.union([f.enum(["public","shared","restricted"]),f.literal("private")]).optional().transform((A)=>{if(A===void 0)return"public";if(A==="private")return"restricted";return A}),m62=f.enum(["generating","draft","published","failed"]),Yjw=f.object({title:f.string(),slug:f.string().optional(),status:m62,publishedAt:f.string().optional(),description:f.string(),year:f.number(),coverImageId:f.string().optional(),ogImageId:f.string().optional(),url:f.url().optional()}),Zjw=f.object({title:f.string(),status:m62,publishedAt:f.string().optional(),year:f.number(),slug:f.string(),error:f.string().optional()}),fjw=f.object({context:f.string(),problem:f.string(),solution:f.string(),outcome:f.string()}),wH0=f.object({id:f.string(),entityType:f.literal("project"),content:f.string(),created:f.string(),updated:f.string(),visibility:Xjw,metadata:Zjw,contentHash:f.string(),frontmatter:Yjw,body:f.string(),structuredContent:fjw.optional(),url:f.string().optional(),typeLabel:f.string().optional(),coverImageUrl:f.string().optional(),ogImageUrl:f.string().optional(),coverImageWidth:f.number().optional(),coverImageHeight:f.number().optional()}),Hjw=f.object({projects:f.array(wH0),pageTitle:f.string().optional(),pagination:Bjw.nullable(),baseUrl:f.string().optional()}),Wjw=f.object({prompt:f.string(),year:f.number()});function Kjw(A,Q){for(let w of[A,Q]){let $=w?.match(/\b(19\d{2}|20\d{2})\b/);if($?.[1])return Number($[1])}return null}class ke0 extends Zw{entityType="project";schema=NL;adapter=GM;unregisterAtprotoProjection;unregisterPrintableAttachmentProvider;unregisterOgImageAttachmentProvider;constructor(A={}){super("portfolio",S62,A,qe0)}async interceptCreate(A,Q,w){if(!A.prompt||A.content)return{kind:"continue",input:A};let $=Kjw(A.title,A.prompt);if(!$)return{kind:"continue",input:A};return{kind:"handled",result:{success:!0,data:{status:"generating",jobId:await w.jobs.enqueue({type:"project:generation",data:{prompt:A.prompt,...A.title?{title:A.title}:{},year:$},toolContext:Q,options:{source:this.id,metadata:{operationType:"content_operations"}}})}}}}createGenerationHandler(A){return new tf0(this.logger.child("ProjectGenerationJobHandler"),A)}getTemplates(){return{"project-list":e1({name:"project-list",description:"Portfolio project list page template",schema:Hjw,dataSourceId:"portfolio:entities",requiredPermission:"public",layout:{component:ze0}}),"project-detail":e1({name:"project-detail",description:"Individual project case study template",schema:f.object({project:wH0,prevProject:wH0.nullable(),nextProject:wH0.nullable()}),dataSourceId:"portfolio:entities",requiredPermission:"public",layout:{component:Ve0}}),generation:Je0}}getDataSources(){return[new ef0(this.logger.child("ProjectDataSource"))]}async onRegister(A){this.registerEvalHandlers(A),this.unregisterPrintableAttachmentProvider=A.attachments.register("project",AH0,new be0(A)),this.unregisterOgImageAttachmentProvider=A.attachments.register("project",QH0,new Le0(A)),this.deferPublishRegistration(A),this.subscribeToPublishExecute(A),this.unregisterAtprotoProjection=kB.getInstance().register(Fe0())}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 w=Wjw.parse(Q);return A.ai.generate({prompt:Ie0(w),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:w,entityId:$}=Q.payload;if(w!=="project")return{success:!0};try{let B=await A.entityService.getEntity({entityType:"project",id:$});if(!B)return await A.messaging.send({type:"publish:report:failure",payload:{entityType:w,entityId:$,error:`Project not found: ${$}`}}),{success:!0};if(B.metadata.status==="published")return{success:!0};let X=$Q(B.content,h7),Y=new Date().toISOString(),Z=m5(X.content,{...X.metadata,status:"published",publishedAt:Y});await A.entityService.updateEntity({entity:{...B,content:Z,metadata:{...B.metadata,status:"published",publishedAt:Y}}}),await A.messaging.send({type:"publish:report:success",payload:{entityType:w,entityId:$,publishedAt:Y}})}catch(B){await A.messaging.send({type:"publish:report:failure",payload:{entityType:w,entityId:$,error:dA(B)}})}return{success:!0}})}}function _e0(A={}){return new ke0(A)}fA();C0();C0();var Ujw=f.enum(["public","shared","restricted"]),u62=f.object({includeEntityTypes:f.array(f.string()).default([]),minRelevanceScore:f.number().min(0).max(1).default(0.5),mergeSimilarityThreshold:f.number().min(0).max(1).default(0.85),autoMerge:f.boolean().default(!0),extractableStatuses:f.array(f.string()).default(["published"]),enableAutoExtraction:f.boolean().default(!0),extractionVisibility:Ujw.default("public"),sourceChangeBatchDelayMs:f.number().int().min(0).default(1000)});fA();C0();fA();var ML8=f.object({}),Gjw=f.record(f.string(),f.unknown()).transform(()=>({})),gE=EQ.extend({entityType:f.literal("topic"),metadata:Gjw}),OL8=f.object({content:f.string()}),c62=f.object({title:f.string().describe("Topic title")});var DM="topics",f$="topic",Ne0="topics-projection",l62="topic:project",$H0="topics-plugin",p62="topics:batch-completed",i62="topics-source-batch";class HG extends d2{constructor(){super({entityType:f$,purpose:"A recurring theme or subject derived from the user's content.",schema:gE,frontmatterSchema:c62})}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:f$}}extractMetadata(A){return{}}generateFrontMatter(A){let Q=this.parseTopicBody(A.content),$=this.buildMarkdown("",this.buildFrontmatter(Q.title)).match(/^---\n[\s\S]*?\n---/);return $?$[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))}}fA();C0();C0();var Djw=f.object({title:f.string().max(100),content:f.string(),relevanceScore:f.number().min(0).max(1)}),d62=f.array(Djw);var qjw=f.object({topics:d62}),n62=e1({name:"topics:extraction",description:"Extract topics from conversation text",dataSourceId:"shell:ai-content",schema:qjw,basePrompt:`You are an expert at analyzing content and extracting key topics.
7670
7670
 
7671
7671
  Analyze the provided content and extract meaningful topics discussed.
7672
7672
 
@@ -7769,13 +7769,13 @@ ${A.incomingTopic.content}`})}}function Pjw(A){if(A.length===0)return"";return A
7769
7769
 
7770
7770
  ${Q.content}`}).join(`
7771
7771
 
7772
- `)}async function qM(A,Q,w,$={}){if(A.length===0)return{created:0,merged:0,skipped:0,batches:0};let B=$.minRelevanceScore??0,X=$.autoMerge??!1,Y=$.mergeSimilarityThreshold??0.85,Z=$.targetVisibility??"public",H=B$2(A),W=new WG(Q.entityService,w),K=$.topicMergeSynthesizer??new Re0(Q,w),U=await fH0(Q.entityService,void 0,Z),G=new Map,q=0,V=0,I=0;for(let k of H){w.info(`Processing batch of ${k.length} entities`);let j=Pjw(k),_=HH0({entityTitle:`Batch of ${k.length} entities`,entityType:"batch",content:j,existingTopicTitles:U});try{let v=(await Q.ai.generate({prompt:_,templateName:"topics:extraction"})).topics.filter((O)=>O.relevanceScore>=B);for(let O of v)try{if(X){let u=await W.findMergeCandidate({incoming:O,threshold:Y,additionalCandidates:Array.from(G.values()),targetVisibility:Z});if(u){let n=await K.synthesize({existingTopic:u.topic,incomingTopic:O}),e=await W.applySynthesizedMerge({existingId:u.topic.id,synthesized:{...n,title:u.title},visibility:Z});if(!e)throw Error(`Failed to merge topic: ${O.title}`);G.set(e.id,e),V++;continue}}let M=W.getTopicIdForTitle(O.title,Z);if(G.has(M)){I++;continue}let S=await W.createTopicOptimistic({title:O.title,content:O.content,visibility:Z});if(S.topic)G.set(S.topic.id,S.topic);if(S.created)q++;else I++}catch(M){w.error("Topic batch item failed",{title:O.title,error:dA(M)})}}catch(x){w.error("Batch topic extraction failed",{batchSize:k.length,promptChars:_.length,error:dA(x)})}}let J={created:q,merged:V,skipped:I,batches:H.length};if(q>0||V>0)await Q.messaging.send({type:p62,payload:J,broadcast:!0});return J}fA();C0();var Mjw=f.discriminatedUnion("mode",[f.object({mode:f.literal("derive"),reason:f.string().optional()}),f.object({mode:f.literal("rebuild"),reason:f.string().optional()}),f.object({mode:f.literal("source-batch"),minRelevanceScore:f.number().min(0).max(1).optional()})]);class ve0{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 W$2(A){let{context:Q,logger:w,config:$}=A;return{process:async(B)=>{if(B.mode==="derive")return await A.extractAllTopics(),{success:!0};if(B.mode==="rebuild")return await A.rebuildAllTopics(),{success:!0};return Ojw({context:Q,logger:w,config:$,sourceBatch:A.sourceBatch,isEntityPublished:A.isEntityPublished,minRelevanceScore:B.minRelevanceScore??$.minRelevanceScore})},validateAndParse:(B)=>{let X=Mjw.safeParse(B??{});return X.success?X.data:null}}}async function Ojw(A){let Q=A.sourceBatch.drain(),w=await Promise.all(Q.map(async(W)=>({ref:W,entity:await A.context.entityService.getEntity({entityType:W.entityType,id:W.entityId})}))),$=0,B=0,X=0,Y=0,Z=[];for(let{ref:W,entity:K}of w){if(!K){B++;continue}if(K.contentHash!==W.contentHash){$++;continue}if(!A.isEntityPublished(K)){X++;continue}if(!_I(K.visibility,A.config.extractionVisibility)){Y++;continue}Z.push(K)}if(Z.length===0)return{success:!0,sources:Q.length,created:0,merged:0,skipped:0,batches:0,stale:$,missing:B,unpublished:X,hidden:Y};let H=await qM(Z,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,...H,stale:$,missing:B,unpublished:X,hidden:Y}}function K$2(){return{priority:5,source:$H0,deduplication:"coalesce",deduplicationKey:"topics-initial-derivation",metadata:{operationType:"data_processing",operationTarget:"topics-initial-derivation",pluginId:DM}}}async function U$2(A){let Q=await D$2(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 w=await qM(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",w)}async function G$2(A){let Q=await D$2(A),w=await he0(Q,A.context,A.logger,A.config);A.logger.info("Topic rebuild complete",w)}async function he0(A,Q,w,$){let B=new WG(Q.entityService,w),X=await B.listTopics({visibility:$.extractionVisibility});for(let Z of X)await B.deleteTopic(Z.id);if(A.length===0)return{deleted:X.length,created:0,merged:0,skipped:0,batches:0};let Y=await qM(A,Q,w,{minRelevanceScore:$.minRelevanceScore,autoMerge:$.autoMerge,mergeSimilarityThreshold:$.mergeSimilarityThreshold,targetVisibility:$.extractionVisibility});return{deleted:X.length,...Y}}async function D$2(A){let Q=xjw(A),w=[];for(let $ of Q){let B=await A.context.entityService.listEntities({entityType:$,options:{filter:{visibilityScope:A.config.extractionVisibility}}});for(let X of B){if(!A.isEntityPublished(X))continue;w.push(X)}}return w}function xjw(A){return A.context.entityService.getEntityTypes().filter((w)=>A.shouldProcessEntityType(w))}var TE=f.object({entityType:f.string(),content:f.string(),metadata:f.record(f.string(),f.unknown()).optional()}),Rjw=TE.extend({minRelevanceScore:f.number().optional()}),vjw=f.object({contentA:TE,contentB:TE,minRelevanceScore:f.number().optional(),threshold:f.number().min(0).max(1).optional()}),ss=f.object({title:f.string(),content:f.string()}),hjw=f.object({existingTopics:f.array(ss),incomingTopic:ss,threshold:f.number().optional()}),Cjw=f.object({existingTopics:f.array(ss).default([]),incomingTopic:ss.extend({relevanceScore:f.number().min(0).max(1).optional()}),threshold:f.number().optional()}),gjw=f.object({entities:f.array(TE).min(1),minRelevanceScore:f.number().optional()}),yjw=f.object({existingTopics:f.array(ss).optional(),entities:f.array(TE)}),Ejw=f.object({entities:f.array(TE)});function EE(A,Q=""){return{id:`eval${Q}-${Date.now()}`,entityType:A.entityType,content:A.content,contentHash:I6(A.content),visibility:"public",metadata:A.metadata??{},created:new Date().toISOString(),updated:new Date().toISOString()}}function q$2(A){return{title:A.title,relevanceScore:A.relevanceScore}}function Tjw(A){let Q=A.metadata.title;return typeof Q==="string"?Q:A.id}function Sjw(A,Q){return{...A,sources:[{id:Q.id,type:Q.entityType,title:Tjw(Q)}]}}async function zM(A){let Q=await A.entityService.listEntities({entityType:f$});await Promise.all(Q.map((w)=>A.entityService.deleteEntity({entityType:f$,id:w.id})))}async function mjw(A){for(;;){if((await A.jobs.getActiveJobs(["shell:embedding"])).length===0)return;await new Promise((w)=>setTimeout(w,100))}}function z$2(A){let{context:Q,logger:w,config:$}=A,B=new xe0(Q,w),X=async(Y,Z,H="")=>{let W=EE(Y,H);return B.extractFromEntity(W,Z)};Q.eval.registerHandler("extractFromEntity",async(Y)=>{await zM(Q);let Z=Rjw.parse(Y),H=Z.minRelevanceScore??$.minRelevanceScore,W=EE(Z);return(await B.extractFromEntity(W,H)).map((U)=>Sjw(U,W))}),Q.eval.registerHandler("checkMergeSimilarity",async(Y)=>{await zM(Q);let Z=vjw.parse(Y),H=Z.minRelevanceScore??$.minRelevanceScore,W=Z.threshold??$.mergeSimilarityThreshold,[K,U]=await Promise.all([X(Z.contentA,H,"-a"),X(Z.contentB,H,"-b")]),G=new WG(Q.entityService,w),q=[];for(let J of K){let k=await G.createTopic(J);if(k)q.push(k)}let V=(await Promise.all(U.map(async(J)=>{let k=await G.findMergeCandidate({incoming:J,threshold:W,additionalCandidates:q});if(!k)return null;return{incomingTitle:J.title,candidateTitle:k.title,candidateScore:k.score}}))).filter((J)=>J!==null),I=V.map((J)=>J.candidateTitle);return{topicsA:K.map(q$2),topicsB:U.map(q$2),matchingTitles:I,mergeCandidates:V,wouldMerge:V.length>0}}),Q.eval.registerHandler("detectMergeCandidate",async(Y)=>{await zM(Q);let Z=hjw.parse(Y),H=Z.threshold??$.mergeSimilarityThreshold,W=new WG(Q.entityService,w),K=[];for(let G of Z.existingTopics){let q=await W.createTopic(G);if(q)K.push(q)}let U=await W.findMergeCandidate({incoming:{title:Z.incomingTopic.title},threshold:H,additionalCandidates:K});return{found:U!==null,candidateTitle:U?.title,candidateScore:U?.score}}),Q.eval.registerHandler("processTopicWithAutoMerge",async(Y)=>{await zM(Q);let Z=Cjw.parse(Y),H=new WG(Q.entityService,w);for(let G of Z.existingTopics)await H.createTopic({title:G.title,content:G.content});await mjw(Q);let W=EE({entityType:"post",content:Z.incomingTopic.content,metadata:{title:Z.incomingTopic.title}},"-source"),K=await qM([W],Q,w,{minRelevanceScore:0,autoMerge:!0,mergeSimilarityThreshold:Z.threshold??$.mergeSimilarityThreshold}),U=await Q.entityService.listEntities({entityType:f$});return{...K,topicCount:U.length,topics:U.map(Me0)}}),Q.eval.registerHandler("rebuildTopics",async(Y)=>{await zM(Q);let Z=yjw.parse(Y),H=new WG(Q.entityService,w);for(let G of Z.existingTopics??[])await H.createTopic(G);let W=Z.entities.map((G,q)=>EE(G,`-rebuild-${q}`)),K=await he0(W,Q,w,$),U=await Q.entityService.listEntities({entityType:f$});return{...K,topicCount:U.length,topics:U.map(Me0)}}),Q.eval.registerHandler("extractSequentially",async(Y)=>{await zM(Q);let Z=gjw.parse(Y),H=Z.minRelevanceScore??$.minRelevanceScore,W=new WG(Q.entityService,w),K=[];for(let[G,q]of Z.entities.entries()){let V=EE(q,`-sequential-${G}`),I=await B.extractFromEntity(V,H);for(let J of I)await W.createTopic({title:J.title,content:J.content});K.push({extractedTitles:I.map((J)=>J.title)})}let U=await Q.entityService.listEntities({entityType:f$});return{totalTopics:U.length,perEntity:K,topics:U.map(yE)}}),Q.eval.registerHandler("batchExtract",async(Y)=>{await zM(Q);let H=Ejw.parse(Y).entities.map((U,G)=>EE(U,`-batch-${G}`)),W=await qM(H,Q,w,{minRelevanceScore:$.minRelevanceScore}),K=await Q.entityService.listEntities({entityType:f$});return{...W,topics:K.map(yE)}})}var ujw=new HG;async function V$2({entity:A,config:Q}){let w=gE.parse(A),$=ujw.parseTopicBody(w.content);return{$type:"ai.rizom.brain.topic",title:$.title,body:$.content,format:"text/markdown",...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"topic",sourceEntityId:w.id,createdAt:w.created,...w.updated&&{updatedAt:w.updated}}}function Ce0(){return{entityType:"topic",collection:"ai.rizom.brain.topic",lexicon:S6["ai.rizom.brain.topic"],validate:!1,buildRecord:V$2}}var J$2={name:"@brains/topics",version:"0.2.0-alpha.158",description:"Extract and manage topics from conversations",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":"^1.3.14","@types/node":"^20.19.43",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},main:"./src/index.ts",private:!0,scripts:{eval:"cd evals && bun run brain-eval",lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module",types:"./src/index.ts"};var ljw=new HG,pjw=f.looseObject({status:f.unknown().optional()});class I$2 extends Zw{entityType=f$;schema=gE;adapter=ljw;unregisterAtprotoProjection;sourceBatch=new ve0;constructor(A={}){super(DM,J$2,A,u62)}getEntityTypeConfig(){return{weight:0.5,projectionSource:!1}}getTemplates(){return{extraction:n62,"merge-synthesis":r62,"topic-list":o62,"topic-detail":s62}}getDataSources(){return[new Oe0(this.logger.child("TopicsDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableAutoExtraction)return[];return[{id:Ne0,targetType:f$,job:{type:l62,handler:W$2({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 L_(A,f$,{visibility:this.config.extractionVisibility}),jobData:{mode:"derive",reason:"initial-sync"},jobOptions:K$2()},sourceChange:{sourceTypes:this.config.includeEntityTypes,requireInitialSync:!0,jobData:(Q)=>{let w=Q.entity;if(!w)return null;if(!this.shouldProcessEntityType(w.entityType,A.entityService))return null;if(!this.isEntityPublished(w))return null;if(!_I(w.visibility,this.config.extractionVisibility))return null;return this.sourceBatch.add({entityId:w.id,entityType:w.entityType,contentHash:w.contentHash}),{mode:"source-batch"}},jobOptions:()=>({priority:5,source:$H0,delayMs:this.config.sourceChangeBatchDelayMs,deduplication:"skip",deduplicationKey:i62,metadata:{operationType:"data_processing",operationTarget:"topic-source-batch",pluginId:DM}})}}]}async onRegister(A){A.insights.register("topic-distribution",e62()),A$2({context:A,pluginId:this.id}),z$2({context:A,logger:this.logger,config:this.config}),this.unregisterAtprotoProjection=kB.getInstance().register(Ce0())}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}hasRunInitialDerivation(){return this.getDerivedEntityProjectionController(Ne0)?.hasQueuedInitialSync()??!1}shouldProcessEntityType(A,Q){if(A===f$)return!1;if(!this.config.includeEntityTypes.includes(A))return!1;return Q.getEntityTypeConfig(A).projectionSource!==!1}isEntityPublished(A){let Q=pjw.safeParse(A.metadata),w=Q.success?Q.data.status:void 0;if(w===void 0||w===null)return!0;if(typeof w!=="string")return!1;return this.config.extractableStatuses.includes(w)}async extractAllTopics(A){await U$2({context:A,logger:this.logger,config:this.config,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q,A.entityService),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}async rebuildAllTopics(A){await G$2({context:A,logger:this.logger,config:this.config,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q,A.entityService),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}}function WH0(A={}){return new I$2(A)}fA();C0();fA();var ge0=f.enum(["linkedin"]),F$2=f.enum(["linkedin"]),ye0=f.enum(["generating","draft","queued","published","failed"]),b$2=f.enum(["generating","draft","queued","published","failed"]),L$2=f.enum(["post","deck"]),ijw=f.enum(["post","deck"]),k$2=f.object({id:f.string().min(1).describe("Document entity ID")}),djw=f.object({id:f.string().min(1)}),KG=f.object({title:f.string().describe("Short descriptive title (3-6 words) for file naming"),platform:ge0.describe("Target platform"),status:ye0,coverImageId:f.string().optional().describe("Image entity ID for post image"),documents:f.array(k$2).optional().describe("Document attachments for publishing"),publishedAt:f.string().datetime().optional(),platformPostId:f.string().optional().describe("ID from platform after publishing"),sourceEntityId:f.string().optional().describe("Source entity ID if auto-generated"),sourceEntityType:L$2.optional().describe("Source entity type (post, deck)")}),_$2=KG.extend({platform:ge0.optional(),status:ye0.optional()}),njw=KG.pick({title:!0,platform:!0,status:!0,publishedAt:!0,platformPostId:!0}).extend({slug:f.string().describe("URL-friendly identifier: {platform}-{title}"),error:f.string().optional()}),rjw=f.object({title:f.string(),platform:F$2,status:b$2,publishedAt:f.string().datetime().optional(),platformPostId:f.string().optional(),slug:f.string(),error:f.string().optional()}),ojw=f.object({title:f.string(),platform:F$2,status:b$2,coverImageId:f.string().optional(),documents:f.array(djw).optional(),publishedAt:f.string().datetime().optional(),platformPostId:f.string().optional(),sourceEntityId:f.string().optional(),sourceEntityType:ijw.optional()}),jL=EQ.extend({entityType:f.literal("social-post"),metadata:rjw}),KH0=jL.extend({frontmatter:ojw,body:f.string()}),sjw=KH0.extend({url:f.string().optional(),listUrl:f.string().optional(),listLabel:f.string().optional(),typeLabel:f.string().optional(),coverImageUrl:f.string().optional(),coverImageWidth:f.number().optional(),coverImageHeight:f.number().optional()});fA();b2();class Ee0 extends d2{constructor(){super({entityType:"social-post",purpose:"A short post drafted for social media such as LinkedIn or X.",schema:jL,frontmatterSchema:KG,supportsCoverImage:!0})}toMarkdown(A){let Q,w={};try{w=this.parseFrontMatter(A.content,KG),Q=this.extractBody(A.content)}catch{Q=A.content}let $={...w,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,$)}fromMarkdown(A){let Q=this.parseFrontMatter(A,_$2),w=Q.platform??"linkedin",$=Q.status??"draft",B=`${w}-${q1(Q.title)}`;return{content:A,entityType:"social-post",metadata:{title:Q.title,slug:B,platform:w,status:$,publishedAt:Q.publishedAt,platformPostId:Q.platformPostId}}}parsePostFrontmatter(A){return this.parseFrontMatter(A.content,KG)}getPostContent(A){return this.extractBody(A.content)}createPostContent(A,Q){return this.buildMarkdown(Q,A)}buildStub(A){let w={title:A.title,platform:"linkedin",status:"generating"};return{content:this.buildMarkdown("",w),metadata:{title:A.title,slug:`linkedin-${q1(A.title)}`,platform:"linkedin",status:"generating"}}}}var G4=new Ee0;fA();fA();C0();var ajw=f.looseObject({id:f.string().optional(),limit:f.number().optional(),page:f.number().optional(),pageSize:f.number().optional(),baseUrl:f.string().optional(),platform:f.enum(["linkedin"]).optional(),status:f.enum(["generating","draft","queued","published","failed"]).optional(),sortByQueue:f.boolean().optional(),nextInQueue:f.boolean().optional()}),tjw=f.looseObject({entityType:f.string().optional(),query:ajw.optional()});function N$2(A){let Q=$Q(A.content,KG);return KH0.parse({...A,frontmatter:Q.metadata,body:Q.content})}class UH0 extends c5{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=tjw.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}transformEntity(A){return N$2(A)}buildDetailResult(A,Q){return{post:A}}buildListResult(A,Q,w){return{posts:A,totalCount:Q?.totalItems??A.length,pagination:Q,baseUrl:w.baseUrl}}async fetch(A,Q,w){let{query:$}=this.parseQuery(A),B=w.entityService;if($.nextInQueue)return this.fetchNextInQueue(Q,B);if($.id){let{item:K}=await this.fetchDetail($.id,B);return Q.parse(this.buildDetailResult(K,null))}let X={};if($.platform)X.platform=$.platform;if($.status)X.status=$.status;let Y=Object.keys(X).length>0,Z=$.sortByQueue?[{field:"queueOrder",direction:"asc"}]:this.config.defaultSort,{items:H,pagination:W}=await this.fetchList($,B,{...Y&&{filter:{metadata:X}},sortFields:Z});return Q.parse(this.buildListResult(H,W,$))}async fetchNextInQueue(A,Q){let $=(await Q.listEntities({entityType:this.config.entityType,options:{filter:{metadata:{status:"queued"}},sortFields:[{field:"queueOrder",direction:"asc"}],limit:1}}))[0],B=$?N$2($):null;return A.parse({post:B})}}C0();var j$2=f.object({accessToken:f.string().optional(),refreshToken:f.string().optional(),organizationId:f.string().optional(),apiVersion:f.string().regex(/^\d{6}$/).optional()}),Te0=f.object({linkedin:j$2.optional(),publishInterval:f.number().default(3600000),enabled:f.boolean().default(!0),defaultPrompt:f.string().default("Create an engaging social media post that drives engagement"),maxRetries:f.number().default(3),autoGenerateOnBlogPublish:f.boolean().default(!1)});fA();b2();C0();e6();me0();import{jsxDEV as b5,Fragment as QPw}from"preact/jsx-dev-runtime";function ejw(A,Q){if(A.length<=Q)return A;return A.slice(0,Q).trim()+"..."}function APw(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"})}var DH0=({posts:A,pageTitle:Q,pagination:w,baseUrl:$="/social-posts"})=>{let B=Q??"Social Posts",X=w?.totalItems??A.length,Y=`Browse all ${X} social ${X===1?"post":"posts"}`;return b5(QPw,{children:[b5($w,{title:B,description:Y},void 0,!1,void 0,this),b5("div",{className:"social-post-list bg-theme",children:b5("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[b5("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:B},void 0,!1,void 0,this),A.length===0?b5("p",{className:"text-theme-muted italic",children:"No social posts yet."},void 0,!1,void 0,this):b5("ul",{className:"space-y-6",children:A.map((Z)=>b5("li",{children:b5(O6,{href:Z.url,variant:"horizontal",children:b5("div",{className:"flex flex-col sm:flex-row gap-4",children:[Z.coverImageUrl&&b5("img",{src:Z.coverImageUrl,alt:Z.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),b5("div",{className:"flex-1 min-w-0",children:[b5("div",{className:"flex items-start justify-between gap-4 mb-2",children:[b5("h2",{className:"text-lg font-semibold text-heading",children:Z.frontmatter.title},void 0,!1,void 0,this),b5("time",{className:"text-sm text-theme-muted shrink-0",children:APw(Z.frontmatter.publishedAt??Z.created)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),b5("div",{className:"flex items-center gap-2 mb-3",children:[b5(VZ,{status:Z.frontmatter.status},void 0,!1,void 0,this),b5("span",{className:"text-xs text-theme-muted uppercase",children:Z.frontmatter.platform},void 0,!1,void 0,this),b5("span",{className:"text-xs text-theme-muted font-mono",children:Z.id},void 0,!1,void 0,this)]},void 0,!0,void 0,this),b5("p",{className:"text-theme leading-relaxed",children:ejw(Z.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)},Z.id,!1,void 0,this))},void 0,!1,void 0,this),w&&w.totalPages>1&&b5(CV,{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)};import{jsxDEV as L5,Fragment as wPw}from"preact/jsx-dev-runtime";function P$2(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric",hour:"numeric",minute:"2-digit"})}var qH0=({post:A})=>{let Q=`Social Post - ${A.frontmatter.platform}`,w=A.body.slice(0,160),$=[{label:"Home",href:"/"},{label:A.listLabel??"Social Posts",href:A.listUrl??"/social-posts"},{label:A.frontmatter.platform}];return L5(wPw,{children:[L5($w,{title:Q,description:w},void 0,!1,void 0,this),L5("section",{className:"social-post-detail",children:L5("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:L5("div",{className:"max-w-3xl mx-auto",children:[L5(qq,{items:$},void 0,!1,void 0,this),L5("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-4",children:A.frontmatter.title},void 0,!1,void 0,this),L5("div",{className:"flex flex-wrap items-center gap-3 mb-6",children:[L5(VZ,{status:A.frontmatter.status},void 0,!1,void 0,this),L5("span",{className:"text-sm text-theme-muted uppercase",children:A.frontmatter.platform},void 0,!1,void 0,this),L5("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&&L5(vV,{src:A.coverImageUrl,alt:A.frontmatter.title,width:A.coverImageWidth,height:A.coverImageHeight,className:"mb-8"},void 0,!1,void 0,this),L5(O6,{className:"p-8 mb-8",children:L5("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),L5("div",{className:"space-y-4 text-sm text-theme-muted",children:[L5("div",{children:[L5("span",{className:"font-medium",children:"Created:"},void 0,!1,void 0,this)," ",P$2(A.created)]},void 0,!0,void 0,this),A.frontmatter.publishedAt&&L5("div",{children:[L5("span",{className:"font-medium",children:"Published:"},void 0,!1,void 0,this)," ",P$2(A.frontmatter.publishedAt)]},void 0,!0,void 0,this),A.frontmatter.platformPostId&&L5("div",{children:L5("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 as(A){return`social-media:${A}`}var $Pw=f.union([f.boolean(),f.object({generate:f.boolean().optional(),prompt:f.string().optional()})]),ue0=f.object({prompt:f.string().optional(),platform:f.enum(["linkedin"]).optional(),sourceEntityType:f.enum(["post","deck"]).optional(),sourceEntityId:f.string().optional(),title:f.string().optional().describe("Required when content is provided directly"),content:f.string().optional(),addToQueue:f.boolean().optional(),generateImage:f.boolean().optional().describe("Auto-generate cover image for post"),coverImage:$Pw.optional().describe("Generic cover image generation request")}),BPw=aZ.extend({slug:f.string().optional()});class VM extends S4{constructor(A,Q){super(A,Q,{schema:ue0,jobTypeName:"social-post-generation",entityType:"social-post"})}async generate(A,Q){let w=A.platform??"linkedin",$=A.addToQueue??!1,{prompt:B,sourceEntityType:X,sourceEntityId:Y}=A,{content:Z,title:H}=A;if(Z&&H)await this.reportProgress(Q,{progress:50,message:"Using provided content"});else if(Z&&!H){await this.reportProgress(Q,{progress:10,message:"Shaping content with AI"});let J=await this.context.ai.generate({prompt:Z,templateName:as(w)});H=J.title,Z=J.content,await this.reportProgress(Q,{progress:50,message:"Social post shaped from content"})}else if(Y&&X){await this.reportProgress(Q,{progress:10,message:`Fetching source ${X}`});let J=await this.context.entityService.getEntity({entityType:X,id:Y});if(!J)this.failEarly(`Source entity not found: ${X}/${Y}`);await this.reportProgress(Q,{progress:30,message:"Generating social post from source content"});let j=f.looseObject({slug:f.string()}).safeParse(J.metadata),_=j.success?j.data.slug:Y,x=await this.context.ai.generate({prompt:`Create an engaging ${w} post to promote this ${X}:
7772
+ `)}async function qM(A,Q,w,$={}){if(A.length===0)return{created:0,merged:0,skipped:0,batches:0};let B=$.minRelevanceScore??0,X=$.autoMerge??!1,Y=$.mergeSimilarityThreshold??0.85,Z=$.targetVisibility??"public",H=B$2(A),W=new WG(Q.entityService,w),K=$.topicMergeSynthesizer??new Re0(Q,w),U=await fH0(Q.entityService,void 0,Z),G=new Map,q=0,V=0,I=0;for(let k of H){w.info(`Processing batch of ${k.length} entities`);let j=Pjw(k),_=HH0({entityTitle:`Batch of ${k.length} entities`,entityType:"batch",content:j,existingTopicTitles:U});try{let v=(await Q.ai.generate({prompt:_,templateName:"topics:extraction"})).topics.filter((O)=>O.relevanceScore>=B);for(let O of v)try{if(X){let u=await W.findMergeCandidate({incoming:O,threshold:Y,additionalCandidates:Array.from(G.values()),targetVisibility:Z});if(u){let n=await K.synthesize({existingTopic:u.topic,incomingTopic:O}),e=await W.applySynthesizedMerge({existingId:u.topic.id,synthesized:{...n,title:u.title},visibility:Z});if(!e)throw Error(`Failed to merge topic: ${O.title}`);G.set(e.id,e),V++;continue}}let M=W.getTopicIdForTitle(O.title,Z);if(G.has(M)){I++;continue}let S=await W.createTopicOptimistic({title:O.title,content:O.content,visibility:Z});if(S.topic)G.set(S.topic.id,S.topic);if(S.created)q++;else I++}catch(M){w.error("Topic batch item failed",{title:O.title,error:dA(M)})}}catch(x){w.error("Batch topic extraction failed",{batchSize:k.length,promptChars:_.length,error:dA(x)})}}let J={created:q,merged:V,skipped:I,batches:H.length};if(q>0||V>0)await Q.messaging.send({type:p62,payload:J,broadcast:!0});return J}fA();C0();var Mjw=f.discriminatedUnion("mode",[f.object({mode:f.literal("derive"),reason:f.string().optional()}),f.object({mode:f.literal("rebuild"),reason:f.string().optional()}),f.object({mode:f.literal("source-batch"),minRelevanceScore:f.number().min(0).max(1).optional()})]);class ve0{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 W$2(A){let{context:Q,logger:w,config:$}=A;return{process:async(B)=>{if(B.mode==="derive")return await A.extractAllTopics(),{success:!0};if(B.mode==="rebuild")return await A.rebuildAllTopics(),{success:!0};return Ojw({context:Q,logger:w,config:$,sourceBatch:A.sourceBatch,isEntityPublished:A.isEntityPublished,minRelevanceScore:B.minRelevanceScore??$.minRelevanceScore})},validateAndParse:(B)=>{let X=Mjw.safeParse(B??{});return X.success?X.data:null}}}async function Ojw(A){let Q=A.sourceBatch.drain(),w=await Promise.all(Q.map(async(W)=>({ref:W,entity:await A.context.entityService.getEntity({entityType:W.entityType,id:W.entityId})}))),$=0,B=0,X=0,Y=0,Z=[];for(let{ref:W,entity:K}of w){if(!K){B++;continue}if(K.contentHash!==W.contentHash){$++;continue}if(!A.isEntityPublished(K)){X++;continue}if(!_I(K.visibility,A.config.extractionVisibility)){Y++;continue}Z.push(K)}if(Z.length===0)return{success:!0,sources:Q.length,created:0,merged:0,skipped:0,batches:0,stale:$,missing:B,unpublished:X,hidden:Y};let H=await qM(Z,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,...H,stale:$,missing:B,unpublished:X,hidden:Y}}function K$2(){return{priority:5,source:$H0,deduplication:"coalesce",deduplicationKey:"topics-initial-derivation",metadata:{operationType:"data_processing",operationTarget:"topics-initial-derivation",pluginId:DM}}}async function U$2(A){let Q=await D$2(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 w=await qM(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",w)}async function G$2(A){let Q=await D$2(A),w=await he0(Q,A.context,A.logger,A.config);A.logger.info("Topic rebuild complete",w)}async function he0(A,Q,w,$){let B=new WG(Q.entityService,w),X=await B.listTopics({visibility:$.extractionVisibility});for(let Z of X)await B.deleteTopic(Z.id);if(A.length===0)return{deleted:X.length,created:0,merged:0,skipped:0,batches:0};let Y=await qM(A,Q,w,{minRelevanceScore:$.minRelevanceScore,autoMerge:$.autoMerge,mergeSimilarityThreshold:$.mergeSimilarityThreshold,targetVisibility:$.extractionVisibility});return{deleted:X.length,...Y}}async function D$2(A){let Q=xjw(A),w=[];for(let $ of Q){let B=await A.context.entityService.listEntities({entityType:$,options:{filter:{visibilityScope:A.config.extractionVisibility}}});for(let X of B){if(!A.isEntityPublished(X))continue;w.push(X)}}return w}function xjw(A){return A.context.entityService.getEntityTypes().filter((w)=>A.shouldProcessEntityType(w))}var TE=f.object({entityType:f.string(),content:f.string(),metadata:f.record(f.string(),f.unknown()).optional()}),Rjw=TE.extend({minRelevanceScore:f.number().optional()}),vjw=f.object({contentA:TE,contentB:TE,minRelevanceScore:f.number().optional(),threshold:f.number().min(0).max(1).optional()}),ss=f.object({title:f.string(),content:f.string()}),hjw=f.object({existingTopics:f.array(ss),incomingTopic:ss,threshold:f.number().optional()}),Cjw=f.object({existingTopics:f.array(ss).default([]),incomingTopic:ss.extend({relevanceScore:f.number().min(0).max(1).optional()}),threshold:f.number().optional()}),gjw=f.object({entities:f.array(TE).min(1),minRelevanceScore:f.number().optional()}),yjw=f.object({existingTopics:f.array(ss).optional(),entities:f.array(TE)}),Ejw=f.object({entities:f.array(TE)});function EE(A,Q=""){return{id:`eval${Q}-${Date.now()}`,entityType:A.entityType,content:A.content,contentHash:I6(A.content),visibility:"public",metadata:A.metadata??{},created:new Date().toISOString(),updated:new Date().toISOString()}}function q$2(A){return{title:A.title,relevanceScore:A.relevanceScore}}function Tjw(A){let Q=A.metadata.title;return typeof Q==="string"?Q:A.id}function Sjw(A,Q){return{...A,sources:[{id:Q.id,type:Q.entityType,title:Tjw(Q)}]}}async function zM(A){let Q=await A.entityService.listEntities({entityType:f$});await Promise.all(Q.map((w)=>A.entityService.deleteEntity({entityType:f$,id:w.id})))}async function mjw(A){for(;;){if((await A.jobs.getActiveJobs(["shell:embedding"])).length===0)return;await new Promise((w)=>setTimeout(w,100))}}function z$2(A){let{context:Q,logger:w,config:$}=A,B=new xe0(Q,w),X=async(Y,Z,H="")=>{let W=EE(Y,H);return B.extractFromEntity(W,Z)};Q.eval.registerHandler("extractFromEntity",async(Y)=>{await zM(Q);let Z=Rjw.parse(Y),H=Z.minRelevanceScore??$.minRelevanceScore,W=EE(Z);return(await B.extractFromEntity(W,H)).map((U)=>Sjw(U,W))}),Q.eval.registerHandler("checkMergeSimilarity",async(Y)=>{await zM(Q);let Z=vjw.parse(Y),H=Z.minRelevanceScore??$.minRelevanceScore,W=Z.threshold??$.mergeSimilarityThreshold,[K,U]=await Promise.all([X(Z.contentA,H,"-a"),X(Z.contentB,H,"-b")]),G=new WG(Q.entityService,w),q=[];for(let J of K){let k=await G.createTopic(J);if(k)q.push(k)}let V=(await Promise.all(U.map(async(J)=>{let k=await G.findMergeCandidate({incoming:J,threshold:W,additionalCandidates:q});if(!k)return null;return{incomingTitle:J.title,candidateTitle:k.title,candidateScore:k.score}}))).filter((J)=>J!==null),I=V.map((J)=>J.candidateTitle);return{topicsA:K.map(q$2),topicsB:U.map(q$2),matchingTitles:I,mergeCandidates:V,wouldMerge:V.length>0}}),Q.eval.registerHandler("detectMergeCandidate",async(Y)=>{await zM(Q);let Z=hjw.parse(Y),H=Z.threshold??$.mergeSimilarityThreshold,W=new WG(Q.entityService,w),K=[];for(let G of Z.existingTopics){let q=await W.createTopic(G);if(q)K.push(q)}let U=await W.findMergeCandidate({incoming:{title:Z.incomingTopic.title},threshold:H,additionalCandidates:K});return{found:U!==null,candidateTitle:U?.title,candidateScore:U?.score}}),Q.eval.registerHandler("processTopicWithAutoMerge",async(Y)=>{await zM(Q);let Z=Cjw.parse(Y),H=new WG(Q.entityService,w);for(let G of Z.existingTopics)await H.createTopic({title:G.title,content:G.content});await mjw(Q);let W=EE({entityType:"post",content:Z.incomingTopic.content,metadata:{title:Z.incomingTopic.title}},"-source"),K=await qM([W],Q,w,{minRelevanceScore:0,autoMerge:!0,mergeSimilarityThreshold:Z.threshold??$.mergeSimilarityThreshold}),U=await Q.entityService.listEntities({entityType:f$});return{...K,topicCount:U.length,topics:U.map(Me0)}}),Q.eval.registerHandler("rebuildTopics",async(Y)=>{await zM(Q);let Z=yjw.parse(Y),H=new WG(Q.entityService,w);for(let G of Z.existingTopics??[])await H.createTopic(G);let W=Z.entities.map((G,q)=>EE(G,`-rebuild-${q}`)),K=await he0(W,Q,w,$),U=await Q.entityService.listEntities({entityType:f$});return{...K,topicCount:U.length,topics:U.map(Me0)}}),Q.eval.registerHandler("extractSequentially",async(Y)=>{await zM(Q);let Z=gjw.parse(Y),H=Z.minRelevanceScore??$.minRelevanceScore,W=new WG(Q.entityService,w),K=[];for(let[G,q]of Z.entities.entries()){let V=EE(q,`-sequential-${G}`),I=await B.extractFromEntity(V,H);for(let J of I)await W.createTopic({title:J.title,content:J.content});K.push({extractedTitles:I.map((J)=>J.title)})}let U=await Q.entityService.listEntities({entityType:f$});return{totalTopics:U.length,perEntity:K,topics:U.map(yE)}}),Q.eval.registerHandler("batchExtract",async(Y)=>{await zM(Q);let H=Ejw.parse(Y).entities.map((U,G)=>EE(U,`-batch-${G}`)),W=await qM(H,Q,w,{minRelevanceScore:$.minRelevanceScore}),K=await Q.entityService.listEntities({entityType:f$});return{...W,topics:K.map(yE)}})}var ujw=new HG;async function V$2({entity:A,config:Q}){let w=gE.parse(A),$=ujw.parseTopicBody(w.content);return{$type:"ai.rizom.brain.topic",title:$.title,body:$.content,format:"text/markdown",...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"topic",sourceEntityId:w.id,createdAt:w.created,...w.updated&&{updatedAt:w.updated}}}function Ce0(){return{entityType:"topic",collection:"ai.rizom.brain.topic",lexicon:S6["ai.rizom.brain.topic"],validate:!1,buildRecord:V$2}}var J$2={name:"@brains/topics",version:"0.2.0-alpha.159",description:"Extract and manage topics from conversations",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":"^1.3.14","@types/node":"^20.19.43",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},main:"./src/index.ts",private:!0,scripts:{eval:"cd evals && bun run brain-eval",lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module",types:"./src/index.ts"};var ljw=new HG,pjw=f.looseObject({status:f.unknown().optional()});class I$2 extends Zw{entityType=f$;schema=gE;adapter=ljw;unregisterAtprotoProjection;sourceBatch=new ve0;constructor(A={}){super(DM,J$2,A,u62)}getEntityTypeConfig(){return{weight:0.5,projectionSource:!1}}getTemplates(){return{extraction:n62,"merge-synthesis":r62,"topic-list":o62,"topic-detail":s62}}getDataSources(){return[new Oe0(this.logger.child("TopicsDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableAutoExtraction)return[];return[{id:Ne0,targetType:f$,job:{type:l62,handler:W$2({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 L_(A,f$,{visibility:this.config.extractionVisibility}),jobData:{mode:"derive",reason:"initial-sync"},jobOptions:K$2()},sourceChange:{sourceTypes:this.config.includeEntityTypes,requireInitialSync:!0,jobData:(Q)=>{let w=Q.entity;if(!w)return null;if(!this.shouldProcessEntityType(w.entityType,A.entityService))return null;if(!this.isEntityPublished(w))return null;if(!_I(w.visibility,this.config.extractionVisibility))return null;return this.sourceBatch.add({entityId:w.id,entityType:w.entityType,contentHash:w.contentHash}),{mode:"source-batch"}},jobOptions:()=>({priority:5,source:$H0,delayMs:this.config.sourceChangeBatchDelayMs,deduplication:"skip",deduplicationKey:i62,metadata:{operationType:"data_processing",operationTarget:"topic-source-batch",pluginId:DM}})}}]}async onRegister(A){A.insights.register("topic-distribution",e62()),A$2({context:A,pluginId:this.id}),z$2({context:A,logger:this.logger,config:this.config}),this.unregisterAtprotoProjection=kB.getInstance().register(Ce0())}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}hasRunInitialDerivation(){return this.getDerivedEntityProjectionController(Ne0)?.hasQueuedInitialSync()??!1}shouldProcessEntityType(A,Q){if(A===f$)return!1;if(!this.config.includeEntityTypes.includes(A))return!1;return Q.getEntityTypeConfig(A).projectionSource!==!1}isEntityPublished(A){let Q=pjw.safeParse(A.metadata),w=Q.success?Q.data.status:void 0;if(w===void 0||w===null)return!0;if(typeof w!=="string")return!1;return this.config.extractableStatuses.includes(w)}async extractAllTopics(A){await U$2({context:A,logger:this.logger,config:this.config,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q,A.entityService),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}async rebuildAllTopics(A){await G$2({context:A,logger:this.logger,config:this.config,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q,A.entityService),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}}function WH0(A={}){return new I$2(A)}fA();C0();fA();var ge0=f.enum(["linkedin"]),F$2=f.enum(["linkedin"]),ye0=f.enum(["generating","draft","queued","published","failed"]),b$2=f.enum(["generating","draft","queued","published","failed"]),L$2=f.enum(["post","deck"]),ijw=f.enum(["post","deck"]),k$2=f.object({id:f.string().min(1).describe("Document entity ID")}),djw=f.object({id:f.string().min(1)}),KG=f.object({title:f.string().describe("Short descriptive title (3-6 words) for file naming"),platform:ge0.describe("Target platform"),status:ye0,coverImageId:f.string().optional().describe("Image entity ID for post image"),documents:f.array(k$2).optional().describe("Document attachments for publishing"),publishedAt:f.string().datetime().optional(),platformPostId:f.string().optional().describe("ID from platform after publishing"),sourceEntityId:f.string().optional().describe("Source entity ID if auto-generated"),sourceEntityType:L$2.optional().describe("Source entity type (post, deck)")}),_$2=KG.extend({platform:ge0.optional(),status:ye0.optional()}),njw=KG.pick({title:!0,platform:!0,status:!0,publishedAt:!0,platformPostId:!0}).extend({slug:f.string().describe("URL-friendly identifier: {platform}-{title}"),error:f.string().optional()}),rjw=f.object({title:f.string(),platform:F$2,status:b$2,publishedAt:f.string().datetime().optional(),platformPostId:f.string().optional(),slug:f.string(),error:f.string().optional()}),ojw=f.object({title:f.string(),platform:F$2,status:b$2,coverImageId:f.string().optional(),documents:f.array(djw).optional(),publishedAt:f.string().datetime().optional(),platformPostId:f.string().optional(),sourceEntityId:f.string().optional(),sourceEntityType:ijw.optional()}),jL=EQ.extend({entityType:f.literal("social-post"),metadata:rjw}),KH0=jL.extend({frontmatter:ojw,body:f.string()}),sjw=KH0.extend({url:f.string().optional(),listUrl:f.string().optional(),listLabel:f.string().optional(),typeLabel:f.string().optional(),coverImageUrl:f.string().optional(),coverImageWidth:f.number().optional(),coverImageHeight:f.number().optional()});fA();b2();class Ee0 extends d2{constructor(){super({entityType:"social-post",purpose:"A short post drafted for social media such as LinkedIn or X.",schema:jL,frontmatterSchema:KG,supportsCoverImage:!0})}toMarkdown(A){let Q,w={};try{w=this.parseFrontMatter(A.content,KG),Q=this.extractBody(A.content)}catch{Q=A.content}let $={...w,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,$)}fromMarkdown(A){let Q=this.parseFrontMatter(A,_$2),w=Q.platform??"linkedin",$=Q.status??"draft",B=`${w}-${q1(Q.title)}`;return{content:A,entityType:"social-post",metadata:{title:Q.title,slug:B,platform:w,status:$,publishedAt:Q.publishedAt,platformPostId:Q.platformPostId}}}parsePostFrontmatter(A){return this.parseFrontMatter(A.content,KG)}getPostContent(A){return this.extractBody(A.content)}createPostContent(A,Q){return this.buildMarkdown(Q,A)}buildStub(A){let w={title:A.title,platform:"linkedin",status:"generating"};return{content:this.buildMarkdown("",w),metadata:{title:A.title,slug:`linkedin-${q1(A.title)}`,platform:"linkedin",status:"generating"}}}}var G4=new Ee0;fA();fA();C0();var ajw=f.looseObject({id:f.string().optional(),limit:f.number().optional(),page:f.number().optional(),pageSize:f.number().optional(),baseUrl:f.string().optional(),platform:f.enum(["linkedin"]).optional(),status:f.enum(["generating","draft","queued","published","failed"]).optional(),sortByQueue:f.boolean().optional(),nextInQueue:f.boolean().optional()}),tjw=f.looseObject({entityType:f.string().optional(),query:ajw.optional()});function N$2(A){let Q=$Q(A.content,KG);return KH0.parse({...A,frontmatter:Q.metadata,body:Q.content})}class UH0 extends c5{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=tjw.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}transformEntity(A){return N$2(A)}buildDetailResult(A,Q){return{post:A}}buildListResult(A,Q,w){return{posts:A,totalCount:Q?.totalItems??A.length,pagination:Q,baseUrl:w.baseUrl}}async fetch(A,Q,w){let{query:$}=this.parseQuery(A),B=w.entityService;if($.nextInQueue)return this.fetchNextInQueue(Q,B);if($.id){let{item:K}=await this.fetchDetail($.id,B);return Q.parse(this.buildDetailResult(K,null))}let X={};if($.platform)X.platform=$.platform;if($.status)X.status=$.status;let Y=Object.keys(X).length>0,Z=$.sortByQueue?[{field:"queueOrder",direction:"asc"}]:this.config.defaultSort,{items:H,pagination:W}=await this.fetchList($,B,{...Y&&{filter:{metadata:X}},sortFields:Z});return Q.parse(this.buildListResult(H,W,$))}async fetchNextInQueue(A,Q){let $=(await Q.listEntities({entityType:this.config.entityType,options:{filter:{metadata:{status:"queued"}},sortFields:[{field:"queueOrder",direction:"asc"}],limit:1}}))[0],B=$?N$2($):null;return A.parse({post:B})}}C0();var j$2=f.object({accessToken:f.string().optional(),refreshToken:f.string().optional(),organizationId:f.string().optional(),apiVersion:f.string().regex(/^\d{6}$/).optional()}),Te0=f.object({linkedin:j$2.optional(),publishInterval:f.number().default(3600000),enabled:f.boolean().default(!0),defaultPrompt:f.string().default("Create an engaging social media post that drives engagement"),maxRetries:f.number().default(3),autoGenerateOnBlogPublish:f.boolean().default(!1)});fA();b2();C0();e6();me0();import{jsxDEV as b5,Fragment as QPw}from"preact/jsx-dev-runtime";function ejw(A,Q){if(A.length<=Q)return A;return A.slice(0,Q).trim()+"..."}function APw(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"})}var DH0=({posts:A,pageTitle:Q,pagination:w,baseUrl:$="/social-posts"})=>{let B=Q??"Social Posts",X=w?.totalItems??A.length,Y=`Browse all ${X} social ${X===1?"post":"posts"}`;return b5(QPw,{children:[b5($w,{title:B,description:Y},void 0,!1,void 0,this),b5("div",{className:"social-post-list bg-theme",children:b5("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[b5("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:B},void 0,!1,void 0,this),A.length===0?b5("p",{className:"text-theme-muted italic",children:"No social posts yet."},void 0,!1,void 0,this):b5("ul",{className:"space-y-6",children:A.map((Z)=>b5("li",{children:b5(O6,{href:Z.url,variant:"horizontal",children:b5("div",{className:"flex flex-col sm:flex-row gap-4",children:[Z.coverImageUrl&&b5("img",{src:Z.coverImageUrl,alt:Z.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),b5("div",{className:"flex-1 min-w-0",children:[b5("div",{className:"flex items-start justify-between gap-4 mb-2",children:[b5("h2",{className:"text-lg font-semibold text-heading",children:Z.frontmatter.title},void 0,!1,void 0,this),b5("time",{className:"text-sm text-theme-muted shrink-0",children:APw(Z.frontmatter.publishedAt??Z.created)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),b5("div",{className:"flex items-center gap-2 mb-3",children:[b5(VZ,{status:Z.frontmatter.status},void 0,!1,void 0,this),b5("span",{className:"text-xs text-theme-muted uppercase",children:Z.frontmatter.platform},void 0,!1,void 0,this),b5("span",{className:"text-xs text-theme-muted font-mono",children:Z.id},void 0,!1,void 0,this)]},void 0,!0,void 0,this),b5("p",{className:"text-theme leading-relaxed",children:ejw(Z.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)},Z.id,!1,void 0,this))},void 0,!1,void 0,this),w&&w.totalPages>1&&b5(CV,{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)};import{jsxDEV as L5,Fragment as wPw}from"preact/jsx-dev-runtime";function P$2(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric",hour:"numeric",minute:"2-digit"})}var qH0=({post:A})=>{let Q=`Social Post - ${A.frontmatter.platform}`,w=A.body.slice(0,160),$=[{label:"Home",href:"/"},{label:A.listLabel??"Social Posts",href:A.listUrl??"/social-posts"},{label:A.frontmatter.platform}];return L5(wPw,{children:[L5($w,{title:Q,description:w},void 0,!1,void 0,this),L5("section",{className:"social-post-detail",children:L5("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:L5("div",{className:"max-w-3xl mx-auto",children:[L5(qq,{items:$},void 0,!1,void 0,this),L5("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-4",children:A.frontmatter.title},void 0,!1,void 0,this),L5("div",{className:"flex flex-wrap items-center gap-3 mb-6",children:[L5(VZ,{status:A.frontmatter.status},void 0,!1,void 0,this),L5("span",{className:"text-sm text-theme-muted uppercase",children:A.frontmatter.platform},void 0,!1,void 0,this),L5("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&&L5(vV,{src:A.coverImageUrl,alt:A.frontmatter.title,width:A.coverImageWidth,height:A.coverImageHeight,className:"mb-8"},void 0,!1,void 0,this),L5(O6,{className:"p-8 mb-8",children:L5("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),L5("div",{className:"space-y-4 text-sm text-theme-muted",children:[L5("div",{children:[L5("span",{className:"font-medium",children:"Created:"},void 0,!1,void 0,this)," ",P$2(A.created)]},void 0,!0,void 0,this),A.frontmatter.publishedAt&&L5("div",{children:[L5("span",{className:"font-medium",children:"Published:"},void 0,!1,void 0,this)," ",P$2(A.frontmatter.publishedAt)]},void 0,!0,void 0,this),A.frontmatter.platformPostId&&L5("div",{children:L5("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 as(A){return`social-media:${A}`}var $Pw=f.union([f.boolean(),f.object({generate:f.boolean().optional(),prompt:f.string().optional()})]),ue0=f.object({prompt:f.string().optional(),platform:f.enum(["linkedin"]).optional(),sourceEntityType:f.enum(["post","deck"]).optional(),sourceEntityId:f.string().optional(),title:f.string().optional().describe("Required when content is provided directly"),content:f.string().optional(),addToQueue:f.boolean().optional(),generateImage:f.boolean().optional().describe("Auto-generate cover image for post"),coverImage:$Pw.optional().describe("Generic cover image generation request")}),BPw=aZ.extend({slug:f.string().optional()});class VM extends S4{constructor(A,Q){super(A,Q,{schema:ue0,jobTypeName:"social-post-generation",entityType:"social-post"})}async generate(A,Q){let w=A.platform??"linkedin",$=A.addToQueue??!1,{prompt:B,sourceEntityType:X,sourceEntityId:Y}=A,{content:Z,title:H}=A;if(Z&&H)await this.reportProgress(Q,{progress:50,message:"Using provided content"});else if(Z&&!H){await this.reportProgress(Q,{progress:10,message:"Shaping content with AI"});let J=await this.context.ai.generate({prompt:Z,templateName:as(w)});H=J.title,Z=J.content,await this.reportProgress(Q,{progress:50,message:"Social post shaped from content"})}else if(Y&&X){await this.reportProgress(Q,{progress:10,message:`Fetching source ${X}`});let J=await this.context.entityService.getEntity({entityType:X,id:Y});if(!J)this.failEarly(`Source entity not found: ${X}/${Y}`);await this.reportProgress(Q,{progress:30,message:"Generating social post from source content"});let j=f.looseObject({slug:f.string()}).safeParse(J.metadata),_=j.success?j.data.slug:Y,x=await this.context.ai.generate({prompt:`Create an engaging ${w} post to promote this ${X}:
7773
7773
 
7774
7774
  Source: ${X}/${_}
7775
7775
 
7776
7776
  ${J.content}`,templateName:as(w)});H=x.title,Z=x.content,await this.reportProgress(Q,{progress:50,message:"Social post generated from source"})}else if(B){await this.reportProgress(Q,{progress:10,message:"Generating social post with AI"});let J=await this.context.ai.generate({prompt:B,templateName:as(w)});H=J.title,Z=J.content,await this.reportProgress(Q,{progress:50,message:"Social post generated"})}else this.failEarly("No content source provided (prompt, sourceEntityId, or content)");if(!Z||!H)this.failEarly("Content or title was not generated");let K={title:H,platform:w,status:$?"queued":"draft",...Y&&{sourceEntityId:Y},...X&&{sourceEntityType:X}},U=G4.createPostContent(K,Z),q=G4.fromMarkdown(U).metadata;if(!q)this.failEarly("Failed to parse social post metadata");let V=await rK({entityType:"social-post",title:H,deriveId:(J)=>`${w}-${q1(J)}`,regeneratePrompt:"Generate a different social media post title on the same topic.",context:this.context}),I=U;if(V!==H){q.title=V,q.slug=`${w}-${q1(V)}`;let J={...K,title:V};I=G4.createPostContent(J,Z)}return{id:q.slug,content:I,metadata:q,title:V,resultExtras:{slug:q.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,w,$){if(A.generateImage){await this.reportProgress(w,{progress:90,message:"Queueing image generation"});let B=$.title??"Social Post";await this.context.jobs.enqueue({type:"image:image-generate",data:{prompt:`Social media graphic for: ${B}`,title:`${B} 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}}}C0();var M$2=200,O$2="com.linkedin.digitalmedia.uploading.MediaUploadHttpRequest";function ts(A){if(A.length<=M$2)return A;return`${A.slice(0,M$2)}\u2026 (truncated, ${A.length} bytes)`}var XPw=f.looseObject({sub:f.string()}),YPw=f.looseObject({id:f.string()}),ZPw=f.looseObject({value:f.looseObject({asset:f.string(),uploadMechanism:f.looseObject({[O$2]:f.looseObject({uploadUrl:f.url()})})})}).transform((A)=>({uploadUrl:A.value.uploadMechanism[O$2].uploadUrl,assetUrn:A.value.asset})),fPw=f.looseObject({value:f.looseObject({uploadUrl:f.url(),document:f.string()})}).transform((A)=>({uploadUrl:A.value.uploadUrl,documentUrn:A.value.document}));function HPw(A){let Q={status:"READY",media:A.urn};if(A.title)Q.title={text:A.title};return Q}function WPw(A){let Q=ZPw.safeParse(A);return Q.success?Q.data:null}function KPw(A){let Q=fPw.safeParse(A);return Q.success?Q.data:null}var UPw="202604";class ce0{config;logger;name="linkedin";apiBaseUrl="https://api.linkedin.com/v2";restApiBaseUrl="https://api.linkedin.com/rest";fetch;cachedUserId=null;constructor(A,Q,w={}){this.config=A,this.logger=Q,this.fetch=w.fetch??globalThis.fetch.bind(globalThis)}async publish(A,Q,w,$){if(!this.config.accessToken)throw Error("LinkedIn access token not configured");let B=await this.getAuthor(),X=$?.[0];if($&&$.length>1)this.logger.warn("LinkedIn document publishing supports one PDF",{count:$.length});let Y=null;if(X){let U=await this.uploadDocument(B,X);return this.publishDocumentPost(B,A,U,X.filename)}else if(w){let U=await this.uploadImage(B,w);if(U)Y={category:"IMAGE",urn:U}}let Z={shareCommentary:{text:A},shareMediaCategory:Y?.category??"NONE",...Y&&{media:[HPw(Y)]}},H=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:B,lifecycleState:"PUBLISHED",specificContent:{"com.linkedin.ugc.ShareContent":Z},visibility:{"com.linkedin.ugc.MemberNetworkVisibility":"PUBLIC"}})});if(!H.ok){let U=ts(await H.text());throw this.logger.error("LinkedIn API error",{status:H.status,error:U}),Error(`LinkedIn API error: ${H.status} - ${U}`)}let W=H.headers.get("X-RestLi-Id")??"";this.logger.info("LinkedIn post created",{postId:W,mediaCategory:Y?.category??"NONE"});let K={id:W};if(W)K.url=`https://www.linkedin.com/feed/update/${W}`;return K}getRestHeaders(){return{Authorization:`Bearer ${this.config.accessToken}`,"Content-Type":"application/json","Linkedin-Version":this.config.apiVersion??UPw,"X-Restli-Protocol-Version":"2.0.0"}}async uploadImage(A,Q){try{let w=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(!w.ok){let Z=ts(await w.text());return this.logger.warn("LinkedIn image upload registration failed",{status:w.status,error:Z}),null}let $=WPw(await w.json());if(!$)return this.logger.warn("LinkedIn image upload registration was malformed"),null;let{uploadUrl:B,assetUrn:X}=$,Y=await this.fetch(B,{method:"PUT",headers:{Authorization:`Bearer ${this.config.accessToken}`,"Content-Type":Q.mimeType},body:new Uint8Array(Q.data)});if(!Y.ok)return this.logger.warn("LinkedIn image binary upload failed",{status:Y.status}),null;return this.logger.info("LinkedIn image uploaded",{assetUrn:X}),X}catch(w){return this.logger.warn("LinkedIn image upload error",{error:w}),null}}async uploadDocument(A,Q){let w=await this.fetch(`${this.restApiBaseUrl}/documents?action=initializeUpload`,{method:"POST",headers:this.getRestHeaders(),body:JSON.stringify({initializeUploadRequest:{owner:A}})});if(!w.ok){let X=ts(await w.text());throw Error(`LinkedIn document upload initialization failed: ${w.status} - ${X}`)}let $=KPw(await w.json());if(!$)throw Error("LinkedIn document upload initialization was malformed");let B=await this.fetch($.uploadUrl,{method:"PUT",headers:{Authorization:`Bearer ${this.config.accessToken}`,"Content-Type":Q.mimeType},body:new Uint8Array(Q.data)});if(!B.ok)throw Error(`LinkedIn document binary upload failed: ${B.status}`);return this.logger.info("LinkedIn document uploaded",{documentUrn:$.documentUrn,filename:Q.filename}),$.documentUrn}async publishDocumentPost(A,Q,w,$){let B=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:w,title:$}},lifecycleState:"PUBLISHED",isReshareDisabledByAuthor:!1})});if(!B.ok){let Z=ts(await B.text());throw this.logger.error("LinkedIn document post API error",{status:B.status,error:Z}),Error(`LinkedIn document post API error: ${B.status} - ${Z}`)}let X=B.headers.get("X-RestLi-Id")??"";this.logger.info("LinkedIn document post created",{postId:X,documentUrn:w});let Y={id:X};if(X)Y.url=`https://www.linkedin.com/feed/update/${X}`;return Y}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 w=await this.fetch("https://api.linkedin.com/v2/userinfo",{headers:{Authorization:`Bearer ${this.config.accessToken}`}});if(w.ok){let $=XPw.safeParse(await w.json());if($.success)return this.cachedUserId=`urn:li:person:${$.data.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 w=ts(await A.text());throw Error(`Failed to get LinkedIn user ID: ${A.status} - ${w}`)}let Q=YPw.parse(await A.json());return this.cachedUserId=`urn:li:person:${Q.id}`,this.cachedUserId}}function le0(A,Q,w={}){return new ce0(A,Q,w)}C0();p$();me0();var GPw=f.object({currentPage:f.number(),totalPages:f.number(),totalItems:f.number(),pageSize:f.number(),hasNextPage:f.boolean(),hasPrevPage:f.boolean()}),DPw=f.union([f.enum(["public","shared","restricted"]),f.literal("private")]).optional().transform((A)=>{if(A===void 0)return"public";if(A==="private")return"restricted";return A}),x$2=f.enum(["linkedin"]),R$2=f.enum(["generating","draft","queued","published","failed"]),qPw=f.enum(["post","deck"]),zPw=f.object({id:f.string().min(1)}),VPw=f.object({title:f.string(),platform:x$2,status:R$2,coverImageId:f.string().optional(),documents:f.array(zPw).optional(),publishedAt:f.string().optional(),platformPostId:f.string().optional(),sourceEntityId:f.string().optional(),sourceEntityType:qPw.optional()}),JPw=f.object({title:f.string(),platform:x$2,status:R$2,publishedAt:f.string().optional(),platformPostId:f.string().optional(),slug:f.string(),error:f.string().optional()}),v$2=f.object({id:f.string(),entityType:f.literal("social-post"),content:f.string(),created:f.string(),updated:f.string(),visibility:DPw,metadata:JPw,contentHash:f.string(),frontmatter:VPw,body:f.string(),url:f.string().optional(),listUrl:f.string().optional(),listLabel:f.string().optional(),typeLabel:f.string().optional(),coverImageUrl:f.string().optional(),coverImageWidth:f.number().optional(),coverImageHeight:f.number().optional()}),IPw=f.object({posts:f.array(v$2),totalCount:f.number().optional(),pagination:GPw.nullable(),baseUrl:f.string().optional()}),FPw=f.object({post:v$2});function h$2(){return{linkedin:GH0,"social-post-list":e1({name:"social-post-list",description:"Social post list page template",schema:IPw,dataSourceId:"social-media:posts",requiredPermission:"public",layout:{component:DH0}}),"social-post-detail":e1({name:"social-post-detail",description:"Individual social post template",schema:FPw,dataSourceId:"social-media:posts",requiredPermission:"public",layout:{component:qH0}})}}C0();var bPw=f.object({prompt:f.string().optional(),content:f.string().optional(),platform:f.enum(["linkedin"]).default("linkedin")}),LPw=f.object({prompt:f.string().optional(),content:f.string().optional(),title:f.string().optional(),platform:f.enum(["linkedin"]).optional()});function C$2(A){A.eval.registerHandler("generation",async(Q)=>{let w=bPw.parse(Q),$=w.content?`Create an engaging LinkedIn post to share this content:
7777
7777
 
7778
- ${w.content}`:w.prompt??"Write an engaging LinkedIn post";return A.ai.generate({prompt:$,templateName:`social-media:${w.platform}`})}),A.eval.registerHandler("create",async(Q)=>{let w=LPw.parse(Q),$=[],B=hX.from(async(W)=>{let K={progress:W.progress};if(W.message!==void 0)K.message=W.message;$.push(K)});if(!B)throw Error("Failed to create progress reporter");let Y=await new VM(A.logger,A).process(w,`eval-${Date.now()}`,B),Z=!1,H;if(Y.success&&Y.entityId){let W=await A.entityService.getEntity({entityType:"social-post",id:Y.entityId});Z=!!W,H=W?.content.slice(0,300)}return{...Y,entityExists:Z,entityPreview:H,progressSteps:$}})}fA();class es{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:w}=A;if(Q!=="social-post")return;this.permissions.assertEntityActionAllowed(Q,"publish",A.authContext??{userPermissionLevel:"anchor"}),this.logger.debug("Handling publish:execute",{entityId:w});try{let $=await this.entityService.getEntity({entityType:"social-post",id:w});if(!$){await this.reportFailure(Q,w,`Post not found: ${w}`);return}let B=$;if(B.metadata.status==="published"){this.logger.debug("Post already published, skipping",{entityId:w});return}let X=B.metadata.platform,Y=this.providers.get(X);if(!Y){await this.reportFailure(Q,w,`No provider configured for platform: ${X}`);return}let Z=$Q(B.content,KG),H;if(Z.metadata.coverImageId)H=await this.fetchImageData(Z.metadata.coverImageId);let W=Z.metadata.documents??[],K=await this.fetchDocumentData(W);try{if(W.length>0&&K.length===0)throw Error(`Refusing to publish: ${W.length} document(s) referenced but none could be fetched`);let U=W.length===0?await this.resolveSourceAttachment(Z.metadata):[],G=K.length>0?K:U,q=G.length?await Y.publish(Z.content,B.metadata,H,G):await Y.publish(Z.content,B.metadata,H),V=new Date().toISOString(),I=q.id||void 0,J={...Z.metadata,status:"published",publishedAt:V,...I&&{platformPostId:I}},k=G4.createPostContent(J,Z.content);await this.entityService.updateEntity({entity:{...B,content:k,metadata:{...B.metadata,status:"published",publishedAt:V,platformPostId:I}}}),await this.reportSuccess(Q,w,q.id),this.logger.info(`Post published successfully: ${w}`,{platform:X,platformPostId:I})}catch(U){let G=U instanceof Error?U.message:String(U),q={...Z.metadata,status:"failed"},V=G4.createPostContent(q,Z.content);await this.entityService.updateEntity({entity:{...B,content:V,metadata:{...B.metadata,status:"failed"}}}),await this.reportFailure(Q,w,G),this.logger.error(`Post publish failed: ${w}`,{platform:X,error:G})}}catch($){let B=dA($);this.logger.error("Unexpected error in publish handler",{entityId:w,error:B}),await this.reportFailure(Q,w,B)}}async reportSuccess(A,Q,w){await this.sendMessage({type:"publish:report:success",payload:{entityType:A,entityId:Q,result:{id:w}}})}async reportFailure(A,Q,w){await this.sendMessage({type:"publish:report:failure",payload:{entityType:A,entityId:Q,error:w}})}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 w of A){let $=await this.fetchSingleDocumentData(w.id);if($)Q.push($)}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 w=Q.content.match(/^data:application\/pdf;base64,(.+)$/);if(!w?.[1]){this.logger.warn("Invalid document data URL format",{documentId:A});return}let $=typeof Q.metadata.filename==="string"?Q.metadata.filename:`${A}.pdf`;return{type:"document",data:Buffer.from(w[1],"base64"),mimeType:"application/pdf",filename:$}}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 $=Q.content.match(/^data:([^;]+);base64,(.+)$/);if(!$?.[1]||!$[2]){this.logger.warn("Invalid image data URL format",{imageId:A});return}let B=$[1],X=$[2];return{data:Buffer.from(X,"base64"),mimeType:B}}catch(Q){this.logger.warn("Failed to fetch cover image",{imageId:A,error:Q});return}}}function g$2(A,Q,w){if(Q.size===0){w.debug("No providers configured, skipping publish-pipeline registration");return}A.messaging.subscribe("system:plugins:ready",async()=>{let $=Q.values().next().value;return await A.messaging.send({type:"publish:register",payload:{entityType:"social-post",provider:$,config:{publishResultIdField:"platformPostId"}}}),w.info("Registered social-post with publish-pipeline"),{success:!0}})}function y$2(A,Q,w){let $=new es({sendMessage:A.messaging.send,logger:w.child("PublishExecuteHandler"),entityService:A.entityService,providers:Q,permissions:A.permissions,resolveAttachment:A.attachments.resolve});A.messaging.subscribe("publish:execute",async(B)=>{return await $.handle(B.payload),{success:!0}}),w.debug("Subscribed to publish:execute messages")}function E$2(A,Q){A.messaging.subscribe("entity:updated",async(w)=>{let{entityType:$,entityId:B,entity:X}=w.payload;if($!=="post")return{success:!0};if(X.metadata?.status!=="queued")return{success:!0};try{if((await A.entityService.listEntities({entityType:"social-post",options:{filter:{metadata:{sourceEntityType:"post",sourceEntityId:B}},limit:1}})).length>0)return Q.debug(`Social post already exists for ${B}, skipping auto-generate`),{success:!0};return await A.messaging.send({type:"social:auto-generate",payload:{sourceEntityType:$,sourceEntityId:B,platform:"linkedin"}}),Q.info(`Auto-generate social post triggered for queued post ${B}`),{success:!0}}catch(Z){let H=dA(Z);return Q.error(`Failed to trigger auto-generate for ${B}:`,{error:H}),{success:!0}}}),Q.debug("Subscribed to entity:updated for auto-generation")}function T$2(A,Q){A.messaging.subscribe("social:auto-generate",async(w)=>{let{sourceEntityType:$,sourceEntityId:B,platform:X}=w.payload;try{let Y=await A.jobs.enqueue({type:`${G4.entityType}:generation`,data:{sourceEntityType:$,sourceEntityId:B,platform:X,addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}});return Q.info(`Social post generation job enqueued for ${$}/${B}`,{jobId:Y}),{success:!0,jobId:Y}}catch(Y){let Z=dA(Y);return Q.error(`Failed to enqueue social post generation for ${B}:`,{error:Z}),{success:!1}}}),Q.debug("Subscribed to social:auto-generate messages")}function S$2(A,Q){A.messaging.subscribe("generate:execute",async(w)=>{let{entityType:$}=w.payload;if($!=="social-post")return{success:!0};Q.info("Received generate:execute for social-post");try{let B=await A.entityService.listEntities({entityType:"post",options:{filter:{metadata:{status:"published"}},limit:5}});if(B.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 X=null;for(let Z of B)if((await A.entityService.listEntities({entityType:"social-post",options:{filter:{metadata:{sourceEntityType:"post",sourceEntityId:Z.id}},limit:1}})).length===0){X=Z;break}if(!X)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 Y=await A.jobs.enqueue({type:`${G4.entityType}:generation`,data:{sourceEntityType:"post",sourceEntityId:X.id,platform:"linkedin",addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}});return Q.info("Social post generation job queued",{jobId:Y,sourcePostId:X.id}),{success:!0}}catch(B){let X=dA(B);return Q.error("Failed to handle generate:execute:",{error:X}),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:X}}),{success:!0}}}),Q.debug("Subscribed to generate:execute messages")}async function m$2({entity:A,config:Q}){let w=jL.parse(A),$=G4.parsePostFrontmatter(w),B=G4.getPostContent(w);return{$type:"ai.rizom.brain.socialPost",title:$.title,platform:$.platform,body:B,format:"text/markdown",status:$.status,...$.publishedAt&&{publishedAt:$.publishedAt},...$.platformPostId&&{platformPostId:$.platformPostId},...$.sourceEntityType&&{sourceLocalEntityType:$.sourceEntityType},...$.sourceEntityId&&{sourceLocalEntityId:$.sourceEntityId},...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"social-post",sourceEntityId:w.id,createdAt:w.created,...w.updated&&{updatedAt:w.updated}}}function pe0(){return{entityType:"social-post",collection:"ai.rizom.brain.socialPost",lexicon:S6["ai.rizom.brain.socialPost"],validate:!1,buildRecord:m$2}}var u$2={name:"@brains/social-media",version:"0.2.0-alpha.158",description:"Multi-provider social media posting with queue-based publishing",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":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts","./env-schema":"./src/env-schema.ts"},private:!0,scripts:{eval:"cd evals && bun run brain-eval",lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};class ie0 extends Zw{entityType=G4.entityType;schema=jL;adapter=G4;providers=new Map;unregisterAtprotoProjection;constructor(A={}){super("social-media",u$2,A,Te0)}createGenerationHandler(A){return new VM(this.logger.child("GenerationJobHandler"),A)}getTemplates(){return h$2()}getDataSources(){return[new UH0(this.logger.child("SocialPostDataSource"))]}getEntityTypeConfig(){return{publish:{publishStatuses:["queued","published","failed"]}}}async onRegister(A){if(this.initializeProviders(),g$2(A,this.providers,this.logger),y$2(A,this.providers,this.logger),this.config.autoGenerateOnBlogPublish)E$2(A,this.logger),T$2(A,this.logger),this.logger.info("Auto-generate on blog publish enabled");S$2(A,this.logger),C$2(A),this.unregisterAtprotoProjection=kB.getInstance().register(pe0()),this.logger.info("Social media plugin registered successfully")}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}initializeProviders(){if(this.config.linkedin?.accessToken){let A=le0(this.config.linkedin,this.logger.child("LinkedInClient"));this.providers.set("linkedin",A),this.logger.info("LinkedIn provider initialized")}}}function Aa(A={}){return new ie0(A)}C0();var _Pw=f.enum(["draft","queued","published","failed"]),c$2=f.object({status:_Pw.default("draft"),queueOrder:f.number().optional().describe("Position in publish queue (lower = sooner)"),publishedAt:f.string().datetime().optional()});class de0{name="internal";async publish(A,Q){return{id:"internal"}}}var Qa={interfaceType:"system",userId:"system",userPermissionLevel:"anchor",authorization:"system"},FY={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"},PL={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"},l$2={REGISTER:"publish-assets:register"};C0();var NPw=f.enum(["provider"]),p$2=f.object({executionMode:NPw.optional(),publishResultIdField:f.string().min(1).optional(),publishTimestampField:f.string().min(1).optional(),enabled:f.boolean().optional()}).strict();var jPw=f.object({skipIfDraftExists:f.boolean().optional(),minSourceEntities:f.number().optional(),maxUnpublishedDrafts:f.number().optional(),sourceEntityType:f.string().optional()}),i$2=f.object({entitySchedules:f.record(f.string(),f.string()).optional(),generationSchedules:f.record(f.string(),f.string()).optional(),generationConditions:f.record(f.string(),jPw).optional()});class Tq{static instance=null;queues=new Map;static getInstance(){return Tq.instance??=new Tq,Tq.instance}static resetInstance(){Tq.instance=null}static createFresh(){return new Tq}constructor(){}async add(A,Q,w=Qa){let $=this.getOrCreateQueue(A),B=$.find((Z)=>Z.entityId===Q);if(B)return{position:B.position};let X=$.length+1,Y={entityId:Q,entityType:A,position:X,queuedAt:new Date().toISOString(),authContext:{...w}};return $.push(Y),{position:X}}async remove(A,Q){let w=this.queues.get(A);if(!w)return;let $=w.findIndex((B)=>B.entityId===Q);if($===-1)return;w.splice($,1),this.recalculatePositions(w)}async reorder(A,Q,w){let $=this.queues.get(A);if(!$)return;let B=$.findIndex((Z)=>Z.entityId===Q);if(B===-1)return;let[X]=$.splice(B,1);if(!X)return;let Y=Math.max(0,Math.min(w-1,$.length));$.splice(Y,0,X),this.recalculatePositions($)}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 w=Q[0];if(!w)continue;if(!A||w.queuedAt<A.queuedAt)A=w}return A}async popNext(A){let Q=this.queues.get(A);if(!Q||Q.length===0)return null;let w=Q.shift()??null;if(w)this.recalculatePositions(Q);return w}getRegisteredTypes(){return Array.from(this.queues.keys())}async getQueuedEntityTypes(){let A=[];for(let[Q,w]of this.queues.entries())if(w.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,w)=>{Q.position=w+1})}}class Sq{static instance=null;providers=new Map;executionModes=new Map;publishResultIdFields=new Map;publishTimestampFields=new Map;defaultProvider=new de0;static getInstance(){return Sq.instance??=new Sq,Sq.instance}static resetInstance(){Sq.instance=null}static createFresh(){return new Sq}constructor(){}register(A,Q,w){let $=this.providers.get(A);if($&&$.name!=="internal"&&Q.name==="internal")return;if(this.providers.set(A,Q),this.executionModes.set(A,w?.executionMode??"provider"),w?.publishResultIdField)this.publishResultIdFields.set(A,w.publishResultIdField);else this.publishResultIdFields.delete(A);if(w?.publishTimestampField)this.publishTimestampFields.set(A,w.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())}}async function d$2(A,Q){if(!Q.publishExecutor){Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:"Publish executor not configured",retryCount:0,willRetry:!1});return}await PPw(A,Q)}async function PPw(A,Q){if(!Q.publishExecutor)return;try{let w=await Q.publishExecutor.publish({entityType:A.entityType,id:A.entityId});if("error"in w){let $={entityType:A.entityType,entityId:A.entityId,error:w.error,retryCount:0,willRetry:!1};if(Q.messageBus)await Q.messageBus.send({type:FY.FAILED,payload:$,sender:"publish-service",broadcast:!0});Q.onFailed?.($);return}ne0(A.entityType,A.entityId,w.result,Q)}catch(w){let $=dA(w);Q.retryTracker.recordFailure(A.entityId,$);let B=Q.retryTracker.getRetryInfo(A.entityId);Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:$,retryCount:B?.retryCount??1,willRetry:!1})}}function ne0(A,Q,w,$){if($.retryTracker.clearRetries(Q),$.messageBus)$.messageBus.send({type:FY.COMPLETED,payload:{entityType:A,entityId:Q,result:w},sender:"publish-service",broadcast:!0});$.onPublish?.({entityType:A,entityId:Q,result:w})}function n$2(A,Q,w,$){$.retryTracker.recordFailure(Q,w);let B=$.retryTracker.getRetryInfo(Q),X={entityType:A,entityId:Q,error:w,retryCount:B?.retryCount??1,willRetry:!1};if($.messageBus)$.messageBus.send({type:FY.FAILED,payload:X,sender:"publish-service",broadcast:!0});$.onFailed?.(X)}async function r$2(A,Q){let w=Q.generationConditions[A];if(w&&Q.onCheckGenerationConditions){let B=await Q.onCheckGenerationConditions(A,w);if(!B.shouldGenerate){if(Q.messageBus)Q.messageBus.send({type:PL.SKIPPED,payload:{entityType:A,reason:B.reason??"Conditions not met"},sender:"content-pipeline"});return}}let $={entityType:A};if(Q.messageBus)await Q.messageBus.send({type:PL.EXECUTE,payload:$,sender:"content-pipeline"});Q.onGenerate?.($)}function o$2(A,Q,w){if(w)w.send({type:PL.COMPLETED,payload:{entityType:A,entityId:Q},sender:"content-pipeline"})}function s$2(A,Q,w){if(w)w.send({type:PL.FAILED,payload:{entityType:A,error:Q},sender:"content-pipeline"})}var MPw=1000;class re0{deps;publishJobs=new Map;immediateIntervalJob=null;constructor(A){this.deps=A}start(){for(let[A,Q]of Object.entries(this.entitySchedules)){let w=this.deps.config.backend.scheduleCron(Q,()=>this.processEntityType(A));this.publishJobs.set(A,w)}this.immediateIntervalJob=this.deps.config.backend.scheduleInterval(MPw,()=>this.processUnscheduledTypes())}stop(){if(OPw(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 w=await this.deps.config.queueManager.getNext(Q);if(w){await this.processEntry(w);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 d$2(A,Q)}get entitySchedules(){return this.deps.config.entitySchedules}}function OPw(A){for(let Q of A.values())Q.stop();A.clear()}class oe0{deps;generationJobs=new Map;constructor(A){this.deps=A}start(){for(let[A,Q]of Object.entries(this.generationSchedules)){let w=this.deps.config.backend.scheduleCron(Q,()=>this.handleTriggerGeneration(A));this.generationJobs.set(A,w)}}stop(){xPw(this.generationJobs)}async handleTriggerGeneration(A){if(!this.deps.isRunning())return;try{await r$2(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 xPw(A){for(let Q of A.values())Q.stop();A.clear()}class UG{static instance=null;config;publishRunner;generationRunner;running=!1;static getInstance(A){return UG.instance??=new UG(A),UG.instance}static resetInstance(){if(UG.instance)UG.instance.stop();UG.instance=null}static createFresh(A){return new UG(A)}constructor(A){this.config={...A,entitySchedules:A.entitySchedules??{},generationSchedules:A.generationSchedules??{},generationConditions:A.generationConditions??{}},this.validateCronExpressions(),this.publishRunner=new re0({config:this.config,getPublishDeps:()=>this.publishDeps,isRunning:()=>this.running}),this.generationRunner=new oe0({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,w){ne0(A,Q,w,this.publishDeps)}failPublish(A,Q,w){n$2(A,Q,w,this.publishDeps)}completeGeneration(A,Q){o$2(A,Q,this.config.messageBus)}failGeneration(A,Q){s$2(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,w){try{this.config.backend.validateCron(Q)}catch($){throw Error(`Invalid ${w} cron expression for ${A}: "${Q}" - ${dA($)}`,{cause:$})}}}class mq{static instance=null;retries=new Map;static getInstance(){return mq.instance??=new mq,mq.instance}static resetInstance(){mq.instance=null}static createFresh(){return new mq}constructor(){}recordFailure(A,Q){let $=(this.retries.get(A)?.retryCount??0)+1;this.retries.set(A,{entityId:A,retryCount:$,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 wa(A){return Date.UTC(A.y,A.m-1,A.d,A.h,A.i,A.s)}function se0(A,Q){return A.y===Q.y&&A.m===Q.m&&A.d===Q.d&&A.h===Q.h&&A.i===Q.i&&A.s===Q.s}function RPw(A,Q){let w=new Date(Date.parse(A));if(isNaN(w))throw Error("Invalid ISO8601 passed to timezone parser.");let $=A.substring(9);return $.includes("Z")||$.includes("+")||$.includes("-")?te0(w.getUTCFullYear(),w.getUTCMonth()+1,w.getUTCDate(),w.getUTCHours(),w.getUTCMinutes(),w.getUTCSeconds(),"Etc/UTC"):te0(w.getFullYear(),w.getMonth()+1,w.getDate(),w.getHours(),w.getMinutes(),w.getSeconds(),Q)}function a$2(A,Q,w){return A82(RPw(A,Q),w)}function A82(A,Q){let w=new Date(wa(A)),$=$a(w,A.tz),B=wa(A),X=wa($),Y=B-X,Z=new Date(w.getTime()+Y),H=$a(Z,A.tz);if(se0(H,A)){let U=new Date(Z.getTime()-3600000),G=$a(U,A.tz);return se0(G,A)?U:Z}let W=new Date(Z.getTime()+wa(A)-wa(H)),K=$a(W,A.tz);if(se0(K,A))return W;if(Q)throw Error("Invalid date passed to fromTZ()");return Z.getTime()>W.getTime()?Z:W}function $a(A,Q){let w,$;try{w=new Intl.DateTimeFormat("en-US",{timeZone:Q,year:"numeric",month:"numeric",day:"numeric",hour:"numeric",minute:"numeric",second:"numeric",hour12:!1}),$=w.formatToParts(A)}catch(X){let Y=X instanceof Error?X.message:String(X);throw RangeError(`toTZ: Invalid timezone '${Q}' or date. Please provide a valid IANA timezone (e.g., 'America/New_York', 'Europe/Stockholm'). Original error: ${Y}`)}let B={year:0,month:0,day:0,hour:0,minute:0,second:0};for(let X of $)(X.type==="year"||X.type==="month"||X.type==="day"||X.type==="hour"||X.type==="minute"||X.type==="second")&&(B[X.type]=parseInt(X.value,10));if(isNaN(B.year)||isNaN(B.month)||isNaN(B.day)||isNaN(B.hour)||isNaN(B.minute)||isNaN(B.second))throw Error(`toTZ: Failed to parse all date components from timezone '${Q}'. This may indicate an invalid date or timezone configuration. Parsed components: ${JSON.stringify(B)}`);return B.hour===24&&(B.hour=0),{y:B.year,m:B.month,d:B.day,h:B.hour,i:B.minute,s:B.second,tz:Q}}function te0(A,Q,w,$,B,X,Y){return{y:A,m:Q,d:w,h:$,i:B,s:X,tz:Y}}var Q82=[1,2,4,8,16],t$2=class{pattern;timezone;mode;alternativeWeekdays;sloppyRanges;second;minute;hour;day;month;dayOfWeek;year;lastDayOfMonth;lastWeekday;nearestWeekdays;starDOM;starDOW;starYear;useAndLogic;constructor(A,Q,w){this.pattern=A,this.timezone=Q,this.mode=w?.mode??"auto",this.alternativeWeekdays=w?.alternativeWeekdays??!1,this.sloppyRanges=w?.sloppyRanges??!1,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.year=Array(1e4).fill(0),this.lastDayOfMonth=!1,this.lastWeekday=!1,this.nearestWeekdays=Array(31).fill(0),this.starDOM=!1,this.starDOW=!1,this.starYear=!1,this.useAndLogic=!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.match(/\S+/g)||[""],Q=A.length;if(A.length<5||A.length>7)throw TypeError("CronPattern: invalid configuration format ('"+this.pattern+"'), exactly five, six, or seven space separated parts are required.");if(this.mode!=="auto"){let $;switch(this.mode){case"5-part":$=5;break;case"6-part":$=6;break;case"7-part":$=7;break;case"5-or-6-parts":$=[5,6];break;case"6-or-7-parts":$=[6,7];break;default:$=0}if(!(Array.isArray($)?$.includes(Q):Q===$)){let B=Array.isArray($)?$.join(" or "):$.toString();throw TypeError(`CronPattern: mode '${this.mode}' requires exactly ${B} parts, but pattern '${this.pattern}' has ${Q} parts.`)}}if(A.length===5&&A.unshift("0"),A.length===6&&A.push("*"),A[3].toUpperCase()==="LW"?(this.lastWeekday=!0,A[3]=""):A[3].toUpperCase().indexOf("L")>=0&&(A[3]=A[3].replace(/L/gi,""),this.lastDayOfMonth=!0),A[3]=="*"&&(this.starDOM=!0),A[6]=="*"&&(this.starYear=!0),A[4].length>=3&&(A[4]=this.replaceAlphaMonths(A[4])),A[5].length>=3&&(A[5]=this.alternativeWeekdays?this.replaceAlphaDaysQuartz(A[5]):this.replaceAlphaDays(A[5])),A[5].startsWith("+")&&(this.useAndLogic=!0,A[5]=A[5].substring(1),A[5]===""))throw TypeError("CronPattern: Day-of-week field cannot be empty after '+' modifier.");switch(A[5]=="*"&&(this.starDOW=!0),this.pattern.indexOf("?")>=0&&(A[0]=A[0].replace(/\?/g,"*"),A[1]=A[1].replace(/\?/g,"*"),A[2]=A[2].replace(/\?/g,"*"),A[3]=A[3].replace(/\?/g,"*"),A[4]=A[4].replace(/\?/g,"*"),A[5]=A[5].replace(/\?/g,"*"),A[6]&&(A[6]=A[6].replace(/\?/g,"*"))),this.mode){case"5-part":A[0]="0",A[6]="*";break;case"6-part":A[6]="*";break;case"5-or-6-parts":A[6]="*";break;case"6-or-7-parts":break;case"7-part":case"auto":break}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);let w=this.alternativeWeekdays?-1:0;this.partToArray("dayOfWeek",A[5],w,63),this.partToArray("year",A[6],0,1),!this.alternativeWeekdays&&this.dayOfWeek[7]&&(this.dayOfWeek[0]=this.dayOfWeek[7])}partToArray(A,Q,w,$){let B=this[A],X=A==="day"&&this.lastDayOfMonth,Y=A==="day"&&this.lastWeekday;if(Q===""&&!X&&!Y)throw TypeError("CronPattern: configuration entry "+A+" ("+Q+") is empty, check for trailing spaces.");if(Q==="*")return B.fill($);let Z=Q.split(",");if(Z.length>1)for(let H=0;H<Z.length;H++)this.partToArray(A,Z[H],w,$);else Q.indexOf("-")!==-1&&Q.indexOf("/")!==-1?this.handleRangeWithStepping(Q,A,w,$):Q.indexOf("-")!==-1?this.handleRange(Q,A,w,$):Q.indexOf("/")!==-1?this.handleStepping(Q,A,w,$):Q!==""&&this.handleNumber(Q,A,w,$)}throwAtIllegalCharacters(A){for(let Q=0;Q<A.length;Q++)if((Q===3?/[^/*0-9,\-WwLl]+/:Q===5?/[^/*0-9,\-#Ll]+/:/[^/*0-9,\-]+/).test(A[Q]))throw TypeError("CronPattern: configuration entry "+Q+" ("+A[Q]+") contains illegal characters.")}handleNumber(A,Q,w,$){let B=this.extractNth(A,Q),X=A.toUpperCase().includes("W");if(Q!=="day"&&X)throw TypeError("CronPattern: Nearest weekday modifier (W) only allowed in day-of-month.");X&&(Q="nearestWeekdays");let Y=parseInt(B[0],10)+w;if(isNaN(Y))throw TypeError("CronPattern: "+Q+" is not a number: '"+A+"'");this.setPart(Q,Y,B[1]||$)}setPart(A,Q,w){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,w);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"||A==="nearestWeekdays"){if(Q<0||Q>=31)throw RangeError("CronPattern: Invalid value for "+A+": "+Q)}else if(A==="month"){if(Q<0||Q>=12)throw RangeError("CronPattern: Invalid value for "+A+": "+Q)}else if(A==="year"&&(Q<1||Q>=1e4))throw RangeError("CronPattern: Invalid value for "+A+": "+Q+" (supported range: 1-9999)");this[A][Q]=w}validateNotNaN(A,Q){if(isNaN(A))throw TypeError(Q)}validateRange(A,Q,w,$,B){if(A>Q)throw TypeError("CronPattern: From value is larger than to value: '"+B+"'");if(w!==void 0){if(w===0)throw TypeError("CronPattern: Syntax error, illegal stepping: 0");if(w>this[$].length)throw TypeError("CronPattern: Syntax error, steps cannot be greater than maximum value of part ("+this[$].length+")")}}handleRangeWithStepping(A,Q,w,$){if(A.toUpperCase().includes("W"))throw TypeError("CronPattern: Syntax error, W is not allowed in ranges with stepping.");let B=this.extractNth(A,Q),X=B[0].match(/^(\d+)-(\d+)\/(\d+)$/);if(X===null)throw TypeError("CronPattern: Syntax error, illegal range with stepping: '"+A+"'");let[,Y,Z,H]=X,W=parseInt(Y,10)+w,K=parseInt(Z,10)+w,U=parseInt(H,10);this.validateNotNaN(W,"CronPattern: Syntax error, illegal lower range (NaN)"),this.validateNotNaN(K,"CronPattern: Syntax error, illegal upper range (NaN)"),this.validateNotNaN(U,"CronPattern: Syntax error, illegal stepping: (NaN)"),this.validateRange(W,K,U,Q,A);for(let G=W;G<=K;G+=U)this.setPart(Q,G,B[1]||$)}extractNth(A,Q){let w=A,$;if(w.includes("#")){if(Q!=="dayOfWeek")throw Error("CronPattern: nth (#) only allowed in day-of-week field");$=w.split("#")[1],w=w.split("#")[0]}else if(w.toUpperCase().endsWith("L")){if(Q!=="dayOfWeek")throw Error("CronPattern: L modifier only allowed in day-of-week field (use L alone for day-of-month)");$="L",w=w.slice(0,-1)}return[w,$]}handleRange(A,Q,w,$){if(A.toUpperCase().includes("W"))throw TypeError("CronPattern: Syntax error, W is not allowed in a range.");let B=this.extractNth(A,Q),X=B[0].split("-");if(X.length!==2)throw TypeError("CronPattern: Syntax error, illegal range: '"+A+"'");let Y=parseInt(X[0],10)+w,Z=parseInt(X[1],10)+w;this.validateNotNaN(Y,"CronPattern: Syntax error, illegal lower range (NaN)"),this.validateNotNaN(Z,"CronPattern: Syntax error, illegal upper range (NaN)"),this.validateRange(Y,Z,void 0,Q,A);for(let H=Y;H<=Z;H++)this.setPart(Q,H,B[1]||$)}handleStepping(A,Q,w,$){if(A.toUpperCase().includes("W"))throw TypeError("CronPattern: Syntax error, W is not allowed in parts with stepping.");let B=this.extractNth(A,Q),X=B[0].split("/");if(X.length!==2)throw TypeError("CronPattern: Syntax error, illegal stepping: '"+A+"'");if(this.sloppyRanges)X[0]===""&&(X[0]="*");else{if(X[0]==="")throw TypeError("CronPattern: Syntax error, stepping with missing prefix ('"+A+"') is not allowed. Use wildcard (*/step) or range (min-max/step) instead.");if(X[0]!=="*")throw TypeError("CronPattern: Syntax error, stepping with numeric prefix ('"+A+"') is not allowed. Use wildcard (*/step) or range (min-max/step) instead.")}let Y=0;X[0]!=="*"&&(Y=parseInt(X[0],10)+w);let Z=parseInt(X[1],10);this.validateNotNaN(Z,"CronPattern: Syntax error, illegal stepping: (NaN)"),this.validateRange(0,this[Q].length-1,Z,Q,A);for(let H=Y;H<this[Q].length;H+=Z)this.setPart(Q,H,B[1]||$)}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")}replaceAlphaDaysQuartz(A){return A.replace(/sun/gi,"1").replace(/mon/gi,"2").replace(/tue/gi,"3").replace(/wed/gi,"4").replace(/thu/gi,"5").replace(/fri/gi,"6").replace(/sat/gi,"7")}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();if(Q==="@yearly"||Q==="@annually")return"0 0 1 1 *";if(Q==="@monthly")return"0 0 1 * *";if(Q==="@weekly")return"0 0 * * 0";if(Q==="@daily"||Q==="@midnight")return"0 0 * * *";if(Q==="@hourly")return"0 * * * *";if(Q==="@reboot")throw TypeError("CronPattern: @reboot is not supported in this environment. This is an event-based trigger that requires system startup detection.");return A}setNthWeekdayOfMonth(A,Q){if(typeof Q!="number"&&Q.toUpperCase()==="L")this.dayOfWeek[A]=this.dayOfWeek[A]|32;else if(Q===63)this.dayOfWeek[A]=63;else if(Q<6&&Q>0)this.dayOfWeek[A]=this.dayOfWeek[A]|Q82[Q-1];else throw TypeError(`CronPattern: nth weekday out of range, should be 1-5 or L. Value: ${Q}, Type: ${typeof Q}`)}},ae0=[31,28,31,30,31,30,31,31,30,31,30,31],h8=[["month","year",0],["day","month",-1],["hour","day",0],["minute","hour",0],["second","minute",0]],D4=class A{tz;ms;second;minute;hour;day;month;year;constructor(Q,w){if(this.tz=w,Q&&Q instanceof Date)if(!isNaN(Q))this.fromDate(Q);else throw TypeError("CronDate: Invalid date passed to CronDate constructor");else if(Q==null)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")}getLastDayOfMonth(Q,w){return w!==1?ae0[w]:new Date(Date.UTC(Q,w+1,0)).getUTCDate()}getLastWeekday(Q,w){let $=this.getLastDayOfMonth(Q,w),B=new Date(Date.UTC(Q,w,$)).getUTCDay();return B===0?$-2:B===6?$-1:$}getNearestWeekday(Q,w,$){let B=this.getLastDayOfMonth(Q,w);if($>B)return-1;let X=new Date(Date.UTC(Q,w,$)).getUTCDay();return X===0?$===B?$-2:$+1:X===6?$===1?$+2:$-1:$}isNthWeekdayOfMonth(Q,w,$,B){let X=new Date(Date.UTC(Q,w,$)).getUTCDay(),Y=0;for(let Z=1;Z<=$;Z++)new Date(Date.UTC(Q,w,Z)).getUTCDay()===X&&Y++;if(B&63&&Q82[Y-1]&B)return!0;if(B&32){let Z=this.getLastDayOfMonth(Q,w);for(let H=$+1;H<=Z;H++)if(new Date(Date.UTC(Q,w,H)).getUTCDay()===X)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 try{let w=$a(Q,this.tz);this.ms=Q.getMilliseconds(),this.second=w.s,this.minute=w.i,this.hour=w.h,this.day=w.d,this.month=w.m-1,this.year=w.y}catch(w){let $=w instanceof Error?w.message:String(w);throw TypeError(`CronDate: Failed to convert date to timezone '${this.tz}'. This may happen with invalid timezone names or dates. Original error: ${$}`)}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.month<0||this.day>ae0[this.month]||this.day<1||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 w=a$2(Q);this.ms=w.getUTCMilliseconds(),this.second=w.getUTCSeconds(),this.minute=w.getUTCMinutes(),this.hour=w.getUTCHours(),this.day=w.getUTCDate(),this.month=w.getUTCMonth(),this.year=w.getUTCFullYear(),this.apply()}else return this.fromDate(a$2(Q,this.tz))}findNext(Q,w,$,B){return this._findMatch(Q,w,$,B,1)}_findMatch(Q,w,$,B,X){let Y=this[w],Z;$.lastDayOfMonth&&(Z=this.getLastDayOfMonth(this.year,this.month));let H=!$.starDOW&&w=="day"?new Date(Date.UTC(this.year,this.month,1,0,0,0,0)).getUTCDay():void 0,W=this[w]+B,K=X===1?(U)=>U<$[w].length:(U)=>U>=0;for(let U=W;K(U);U+=X){let G=$[w][U];if(w==="day"&&!G){for(let q=0;q<$.nearestWeekdays.length;q++)if($.nearestWeekdays[q]){let V=this.getNearestWeekday(this.year,this.month,q-B);if(V===-1)continue;if(V===U-B){G=1;break}}}if(w==="day"&&$.lastWeekday){let q=this.getLastWeekday(this.year,this.month);U-B===q&&(G=1)}if(w==="day"&&$.lastDayOfMonth&&U-B==Z&&(G=1),w==="day"&&!$.starDOW){let q=$.dayOfWeek[(H+(U-B-1))%7];if(q&&q&63)q=this.isNthWeekdayOfMonth(this.year,this.month,U-B,q)?1:0;else if(q)throw Error(`CronDate: Invalid value for dayOfWeek encountered. ${q}`);$.useAndLogic?G=G&&q:!Q.domAndDow&&!$.starDOM?G=G||q:G=G&&q}if(G)return this[w]=U-B,Y!==this[w]?2:1}return 3}recurse(Q,w,$){if($===0&&!Q.starYear){if(this.year>=0&&this.year<Q.year.length&&Q.year[this.year]===0){let X=-1;for(let Y=this.year+1;Y<Q.year.length&&Y<1e4;Y++)if(Q.year[Y]===1){X=Y;break}if(X===-1)return null;this.year=X,this.month=0,this.day=1,this.hour=0,this.minute=0,this.second=0,this.ms=0}if(this.year>=1e4)return null}let B=this.findNext(w,h8[$][0],Q,h8[$][2]);if(B>1){let X=$+1;for(;X<h8.length;)this[h8[X][0]]=-h8[X][2],X++;if(B===3){if(this[h8[$][1]]++,this[h8[$][0]]=-h8[$][2],this.apply(),$===0&&!Q.starYear){for(;this.year>=0&&this.year<Q.year.length&&Q.year[this.year]===0&&this.year<1e4;)this.year++;if(this.year>=1e4||this.year>=Q.year.length)return null}return this.recurse(Q,w,0)}else if(this.apply())return this.recurse(Q,w,$-1)}return $+=1,$>=h8.length?this:(Q.starYear?this.year>=3000:this.year>=1e4)?null:this.recurse(Q,w,$)}increment(Q,w,$){return this.second+=w.interval!==void 0&&w.interval>1&&$?w.interval:1,this.ms=0,this.apply(),this.recurse(Q,w,0)}decrement(Q,w){return this.second-=w.interval!==void 0&&w.interval>1?w.interval:1,this.ms=0,this.apply(),this.recurseBackward(Q,w,0,0)}recurseBackward(Q,w,$,B=0){if(B>1e4)return null;if($===0&&!Q.starYear){if(this.year>=0&&this.year<Q.year.length&&Q.year[this.year]===0){let Y=-1;for(let Z=this.year-1;Z>=0;Z--)if(Q.year[Z]===1){Y=Z;break}if(Y===-1)return null;this.year=Y,this.month=11,this.day=31,this.hour=23,this.minute=59,this.second=59,this.ms=0}if(this.year<0)return null}let X=this.findPrevious(w,h8[$][0],Q,h8[$][2]);if(X>1){let Y=$+1;for(;Y<h8.length;){let Z=h8[Y][0],H=h8[Y][2],W=this.getMaxPatternValue(Z,Q,H);this[Z]=W,Y++}if(X===3){if(this[h8[$][1]]--,$===0){let K=this.getLastDayOfMonth(this.year,this.month);this.day>K&&(this.day=K)}if($===1)if(this.day<=0)this.day=1;else{let K=this.year,U=this.month;for(;U<0;)U+=12,K--;for(;U>11;)U-=12,K++;let G=U!==1?ae0[U]:new Date(Date.UTC(K,U+1,0)).getUTCDate();this.day>G&&(this.day=G)}this.apply();let Z=h8[$][0],H=h8[$][2],W=this.getMaxPatternValue(Z,Q,H);if(Z==="day"){let K=this.getLastDayOfMonth(this.year,this.month);this[Z]=Math.min(W,K)}else this[Z]=W;if(this.apply(),$===0){let K=h8[1][2],U=this.getMaxPatternValue("day",Q,K),G=this.getLastDayOfMonth(this.year,this.month),q=Math.min(U,G);q!==this.day&&(this.day=q,this.hour=this.getMaxPatternValue("hour",Q,h8[2][2]),this.minute=this.getMaxPatternValue("minute",Q,h8[3][2]),this.second=this.getMaxPatternValue("second",Q,h8[4][2]))}if($===0&&!Q.starYear){for(;this.year>=0&&this.year<Q.year.length&&Q.year[this.year]===0;)this.year--;if(this.year<0)return null}return this.recurseBackward(Q,w,0,B+1)}else if(this.apply())return this.recurseBackward(Q,w,$-1,B+1)}return $+=1,$>=h8.length?this:this.year<0?null:this.recurseBackward(Q,w,$,B+1)}getMaxPatternValue(Q,w,$){if(Q==="day"&&w.lastDayOfMonth)return this.getLastDayOfMonth(this.year,this.month);if(Q==="day"&&!w.starDOW)return this.getLastDayOfMonth(this.year,this.month);for(let B=w[Q].length-1;B>=0;B--)if(w[Q][B])return B-$;return w[Q].length-1-$}findPrevious(Q,w,$,B){return this._findMatch(Q,w,$,B,-1)}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)):A82(te0(this.year,this.month+1,this.day,this.hour,this.minute,this.second,this.tz),!1)}getTime(){return this.getDate(!1).getTime()}match(Q,w){if(!Q.starYear&&(this.year<0||this.year>=Q.year.length||Q.year[this.year]===0))return!1;for(let $=0;$<h8.length;$++){let B=h8[$][0],X=h8[$][2],Y=this[B];if(Y+X<0||Y+X>=Q[B].length)return!1;let Z=Q[B][Y+X];if(B==="day"){if(!Z){for(let H=0;H<Q.nearestWeekdays.length;H++)if(Q.nearestWeekdays[H]){let W=this.getNearestWeekday(this.year,this.month,H-X);if(W!==-1&&W===Y){Z=1;break}}}if(Q.lastWeekday){let H=this.getLastWeekday(this.year,this.month);Y===H&&(Z=1)}if(Q.lastDayOfMonth){let H=this.getLastDayOfMonth(this.year,this.month);Y===H&&(Z=1)}if(!Q.starDOW){let H=new Date(Date.UTC(this.year,this.month,1,0,0,0,0)).getUTCDay(),W=Q.dayOfWeek[(H+(Y-1))%7];W&&W&63&&(W=this.isNthWeekdayOfMonth(this.year,this.month,Y,W)?1:0),Q.useAndLogic?Z=Z&&W:!w.domAndDow&&!Q.starDOM?Z=Z||W:Z=Z&&W}}if(!Z)return!1}return!0}};function vPw(A){if(A===void 0&&(A={}),delete A.name,A.legacyMode!==void 0&&A.domAndDow===void 0?A.domAndDow=!A.legacyMode:A.domAndDow===void 0&&(A.domAndDow=!1),A.legacyMode=!A.domAndDow,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.dayOffset=A.dayOffset===void 0?0:parseInt(A.dayOffset.toString(),10),A.unref=A.unref===void 0?!1:A.unref,A.mode=A.mode===void 0?"auto":A.mode,A.alternativeWeekdays=A.alternativeWeekdays===void 0?!1:A.alternativeWeekdays,A.sloppyRanges=A.sloppyRanges===void 0?!1:A.sloppyRanges,!["auto","5-part","6-part","7-part","5-or-6-parts","6-or-7-parts"].includes(A.mode))throw Error("CronOptions: mode must be one of 'auto', '5-part', '6-part', '7-part', '5-or-6-parts', or '6-or-7-parts'.");if(A.startAt&&(A.startAt=new D4(A.startAt,A.timezone)),A.stopAt&&(A.stopAt=new D4(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).");if(A.dayOffset!==void 0&&A.dayOffset!==0&&isNaN(A.dayOffset))throw Error("CronOptions: Invalid value passed for dayOffset, should be a number representing days to offset.");return A}function Ba(A){return Object.prototype.toString.call(A)==="[object Function]"||typeof A=="function"||A instanceof Function}function hPw(A){return Ba(A)}function CPw(A){typeof Deno<"u"&&typeof Deno.unrefTimer<"u"?Deno.unrefTimer(A):A&&typeof A.unref<"u"&&A.unref()}var e$2=30000,zH0=[],ee0=class{name;options;_states;fn;getTz(){return this.options.timezone||this.options.utcOffset}applyDayOffset(A){if(this.options.dayOffset!==void 0&&this.options.dayOffset!==0){let Q=this.options.dayOffset*24*60*60*1000;return new Date(A.getTime()+Q)}return A}constructor(A,Q,w){let $,B;if(Ba(Q))B=Q;else if(typeof Q=="object")$=Q;else if(Q!==void 0)throw Error("Cron: Invalid argument passed for optionsIn. Should be one of function, or object (options).");if(Ba(w))B=w;else if(typeof w=="object")$=w;else if(w!==void 0)throw Error("Cron: Invalid argument passed for funcIn. Should be one of function, or object (options).");if(this.name=$?.name,this.options=vPw($),this._states={kill:!1,blocking:!1,previousRun:void 0,currentRun:void 0,once:void 0,currentTimeout:void 0,maxRuns:$?$.maxRuns:void 0,paused:$?$.paused:!1,pattern:new t$2("* * * * *",void 0,{mode:"auto"})},A&&(A instanceof Date||typeof A=="string"&&A.indexOf(":")>0)?this._states.once=new D4(A,this.getTz()):this._states.pattern=new t$2(A,this.options.timezone,{mode:this.options.mode,alternativeWeekdays:this.options.alternativeWeekdays,sloppyRanges:this.options.sloppyRanges}),this.name){if(zH0.find((X)=>X.name===this.name))throw Error("Cron: Tried to initialize new named job '"+this.name+"', but name already taken.");zH0.push(this)}return B!==void 0&&hPw(B)&&(this.fn=B,this.schedule()),this}nextRun(A){let Q=this._next(A);return Q?this.applyDayOffset(Q.getDate(!1)):null}nextRuns(A,Q){this._states.maxRuns!==void 0&&A>this._states.maxRuns&&(A=this._states.maxRuns);let w=Q||this._states.currentRun||void 0;return this._enumerateRuns(A,w,"next")}previousRuns(A,Q){return this._enumerateRuns(A,Q||void 0,"previous")}_enumerateRuns(A,Q,w){let $=[],B=Q?new D4(Q,this.getTz()):null,X=w==="next"?this._next:this._previous;for(;A--;){let Y=X.call(this,B);if(!Y)break;let Z=Y.getDate(!1);$.push(this.applyDayOffset(Z)),B=Y}return $}match(A){if(this._states.once){let w=new D4(A,this.getTz());w.ms=0;let $=new D4(this._states.once,this.getTz());return $.ms=0,w.getTime()===$.getTime()}let Q=new D4(A,this.getTz());return Q.ms=0,Q.match(this._states.pattern,this.options)}getPattern(){if(!this._states.once)return this._states.pattern?this._states.pattern.pattern:void 0}getOnce(){return this._states.once?this._states.once.getDate():null}isRunning(){let A=this.nextRun(this._states.currentRun),Q=!this._states.paused,w=this.fn!==void 0,$=!this._states.kill;return Q&&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 D4||A instanceof Date?Q.getTime()-A.getTime():Q.getTime()-new D4(A).getTime():null}stop(){this._states.kill=!0,this._states.currentTimeout&&clearTimeout(this._states.currentTimeout);let A=zH0.indexOf(this);A>=0&&zH0.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(),w=this.nextRun(this._states.currentRun);return Q==null||isNaN(Q)||w===null?this:(Q>e$2&&(Q=e$2),this._states.currentTimeout=setTimeout(()=>this._checkTrigger(w),Q),this._states.currentTimeout&&this.options.unref&&CPw(this._states.currentTimeout),this)}async _trigger(A){this._states.blocking=!0,this._states.currentRun=new D4(void 0,this.getTz());try{if(this.options.catch)try{this.fn!==void 0&&await this.fn(this,this.options.context)}catch(Q){if(Ba(this.options.catch))try{this.options.catch(Q,this)}catch{}}else this.fn!==void 0&&await this.fn(this,this.options.context)}finally{this._states.previousRun=new D4(A,this.getTz()),this._states.blocking=!1}}async trigger(){await this._trigger()}runsLeft(){return this._states.maxRuns}_checkTrigger(A){let Q=new Date,w=!this._states.paused&&Q.getTime()>=A.getTime(),$=this._states.blocking&&this.options.protect;w&&!$?(this._states.maxRuns!==void 0&&this._states.maxRuns--,this._trigger()):w&&$&&Ba(this.options.protect)&&setTimeout(()=>this.options.protect(this),0),this.schedule()}_next(A){let Q=!!(A||this._states.currentRun),w=!1;!A&&this.options.startAt&&this.options.interval&&([A,Q]=this._calculatePreviousRun(A,Q),w=!A),A=new D4(A,this.getTz()),this.options.startAt&&A&&A.getTime()<this.options.startAt.getTime()&&(A=this.options.startAt);let $=this._states.once||new D4(A,this.getTz());return!w&&$!==this._states.once&&($=$.increment(this._states.pattern,this.options,Q)),this._states.once&&this._states.once.getTime()<=A.getTime()||$===null||this._states.maxRuns!==void 0&&this._states.maxRuns<=0||this._states.kill||this.options.stopAt&&$.getTime()>=this.options.stopAt.getTime()?null:$}_previous(A){let Q=new D4(A,this.getTz());this.options.stopAt&&Q.getTime()>this.options.stopAt.getTime()&&(Q=this.options.stopAt);let w=new D4(Q,this.getTz());return this._states.once?this._states.once.getTime()<Q.getTime()?this._states.once:null:(w=w.decrement(this._states.pattern,this.options),w===null||this.options.startAt&&w.getTime()<this.options.startAt.getTime()?null:w)}_calculatePreviousRun(A,Q){let w=new D4(void 0,this.getTz()),$=A;if(this.options.startAt.getTime()<=w.getTime()){$=this.options.startAt;let B=$.getTime()+this.options.interval*1000;for(;B<=w.getTime();)$=new D4($,this.getTz()).increment(this._states.pattern,this.options,!0),B=$.getTime()+this.options.interval*1000;Q=!0}return $===null&&($=void 0),[$,Q]}};class VH0{scheduleCron(A,Q){let w=new ee0(A,()=>{Q()});return{stop:()=>w.stop()}}scheduleInterval(A,Q){let w=setInterval(()=>{Q()},A);return{stop:()=>clearInterval(w)}}validateCron(A){new ee0(A).stop()}}C0();var w82=f.union([f.string().min(1),f.object({location:f.enum(["metadata","frontmatter"]),field:f.string().min(1)})]),JH0=f.object({entityType:f.string().min(1),attachmentType:f.string().min(1),mediaEntityType:f.enum(["image","document"]),targetEntityField:w82.optional(),requiredWhen:f.object({status:f.string().min(1).optional(),visibility:f.string().min(1).optional()}).optional(),autoGenerate:f.boolean().optional(),requiredForPublish:f.boolean().optional(),jobType:f.string().min(1).optional()});function A0A(A){return`${A.entityType}:${A.attachmentType}`}class uq{static instance=null;definitions=new Map;static getInstance(){return uq.instance??=new uq,uq.instance}static resetInstance(){uq.instance=null}static createFresh(){return new uq}constructor(){}register(A){let Q=JH0.parse(A),w=A0A(Q);return this.definitions.set(w,Q),()=>this.unregister(Q.entityType,Q.attachmentType)}get(A,Q){return this.definitions.get(A0A({entityType:A,attachmentType:Q}))}list(A){let Q=Array.from(this.definitions.values());return A?Q.filter((w)=>w.entityType===A):Q}has(A,Q){return this.get(A,Q)!==void 0}unregister(A,Q){this.definitions.delete(A0A({entityType:A,attachmentType:Q}))}clear(){this.definitions.clear()}}H7();b2();class IH0{deps;constructor(A){this.deps=A}async ensureForEntity(A,Q={}){let w=this.deps.registry.list(A.entityType).filter((B)=>B.autoGenerate===!0).filter((B)=>!Q.attachmentType||B.attachmentType===Q.attachmentType),$={checked:w.length,enqueued:0,skipped:0};for(let B of w)if(await this.ensureDefinition(A,B))$.enqueued+=1;else $.skipped+=1;return $}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 w=this.resolveJobType(Q);if(!w)return!1;let $=this.getPredictedMediaId(A,Q),B=this.getDeduplicationKey(A,Q);return await this.deps.context.jobs.enqueue({type:w,data:{sourceEntityType:A.entityType,sourceEntityId:A.id,attachmentType:Q.attachmentType,imageId:$,dedupKey:B,targetEntityType:A.entityType,targetEntityId:A.id,...this.getTargetImageFieldData(Q.targetEntityField)},options:{source:"content-pipeline",metadata:{operationType:"content_operations"},deduplication:"skip",deduplicationKey:B}}),this.deps.context.logger.debug("Queued publish asset generation",{entityType:A.entityType,entityId:A.id,attachmentType:Q.attachmentType,jobType:w}),!0}matchesPolicy(A,Q){let{requiredWhen:w}=Q;if(!w)return!0;if(w.status&&A.metadata.status!==w.status)return!1;if(w.visibility&&A.visibility!==w.visibility)return!1;return!0}hasTargetField(A,Q){if(!Q)return!1;if(typeof Q==="string")return Q0A(A.metadata[Q]);if(Q.location==="metadata")return Q0A(A.metadata[Q.field]);let{frontmatter:w}=l6(A.content);return Q0A(w[Q.field])}resolveJobType(A){if(A.jobType)return A.jobType;if(A.mediaEntityType==="image")return"image:image-render-source";return}getPredictedMediaId(A,Q){let w=Q.attachmentType==="og-image"?"og":Q.attachmentType;return q1(`${w}-${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 Q0A(A){return typeof A==="string"?A.length>0:A!==void 0}fA();C0();var gPw=f.object({id:f.string().min(1)});async function B82(A,Q){let{bodyContent:w,coverImageId:$,documents:B,sourceEntityType:X,sourceEntityId:Y}=yPw(Q.content),Z=$?await SPw(A,$):void 0,H;if(B&&B.length>0){let K=await mPw(A,B);if(K.length>0)H=K}H??=await TPw(A,X,Y);let W={bodyContent:w};if(Z)W.imageData=Z;if(H&&H.length>0)W.documentData=H;return W}function yPw(A){try{let Q=$Q(A,f.record(f.string(),f.unknown())),w=Q.metadata.coverImageId,$=typeof w==="string"?w:void 0,B=EPw(Q.metadata.documents),X=$82(Q.metadata.sourceEntityType),Y=$82(Q.metadata.sourceEntityId);return{bodyContent:Q.content,...$&&{coverImageId:$},...B.length>0&&{documents:B},...X&&{sourceEntityType:X},...Y&&{sourceEntityId:Y}}}catch{return{bodyContent:A}}}function EPw(A){if(!Array.isArray(A))return[];return A.flatMap((Q)=>{let w=gPw.safeParse(Q);return w.success?[w.data]:[]})}function $82(A){return typeof A==="string"&&A.length>0?A:void 0}async function TPw(A,Q,w){if(!Q||!w)return;let $=await A.attachments.resolve({sourceEntityType:Q,sourceEntityId:w,attachmentType:"carousel"});return $?[$]:void 0}async function SPw(A,Q){let w=await A.entityService.getEntity({entityType:"image",id:Q});if(!w?.content)return;let $=X82(w.content);if(!$?.mimeType.startsWith("image/"))return;return{data:$.data,mimeType:$.mimeType}}async function mPw(A,Q){return(await Promise.all(Q.map(($)=>uPw(A,$)))).filter(($)=>$!==void 0)}async function uPw(A,Q){let w=await A.entityService.getEntity({entityType:"document",id:Q.id});if(!w?.content)return;let $=X82(w.content);if($?.mimeType!=="application/pdf")return;return{type:"document",data:$.data,mimeType:"application/pdf",filename:cPw(w,Q.id)}}function X82(A){let Q=A.match(/^data:([^;]+);base64,(.+)$/);if(!Q?.[1]||!Q[2])return;return{mimeType:Q[1],data:Buffer.from(Q[2],"base64")}}function cPw(A,Q){let w=A.metadata.filename;return typeof w==="string"&&w.length>0?w:`${Q}.pdf`}H7();var lPw=/^---\r?\n[\s\S]*?\r?\n---(?:\r?\n|$)/;async function w0A(A,Q,w,$={}){let B=$.publishTimestampField??"publishedAt",X=Q.metadata[B],Y=$.publishedAt??(typeof X==="string"?X:void 0)??new Date().toISOString(),Z={...Q.metadata,status:"published",[B]:Y,platformId:w.id,...pPw(w.id,$.publishResultIdField)},H={...Q,content:Y82(Q.content,Y,w.id,$.publishResultIdField,B),metadata:Z};return await A.entityService.updateEntity({entity:H}),H}function Y82(A,Q,w,$,B="publishedAt"){if(!lPw.test(A))return A;let X=E4(E4(A,"status","published"),B,Q);if(!w||!$)return X;return E4(X,$,w)}function pPw(A,Q){if(!Q||Q==="platformId")return{};return{[Q]:A}}class SE{deps;constructor(A){this.deps=A}async resolveCandidate(A){let{entityType:Q,id:w,slug:$}=A;if(!w&&!$)return{error:"Either 'id' or 'slug' must be provided"};let B=await this.findPublishableEntity(Q,w,$);if(!B)return{error:`Entity not found: ${Q}:${w??$}`};if(B.visibility!=="public")return{error:`Cannot publish ${Q}:${B.id} to a public provider because visibility is ${B.visibility}`};if(B.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:B}}async publish(A){let Q=await this.resolveCandidate(A);if("error"in Q)return Q;let{entity:w}=Q,{entityType:$}=A,B=this.deps.providerRegistry.get($),{bodyContent:X,imageData:Y,documentData:Z}=await B82(this.deps.context,w),H=await B.publish(X,w.metadata,Y,Z),W=this.deps.providerRegistry.getPublishResultIdField($),K=this.deps.providerRegistry.getPublishTimestampField($),U=await w0A(this.deps.context,w,H,{...W?{publishResultIdField:W}:{},...K?{publishTimestampField:K}:{}});return await this.runPublishAssetPreflight(U),{entity:U,result:H}}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,w){if(Q)return this.deps.context.entityService.getEntity({entityType:A,id:Q});if(!w)return null;return(await this.deps.context.entityService.listEntities({entityType:A,options:{filter:{metadata:{slug:w}},limit:1}}))[0]??null}}fA();C0();var $0A=f.object({action:f.enum(["list","add","remove","reorder"]).describe("Queue action to perform"),entityType:f.string().optional().describe("Entity type (required for add/remove/reorder, optional for list)"),entityId:f.string().optional().describe("Entity ID (required for add/remove/reorder)"),position:f.number().optional().describe("New position for reorder action (1-based)")}),B0A=f.object({position:f.number(),entityType:f.string(),entityId:f.string(),queuedAt:f.string()}),iPw=f.object({success:f.literal(!0),message:f.string().optional(),data:f.object({queue:f.array(B0A).optional(),entityType:f.string().optional(),entityId:f.string().optional(),position:f.number().optional()}).optional()}),dPw=f.object({success:f.literal(!1),error:f.string(),code:f.string().optional()}),X0A=f.union([iPw,dPw]);function FH0(A,Q,w){return{...p6(Q,"queue","Manage the publish queue for all entity types (list, add, remove, reorder)",$0A,async(B,X)=>{let{action:Y,entityType:Z,entityId:H,position:W}=B;switch(Y){case"list":return nPw(w,Z);case"add":return rPw(A,w,Z,H,X);case"remove":return oPw(A,w,Z,H,X);case"reorder":return sPw(A,w,Z,H,W,X);default:return{success:!1,error:`Unknown action: ${Y}`}}},{sideEffects:"writes"}),outputSchema:X0A}}async function nPw(A,Q){let w=[];if(Q)w=await A.list(Q);else{let B=A.getRegisteredTypes();for(let X of B){let Y=await A.list(X);w.push(...Y)}w.sort((X,Y)=>new Date(X.queuedAt).getTime()-new Date(Y.queuedAt).getTime())}if(w.length===0)return{success:!0,data:{queue:[]},message:"No items in queue"};return{success:!0,data:{queue:w.map((B,X)=>({position:X+1,entityType:B.entityType,entityId:B.entityId,queuedAt:B.queuedAt}))},message:`${w.length} items in queue`}}async function rPw(A,Q,w,$,B){let X=Y0A("add",w,$);if(!X.success)return X.error;A.permissions.assertEntityActionAllowed(X.entityType,"publish",B??{});let Y=await Q.add(X.entityType,X.entityId,{...B,authorization:"user"});return{success:!0,data:{entityType:X.entityType,entityId:X.entityId,position:Y.position},message:`Added to queue at position ${Y.position}`}}async function oPw(A,Q,w,$,B){let X=Y0A("remove",w,$);if(!X.success)return X.error;return A.permissions.assertEntityActionAllowed(X.entityType,"update",B??{}),await Q.remove(X.entityType,X.entityId),{success:!0,data:{entityType:X.entityType,entityId:X.entityId},message:"Removed from queue"}}async function sPw(A,Q,w,$,B,X){let Y=Y0A("reorder",w,$);if(!Y.success)return Y.error;let Z=aPw(B);if(!Z.success)return Z.error;return A.permissions.assertEntityActionAllowed(Y.entityType,"update",X??{}),await Q.reorder(Y.entityType,Y.entityId,Z.position),{success:!0,data:{entityType:Y.entityType,entityId:Y.entityId,position:Z.position},message:`Moved to position ${Z.position}`}}function Y0A(A,Q,w){if(!Q)return{success:!1,error:{success:!1,error:`entityType is required for ${A} action`}};if(!w)return{success:!1,error:{success:!1,error:`entityId is required for ${A} action`}};return{success:!0,entityType:Q,entityId:w}}function aPw(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}}C0();import{createHash as tPw}from"crypto";var Z0A=f.object({entityType:f.string().describe("Entity type to publish (e.g., social-post, post, deck)"),id:f.string().optional().describe("Entity ID to publish"),slug:f.string().optional().describe("Entity slug to publish"),confirmed:f.boolean().optional(),confirmationToken:f.string().optional(),contentHash:f.string().optional(),expiresAt:f.string().datetime().optional()}),ePw=f.object({entityType:f.string(),id:f.string().optional(),slug:f.string().optional(),confirmed:f.boolean().optional(),confirmationToken:f.string().optional(),contentHash:f.string().optional(),expiresAt:f.string().datetime().optional()}),AMw=f.object({success:f.literal(!0),message:f.string().optional(),data:f.object({entityType:f.string().optional(),entityId:f.string().optional(),platformId:f.string().optional(),url:f.string().optional()}).optional()}),QMw=f.object({success:f.literal(!1),error:f.string(),code:f.string().optional()}),wMw=f.object({success:f.literal(!1).optional(),error:f.string().optional(),needsConfirmation:f.literal(!0),toolName:f.string(),summary:f.string(),preview:f.string().optional(),args:f.unknown()}),f0A=f.union([AMw,QMw,wMw]),$Mw=900000;function bH0(A,Q,w,$){let B=$??new SE({context:A,providerRegistry:w}),X=`${Q}_publish`;return{name:X,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.). For follow-up requests like 'publish it now', use the entity just read, generated, or updated in the conversation, including a post just changed to draft.",inputSchema:Z0A.shape,outputSchema:f0A,visibility:"anchor",sideEffects:"external",handler:async(Y,Z)=>{let H=ePw.safeParse(Y);if(!H.success)return{success:!1,error:`Invalid input: ${H.error.issues.map((I)=>`${I.path.join(".")}: ${I.message}`).join(", ")}`};let W=H.data,{entityType:K,id:U,slug:G}=W;try{A.permissions.assertEntityActionAllowed(K,"publish",Z)}catch(I){return{success:!1,error:I instanceof Error?I.message:String(I)}}let q=await B.resolveCandidate({entityType:K,id:U,slug:G});if("error"in q)return{success:!1,error:q.error};let{entity:V}=q;if(W.confirmed){let I=XMw(X,W,V);if(I!==null)return I;let J;try{J=await B.publish({entityType:K,id:V.id})}catch(_){return{success:!1,error:_ instanceof Error?_.message:String(_)}}if("error"in J)return{success:!1,error:J.error};let{entity:k,result:j}=J;return{success:!0,data:{entityType:K,entityId:k.id,platformId:j.id,url:j.url},message:`Published ${K}:${k.id}`}}return BMw(X,W,V)}}}function BMw(A,Q,w){let $=new Date(Date.now()+$Mw).toISOString(),B=Z82(A,w,$),X=YMw(w);return{needsConfirmation:!0,toolName:A,summary:`Publish "${X}"?`,preview:`This will publish ${w.entityType}:${w.id} to its registered public publish provider.`,args:{...Q,id:w.id,slug:void 0,confirmed:!0,confirmationToken:B,contentHash:w.contentHash,expiresAt:$}}}function XMw(A,Q,w){let{confirmationToken:$,contentHash:B,expiresAt:X}=Q;if(!$||!X)return{success:!1,error:"Invalid publish confirmation token. Request confirmation again and retry with the returned confirmation args.",code:"INVALID_CONFIRMATION_TOKEN"};let Y=Date.parse(X);if(Number.isNaN(Y))return{success:!1,error:"Invalid publish confirmation expiry. Request confirmation again and retry with the returned confirmation args.",code:"INVALID_CONFIRMATION_TOKEN"};if(Y<=Date.now())return{success:!1,error:"Publish confirmation expired. Request confirmation again before publishing.",code:"EXPIRED_CONFIRMATION_TOKEN"};if(B&&B!==w.contentHash)return{success:!1,error:`Cannot publish ${w.entityType}:${w.id} because it changed after confirmation. Review it and try again.`};if($!==Z82(A,w,X))return{success:!1,error:"Invalid publish confirmation token. Request confirmation again and retry with the returned confirmation args.",code:"INVALID_CONFIRMATION_TOKEN"};return null}function Z82(A,Q,w){return tPw("sha256").update(A).update("\x00").update(Q.entityType).update("\x00").update(Q.id).update("\x00").update(Q.contentHash).update("\x00").update(w).digest("hex")}function YMw(A){let Q=A.metadata.title;if(typeof Q==="string"&&Q.length>0)return Q;let w=A.metadata.subject;if(typeof w==="string"&&w.length>0)return w;let $=A.metadata.slug;if(typeof $==="string"&&$.length>0)return $;return A.id}fA();C0();var H0A=f.object({entityType:f.string().min(1).describe("Entity type to reconcile"),status:f.string().min(1).optional().describe("Optional metadata status filter, e.g. published"),assetType:f.string().min(1).optional().describe("Optional attachment type filter, e.g. og-image")}),W0A=f.object({success:f.literal(!0),data:f.object({entityType:f.string(),assetType:f.string().optional(),checkedEntities:f.number(),checkedAssets:f.number(),enqueued:f.number(),skipped:f.number()}),message:f.string().optional()});function LH0(A,Q,w,$){return{...p6(Q,"ensure-assets","Reconcile configured publish assets for existing entities, queueing missing generated assets such as OG images.",H0A,async(X,Y)=>{if(A.permissions.assertEntityActionAllowed(X.entityType,"publish",Y),w.list(X.entityType).filter((G)=>G.autoGenerate===!0).filter((G)=>!X.assetType||G.attachmentType===X.assetType).length===0)return{success:!0,data:{entityType:X.entityType,...X.assetType&&{assetType:X.assetType},checkedEntities:0,checkedAssets:0,enqueued:0,skipped:0},message:`No publish assets configured for ${X.entityType}`};let H=await A.entityService.listEntities({entityType:X.entityType,options:{...X.status&&{filter:{metadata:{status:X.status}}}}}),W=0,K=0,U=0;for(let G of H){let q=await $.ensureForEntity(G,{...X.assetType&&{attachmentType:X.assetType}});W+=q.checked,K+=q.enqueued,U+=q.skipped}return{success:!0,data:{entityType:X.entityType,...X.assetType&&{assetType:X.assetType},checkedEntities:H.length,checkedAssets:W,enqueued:K,skipped:U},message:`Queued ${K} publish asset job(s)`}},{sideEffects:"writes"}),outputSchema:W0A}}fA();function f82(A,Q){ZMw(A,Q),fMw(A,Q),HMw(A,Q),WMw(A,Q)}function ZMw(A,Q){A.messaging.subscribe(FY.REGISTER,async(w)=>KMw(Q,w.payload)),A.messaging.subscribe(FY.QUEUE,async(w)=>qMw(A,Q,w.payload)),A.messaging.subscribe(FY.DIRECT,async(w)=>zMw(A,Q,w.payload)),A.messaging.subscribe(FY.REMOVE,async(w)=>VMw(Q,w.payload)),A.messaging.subscribe(FY.REORDER,async(w)=>JMw(Q,w.payload)),A.messaging.subscribe(FY.LIST,async(w)=>IMw(A,Q,w.payload)),A.messaging.subscribe(FY.REPORT_SUCCESS,async(w)=>FMw(Q,w.payload)),A.messaging.subscribe(FY.REPORT_FAILURE,async(w)=>bMw(Q,w.payload)),Q.logger.debug("Subscribed to publish messages")}function fMw(A,Q){A.messaging.subscribe(PL.REPORT_SUCCESS,async(w)=>LMw(Q,w.payload)),A.messaging.subscribe(PL.REPORT_FAILURE,async(w)=>kMw(Q,w.payload)),Q.logger.debug("Subscribed to generation messages")}function HMw(A,Q){A.messaging.subscribe(l$2.REGISTER,async(w)=>UMw(Q,w.payload)),Q.logger.debug("Subscribed to publish asset messages")}function WMw(A,Q){let w=async($)=>GMw(A,Q,$.payload);A.messaging.subscribe("entity:created",w),A.messaging.subscribe("entity:updated",w),Q.logger.debug("Subscribed to entity change messages for publish assets")}async function KMw(A,Q){let{entityType:w,provider:$,config:B}=Q;try{let X=B?p$2.safeParse(B):void 0;if(X&&!X.success)return A.logger.warn("Invalid publish provider config",{entityType:w,error:X.error.message}),{success:!1};if($)A.providerRegistry.register(w,$,X?.data),A.logger.info(`Registered provider for entity type: ${w}`,{providerName:$.name,executionMode:A.providerRegistry.getExecutionMode(w)});return{success:!0}}catch(X){let Y=dA(X);return A.logger.error(`Failed to register provider: ${Y}`),{success:!1}}}async function UMw(A,Q){let w=JH0.safeParse(Q);if(!w.success)return A.logger.warn("Invalid publish asset registration",{error:w.error.message}),{success:!1};return A.publishAssetRegistry.register(w.data),A.logger.info("Registered publish asset",{entityType:w.data.entityType,attachmentType:w.data.attachmentType,mediaEntityType:w.data.mediaEntityType}),{success:!0}}async function GMw(A,Q,w){try{if(Q.publishAssetRegistry.list(w.entityType).length===0)return{success:!0};let $=w.entity??await A.entityService.getEntity({entityType:w.entityType,id:w.entityId});if(!DMw($))return{success:!0};return await Q.publishAssetPreflight.ensureForEntity($),{success:!0}}catch($){return Q.logger.warn("Failed to run publish asset preflight for entity event",{entityType:w.entityType,entityId:w.entityId,error:dA($)}),{success:!1}}}function DMw(A){if(!A)return!1;let Q=c$2.safeParse(A.metadata);return Q.success&&Q.data.status==="published"}async function qMw(A,Q,w){let{entityType:$,entityId:B}=w;try{let X=w.authContext??Qa;A.permissions.assertEntityActionAllowed($,"publish",X);let Y=await Q.queueManager.add($,B,X);return await A.messaging.send({type:FY.QUEUED,payload:{entityType:$,entityId:B,position:Y.position}}),Q.logger.debug(`Entity queued: ${B}`,{entityType:$,position:Y.position}),{success:!0}}catch(X){let Y=dA(X);return Q.logger.error(`Failed to queue entity: ${Y}`),{success:!1}}}async function zMw(A,Q,w){let{entityType:$,entityId:B}=w,X=w.authContext??Qa;try{if(A.permissions.assertEntityActionAllowed($,"publish",X),!Q.providerRegistry.has($))return Q.scheduler.failPublish($,B,`No publish provider registered for ${$}`),{success:!1};let Y=await Q.publishExecutor.publish({entityType:$,id:B});if("error"in Y)return Q.scheduler.failPublish($,B,Y.error),{success:!1};return Q.scheduler.completePublish($,B,Y.result),Q.logger.debug(`Direct publish completed: ${B}`,{entityType:$}),{success:!0}}catch(Y){let Z=dA(Y);return Q.logger.error(`Failed direct publish request: ${Z}`),{success:!1}}}async function VMw(A,Q){let{entityType:w,entityId:$}=Q;try{return await A.queueManager.remove(w,$),A.logger.debug(`Entity removed from queue: ${$}`,{entityType:w}),{success:!0}}catch(B){let X=dA(B);return A.logger.error(`Failed to remove entity: ${X}`),{success:!1}}}async function JMw(A,Q){let{entityType:w,entityId:$,position:B}=Q;try{return await A.queueManager.reorder(w,$,B),A.logger.debug(`Entity reordered: ${$}`,{entityType:w,newPosition:B}),{success:!0}}catch(X){let Y=dA(X);return A.logger.error(`Failed to reorder entity: ${Y}`),{success:!1}}}async function IMw(A,Q,w){let{entityType:$}=w;try{let B=await Q.queueManager.list($);return await A.messaging.send({type:FY.LIST_RESPONSE,payload:{entityType:$,queue:B.map((X)=>({entityId:X.entityId,position:X.position,queuedAt:X.queuedAt}))}}),{success:!0}}catch(B){let X=dA(B);return Q.logger.error(`Failed to list queue: ${X}`),{success:!1}}}async function FMw(A,Q){let{entityType:w,entityId:$,result:B}=Q;return A.scheduler.completePublish(w,$,B),A.logger.info(`Publish reported success: ${$}`,{entityType:w}),{success:!0}}async function bMw(A,Q){let{entityType:w,entityId:$,error:B}=Q;A.scheduler.failPublish(w,$,B);let X=A.retryTracker.getRetryInfo($);return A.logger.info(`Publish reported failure: ${$}`,{entityType:w,error:B,retryCount:X?.retryCount}),{success:!0}}async function LMw(A,Q){let{entityType:w,entityId:$}=Q;return A.scheduler.completeGeneration(w,$),A.logger.info("Generation completed",{entityType:w,entityId:$}),{success:!0}}async function kMw(A,Q){let{entityType:w,error:$}=Q;return A.scheduler.failGeneration(w,$),A.logger.warn("Generation failed",{entityType:w,error:$}),{success:!0}}async function H82(A,Q,w,$){try{if($.skipIfDraftExists!==!1){if((await A.listEntities({entityType:w,options:{filter:{metadata:{status:"draft"}},limit:1}})).length>0)return{shouldGenerate:!1,reason:"Draft already exists"}}if($.maxUnpublishedDrafts!==void 0){let B=await A.listEntities({entityType:w,options:{filter:{metadata:{status:"draft"}},limit:$.maxUnpublishedDrafts+1}});if(B.length>=$.maxUnpublishedDrafts)return{shouldGenerate:!1,reason:`Max unpublished drafts reached (${B.length}/${$.maxUnpublishedDrafts})`}}if($.minSourceEntities!==void 0&&$.sourceEntityType){let B=await A.listEntities({entityType:$.sourceEntityType,options:{publishedOnly:!0,limit:$.minSourceEntities}});if(B.length<$.minSourceEntities)return{shouldGenerate:!1,reason:`Not enough source entities (${B.length}/${$.minSourceEntities} ${$.sourceEntityType})`}}return{shouldGenerate:!0}}catch(B){return Q.error("Failed to check generation conditions",{entityType:w,error:dA(B)}),{shouldGenerate:!1,reason:`Condition check failed: ${dA(B)}`}}}function W82(A){let{context:Q,config:w,queueManager:$,providerRegistry:B,retryTracker:X,publishExecutor:Y,logger:Z}=A,H=_Mw(Q);return UG.createFresh({queueManager:$,providerRegistry:B,retryTracker:X,logger:Z,backend:new VH0,...w.entitySchedules&&{entitySchedules:w.entitySchedules},...w.generationSchedules&&{generationSchedules:w.generationSchedules},...w.generationConditions&&{generationConditions:w.generationConditions},messageBus:H,publishExecutor:Y,onCheckGenerationConditions:(W,K)=>H82(Q.entityService,Z,W,K)})}function _Mw(A){return{send:async(B)=>{return A.messaging.send({type:B.type,payload:B.payload,...B.target!==void 0?{target:B.target}:{},...B.metadata!==void 0?{metadata:B.metadata}:{},...B.broadcast!==void 0?{broadcast:B.broadcast}:{}})},subscribe:()=>()=>{},unsubscribe:()=>{}}}async function K82(A,Q,w){let $=A.getEntityTypes();for(let X of $){let Y=await A.listEntities({entityType:X,options:{filter:{metadata:{status:"queued"}}}});for(let Z of Y)await Q.add(Z.entityType,Z.id)}let B=0;for(let X of $){let Y=await Q.list(X);B+=Y.length}if(B>0)w.info(`Rebuilt queue with ${B} queued entities`)}C0();var NMw=["draft","queued","published","failed"];async function U82(A,Q){await A.messaging.send({type:"dashboard:register-widget",payload:{id:"publication-pipeline",pluginId:Q,title:"Publication Pipeline",group:"publishing",section:"secondary",priority:100,rendererName:"PipelineWidget",visibility:"anchor",dataProvider:()=>xMw(A),digestProvider:PMw}})}var jMw=f.object({summary:f.object({draft:f.number(),queued:f.number(),published:f.number(),failed:f.number()}),generating:f.array(f.unknown())});function PMw(A){let{summary:Q,generating:w}=jMw.parse(A),$=Q.queued+w.length,B=$===0?"idle":`${Q.queued} queued \xB7 ${w.length} generating`,X=Q.failed>0?`${Q.draft} drafts \xB7 ${Q.failed} failed`:`${Q.draft} drafts`,Y=Q.draft+Q.failed;return{digest:[{label:"Pipeline",value:B,...$>0?{tone:"warn"}:{}},{label:"Awaiting review",value:X,...Y>0?{tone:"warn"}:{}},{label:"Published",value:String(Q.published),tone:"good"}],needsOperator:Y}}var MMw=f.object({sourceEntityType:f.string(),sourceEntityId:f.string(),attachmentType:f.string().optional()});async function OMw(A){let Q=await A.jobs.getActiveJobs(),w=[];for(let $ of Q){if($.source!=="content-pipeline")continue;if($.status!=="pending"&&$.status!=="processing")continue;let B;try{B=JSON.parse($.data)}catch{continue}let X=MMw.safeParse(B);if(!X.success)continue;w.push({id:$.id,label:X.data.attachmentType??$.type,target:`${X.data.sourceEntityType}/${X.data.sourceEntityId}`,status:$.status})}return w}async function xMw(A){let Q=A.entityService.getEntityTypes(),w=[],$={draft:0,queued:0,published:0,failed:0};for(let B of Q){let X=await A.entityService.listEntities({entityType:B});for(let Y of X){let Z=RMw(Y.metadata.status);if(!Z)continue;$[Z]++,w.push({id:Y.id,title:vMw(Y.id,Y.metadata.title),type:B,status:Z})}}return{summary:$,items:w,generating:await OMw(A)}}function RMw(A){return NMw.find((Q)=>Q===A)}function vMw(A,Q){return typeof Q==="string"?Q:A}var G82={name:"@brains/content-pipeline",version:"0.2.0-alpha.158",description:"Content pipeline plugin for managing entity publishing queues, scheduling, and generation",dependencies:{"@brains/contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*",croner:"^10.0.1"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14",typescript:"^7.0.2"},exports:{".":{types:"./src/index.ts",default:"./src/index.ts"}},files:["src"],main:"src/index.ts",private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module",types:"src/index.ts"};class K0A extends Kw{pluginContext;queueManager;providerRegistry;retryTracker;publishExecutor;publishAssetRegistry;publishAssetPreflight;scheduler;constructor(A={}){super("content-pipeline",G82,A,i$2)}async onRegister(A){this.pluginContext=A,this.queueManager=Tq.createFresh(),this.providerRegistry=Sq.createFresh(),this.retryTracker=mq.createFresh(),this.publishAssetRegistry=uq.createFresh(),this.publishAssetPreflight=new IH0({context:A,registry:this.publishAssetRegistry}),this.publishExecutor=new SE({context:A,providerRegistry:this.providerRegistry,publishAssetPreflight:this.publishAssetPreflight}),this.scheduler=W82({context:A,config:this.config,queueManager:this.queueManager,providerRegistry:this.providerRegistry,retryTracker:this.retryTracker,publishExecutor:this.publishExecutor,logger:this.logger}),f82(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 K82(A.entityService,this.queueManager,this.logger),await U82(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[FH0(this.pluginContext,this.id,this.queueManager),bH0(this.pluginContext,this.id,this.providerRegistry,this.publishExecutor),LH0(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. Follow-up requests like "publish it now" should target the entity just read, generated, or updated in the conversation, including a post just changed to draft.\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(),Tq.resetInstance(),Sq.resetInstance(),mq.resetInstance(),uq.resetInstance()}}function U0A(A={}){return new K0A(A)}fA();C0();var D82=f.object({accountId:f.string().describe("Cloudflare account ID"),apiToken:f.string().describe("Cloudflare API token with Analytics:Read permission"),siteTag:f.string().describe("Cloudflare Web Analytics site tag")}),G0A=f.object({cloudflare:D82.optional()});fA();C0();var CMw=f.object({date:f.string().describe("Single date in YYYY-MM-DD format").optional(),days:f.number().min(1).max(365).describe("Number of days back from yesterday (e.g., 7 for last week)").optional(),startDate:f.string().describe("Start date in YYYY-MM-DD format (use with endDate)").optional(),endDate:f.string().describe("End date in YYYY-MM-DD format (use with startDate)").optional(),limit:f.number().min(1).max(100).default(20).describe("Maximum items for breakdowns (pages, referrers, countries)")});function gMw(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 q82(A,Q,w){let $=[];if(!w)return $;return $.push(p6(A,"query",`Query website analytics from Cloudflare.
7778
+ ${w.content}`:w.prompt??"Write an engaging LinkedIn post";return A.ai.generate({prompt:$,templateName:`social-media:${w.platform}`})}),A.eval.registerHandler("create",async(Q)=>{let w=LPw.parse(Q),$=[],B=hX.from(async(W)=>{let K={progress:W.progress};if(W.message!==void 0)K.message=W.message;$.push(K)});if(!B)throw Error("Failed to create progress reporter");let Y=await new VM(A.logger,A).process(w,`eval-${Date.now()}`,B),Z=!1,H;if(Y.success&&Y.entityId){let W=await A.entityService.getEntity({entityType:"social-post",id:Y.entityId});Z=!!W,H=W?.content.slice(0,300)}return{...Y,entityExists:Z,entityPreview:H,progressSteps:$}})}fA();class es{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:w}=A;if(Q!=="social-post")return;this.permissions.assertEntityActionAllowed(Q,"publish",A.authContext??{userPermissionLevel:"anchor"}),this.logger.debug("Handling publish:execute",{entityId:w});try{let $=await this.entityService.getEntity({entityType:"social-post",id:w});if(!$){await this.reportFailure(Q,w,`Post not found: ${w}`);return}let B=$;if(B.metadata.status==="published"){this.logger.debug("Post already published, skipping",{entityId:w});return}let X=B.metadata.platform,Y=this.providers.get(X);if(!Y){await this.reportFailure(Q,w,`No provider configured for platform: ${X}`);return}let Z=$Q(B.content,KG),H;if(Z.metadata.coverImageId)H=await this.fetchImageData(Z.metadata.coverImageId);let W=Z.metadata.documents??[],K=await this.fetchDocumentData(W);try{if(W.length>0&&K.length===0)throw Error(`Refusing to publish: ${W.length} document(s) referenced but none could be fetched`);let U=W.length===0?await this.resolveSourceAttachment(Z.metadata):[],G=K.length>0?K:U,q=G.length?await Y.publish(Z.content,B.metadata,H,G):await Y.publish(Z.content,B.metadata,H),V=new Date().toISOString(),I=q.id||void 0,J={...Z.metadata,status:"published",publishedAt:V,...I&&{platformPostId:I}},k=G4.createPostContent(J,Z.content);await this.entityService.updateEntity({entity:{...B,content:k,metadata:{...B.metadata,status:"published",publishedAt:V,platformPostId:I}}}),await this.reportSuccess(Q,w,q.id),this.logger.info(`Post published successfully: ${w}`,{platform:X,platformPostId:I})}catch(U){let G=U instanceof Error?U.message:String(U),q={...Z.metadata,status:"failed"},V=G4.createPostContent(q,Z.content);await this.entityService.updateEntity({entity:{...B,content:V,metadata:{...B.metadata,status:"failed"}}}),await this.reportFailure(Q,w,G),this.logger.error(`Post publish failed: ${w}`,{platform:X,error:G})}}catch($){let B=dA($);this.logger.error("Unexpected error in publish handler",{entityId:w,error:B}),await this.reportFailure(Q,w,B)}}async reportSuccess(A,Q,w){await this.sendMessage({type:"publish:report:success",payload:{entityType:A,entityId:Q,result:{id:w}}})}async reportFailure(A,Q,w){await this.sendMessage({type:"publish:report:failure",payload:{entityType:A,entityId:Q,error:w}})}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 w of A){let $=await this.fetchSingleDocumentData(w.id);if($)Q.push($)}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 w=Q.content.match(/^data:application\/pdf;base64,(.+)$/);if(!w?.[1]){this.logger.warn("Invalid document data URL format",{documentId:A});return}let $=typeof Q.metadata.filename==="string"?Q.metadata.filename:`${A}.pdf`;return{type:"document",data:Buffer.from(w[1],"base64"),mimeType:"application/pdf",filename:$}}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 $=Q.content.match(/^data:([^;]+);base64,(.+)$/);if(!$?.[1]||!$[2]){this.logger.warn("Invalid image data URL format",{imageId:A});return}let B=$[1],X=$[2];return{data:Buffer.from(X,"base64"),mimeType:B}}catch(Q){this.logger.warn("Failed to fetch cover image",{imageId:A,error:Q});return}}}function g$2(A,Q,w){if(Q.size===0){w.debug("No providers configured, skipping publish-pipeline registration");return}A.messaging.subscribe("system:plugins:ready",async()=>{let $=Q.values().next().value;return await A.messaging.send({type:"publish:register",payload:{entityType:"social-post",provider:$,config:{publishResultIdField:"platformPostId"}}}),w.info("Registered social-post with publish-pipeline"),{success:!0}})}function y$2(A,Q,w){let $=new es({sendMessage:A.messaging.send,logger:w.child("PublishExecuteHandler"),entityService:A.entityService,providers:Q,permissions:A.permissions,resolveAttachment:A.attachments.resolve});A.messaging.subscribe("publish:execute",async(B)=>{return await $.handle(B.payload),{success:!0}}),w.debug("Subscribed to publish:execute messages")}function E$2(A,Q){A.messaging.subscribe("entity:updated",async(w)=>{let{entityType:$,entityId:B,entity:X}=w.payload;if($!=="post")return{success:!0};if(X.metadata?.status!=="queued")return{success:!0};try{if((await A.entityService.listEntities({entityType:"social-post",options:{filter:{metadata:{sourceEntityType:"post",sourceEntityId:B}},limit:1}})).length>0)return Q.debug(`Social post already exists for ${B}, skipping auto-generate`),{success:!0};return await A.messaging.send({type:"social:auto-generate",payload:{sourceEntityType:$,sourceEntityId:B,platform:"linkedin"}}),Q.info(`Auto-generate social post triggered for queued post ${B}`),{success:!0}}catch(Z){let H=dA(Z);return Q.error(`Failed to trigger auto-generate for ${B}:`,{error:H}),{success:!0}}}),Q.debug("Subscribed to entity:updated for auto-generation")}function T$2(A,Q){A.messaging.subscribe("social:auto-generate",async(w)=>{let{sourceEntityType:$,sourceEntityId:B,platform:X}=w.payload;try{let Y=await A.jobs.enqueue({type:`${G4.entityType}:generation`,data:{sourceEntityType:$,sourceEntityId:B,platform:X,addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}});return Q.info(`Social post generation job enqueued for ${$}/${B}`,{jobId:Y}),{success:!0,jobId:Y}}catch(Y){let Z=dA(Y);return Q.error(`Failed to enqueue social post generation for ${B}:`,{error:Z}),{success:!1}}}),Q.debug("Subscribed to social:auto-generate messages")}function S$2(A,Q){A.messaging.subscribe("generate:execute",async(w)=>{let{entityType:$}=w.payload;if($!=="social-post")return{success:!0};Q.info("Received generate:execute for social-post");try{let B=await A.entityService.listEntities({entityType:"post",options:{filter:{metadata:{status:"published"}},limit:5}});if(B.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 X=null;for(let Z of B)if((await A.entityService.listEntities({entityType:"social-post",options:{filter:{metadata:{sourceEntityType:"post",sourceEntityId:Z.id}},limit:1}})).length===0){X=Z;break}if(!X)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 Y=await A.jobs.enqueue({type:`${G4.entityType}:generation`,data:{sourceEntityType:"post",sourceEntityId:X.id,platform:"linkedin",addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}});return Q.info("Social post generation job queued",{jobId:Y,sourcePostId:X.id}),{success:!0}}catch(B){let X=dA(B);return Q.error("Failed to handle generate:execute:",{error:X}),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:X}}),{success:!0}}}),Q.debug("Subscribed to generate:execute messages")}async function m$2({entity:A,config:Q}){let w=jL.parse(A),$=G4.parsePostFrontmatter(w),B=G4.getPostContent(w);return{$type:"ai.rizom.brain.socialPost",title:$.title,platform:$.platform,body:B,format:"text/markdown",status:$.status,...$.publishedAt&&{publishedAt:$.publishedAt},...$.platformPostId&&{platformPostId:$.platformPostId},...$.sourceEntityType&&{sourceLocalEntityType:$.sourceEntityType},...$.sourceEntityId&&{sourceLocalEntityId:$.sourceEntityId},...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"social-post",sourceEntityId:w.id,createdAt:w.created,...w.updated&&{updatedAt:w.updated}}}function pe0(){return{entityType:"social-post",collection:"ai.rizom.brain.socialPost",lexicon:S6["ai.rizom.brain.socialPost"],validate:!1,buildRecord:m$2}}var u$2={name:"@brains/social-media",version:"0.2.0-alpha.159",description:"Multi-provider social media posting with queue-based publishing",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":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts","./env-schema":"./src/env-schema.ts"},private:!0,scripts:{eval:"cd evals && bun run brain-eval",lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};class ie0 extends Zw{entityType=G4.entityType;schema=jL;adapter=G4;providers=new Map;unregisterAtprotoProjection;constructor(A={}){super("social-media",u$2,A,Te0)}createGenerationHandler(A){return new VM(this.logger.child("GenerationJobHandler"),A)}getTemplates(){return h$2()}getDataSources(){return[new UH0(this.logger.child("SocialPostDataSource"))]}getEntityTypeConfig(){return{publish:{publishStatuses:["queued","published","failed"]}}}async onRegister(A){if(this.initializeProviders(),g$2(A,this.providers,this.logger),y$2(A,this.providers,this.logger),this.config.autoGenerateOnBlogPublish)E$2(A,this.logger),T$2(A,this.logger),this.logger.info("Auto-generate on blog publish enabled");S$2(A,this.logger),C$2(A),this.unregisterAtprotoProjection=kB.getInstance().register(pe0()),this.logger.info("Social media plugin registered successfully")}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}initializeProviders(){if(this.config.linkedin?.accessToken){let A=le0(this.config.linkedin,this.logger.child("LinkedInClient"));this.providers.set("linkedin",A),this.logger.info("LinkedIn provider initialized")}}}function Aa(A={}){return new ie0(A)}C0();var _Pw=f.enum(["draft","queued","published","failed"]),c$2=f.object({status:_Pw.default("draft"),queueOrder:f.number().optional().describe("Position in publish queue (lower = sooner)"),publishedAt:f.string().datetime().optional()});class de0{name="internal";async publish(A,Q){return{id:"internal"}}}var Qa={interfaceType:"system",userId:"system",userPermissionLevel:"anchor",authorization:"system"},FY={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"},PL={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"},l$2={REGISTER:"publish-assets:register"};C0();var NPw=f.enum(["provider"]),p$2=f.object({executionMode:NPw.optional(),publishResultIdField:f.string().min(1).optional(),publishTimestampField:f.string().min(1).optional(),enabled:f.boolean().optional()}).strict();var jPw=f.object({skipIfDraftExists:f.boolean().optional(),minSourceEntities:f.number().optional(),maxUnpublishedDrafts:f.number().optional(),sourceEntityType:f.string().optional()}),i$2=f.object({entitySchedules:f.record(f.string(),f.string()).optional(),generationSchedules:f.record(f.string(),f.string()).optional(),generationConditions:f.record(f.string(),jPw).optional()});class Tq{static instance=null;queues=new Map;static getInstance(){return Tq.instance??=new Tq,Tq.instance}static resetInstance(){Tq.instance=null}static createFresh(){return new Tq}constructor(){}async add(A,Q,w=Qa){let $=this.getOrCreateQueue(A),B=$.find((Z)=>Z.entityId===Q);if(B)return{position:B.position};let X=$.length+1,Y={entityId:Q,entityType:A,position:X,queuedAt:new Date().toISOString(),authContext:{...w}};return $.push(Y),{position:X}}async remove(A,Q){let w=this.queues.get(A);if(!w)return;let $=w.findIndex((B)=>B.entityId===Q);if($===-1)return;w.splice($,1),this.recalculatePositions(w)}async reorder(A,Q,w){let $=this.queues.get(A);if(!$)return;let B=$.findIndex((Z)=>Z.entityId===Q);if(B===-1)return;let[X]=$.splice(B,1);if(!X)return;let Y=Math.max(0,Math.min(w-1,$.length));$.splice(Y,0,X),this.recalculatePositions($)}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 w=Q[0];if(!w)continue;if(!A||w.queuedAt<A.queuedAt)A=w}return A}async popNext(A){let Q=this.queues.get(A);if(!Q||Q.length===0)return null;let w=Q.shift()??null;if(w)this.recalculatePositions(Q);return w}getRegisteredTypes(){return Array.from(this.queues.keys())}async getQueuedEntityTypes(){let A=[];for(let[Q,w]of this.queues.entries())if(w.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,w)=>{Q.position=w+1})}}class Sq{static instance=null;providers=new Map;executionModes=new Map;publishResultIdFields=new Map;publishTimestampFields=new Map;defaultProvider=new de0;static getInstance(){return Sq.instance??=new Sq,Sq.instance}static resetInstance(){Sq.instance=null}static createFresh(){return new Sq}constructor(){}register(A,Q,w){let $=this.providers.get(A);if($&&$.name!=="internal"&&Q.name==="internal")return;if(this.providers.set(A,Q),this.executionModes.set(A,w?.executionMode??"provider"),w?.publishResultIdField)this.publishResultIdFields.set(A,w.publishResultIdField);else this.publishResultIdFields.delete(A);if(w?.publishTimestampField)this.publishTimestampFields.set(A,w.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())}}async function d$2(A,Q){if(!Q.publishExecutor){Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:"Publish executor not configured",retryCount:0,willRetry:!1});return}await PPw(A,Q)}async function PPw(A,Q){if(!Q.publishExecutor)return;try{let w=await Q.publishExecutor.publish({entityType:A.entityType,id:A.entityId});if("error"in w){let $={entityType:A.entityType,entityId:A.entityId,error:w.error,retryCount:0,willRetry:!1};if(Q.messageBus)await Q.messageBus.send({type:FY.FAILED,payload:$,sender:"publish-service",broadcast:!0});Q.onFailed?.($);return}ne0(A.entityType,A.entityId,w.result,Q)}catch(w){let $=dA(w);Q.retryTracker.recordFailure(A.entityId,$);let B=Q.retryTracker.getRetryInfo(A.entityId);Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:$,retryCount:B?.retryCount??1,willRetry:!1})}}function ne0(A,Q,w,$){if($.retryTracker.clearRetries(Q),$.messageBus)$.messageBus.send({type:FY.COMPLETED,payload:{entityType:A,entityId:Q,result:w},sender:"publish-service",broadcast:!0});$.onPublish?.({entityType:A,entityId:Q,result:w})}function n$2(A,Q,w,$){$.retryTracker.recordFailure(Q,w);let B=$.retryTracker.getRetryInfo(Q),X={entityType:A,entityId:Q,error:w,retryCount:B?.retryCount??1,willRetry:!1};if($.messageBus)$.messageBus.send({type:FY.FAILED,payload:X,sender:"publish-service",broadcast:!0});$.onFailed?.(X)}async function r$2(A,Q){let w=Q.generationConditions[A];if(w&&Q.onCheckGenerationConditions){let B=await Q.onCheckGenerationConditions(A,w);if(!B.shouldGenerate){if(Q.messageBus)Q.messageBus.send({type:PL.SKIPPED,payload:{entityType:A,reason:B.reason??"Conditions not met"},sender:"content-pipeline"});return}}let $={entityType:A};if(Q.messageBus)await Q.messageBus.send({type:PL.EXECUTE,payload:$,sender:"content-pipeline"});Q.onGenerate?.($)}function o$2(A,Q,w){if(w)w.send({type:PL.COMPLETED,payload:{entityType:A,entityId:Q},sender:"content-pipeline"})}function s$2(A,Q,w){if(w)w.send({type:PL.FAILED,payload:{entityType:A,error:Q},sender:"content-pipeline"})}var MPw=1000;class re0{deps;publishJobs=new Map;immediateIntervalJob=null;constructor(A){this.deps=A}start(){for(let[A,Q]of Object.entries(this.entitySchedules)){let w=this.deps.config.backend.scheduleCron(Q,()=>this.processEntityType(A));this.publishJobs.set(A,w)}this.immediateIntervalJob=this.deps.config.backend.scheduleInterval(MPw,()=>this.processUnscheduledTypes())}stop(){if(OPw(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 w=await this.deps.config.queueManager.getNext(Q);if(w){await this.processEntry(w);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 d$2(A,Q)}get entitySchedules(){return this.deps.config.entitySchedules}}function OPw(A){for(let Q of A.values())Q.stop();A.clear()}class oe0{deps;generationJobs=new Map;constructor(A){this.deps=A}start(){for(let[A,Q]of Object.entries(this.generationSchedules)){let w=this.deps.config.backend.scheduleCron(Q,()=>this.handleTriggerGeneration(A));this.generationJobs.set(A,w)}}stop(){xPw(this.generationJobs)}async handleTriggerGeneration(A){if(!this.deps.isRunning())return;try{await r$2(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 xPw(A){for(let Q of A.values())Q.stop();A.clear()}class UG{static instance=null;config;publishRunner;generationRunner;running=!1;static getInstance(A){return UG.instance??=new UG(A),UG.instance}static resetInstance(){if(UG.instance)UG.instance.stop();UG.instance=null}static createFresh(A){return new UG(A)}constructor(A){this.config={...A,entitySchedules:A.entitySchedules??{},generationSchedules:A.generationSchedules??{},generationConditions:A.generationConditions??{}},this.validateCronExpressions(),this.publishRunner=new re0({config:this.config,getPublishDeps:()=>this.publishDeps,isRunning:()=>this.running}),this.generationRunner=new oe0({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,w){ne0(A,Q,w,this.publishDeps)}failPublish(A,Q,w){n$2(A,Q,w,this.publishDeps)}completeGeneration(A,Q){o$2(A,Q,this.config.messageBus)}failGeneration(A,Q){s$2(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,w){try{this.config.backend.validateCron(Q)}catch($){throw Error(`Invalid ${w} cron expression for ${A}: "${Q}" - ${dA($)}`,{cause:$})}}}class mq{static instance=null;retries=new Map;static getInstance(){return mq.instance??=new mq,mq.instance}static resetInstance(){mq.instance=null}static createFresh(){return new mq}constructor(){}recordFailure(A,Q){let $=(this.retries.get(A)?.retryCount??0)+1;this.retries.set(A,{entityId:A,retryCount:$,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 wa(A){return Date.UTC(A.y,A.m-1,A.d,A.h,A.i,A.s)}function se0(A,Q){return A.y===Q.y&&A.m===Q.m&&A.d===Q.d&&A.h===Q.h&&A.i===Q.i&&A.s===Q.s}function RPw(A,Q){let w=new Date(Date.parse(A));if(isNaN(w))throw Error("Invalid ISO8601 passed to timezone parser.");let $=A.substring(9);return $.includes("Z")||$.includes("+")||$.includes("-")?te0(w.getUTCFullYear(),w.getUTCMonth()+1,w.getUTCDate(),w.getUTCHours(),w.getUTCMinutes(),w.getUTCSeconds(),"Etc/UTC"):te0(w.getFullYear(),w.getMonth()+1,w.getDate(),w.getHours(),w.getMinutes(),w.getSeconds(),Q)}function a$2(A,Q,w){return A82(RPw(A,Q),w)}function A82(A,Q){let w=new Date(wa(A)),$=$a(w,A.tz),B=wa(A),X=wa($),Y=B-X,Z=new Date(w.getTime()+Y),H=$a(Z,A.tz);if(se0(H,A)){let U=new Date(Z.getTime()-3600000),G=$a(U,A.tz);return se0(G,A)?U:Z}let W=new Date(Z.getTime()+wa(A)-wa(H)),K=$a(W,A.tz);if(se0(K,A))return W;if(Q)throw Error("Invalid date passed to fromTZ()");return Z.getTime()>W.getTime()?Z:W}function $a(A,Q){let w,$;try{w=new Intl.DateTimeFormat("en-US",{timeZone:Q,year:"numeric",month:"numeric",day:"numeric",hour:"numeric",minute:"numeric",second:"numeric",hour12:!1}),$=w.formatToParts(A)}catch(X){let Y=X instanceof Error?X.message:String(X);throw RangeError(`toTZ: Invalid timezone '${Q}' or date. Please provide a valid IANA timezone (e.g., 'America/New_York', 'Europe/Stockholm'). Original error: ${Y}`)}let B={year:0,month:0,day:0,hour:0,minute:0,second:0};for(let X of $)(X.type==="year"||X.type==="month"||X.type==="day"||X.type==="hour"||X.type==="minute"||X.type==="second")&&(B[X.type]=parseInt(X.value,10));if(isNaN(B.year)||isNaN(B.month)||isNaN(B.day)||isNaN(B.hour)||isNaN(B.minute)||isNaN(B.second))throw Error(`toTZ: Failed to parse all date components from timezone '${Q}'. This may indicate an invalid date or timezone configuration. Parsed components: ${JSON.stringify(B)}`);return B.hour===24&&(B.hour=0),{y:B.year,m:B.month,d:B.day,h:B.hour,i:B.minute,s:B.second,tz:Q}}function te0(A,Q,w,$,B,X,Y){return{y:A,m:Q,d:w,h:$,i:B,s:X,tz:Y}}var Q82=[1,2,4,8,16],t$2=class{pattern;timezone;mode;alternativeWeekdays;sloppyRanges;second;minute;hour;day;month;dayOfWeek;year;lastDayOfMonth;lastWeekday;nearestWeekdays;starDOM;starDOW;starYear;useAndLogic;constructor(A,Q,w){this.pattern=A,this.timezone=Q,this.mode=w?.mode??"auto",this.alternativeWeekdays=w?.alternativeWeekdays??!1,this.sloppyRanges=w?.sloppyRanges??!1,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.year=Array(1e4).fill(0),this.lastDayOfMonth=!1,this.lastWeekday=!1,this.nearestWeekdays=Array(31).fill(0),this.starDOM=!1,this.starDOW=!1,this.starYear=!1,this.useAndLogic=!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.match(/\S+/g)||[""],Q=A.length;if(A.length<5||A.length>7)throw TypeError("CronPattern: invalid configuration format ('"+this.pattern+"'), exactly five, six, or seven space separated parts are required.");if(this.mode!=="auto"){let $;switch(this.mode){case"5-part":$=5;break;case"6-part":$=6;break;case"7-part":$=7;break;case"5-or-6-parts":$=[5,6];break;case"6-or-7-parts":$=[6,7];break;default:$=0}if(!(Array.isArray($)?$.includes(Q):Q===$)){let B=Array.isArray($)?$.join(" or "):$.toString();throw TypeError(`CronPattern: mode '${this.mode}' requires exactly ${B} parts, but pattern '${this.pattern}' has ${Q} parts.`)}}if(A.length===5&&A.unshift("0"),A.length===6&&A.push("*"),A[3].toUpperCase()==="LW"?(this.lastWeekday=!0,A[3]=""):A[3].toUpperCase().indexOf("L")>=0&&(A[3]=A[3].replace(/L/gi,""),this.lastDayOfMonth=!0),A[3]=="*"&&(this.starDOM=!0),A[6]=="*"&&(this.starYear=!0),A[4].length>=3&&(A[4]=this.replaceAlphaMonths(A[4])),A[5].length>=3&&(A[5]=this.alternativeWeekdays?this.replaceAlphaDaysQuartz(A[5]):this.replaceAlphaDays(A[5])),A[5].startsWith("+")&&(this.useAndLogic=!0,A[5]=A[5].substring(1),A[5]===""))throw TypeError("CronPattern: Day-of-week field cannot be empty after '+' modifier.");switch(A[5]=="*"&&(this.starDOW=!0),this.pattern.indexOf("?")>=0&&(A[0]=A[0].replace(/\?/g,"*"),A[1]=A[1].replace(/\?/g,"*"),A[2]=A[2].replace(/\?/g,"*"),A[3]=A[3].replace(/\?/g,"*"),A[4]=A[4].replace(/\?/g,"*"),A[5]=A[5].replace(/\?/g,"*"),A[6]&&(A[6]=A[6].replace(/\?/g,"*"))),this.mode){case"5-part":A[0]="0",A[6]="*";break;case"6-part":A[6]="*";break;case"5-or-6-parts":A[6]="*";break;case"6-or-7-parts":break;case"7-part":case"auto":break}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);let w=this.alternativeWeekdays?-1:0;this.partToArray("dayOfWeek",A[5],w,63),this.partToArray("year",A[6],0,1),!this.alternativeWeekdays&&this.dayOfWeek[7]&&(this.dayOfWeek[0]=this.dayOfWeek[7])}partToArray(A,Q,w,$){let B=this[A],X=A==="day"&&this.lastDayOfMonth,Y=A==="day"&&this.lastWeekday;if(Q===""&&!X&&!Y)throw TypeError("CronPattern: configuration entry "+A+" ("+Q+") is empty, check for trailing spaces.");if(Q==="*")return B.fill($);let Z=Q.split(",");if(Z.length>1)for(let H=0;H<Z.length;H++)this.partToArray(A,Z[H],w,$);else Q.indexOf("-")!==-1&&Q.indexOf("/")!==-1?this.handleRangeWithStepping(Q,A,w,$):Q.indexOf("-")!==-1?this.handleRange(Q,A,w,$):Q.indexOf("/")!==-1?this.handleStepping(Q,A,w,$):Q!==""&&this.handleNumber(Q,A,w,$)}throwAtIllegalCharacters(A){for(let Q=0;Q<A.length;Q++)if((Q===3?/[^/*0-9,\-WwLl]+/:Q===5?/[^/*0-9,\-#Ll]+/:/[^/*0-9,\-]+/).test(A[Q]))throw TypeError("CronPattern: configuration entry "+Q+" ("+A[Q]+") contains illegal characters.")}handleNumber(A,Q,w,$){let B=this.extractNth(A,Q),X=A.toUpperCase().includes("W");if(Q!=="day"&&X)throw TypeError("CronPattern: Nearest weekday modifier (W) only allowed in day-of-month.");X&&(Q="nearestWeekdays");let Y=parseInt(B[0],10)+w;if(isNaN(Y))throw TypeError("CronPattern: "+Q+" is not a number: '"+A+"'");this.setPart(Q,Y,B[1]||$)}setPart(A,Q,w){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,w);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"||A==="nearestWeekdays"){if(Q<0||Q>=31)throw RangeError("CronPattern: Invalid value for "+A+": "+Q)}else if(A==="month"){if(Q<0||Q>=12)throw RangeError("CronPattern: Invalid value for "+A+": "+Q)}else if(A==="year"&&(Q<1||Q>=1e4))throw RangeError("CronPattern: Invalid value for "+A+": "+Q+" (supported range: 1-9999)");this[A][Q]=w}validateNotNaN(A,Q){if(isNaN(A))throw TypeError(Q)}validateRange(A,Q,w,$,B){if(A>Q)throw TypeError("CronPattern: From value is larger than to value: '"+B+"'");if(w!==void 0){if(w===0)throw TypeError("CronPattern: Syntax error, illegal stepping: 0");if(w>this[$].length)throw TypeError("CronPattern: Syntax error, steps cannot be greater than maximum value of part ("+this[$].length+")")}}handleRangeWithStepping(A,Q,w,$){if(A.toUpperCase().includes("W"))throw TypeError("CronPattern: Syntax error, W is not allowed in ranges with stepping.");let B=this.extractNth(A,Q),X=B[0].match(/^(\d+)-(\d+)\/(\d+)$/);if(X===null)throw TypeError("CronPattern: Syntax error, illegal range with stepping: '"+A+"'");let[,Y,Z,H]=X,W=parseInt(Y,10)+w,K=parseInt(Z,10)+w,U=parseInt(H,10);this.validateNotNaN(W,"CronPattern: Syntax error, illegal lower range (NaN)"),this.validateNotNaN(K,"CronPattern: Syntax error, illegal upper range (NaN)"),this.validateNotNaN(U,"CronPattern: Syntax error, illegal stepping: (NaN)"),this.validateRange(W,K,U,Q,A);for(let G=W;G<=K;G+=U)this.setPart(Q,G,B[1]||$)}extractNth(A,Q){let w=A,$;if(w.includes("#")){if(Q!=="dayOfWeek")throw Error("CronPattern: nth (#) only allowed in day-of-week field");$=w.split("#")[1],w=w.split("#")[0]}else if(w.toUpperCase().endsWith("L")){if(Q!=="dayOfWeek")throw Error("CronPattern: L modifier only allowed in day-of-week field (use L alone for day-of-month)");$="L",w=w.slice(0,-1)}return[w,$]}handleRange(A,Q,w,$){if(A.toUpperCase().includes("W"))throw TypeError("CronPattern: Syntax error, W is not allowed in a range.");let B=this.extractNth(A,Q),X=B[0].split("-");if(X.length!==2)throw TypeError("CronPattern: Syntax error, illegal range: '"+A+"'");let Y=parseInt(X[0],10)+w,Z=parseInt(X[1],10)+w;this.validateNotNaN(Y,"CronPattern: Syntax error, illegal lower range (NaN)"),this.validateNotNaN(Z,"CronPattern: Syntax error, illegal upper range (NaN)"),this.validateRange(Y,Z,void 0,Q,A);for(let H=Y;H<=Z;H++)this.setPart(Q,H,B[1]||$)}handleStepping(A,Q,w,$){if(A.toUpperCase().includes("W"))throw TypeError("CronPattern: Syntax error, W is not allowed in parts with stepping.");let B=this.extractNth(A,Q),X=B[0].split("/");if(X.length!==2)throw TypeError("CronPattern: Syntax error, illegal stepping: '"+A+"'");if(this.sloppyRanges)X[0]===""&&(X[0]="*");else{if(X[0]==="")throw TypeError("CronPattern: Syntax error, stepping with missing prefix ('"+A+"') is not allowed. Use wildcard (*/step) or range (min-max/step) instead.");if(X[0]!=="*")throw TypeError("CronPattern: Syntax error, stepping with numeric prefix ('"+A+"') is not allowed. Use wildcard (*/step) or range (min-max/step) instead.")}let Y=0;X[0]!=="*"&&(Y=parseInt(X[0],10)+w);let Z=parseInt(X[1],10);this.validateNotNaN(Z,"CronPattern: Syntax error, illegal stepping: (NaN)"),this.validateRange(0,this[Q].length-1,Z,Q,A);for(let H=Y;H<this[Q].length;H+=Z)this.setPart(Q,H,B[1]||$)}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")}replaceAlphaDaysQuartz(A){return A.replace(/sun/gi,"1").replace(/mon/gi,"2").replace(/tue/gi,"3").replace(/wed/gi,"4").replace(/thu/gi,"5").replace(/fri/gi,"6").replace(/sat/gi,"7")}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();if(Q==="@yearly"||Q==="@annually")return"0 0 1 1 *";if(Q==="@monthly")return"0 0 1 * *";if(Q==="@weekly")return"0 0 * * 0";if(Q==="@daily"||Q==="@midnight")return"0 0 * * *";if(Q==="@hourly")return"0 * * * *";if(Q==="@reboot")throw TypeError("CronPattern: @reboot is not supported in this environment. This is an event-based trigger that requires system startup detection.");return A}setNthWeekdayOfMonth(A,Q){if(typeof Q!="number"&&Q.toUpperCase()==="L")this.dayOfWeek[A]=this.dayOfWeek[A]|32;else if(Q===63)this.dayOfWeek[A]=63;else if(Q<6&&Q>0)this.dayOfWeek[A]=this.dayOfWeek[A]|Q82[Q-1];else throw TypeError(`CronPattern: nth weekday out of range, should be 1-5 or L. Value: ${Q}, Type: ${typeof Q}`)}},ae0=[31,28,31,30,31,30,31,31,30,31,30,31],h8=[["month","year",0],["day","month",-1],["hour","day",0],["minute","hour",0],["second","minute",0]],D4=class A{tz;ms;second;minute;hour;day;month;year;constructor(Q,w){if(this.tz=w,Q&&Q instanceof Date)if(!isNaN(Q))this.fromDate(Q);else throw TypeError("CronDate: Invalid date passed to CronDate constructor");else if(Q==null)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")}getLastDayOfMonth(Q,w){return w!==1?ae0[w]:new Date(Date.UTC(Q,w+1,0)).getUTCDate()}getLastWeekday(Q,w){let $=this.getLastDayOfMonth(Q,w),B=new Date(Date.UTC(Q,w,$)).getUTCDay();return B===0?$-2:B===6?$-1:$}getNearestWeekday(Q,w,$){let B=this.getLastDayOfMonth(Q,w);if($>B)return-1;let X=new Date(Date.UTC(Q,w,$)).getUTCDay();return X===0?$===B?$-2:$+1:X===6?$===1?$+2:$-1:$}isNthWeekdayOfMonth(Q,w,$,B){let X=new Date(Date.UTC(Q,w,$)).getUTCDay(),Y=0;for(let Z=1;Z<=$;Z++)new Date(Date.UTC(Q,w,Z)).getUTCDay()===X&&Y++;if(B&63&&Q82[Y-1]&B)return!0;if(B&32){let Z=this.getLastDayOfMonth(Q,w);for(let H=$+1;H<=Z;H++)if(new Date(Date.UTC(Q,w,H)).getUTCDay()===X)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 try{let w=$a(Q,this.tz);this.ms=Q.getMilliseconds(),this.second=w.s,this.minute=w.i,this.hour=w.h,this.day=w.d,this.month=w.m-1,this.year=w.y}catch(w){let $=w instanceof Error?w.message:String(w);throw TypeError(`CronDate: Failed to convert date to timezone '${this.tz}'. This may happen with invalid timezone names or dates. Original error: ${$}`)}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.month<0||this.day>ae0[this.month]||this.day<1||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 w=a$2(Q);this.ms=w.getUTCMilliseconds(),this.second=w.getUTCSeconds(),this.minute=w.getUTCMinutes(),this.hour=w.getUTCHours(),this.day=w.getUTCDate(),this.month=w.getUTCMonth(),this.year=w.getUTCFullYear(),this.apply()}else return this.fromDate(a$2(Q,this.tz))}findNext(Q,w,$,B){return this._findMatch(Q,w,$,B,1)}_findMatch(Q,w,$,B,X){let Y=this[w],Z;$.lastDayOfMonth&&(Z=this.getLastDayOfMonth(this.year,this.month));let H=!$.starDOW&&w=="day"?new Date(Date.UTC(this.year,this.month,1,0,0,0,0)).getUTCDay():void 0,W=this[w]+B,K=X===1?(U)=>U<$[w].length:(U)=>U>=0;for(let U=W;K(U);U+=X){let G=$[w][U];if(w==="day"&&!G){for(let q=0;q<$.nearestWeekdays.length;q++)if($.nearestWeekdays[q]){let V=this.getNearestWeekday(this.year,this.month,q-B);if(V===-1)continue;if(V===U-B){G=1;break}}}if(w==="day"&&$.lastWeekday){let q=this.getLastWeekday(this.year,this.month);U-B===q&&(G=1)}if(w==="day"&&$.lastDayOfMonth&&U-B==Z&&(G=1),w==="day"&&!$.starDOW){let q=$.dayOfWeek[(H+(U-B-1))%7];if(q&&q&63)q=this.isNthWeekdayOfMonth(this.year,this.month,U-B,q)?1:0;else if(q)throw Error(`CronDate: Invalid value for dayOfWeek encountered. ${q}`);$.useAndLogic?G=G&&q:!Q.domAndDow&&!$.starDOM?G=G||q:G=G&&q}if(G)return this[w]=U-B,Y!==this[w]?2:1}return 3}recurse(Q,w,$){if($===0&&!Q.starYear){if(this.year>=0&&this.year<Q.year.length&&Q.year[this.year]===0){let X=-1;for(let Y=this.year+1;Y<Q.year.length&&Y<1e4;Y++)if(Q.year[Y]===1){X=Y;break}if(X===-1)return null;this.year=X,this.month=0,this.day=1,this.hour=0,this.minute=0,this.second=0,this.ms=0}if(this.year>=1e4)return null}let B=this.findNext(w,h8[$][0],Q,h8[$][2]);if(B>1){let X=$+1;for(;X<h8.length;)this[h8[X][0]]=-h8[X][2],X++;if(B===3){if(this[h8[$][1]]++,this[h8[$][0]]=-h8[$][2],this.apply(),$===0&&!Q.starYear){for(;this.year>=0&&this.year<Q.year.length&&Q.year[this.year]===0&&this.year<1e4;)this.year++;if(this.year>=1e4||this.year>=Q.year.length)return null}return this.recurse(Q,w,0)}else if(this.apply())return this.recurse(Q,w,$-1)}return $+=1,$>=h8.length?this:(Q.starYear?this.year>=3000:this.year>=1e4)?null:this.recurse(Q,w,$)}increment(Q,w,$){return this.second+=w.interval!==void 0&&w.interval>1&&$?w.interval:1,this.ms=0,this.apply(),this.recurse(Q,w,0)}decrement(Q,w){return this.second-=w.interval!==void 0&&w.interval>1?w.interval:1,this.ms=0,this.apply(),this.recurseBackward(Q,w,0,0)}recurseBackward(Q,w,$,B=0){if(B>1e4)return null;if($===0&&!Q.starYear){if(this.year>=0&&this.year<Q.year.length&&Q.year[this.year]===0){let Y=-1;for(let Z=this.year-1;Z>=0;Z--)if(Q.year[Z]===1){Y=Z;break}if(Y===-1)return null;this.year=Y,this.month=11,this.day=31,this.hour=23,this.minute=59,this.second=59,this.ms=0}if(this.year<0)return null}let X=this.findPrevious(w,h8[$][0],Q,h8[$][2]);if(X>1){let Y=$+1;for(;Y<h8.length;){let Z=h8[Y][0],H=h8[Y][2],W=this.getMaxPatternValue(Z,Q,H);this[Z]=W,Y++}if(X===3){if(this[h8[$][1]]--,$===0){let K=this.getLastDayOfMonth(this.year,this.month);this.day>K&&(this.day=K)}if($===1)if(this.day<=0)this.day=1;else{let K=this.year,U=this.month;for(;U<0;)U+=12,K--;for(;U>11;)U-=12,K++;let G=U!==1?ae0[U]:new Date(Date.UTC(K,U+1,0)).getUTCDate();this.day>G&&(this.day=G)}this.apply();let Z=h8[$][0],H=h8[$][2],W=this.getMaxPatternValue(Z,Q,H);if(Z==="day"){let K=this.getLastDayOfMonth(this.year,this.month);this[Z]=Math.min(W,K)}else this[Z]=W;if(this.apply(),$===0){let K=h8[1][2],U=this.getMaxPatternValue("day",Q,K),G=this.getLastDayOfMonth(this.year,this.month),q=Math.min(U,G);q!==this.day&&(this.day=q,this.hour=this.getMaxPatternValue("hour",Q,h8[2][2]),this.minute=this.getMaxPatternValue("minute",Q,h8[3][2]),this.second=this.getMaxPatternValue("second",Q,h8[4][2]))}if($===0&&!Q.starYear){for(;this.year>=0&&this.year<Q.year.length&&Q.year[this.year]===0;)this.year--;if(this.year<0)return null}return this.recurseBackward(Q,w,0,B+1)}else if(this.apply())return this.recurseBackward(Q,w,$-1,B+1)}return $+=1,$>=h8.length?this:this.year<0?null:this.recurseBackward(Q,w,$,B+1)}getMaxPatternValue(Q,w,$){if(Q==="day"&&w.lastDayOfMonth)return this.getLastDayOfMonth(this.year,this.month);if(Q==="day"&&!w.starDOW)return this.getLastDayOfMonth(this.year,this.month);for(let B=w[Q].length-1;B>=0;B--)if(w[Q][B])return B-$;return w[Q].length-1-$}findPrevious(Q,w,$,B){return this._findMatch(Q,w,$,B,-1)}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)):A82(te0(this.year,this.month+1,this.day,this.hour,this.minute,this.second,this.tz),!1)}getTime(){return this.getDate(!1).getTime()}match(Q,w){if(!Q.starYear&&(this.year<0||this.year>=Q.year.length||Q.year[this.year]===0))return!1;for(let $=0;$<h8.length;$++){let B=h8[$][0],X=h8[$][2],Y=this[B];if(Y+X<0||Y+X>=Q[B].length)return!1;let Z=Q[B][Y+X];if(B==="day"){if(!Z){for(let H=0;H<Q.nearestWeekdays.length;H++)if(Q.nearestWeekdays[H]){let W=this.getNearestWeekday(this.year,this.month,H-X);if(W!==-1&&W===Y){Z=1;break}}}if(Q.lastWeekday){let H=this.getLastWeekday(this.year,this.month);Y===H&&(Z=1)}if(Q.lastDayOfMonth){let H=this.getLastDayOfMonth(this.year,this.month);Y===H&&(Z=1)}if(!Q.starDOW){let H=new Date(Date.UTC(this.year,this.month,1,0,0,0,0)).getUTCDay(),W=Q.dayOfWeek[(H+(Y-1))%7];W&&W&63&&(W=this.isNthWeekdayOfMonth(this.year,this.month,Y,W)?1:0),Q.useAndLogic?Z=Z&&W:!w.domAndDow&&!Q.starDOM?Z=Z||W:Z=Z&&W}}if(!Z)return!1}return!0}};function vPw(A){if(A===void 0&&(A={}),delete A.name,A.legacyMode!==void 0&&A.domAndDow===void 0?A.domAndDow=!A.legacyMode:A.domAndDow===void 0&&(A.domAndDow=!1),A.legacyMode=!A.domAndDow,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.dayOffset=A.dayOffset===void 0?0:parseInt(A.dayOffset.toString(),10),A.unref=A.unref===void 0?!1:A.unref,A.mode=A.mode===void 0?"auto":A.mode,A.alternativeWeekdays=A.alternativeWeekdays===void 0?!1:A.alternativeWeekdays,A.sloppyRanges=A.sloppyRanges===void 0?!1:A.sloppyRanges,!["auto","5-part","6-part","7-part","5-or-6-parts","6-or-7-parts"].includes(A.mode))throw Error("CronOptions: mode must be one of 'auto', '5-part', '6-part', '7-part', '5-or-6-parts', or '6-or-7-parts'.");if(A.startAt&&(A.startAt=new D4(A.startAt,A.timezone)),A.stopAt&&(A.stopAt=new D4(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).");if(A.dayOffset!==void 0&&A.dayOffset!==0&&isNaN(A.dayOffset))throw Error("CronOptions: Invalid value passed for dayOffset, should be a number representing days to offset.");return A}function Ba(A){return Object.prototype.toString.call(A)==="[object Function]"||typeof A=="function"||A instanceof Function}function hPw(A){return Ba(A)}function CPw(A){typeof Deno<"u"&&typeof Deno.unrefTimer<"u"?Deno.unrefTimer(A):A&&typeof A.unref<"u"&&A.unref()}var e$2=30000,zH0=[],ee0=class{name;options;_states;fn;getTz(){return this.options.timezone||this.options.utcOffset}applyDayOffset(A){if(this.options.dayOffset!==void 0&&this.options.dayOffset!==0){let Q=this.options.dayOffset*24*60*60*1000;return new Date(A.getTime()+Q)}return A}constructor(A,Q,w){let $,B;if(Ba(Q))B=Q;else if(typeof Q=="object")$=Q;else if(Q!==void 0)throw Error("Cron: Invalid argument passed for optionsIn. Should be one of function, or object (options).");if(Ba(w))B=w;else if(typeof w=="object")$=w;else if(w!==void 0)throw Error("Cron: Invalid argument passed for funcIn. Should be one of function, or object (options).");if(this.name=$?.name,this.options=vPw($),this._states={kill:!1,blocking:!1,previousRun:void 0,currentRun:void 0,once:void 0,currentTimeout:void 0,maxRuns:$?$.maxRuns:void 0,paused:$?$.paused:!1,pattern:new t$2("* * * * *",void 0,{mode:"auto"})},A&&(A instanceof Date||typeof A=="string"&&A.indexOf(":")>0)?this._states.once=new D4(A,this.getTz()):this._states.pattern=new t$2(A,this.options.timezone,{mode:this.options.mode,alternativeWeekdays:this.options.alternativeWeekdays,sloppyRanges:this.options.sloppyRanges}),this.name){if(zH0.find((X)=>X.name===this.name))throw Error("Cron: Tried to initialize new named job '"+this.name+"', but name already taken.");zH0.push(this)}return B!==void 0&&hPw(B)&&(this.fn=B,this.schedule()),this}nextRun(A){let Q=this._next(A);return Q?this.applyDayOffset(Q.getDate(!1)):null}nextRuns(A,Q){this._states.maxRuns!==void 0&&A>this._states.maxRuns&&(A=this._states.maxRuns);let w=Q||this._states.currentRun||void 0;return this._enumerateRuns(A,w,"next")}previousRuns(A,Q){return this._enumerateRuns(A,Q||void 0,"previous")}_enumerateRuns(A,Q,w){let $=[],B=Q?new D4(Q,this.getTz()):null,X=w==="next"?this._next:this._previous;for(;A--;){let Y=X.call(this,B);if(!Y)break;let Z=Y.getDate(!1);$.push(this.applyDayOffset(Z)),B=Y}return $}match(A){if(this._states.once){let w=new D4(A,this.getTz());w.ms=0;let $=new D4(this._states.once,this.getTz());return $.ms=0,w.getTime()===$.getTime()}let Q=new D4(A,this.getTz());return Q.ms=0,Q.match(this._states.pattern,this.options)}getPattern(){if(!this._states.once)return this._states.pattern?this._states.pattern.pattern:void 0}getOnce(){return this._states.once?this._states.once.getDate():null}isRunning(){let A=this.nextRun(this._states.currentRun),Q=!this._states.paused,w=this.fn!==void 0,$=!this._states.kill;return Q&&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 D4||A instanceof Date?Q.getTime()-A.getTime():Q.getTime()-new D4(A).getTime():null}stop(){this._states.kill=!0,this._states.currentTimeout&&clearTimeout(this._states.currentTimeout);let A=zH0.indexOf(this);A>=0&&zH0.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(),w=this.nextRun(this._states.currentRun);return Q==null||isNaN(Q)||w===null?this:(Q>e$2&&(Q=e$2),this._states.currentTimeout=setTimeout(()=>this._checkTrigger(w),Q),this._states.currentTimeout&&this.options.unref&&CPw(this._states.currentTimeout),this)}async _trigger(A){this._states.blocking=!0,this._states.currentRun=new D4(void 0,this.getTz());try{if(this.options.catch)try{this.fn!==void 0&&await this.fn(this,this.options.context)}catch(Q){if(Ba(this.options.catch))try{this.options.catch(Q,this)}catch{}}else this.fn!==void 0&&await this.fn(this,this.options.context)}finally{this._states.previousRun=new D4(A,this.getTz()),this._states.blocking=!1}}async trigger(){await this._trigger()}runsLeft(){return this._states.maxRuns}_checkTrigger(A){let Q=new Date,w=!this._states.paused&&Q.getTime()>=A.getTime(),$=this._states.blocking&&this.options.protect;w&&!$?(this._states.maxRuns!==void 0&&this._states.maxRuns--,this._trigger()):w&&$&&Ba(this.options.protect)&&setTimeout(()=>this.options.protect(this),0),this.schedule()}_next(A){let Q=!!(A||this._states.currentRun),w=!1;!A&&this.options.startAt&&this.options.interval&&([A,Q]=this._calculatePreviousRun(A,Q),w=!A),A=new D4(A,this.getTz()),this.options.startAt&&A&&A.getTime()<this.options.startAt.getTime()&&(A=this.options.startAt);let $=this._states.once||new D4(A,this.getTz());return!w&&$!==this._states.once&&($=$.increment(this._states.pattern,this.options,Q)),this._states.once&&this._states.once.getTime()<=A.getTime()||$===null||this._states.maxRuns!==void 0&&this._states.maxRuns<=0||this._states.kill||this.options.stopAt&&$.getTime()>=this.options.stopAt.getTime()?null:$}_previous(A){let Q=new D4(A,this.getTz());this.options.stopAt&&Q.getTime()>this.options.stopAt.getTime()&&(Q=this.options.stopAt);let w=new D4(Q,this.getTz());return this._states.once?this._states.once.getTime()<Q.getTime()?this._states.once:null:(w=w.decrement(this._states.pattern,this.options),w===null||this.options.startAt&&w.getTime()<this.options.startAt.getTime()?null:w)}_calculatePreviousRun(A,Q){let w=new D4(void 0,this.getTz()),$=A;if(this.options.startAt.getTime()<=w.getTime()){$=this.options.startAt;let B=$.getTime()+this.options.interval*1000;for(;B<=w.getTime();)$=new D4($,this.getTz()).increment(this._states.pattern,this.options,!0),B=$.getTime()+this.options.interval*1000;Q=!0}return $===null&&($=void 0),[$,Q]}};class VH0{scheduleCron(A,Q){let w=new ee0(A,()=>{Q()});return{stop:()=>w.stop()}}scheduleInterval(A,Q){let w=setInterval(()=>{Q()},A);return{stop:()=>clearInterval(w)}}validateCron(A){new ee0(A).stop()}}C0();var w82=f.union([f.string().min(1),f.object({location:f.enum(["metadata","frontmatter"]),field:f.string().min(1)})]),JH0=f.object({entityType:f.string().min(1),attachmentType:f.string().min(1),mediaEntityType:f.enum(["image","document"]),targetEntityField:w82.optional(),requiredWhen:f.object({status:f.string().min(1).optional(),visibility:f.string().min(1).optional()}).optional(),autoGenerate:f.boolean().optional(),requiredForPublish:f.boolean().optional(),jobType:f.string().min(1).optional()});function A0A(A){return`${A.entityType}:${A.attachmentType}`}class uq{static instance=null;definitions=new Map;static getInstance(){return uq.instance??=new uq,uq.instance}static resetInstance(){uq.instance=null}static createFresh(){return new uq}constructor(){}register(A){let Q=JH0.parse(A),w=A0A(Q);return this.definitions.set(w,Q),()=>this.unregister(Q.entityType,Q.attachmentType)}get(A,Q){return this.definitions.get(A0A({entityType:A,attachmentType:Q}))}list(A){let Q=Array.from(this.definitions.values());return A?Q.filter((w)=>w.entityType===A):Q}has(A,Q){return this.get(A,Q)!==void 0}unregister(A,Q){this.definitions.delete(A0A({entityType:A,attachmentType:Q}))}clear(){this.definitions.clear()}}H7();b2();class IH0{deps;constructor(A){this.deps=A}async ensureForEntity(A,Q={}){let w=this.deps.registry.list(A.entityType).filter((B)=>B.autoGenerate===!0).filter((B)=>!Q.attachmentType||B.attachmentType===Q.attachmentType),$={checked:w.length,enqueued:0,skipped:0};for(let B of w)if(await this.ensureDefinition(A,B))$.enqueued+=1;else $.skipped+=1;return $}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 w=this.resolveJobType(Q);if(!w)return!1;let $=this.getPredictedMediaId(A,Q),B=this.getDeduplicationKey(A,Q);return await this.deps.context.jobs.enqueue({type:w,data:{sourceEntityType:A.entityType,sourceEntityId:A.id,attachmentType:Q.attachmentType,imageId:$,dedupKey:B,targetEntityType:A.entityType,targetEntityId:A.id,...this.getTargetImageFieldData(Q.targetEntityField)},options:{source:"content-pipeline",metadata:{operationType:"content_operations"},deduplication:"skip",deduplicationKey:B}}),this.deps.context.logger.debug("Queued publish asset generation",{entityType:A.entityType,entityId:A.id,attachmentType:Q.attachmentType,jobType:w}),!0}matchesPolicy(A,Q){let{requiredWhen:w}=Q;if(!w)return!0;if(w.status&&A.metadata.status!==w.status)return!1;if(w.visibility&&A.visibility!==w.visibility)return!1;return!0}hasTargetField(A,Q){if(!Q)return!1;if(typeof Q==="string")return Q0A(A.metadata[Q]);if(Q.location==="metadata")return Q0A(A.metadata[Q.field]);let{frontmatter:w}=l6(A.content);return Q0A(w[Q.field])}resolveJobType(A){if(A.jobType)return A.jobType;if(A.mediaEntityType==="image")return"image:image-render-source";return}getPredictedMediaId(A,Q){let w=Q.attachmentType==="og-image"?"og":Q.attachmentType;return q1(`${w}-${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 Q0A(A){return typeof A==="string"?A.length>0:A!==void 0}fA();C0();var gPw=f.object({id:f.string().min(1)});async function B82(A,Q){let{bodyContent:w,coverImageId:$,documents:B,sourceEntityType:X,sourceEntityId:Y}=yPw(Q.content),Z=$?await SPw(A,$):void 0,H;if(B&&B.length>0){let K=await mPw(A,B);if(K.length>0)H=K}H??=await TPw(A,X,Y);let W={bodyContent:w};if(Z)W.imageData=Z;if(H&&H.length>0)W.documentData=H;return W}function yPw(A){try{let Q=$Q(A,f.record(f.string(),f.unknown())),w=Q.metadata.coverImageId,$=typeof w==="string"?w:void 0,B=EPw(Q.metadata.documents),X=$82(Q.metadata.sourceEntityType),Y=$82(Q.metadata.sourceEntityId);return{bodyContent:Q.content,...$&&{coverImageId:$},...B.length>0&&{documents:B},...X&&{sourceEntityType:X},...Y&&{sourceEntityId:Y}}}catch{return{bodyContent:A}}}function EPw(A){if(!Array.isArray(A))return[];return A.flatMap((Q)=>{let w=gPw.safeParse(Q);return w.success?[w.data]:[]})}function $82(A){return typeof A==="string"&&A.length>0?A:void 0}async function TPw(A,Q,w){if(!Q||!w)return;let $=await A.attachments.resolve({sourceEntityType:Q,sourceEntityId:w,attachmentType:"carousel"});return $?[$]:void 0}async function SPw(A,Q){let w=await A.entityService.getEntity({entityType:"image",id:Q});if(!w?.content)return;let $=X82(w.content);if(!$?.mimeType.startsWith("image/"))return;return{data:$.data,mimeType:$.mimeType}}async function mPw(A,Q){return(await Promise.all(Q.map(($)=>uPw(A,$)))).filter(($)=>$!==void 0)}async function uPw(A,Q){let w=await A.entityService.getEntity({entityType:"document",id:Q.id});if(!w?.content)return;let $=X82(w.content);if($?.mimeType!=="application/pdf")return;return{type:"document",data:$.data,mimeType:"application/pdf",filename:cPw(w,Q.id)}}function X82(A){let Q=A.match(/^data:([^;]+);base64,(.+)$/);if(!Q?.[1]||!Q[2])return;return{mimeType:Q[1],data:Buffer.from(Q[2],"base64")}}function cPw(A,Q){let w=A.metadata.filename;return typeof w==="string"&&w.length>0?w:`${Q}.pdf`}H7();var lPw=/^---\r?\n[\s\S]*?\r?\n---(?:\r?\n|$)/;async function w0A(A,Q,w,$={}){let B=$.publishTimestampField??"publishedAt",X=Q.metadata[B],Y=$.publishedAt??(typeof X==="string"?X:void 0)??new Date().toISOString(),Z={...Q.metadata,status:"published",[B]:Y,platformId:w.id,...pPw(w.id,$.publishResultIdField)},H={...Q,content:Y82(Q.content,Y,w.id,$.publishResultIdField,B),metadata:Z};return await A.entityService.updateEntity({entity:H}),H}function Y82(A,Q,w,$,B="publishedAt"){if(!lPw.test(A))return A;let X=E4(E4(A,"status","published"),B,Q);if(!w||!$)return X;return E4(X,$,w)}function pPw(A,Q){if(!Q||Q==="platformId")return{};return{[Q]:A}}class SE{deps;constructor(A){this.deps=A}async resolveCandidate(A){let{entityType:Q,id:w,slug:$}=A;if(!w&&!$)return{error:"Either 'id' or 'slug' must be provided"};let B=await this.findPublishableEntity(Q,w,$);if(!B)return{error:`Entity not found: ${Q}:${w??$}`};if(B.visibility!=="public")return{error:`Cannot publish ${Q}:${B.id} to a public provider because visibility is ${B.visibility}`};if(B.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:B}}async publish(A){let Q=await this.resolveCandidate(A);if("error"in Q)return Q;let{entity:w}=Q,{entityType:$}=A,B=this.deps.providerRegistry.get($),{bodyContent:X,imageData:Y,documentData:Z}=await B82(this.deps.context,w),H=await B.publish(X,w.metadata,Y,Z),W=this.deps.providerRegistry.getPublishResultIdField($),K=this.deps.providerRegistry.getPublishTimestampField($),U=await w0A(this.deps.context,w,H,{...W?{publishResultIdField:W}:{},...K?{publishTimestampField:K}:{}});return await this.runPublishAssetPreflight(U),{entity:U,result:H}}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,w){if(Q)return this.deps.context.entityService.getEntity({entityType:A,id:Q});if(!w)return null;return(await this.deps.context.entityService.listEntities({entityType:A,options:{filter:{metadata:{slug:w}},limit:1}}))[0]??null}}fA();C0();var $0A=f.object({action:f.enum(["list","add","remove","reorder"]).describe("Queue action to perform"),entityType:f.string().optional().describe("Entity type (required for add/remove/reorder, optional for list)"),entityId:f.string().optional().describe("Entity ID (required for add/remove/reorder)"),position:f.number().optional().describe("New position for reorder action (1-based)")}),B0A=f.object({position:f.number(),entityType:f.string(),entityId:f.string(),queuedAt:f.string()}),iPw=f.object({success:f.literal(!0),message:f.string().optional(),data:f.object({queue:f.array(B0A).optional(),entityType:f.string().optional(),entityId:f.string().optional(),position:f.number().optional()}).optional()}),dPw=f.object({success:f.literal(!1),error:f.string(),code:f.string().optional()}),X0A=f.union([iPw,dPw]);function FH0(A,Q,w){return{...p6(Q,"queue","Manage the publish queue for all entity types (list, add, remove, reorder)",$0A,async(B,X)=>{let{action:Y,entityType:Z,entityId:H,position:W}=B;switch(Y){case"list":return nPw(w,Z);case"add":return rPw(A,w,Z,H,X);case"remove":return oPw(A,w,Z,H,X);case"reorder":return sPw(A,w,Z,H,W,X);default:return{success:!1,error:`Unknown action: ${Y}`}}},{sideEffects:"writes"}),outputSchema:X0A}}async function nPw(A,Q){let w=[];if(Q)w=await A.list(Q);else{let B=A.getRegisteredTypes();for(let X of B){let Y=await A.list(X);w.push(...Y)}w.sort((X,Y)=>new Date(X.queuedAt).getTime()-new Date(Y.queuedAt).getTime())}if(w.length===0)return{success:!0,data:{queue:[]},message:"No items in queue"};return{success:!0,data:{queue:w.map((B,X)=>({position:X+1,entityType:B.entityType,entityId:B.entityId,queuedAt:B.queuedAt}))},message:`${w.length} items in queue`}}async function rPw(A,Q,w,$,B){let X=Y0A("add",w,$);if(!X.success)return X.error;A.permissions.assertEntityActionAllowed(X.entityType,"publish",B??{});let Y=await Q.add(X.entityType,X.entityId,{...B,authorization:"user"});return{success:!0,data:{entityType:X.entityType,entityId:X.entityId,position:Y.position},message:`Added to queue at position ${Y.position}`}}async function oPw(A,Q,w,$,B){let X=Y0A("remove",w,$);if(!X.success)return X.error;return A.permissions.assertEntityActionAllowed(X.entityType,"update",B??{}),await Q.remove(X.entityType,X.entityId),{success:!0,data:{entityType:X.entityType,entityId:X.entityId},message:"Removed from queue"}}async function sPw(A,Q,w,$,B,X){let Y=Y0A("reorder",w,$);if(!Y.success)return Y.error;let Z=aPw(B);if(!Z.success)return Z.error;return A.permissions.assertEntityActionAllowed(Y.entityType,"update",X??{}),await Q.reorder(Y.entityType,Y.entityId,Z.position),{success:!0,data:{entityType:Y.entityType,entityId:Y.entityId,position:Z.position},message:`Moved to position ${Z.position}`}}function Y0A(A,Q,w){if(!Q)return{success:!1,error:{success:!1,error:`entityType is required for ${A} action`}};if(!w)return{success:!1,error:{success:!1,error:`entityId is required for ${A} action`}};return{success:!0,entityType:Q,entityId:w}}function aPw(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}}C0();import{createHash as tPw}from"crypto";var Z0A=f.object({entityType:f.string().describe("Entity type to publish (e.g., social-post, post, deck)"),id:f.string().optional().describe("Entity ID to publish"),slug:f.string().optional().describe("Entity slug to publish"),confirmed:f.boolean().optional(),confirmationToken:f.string().optional(),contentHash:f.string().optional(),expiresAt:f.string().datetime().optional()}),ePw=f.object({entityType:f.string(),id:f.string().optional(),slug:f.string().optional(),confirmed:f.boolean().optional(),confirmationToken:f.string().optional(),contentHash:f.string().optional(),expiresAt:f.string().datetime().optional()}),AMw=f.object({success:f.literal(!0),message:f.string().optional(),data:f.object({entityType:f.string().optional(),entityId:f.string().optional(),platformId:f.string().optional(),url:f.string().optional()}).optional()}),QMw=f.object({success:f.literal(!1),error:f.string(),code:f.string().optional()}),wMw=f.object({success:f.literal(!1).optional(),error:f.string().optional(),needsConfirmation:f.literal(!0),toolName:f.string(),summary:f.string(),preview:f.string().optional(),args:f.unknown()}),f0A=f.union([AMw,QMw,wMw]),$Mw=900000;function bH0(A,Q,w,$){let B=$??new SE({context:A,providerRegistry:w}),X=`${Q}_publish`;return{name:X,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.). For follow-up requests like 'publish it now', use the entity just read, generated, or updated in the conversation, including a post just changed to draft.",inputSchema:Z0A.shape,outputSchema:f0A,visibility:"anchor",sideEffects:"external",handler:async(Y,Z)=>{let H=ePw.safeParse(Y);if(!H.success)return{success:!1,error:`Invalid input: ${H.error.issues.map((I)=>`${I.path.join(".")}: ${I.message}`).join(", ")}`};let W=H.data,{entityType:K,id:U,slug:G}=W;try{A.permissions.assertEntityActionAllowed(K,"publish",Z)}catch(I){return{success:!1,error:I instanceof Error?I.message:String(I)}}let q=await B.resolveCandidate({entityType:K,id:U,slug:G});if("error"in q)return{success:!1,error:q.error};let{entity:V}=q;if(W.confirmed){let I=XMw(X,W,V);if(I!==null)return I;let J;try{J=await B.publish({entityType:K,id:V.id})}catch(_){return{success:!1,error:_ instanceof Error?_.message:String(_)}}if("error"in J)return{success:!1,error:J.error};let{entity:k,result:j}=J;return{success:!0,data:{entityType:K,entityId:k.id,platformId:j.id,url:j.url},message:`Published ${K}:${k.id}`}}return BMw(X,W,V)}}}function BMw(A,Q,w){let $=new Date(Date.now()+$Mw).toISOString(),B=Z82(A,w,$),X=YMw(w);return{needsConfirmation:!0,toolName:A,summary:`Publish "${X}"?`,preview:`This will publish ${w.entityType}:${w.id} to its registered public publish provider.`,args:{...Q,id:w.id,slug:void 0,confirmed:!0,confirmationToken:B,contentHash:w.contentHash,expiresAt:$}}}function XMw(A,Q,w){let{confirmationToken:$,contentHash:B,expiresAt:X}=Q;if(!$||!X)return{success:!1,error:"Invalid publish confirmation token. Request confirmation again and retry with the returned confirmation args.",code:"INVALID_CONFIRMATION_TOKEN"};let Y=Date.parse(X);if(Number.isNaN(Y))return{success:!1,error:"Invalid publish confirmation expiry. Request confirmation again and retry with the returned confirmation args.",code:"INVALID_CONFIRMATION_TOKEN"};if(Y<=Date.now())return{success:!1,error:"Publish confirmation expired. Request confirmation again before publishing.",code:"EXPIRED_CONFIRMATION_TOKEN"};if(B&&B!==w.contentHash)return{success:!1,error:`Cannot publish ${w.entityType}:${w.id} because it changed after confirmation. Review it and try again.`};if($!==Z82(A,w,X))return{success:!1,error:"Invalid publish confirmation token. Request confirmation again and retry with the returned confirmation args.",code:"INVALID_CONFIRMATION_TOKEN"};return null}function Z82(A,Q,w){return tPw("sha256").update(A).update("\x00").update(Q.entityType).update("\x00").update(Q.id).update("\x00").update(Q.contentHash).update("\x00").update(w).digest("hex")}function YMw(A){let Q=A.metadata.title;if(typeof Q==="string"&&Q.length>0)return Q;let w=A.metadata.subject;if(typeof w==="string"&&w.length>0)return w;let $=A.metadata.slug;if(typeof $==="string"&&$.length>0)return $;return A.id}fA();C0();var H0A=f.object({entityType:f.string().min(1).describe("Entity type to reconcile"),status:f.string().min(1).optional().describe("Optional metadata status filter, e.g. published"),assetType:f.string().min(1).optional().describe("Optional attachment type filter, e.g. og-image")}),W0A=f.object({success:f.literal(!0),data:f.object({entityType:f.string(),assetType:f.string().optional(),checkedEntities:f.number(),checkedAssets:f.number(),enqueued:f.number(),skipped:f.number()}),message:f.string().optional()});function LH0(A,Q,w,$){return{...p6(Q,"ensure-assets","Reconcile configured publish assets for existing entities, queueing missing generated assets such as OG images.",H0A,async(X,Y)=>{if(A.permissions.assertEntityActionAllowed(X.entityType,"publish",Y),w.list(X.entityType).filter((G)=>G.autoGenerate===!0).filter((G)=>!X.assetType||G.attachmentType===X.assetType).length===0)return{success:!0,data:{entityType:X.entityType,...X.assetType&&{assetType:X.assetType},checkedEntities:0,checkedAssets:0,enqueued:0,skipped:0},message:`No publish assets configured for ${X.entityType}`};let H=await A.entityService.listEntities({entityType:X.entityType,options:{...X.status&&{filter:{metadata:{status:X.status}}}}}),W=0,K=0,U=0;for(let G of H){let q=await $.ensureForEntity(G,{...X.assetType&&{attachmentType:X.assetType}});W+=q.checked,K+=q.enqueued,U+=q.skipped}return{success:!0,data:{entityType:X.entityType,...X.assetType&&{assetType:X.assetType},checkedEntities:H.length,checkedAssets:W,enqueued:K,skipped:U},message:`Queued ${K} publish asset job(s)`}},{sideEffects:"writes"}),outputSchema:W0A}}fA();function f82(A,Q){ZMw(A,Q),fMw(A,Q),HMw(A,Q),WMw(A,Q)}function ZMw(A,Q){A.messaging.subscribe(FY.REGISTER,async(w)=>KMw(Q,w.payload)),A.messaging.subscribe(FY.QUEUE,async(w)=>qMw(A,Q,w.payload)),A.messaging.subscribe(FY.DIRECT,async(w)=>zMw(A,Q,w.payload)),A.messaging.subscribe(FY.REMOVE,async(w)=>VMw(Q,w.payload)),A.messaging.subscribe(FY.REORDER,async(w)=>JMw(Q,w.payload)),A.messaging.subscribe(FY.LIST,async(w)=>IMw(A,Q,w.payload)),A.messaging.subscribe(FY.REPORT_SUCCESS,async(w)=>FMw(Q,w.payload)),A.messaging.subscribe(FY.REPORT_FAILURE,async(w)=>bMw(Q,w.payload)),Q.logger.debug("Subscribed to publish messages")}function fMw(A,Q){A.messaging.subscribe(PL.REPORT_SUCCESS,async(w)=>LMw(Q,w.payload)),A.messaging.subscribe(PL.REPORT_FAILURE,async(w)=>kMw(Q,w.payload)),Q.logger.debug("Subscribed to generation messages")}function HMw(A,Q){A.messaging.subscribe(l$2.REGISTER,async(w)=>UMw(Q,w.payload)),Q.logger.debug("Subscribed to publish asset messages")}function WMw(A,Q){let w=async($)=>GMw(A,Q,$.payload);A.messaging.subscribe("entity:created",w),A.messaging.subscribe("entity:updated",w),Q.logger.debug("Subscribed to entity change messages for publish assets")}async function KMw(A,Q){let{entityType:w,provider:$,config:B}=Q;try{let X=B?p$2.safeParse(B):void 0;if(X&&!X.success)return A.logger.warn("Invalid publish provider config",{entityType:w,error:X.error.message}),{success:!1};if($)A.providerRegistry.register(w,$,X?.data),A.logger.info(`Registered provider for entity type: ${w}`,{providerName:$.name,executionMode:A.providerRegistry.getExecutionMode(w)});return{success:!0}}catch(X){let Y=dA(X);return A.logger.error(`Failed to register provider: ${Y}`),{success:!1}}}async function UMw(A,Q){let w=JH0.safeParse(Q);if(!w.success)return A.logger.warn("Invalid publish asset registration",{error:w.error.message}),{success:!1};return A.publishAssetRegistry.register(w.data),A.logger.info("Registered publish asset",{entityType:w.data.entityType,attachmentType:w.data.attachmentType,mediaEntityType:w.data.mediaEntityType}),{success:!0}}async function GMw(A,Q,w){try{if(Q.publishAssetRegistry.list(w.entityType).length===0)return{success:!0};let $=w.entity??await A.entityService.getEntity({entityType:w.entityType,id:w.entityId});if(!DMw($))return{success:!0};return await Q.publishAssetPreflight.ensureForEntity($),{success:!0}}catch($){return Q.logger.warn("Failed to run publish asset preflight for entity event",{entityType:w.entityType,entityId:w.entityId,error:dA($)}),{success:!1}}}function DMw(A){if(!A)return!1;let Q=c$2.safeParse(A.metadata);return Q.success&&Q.data.status==="published"}async function qMw(A,Q,w){let{entityType:$,entityId:B}=w;try{let X=w.authContext??Qa;A.permissions.assertEntityActionAllowed($,"publish",X);let Y=await Q.queueManager.add($,B,X);return await A.messaging.send({type:FY.QUEUED,payload:{entityType:$,entityId:B,position:Y.position}}),Q.logger.debug(`Entity queued: ${B}`,{entityType:$,position:Y.position}),{success:!0}}catch(X){let Y=dA(X);return Q.logger.error(`Failed to queue entity: ${Y}`),{success:!1}}}async function zMw(A,Q,w){let{entityType:$,entityId:B}=w,X=w.authContext??Qa;try{if(A.permissions.assertEntityActionAllowed($,"publish",X),!Q.providerRegistry.has($))return Q.scheduler.failPublish($,B,`No publish provider registered for ${$}`),{success:!1};let Y=await Q.publishExecutor.publish({entityType:$,id:B});if("error"in Y)return Q.scheduler.failPublish($,B,Y.error),{success:!1};return Q.scheduler.completePublish($,B,Y.result),Q.logger.debug(`Direct publish completed: ${B}`,{entityType:$}),{success:!0}}catch(Y){let Z=dA(Y);return Q.logger.error(`Failed direct publish request: ${Z}`),{success:!1}}}async function VMw(A,Q){let{entityType:w,entityId:$}=Q;try{return await A.queueManager.remove(w,$),A.logger.debug(`Entity removed from queue: ${$}`,{entityType:w}),{success:!0}}catch(B){let X=dA(B);return A.logger.error(`Failed to remove entity: ${X}`),{success:!1}}}async function JMw(A,Q){let{entityType:w,entityId:$,position:B}=Q;try{return await A.queueManager.reorder(w,$,B),A.logger.debug(`Entity reordered: ${$}`,{entityType:w,newPosition:B}),{success:!0}}catch(X){let Y=dA(X);return A.logger.error(`Failed to reorder entity: ${Y}`),{success:!1}}}async function IMw(A,Q,w){let{entityType:$}=w;try{let B=await Q.queueManager.list($);return await A.messaging.send({type:FY.LIST_RESPONSE,payload:{entityType:$,queue:B.map((X)=>({entityId:X.entityId,position:X.position,queuedAt:X.queuedAt}))}}),{success:!0}}catch(B){let X=dA(B);return Q.logger.error(`Failed to list queue: ${X}`),{success:!1}}}async function FMw(A,Q){let{entityType:w,entityId:$,result:B}=Q;return A.scheduler.completePublish(w,$,B),A.logger.info(`Publish reported success: ${$}`,{entityType:w}),{success:!0}}async function bMw(A,Q){let{entityType:w,entityId:$,error:B}=Q;A.scheduler.failPublish(w,$,B);let X=A.retryTracker.getRetryInfo($);return A.logger.info(`Publish reported failure: ${$}`,{entityType:w,error:B,retryCount:X?.retryCount}),{success:!0}}async function LMw(A,Q){let{entityType:w,entityId:$}=Q;return A.scheduler.completeGeneration(w,$),A.logger.info("Generation completed",{entityType:w,entityId:$}),{success:!0}}async function kMw(A,Q){let{entityType:w,error:$}=Q;return A.scheduler.failGeneration(w,$),A.logger.warn("Generation failed",{entityType:w,error:$}),{success:!0}}async function H82(A,Q,w,$){try{if($.skipIfDraftExists!==!1){if((await A.listEntities({entityType:w,options:{filter:{metadata:{status:"draft"}},limit:1}})).length>0)return{shouldGenerate:!1,reason:"Draft already exists"}}if($.maxUnpublishedDrafts!==void 0){let B=await A.listEntities({entityType:w,options:{filter:{metadata:{status:"draft"}},limit:$.maxUnpublishedDrafts+1}});if(B.length>=$.maxUnpublishedDrafts)return{shouldGenerate:!1,reason:`Max unpublished drafts reached (${B.length}/${$.maxUnpublishedDrafts})`}}if($.minSourceEntities!==void 0&&$.sourceEntityType){let B=await A.listEntities({entityType:$.sourceEntityType,options:{publishedOnly:!0,limit:$.minSourceEntities}});if(B.length<$.minSourceEntities)return{shouldGenerate:!1,reason:`Not enough source entities (${B.length}/${$.minSourceEntities} ${$.sourceEntityType})`}}return{shouldGenerate:!0}}catch(B){return Q.error("Failed to check generation conditions",{entityType:w,error:dA(B)}),{shouldGenerate:!1,reason:`Condition check failed: ${dA(B)}`}}}function W82(A){let{context:Q,config:w,queueManager:$,providerRegistry:B,retryTracker:X,publishExecutor:Y,logger:Z}=A,H=_Mw(Q);return UG.createFresh({queueManager:$,providerRegistry:B,retryTracker:X,logger:Z,backend:new VH0,...w.entitySchedules&&{entitySchedules:w.entitySchedules},...w.generationSchedules&&{generationSchedules:w.generationSchedules},...w.generationConditions&&{generationConditions:w.generationConditions},messageBus:H,publishExecutor:Y,onCheckGenerationConditions:(W,K)=>H82(Q.entityService,Z,W,K)})}function _Mw(A){return{send:async(B)=>{return A.messaging.send({type:B.type,payload:B.payload,...B.target!==void 0?{target:B.target}:{},...B.metadata!==void 0?{metadata:B.metadata}:{},...B.broadcast!==void 0?{broadcast:B.broadcast}:{}})},subscribe:()=>()=>{},unsubscribe:()=>{}}}async function K82(A,Q,w){let $=A.getEntityTypes();for(let X of $){let Y=await A.listEntities({entityType:X,options:{filter:{metadata:{status:"queued"}}}});for(let Z of Y)await Q.add(Z.entityType,Z.id)}let B=0;for(let X of $){let Y=await Q.list(X);B+=Y.length}if(B>0)w.info(`Rebuilt queue with ${B} queued entities`)}C0();var NMw=["draft","queued","published","failed"];async function U82(A,Q){await A.messaging.send({type:"dashboard:register-widget",payload:{id:"publication-pipeline",pluginId:Q,title:"Publication Pipeline",group:"publishing",section:"secondary",priority:100,rendererName:"PipelineWidget",visibility:"anchor",dataProvider:()=>xMw(A),digestProvider:PMw}})}var jMw=f.object({summary:f.object({draft:f.number(),queued:f.number(),published:f.number(),failed:f.number()}),generating:f.array(f.unknown())});function PMw(A){let{summary:Q,generating:w}=jMw.parse(A),$=Q.queued+w.length,B=$===0?"idle":`${Q.queued} queued \xB7 ${w.length} generating`,X=Q.failed>0?`${Q.draft} drafts \xB7 ${Q.failed} failed`:`${Q.draft} drafts`,Y=Q.draft+Q.failed;return{digest:[{label:"Pipeline",value:B,...$>0?{tone:"warn"}:{}},{label:"Awaiting review",value:X,...Y>0?{tone:"warn"}:{}},{label:"Published",value:String(Q.published),tone:"good"}],needsOperator:Y}}var MMw=f.object({sourceEntityType:f.string(),sourceEntityId:f.string(),attachmentType:f.string().optional()});async function OMw(A){let Q=await A.jobs.getActiveJobs(),w=[];for(let $ of Q){if($.source!=="content-pipeline")continue;if($.status!=="pending"&&$.status!=="processing")continue;let B;try{B=JSON.parse($.data)}catch{continue}let X=MMw.safeParse(B);if(!X.success)continue;w.push({id:$.id,label:X.data.attachmentType??$.type,target:`${X.data.sourceEntityType}/${X.data.sourceEntityId}`,status:$.status})}return w}async function xMw(A){let Q=A.entityService.getEntityTypes(),w=[],$={draft:0,queued:0,published:0,failed:0};for(let B of Q){let X=await A.entityService.listEntities({entityType:B});for(let Y of X){let Z=RMw(Y.metadata.status);if(!Z)continue;$[Z]++,w.push({id:Y.id,title:vMw(Y.id,Y.metadata.title),type:B,status:Z})}}return{summary:$,items:w,generating:await OMw(A)}}function RMw(A){return NMw.find((Q)=>Q===A)}function vMw(A,Q){return typeof Q==="string"?Q:A}var G82={name:"@brains/content-pipeline",version:"0.2.0-alpha.159",description:"Content pipeline plugin for managing entity publishing queues, scheduling, and generation",dependencies:{"@brains/contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*",croner:"^10.0.1"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14",typescript:"^7.0.2"},exports:{".":{types:"./src/index.ts",default:"./src/index.ts"}},files:["src"],main:"src/index.ts",private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module",types:"src/index.ts"};class K0A extends Kw{pluginContext;queueManager;providerRegistry;retryTracker;publishExecutor;publishAssetRegistry;publishAssetPreflight;scheduler;constructor(A={}){super("content-pipeline",G82,A,i$2)}async onRegister(A){this.pluginContext=A,this.queueManager=Tq.createFresh(),this.providerRegistry=Sq.createFresh(),this.retryTracker=mq.createFresh(),this.publishAssetRegistry=uq.createFresh(),this.publishAssetPreflight=new IH0({context:A,registry:this.publishAssetRegistry}),this.publishExecutor=new SE({context:A,providerRegistry:this.providerRegistry,publishAssetPreflight:this.publishAssetPreflight}),this.scheduler=W82({context:A,config:this.config,queueManager:this.queueManager,providerRegistry:this.providerRegistry,retryTracker:this.retryTracker,publishExecutor:this.publishExecutor,logger:this.logger}),f82(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 K82(A.entityService,this.queueManager,this.logger),await U82(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[FH0(this.pluginContext,this.id,this.queueManager),bH0(this.pluginContext,this.id,this.providerRegistry,this.publishExecutor),LH0(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. Follow-up requests like "publish it now" should target the entity just read, generated, or updated in the conversation, including a post just changed to draft.\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(),Tq.resetInstance(),Sq.resetInstance(),mq.resetInstance(),uq.resetInstance()}}function U0A(A={}){return new K0A(A)}fA();C0();var D82=f.object({accountId:f.string().describe("Cloudflare account ID"),apiToken:f.string().describe("Cloudflare API token with Analytics:Read permission"),siteTag:f.string().describe("Cloudflare Web Analytics site tag")}),G0A=f.object({cloudflare:D82.optional()});fA();C0();var CMw=f.object({date:f.string().describe("Single date in YYYY-MM-DD format").optional(),days:f.number().min(1).max(365).describe("Number of days back from yesterday (e.g., 7 for last week)").optional(),startDate:f.string().describe("Start date in YYYY-MM-DD format (use with endDate)").optional(),endDate:f.string().describe("End date in YYYY-MM-DD format (use with startDate)").optional(),limit:f.number().min(1).max(100).default(20).describe("Maximum items for breakdowns (pages, referrers, countries)")});function gMw(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 q82(A,Q,w){let $=[];if(!w)return $;return $.push(p6(A,"query",`Query website analytics from Cloudflare.
7779
7779
 
7780
7780
  Date range options (use only one):
7781
7781
  - No params: yesterday only
@@ -7913,7 +7913,7 @@ Returns pageviews, visitors, top pages, referrers, devices, and countries.`,CMw,
7913
7913
  }
7914
7914
  }
7915
7915
  }
7916
- `,{...this.baseVariables(A),limit:A.limit??20})).map(($)=>({country:$.dimensions.countryName,visits:$.sum.visits}))}}var q0A=7,yMw=10;function V82(A){return async()=>{if(!A)return{unavailable:!0,reason:"Cloudflare analytics not configured"};let Q=U$0(),w=$yA(q0A),$=$h(w),B=$h(Q);try{let[X,Y]=await Promise.all([A.getWebsiteStats({startDate:$,endDate:B}),A.getTopPages({startDate:$,endDate:B,limit:yMw})]);return{days:q0A,startDate:$,endDate:B,pageviews:X.pageviews,visitors:X.visitors,topPages:Y}}catch(X){return{error:X instanceof Error?X.message:"Failed to fetch analytics",days:q0A}}}}var J82={name:"@brains/analytics",version:"0.2.0-alpha.158",description:"Analytics plugin for collecting website and social media metrics",dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts","./env-schema":"./src/env-schema.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};class I82 extends Kw{cloudflareClient;constructor(A={}){super("analytics",J82,A,G0A)}async onRegister(A){this.cloudflareClient=this.config.cloudflare?new D0A(this.config.cloudflare):void 0,A.insights.register("traffic-overview",V82(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:z82(Q)}})}async getTools(){return q82(this.id,this.getContext(),this.cloudflareClient)}}function TMw(A={}){return new I82(A)}var kH0=TMw;fA();C0();fA();C0();import{join as nMw}from"path";b2();var F82="note",SMw=new Set(["description","excerpt","summary","tagline","story"]);function mMw(A){if(A.endsWith("s"))return A;return yK(A)}function Za(A){return A===F82}function b82(A,Q){let w=A===F82?"Note":GI(A),$=Q?.label??w;return{label:$,pluralLabel:Q?.pluralName??mMw($)}}function Xa(A){return typeof A==="object"&&A!==null}function JM(A){if(!Xa(A))return;let Q=A.def;return Xa(Q)?Q:void 0}function L82(A){let Q=JM(A)?.type;return typeof Q==="string"?Q:void 0}function uMw(A){return typeof A==="function"?A():A}function z0A(A,Q=!1,w){let $=L82(A),B=JM(A);if($==="optional"||$==="nullable")return z0A(B?.innerType,!0,w);if($==="default")return z0A(B?.innerType,!0,uMw(B?.defaultValue));let X={inner:A,isOptional:Q};if(w!==void 0)X.defaultValue=w;return X}function cMw(A){let Q=JM(A)?.entries;if(!Xa(Q))return;let w=Object.values(Q);return w.every(($)=>typeof $==="string")?w:void 0}function lMw(A){let Q=JM(A)?.values;return Array.isArray(Q)?Q[0]:void 0}function pMw(A){let Q=JM(A)?.checks;if(!Array.isArray(Q))return!1;return Q.some((w)=>{return JM(w)?.format==="datetime"})}function iMw(A){return A==="imageId"||A.endsWith("ImageId")}function dMw(A){if(!Xa(A))return;let Q=A.shape;return Xa(Q)?Q:void 0}function Ya(A,Q){let{inner:w,isOptional:$,defaultValue:B}=z0A(Q),X=L82(w),Y=B??lMw(w),Z={name:A,label:GI(A),widget:"string",...$&&{required:!1},...Y!==void 0&&{default:Y}};switch(X){case"string":{if(iMw(A))return{...Z,widget:"image"};if(pMw(w))return{...Z,widget:"datetime"};if(SMw.has(A))return{...Z,widget:"text"};return{...Z,widget:"string"}}case"number":return{...Z,widget:"number"};case"boolean":return{...Z,widget:"boolean"};case"enum":{let H=cMw(w);return{...Z,widget:"select",...H?{options:H}:{}}}case"array":{let H=JM(w)?.element,W=Ya("item",H);if(W.widget==="object"&&W.fields)return{...Z,widget:"list",fields:W.fields};return{...Z,widget:"list",field:{name:A,label:GI(A),widget:W.widget}}}case"object":{let H=Object.entries(dMw(w)??{}).map(([W,K])=>Ya(W,K));return{...Z,widget:"object",fields:H}}case"literal":return{...Z,widget:"string"};default:return{...Z,widget:"string"}}}function k82(A){return`<!doctype html>
7916
+ `,{...this.baseVariables(A),limit:A.limit??20})).map(($)=>({country:$.dimensions.countryName,visits:$.sum.visits}))}}var q0A=7,yMw=10;function V82(A){return async()=>{if(!A)return{unavailable:!0,reason:"Cloudflare analytics not configured"};let Q=U$0(),w=$yA(q0A),$=$h(w),B=$h(Q);try{let[X,Y]=await Promise.all([A.getWebsiteStats({startDate:$,endDate:B}),A.getTopPages({startDate:$,endDate:B,limit:yMw})]);return{days:q0A,startDate:$,endDate:B,pageviews:X.pageviews,visitors:X.visitors,topPages:Y}}catch(X){return{error:X instanceof Error?X.message:"Failed to fetch analytics",days:q0A}}}}var J82={name:"@brains/analytics",version:"0.2.0-alpha.159",description:"Analytics plugin for collecting website and social media metrics",dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts","./env-schema":"./src/env-schema.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};class I82 extends Kw{cloudflareClient;constructor(A={}){super("analytics",J82,A,G0A)}async onRegister(A){this.cloudflareClient=this.config.cloudflare?new D0A(this.config.cloudflare):void 0,A.insights.register("traffic-overview",V82(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:z82(Q)}})}async getTools(){return q82(this.id,this.getContext(),this.cloudflareClient)}}function TMw(A={}){return new I82(A)}var kH0=TMw;fA();C0();fA();C0();import{join as nMw}from"path";b2();var F82="note",SMw=new Set(["description","excerpt","summary","tagline","story"]);function mMw(A){if(A.endsWith("s"))return A;return yK(A)}function Za(A){return A===F82}function b82(A,Q){let w=A===F82?"Note":GI(A),$=Q?.label??w;return{label:$,pluralLabel:Q?.pluralName??mMw($)}}function Xa(A){return typeof A==="object"&&A!==null}function JM(A){if(!Xa(A))return;let Q=A.def;return Xa(Q)?Q:void 0}function L82(A){let Q=JM(A)?.type;return typeof Q==="string"?Q:void 0}function uMw(A){return typeof A==="function"?A():A}function z0A(A,Q=!1,w){let $=L82(A),B=JM(A);if($==="optional"||$==="nullable")return z0A(B?.innerType,!0,w);if($==="default")return z0A(B?.innerType,!0,uMw(B?.defaultValue));let X={inner:A,isOptional:Q};if(w!==void 0)X.defaultValue=w;return X}function cMw(A){let Q=JM(A)?.entries;if(!Xa(Q))return;let w=Object.values(Q);return w.every(($)=>typeof $==="string")?w:void 0}function lMw(A){let Q=JM(A)?.values;return Array.isArray(Q)?Q[0]:void 0}function pMw(A){let Q=JM(A)?.checks;if(!Array.isArray(Q))return!1;return Q.some((w)=>{return JM(w)?.format==="datetime"})}function iMw(A){return A==="imageId"||A.endsWith("ImageId")}function dMw(A){if(!Xa(A))return;let Q=A.shape;return Xa(Q)?Q:void 0}function Ya(A,Q){let{inner:w,isOptional:$,defaultValue:B}=z0A(Q),X=L82(w),Y=B??lMw(w),Z={name:A,label:GI(A),widget:"string",...$&&{required:!1},...Y!==void 0&&{default:Y}};switch(X){case"string":{if(iMw(A))return{...Z,widget:"image"};if(pMw(w))return{...Z,widget:"datetime"};if(SMw.has(A))return{...Z,widget:"text"};return{...Z,widget:"string"}}case"number":return{...Z,widget:"number"};case"boolean":return{...Z,widget:"boolean"};case"enum":{let H=cMw(w);return{...Z,widget:"select",...H?{options:H}:{}}}case"array":{let H=JM(w)?.element,W=Ya("item",H);if(W.widget==="object"&&W.fields)return{...Z,widget:"list",fields:W.fields};return{...Z,widget:"list",field:{name:A,label:GI(A),widget:W.widget}}}case"object":{let H=Object.entries(dMw(w)??{}).map(([W,K])=>Ya(W,K));return{...Z,widget:"object",fields:H}}case"literal":return{...Z,widget:"string"};default:return{...Z,widget:"string"}}}function k82(A){return`<!doctype html>
7917
7917
  <html lang="en" data-climate="paper">
7918
7918
  <head>
7919
7919
  <meta charset="utf-8" />
@@ -7971,7 +7971,7 @@ ${ig}
7971
7971
  </html>`}var rMw=nMw(import.meta.dir,"..","dist","ui","cms-app.js"),oMw=f.object({entityType:f.string(),id:f.string(),frontmatter:f.record(f.string(),f.unknown()),body:f.string().optional(),baseContentHash:f.string().optional()}),sMw=f.object({entityType:f.string(),frontmatter:f.record(f.string(),f.unknown()),body:f.string().optional()}),V0A={entityType:f.string(),body:f.string(),frontmatter:f.record(f.string(),f.unknown())},aMw=f.union([f.object({...V0A,variant:f.literal("rewrite").optional(),instruction:f.string().trim().min(1),selection:f.string().min(1).max(8000)}),f.object({...V0A,variant:f.literal("summarise"),targetField:f.string().trim().min(1),body:f.string().min(1)}),f.object({...V0A,variant:f.literal("tag-suggest"),targetField:f.string().trim().min(1),body:f.string().min(1)})]),_82=f.object({suggestion:f.string()}),tMw=f.object({suggestions:f.array(f.string().trim().min(1)).max(12)}),eMw=f.object({selection:f.string().min(1).max(8000),instruction:f.string().trim().min(1).max(2000),agent:f.string().trim().min(1).max(253)}),AOw=f.looseObject({response:f.string()}),QOw=f.object({agents:f.array(f.object({id:f.string(),label:f.string()}))}),wOw="file",N82=10485760,$Ow=f.object({watchEnabled:f.boolean(),lastSync:f.string().nullable(),git:f.object({branch:f.string(),hasChanges:f.boolean(),ahead:f.number(),behind:f.number(),lastCommit:f.string().nullable(),remote:f.string().nullable()}).nullable()});function j82(A){let{routePath:Q,getContext:w,resolveOperatorSession:$,getEntityDisplay:B}=A,X=`${Q}/assets/app.js`,Y=(H)=>`${Q}/api/${H}`,Z=async(H)=>await $(H)?null:hQ({error:"Operator session required"},401);return[{path:Q,method:"GET",public:!0,handler:async(H)=>{if(!await $(H))return new Response(null,{status:302,headers:{Location:`/login?return_to=${encodeURIComponent(Q)}`,"Cache-Control":"no-store"}});return new Response(k82({assetPath:X,surfaces:Eb(w().webRoutes.getRoutes(),{activeId:"cms",self:{id:"cms",href:Q}}),sessionHref:`/logout?return_to=${encodeURIComponent(Q)}`}),{headers:{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store"}})}},{path:X,method:"GET",public:!0,handler:async()=>{let H=Bun.file(rMw);if(!await H.exists())return new Response("CMS editor UI asset not built",{status:404});return new Response(H,{headers:{"Content-Type":"text/javascript; charset=utf-8","Cache-Control":"no-cache"}})}},{path:Y("types"),method:"GET",public:!0,handler:async(H)=>{let W=await Z(H);if(W)return W;return XOw(w(),B())}},{path:Y("schema"),method:"GET",public:!0,handler:async(H)=>{let W=await Z(H);if(W)return W;return YOw(w(),H)}},{path:Y("entities"),method:"GET",public:!0,handler:async(H)=>{let W=await Z(H);if(W)return W;return ZOw(w(),H)}},{path:Y("entities"),method:"PUT",public:!0,handler:async(H)=>{let W=await Z(H);if(W)return W;return fOw(w(),H)}},{path:Y("entities"),method:"POST",public:!0,handler:async(H)=>{let W=await Z(H);if(W)return W;return HOw(w(),H)}},{path:Y("entities"),method:"DELETE",public:!0,handler:async(H)=>{let W=await Z(H);if(W)return W;return WOw(w(),H)}},{path:Y("upload"),method:"POST",public:!0,handler:async(H)=>{let W=await Z(H);if(W)return W;return DOw(w(),H,Y("upload"))}},{path:Y("assist"),method:"POST",public:!0,handler:async(H)=>{let W=await Z(H);if(W)return W;return KOw(w(),H)}},{path:Y("agents"),method:"GET",public:!0,handler:async(H)=>{let W=await Z(H);if(W)return W;return UOw(w())}},{path:Y("ask-agent"),method:"POST",public:!0,handler:async(H)=>{let W=await Z(H);if(W)return W;return GOw(w(),H)}},{path:Y("sync-status"),method:"GET",public:!0,handler:async(H)=>{let W=await Z(H);if(W)return W;return BOw(w())}}]}async function BOw(A){let Q={directorySync:null,git:null},w=await A.messaging.send({type:"sync:status:request",payload:{}});if(!("success"in w)||!w.success)return hQ(Q);let $=$Ow.safeParse(w.data);if(!$.success)return hQ(Q);return hQ({directorySync:{lastSync:$.data.lastSync,watching:$.data.watchEnabled},git:$.data.git})}async function XOw(A,Q){let w=new Map((await A.entityService.getEntityCounts()).map((B)=>[B.entityType,B.count])),$=A.entityService.getEntityTypes().flatMap((B)=>{if(!A.entities.getEffectiveFrontmatterSchema(B))return[];let Y=A.entities.getAdapter(B);return[{entityType:B,label:b82(B,Q?.[B]).pluralLabel,isSingleton:Y?.isSingleton===!0,hasBody:Y?.hasBody!==!1,count:w.get(B)??0}]});return hQ({types:$})}function YOw(A,Q){let w=new URL(Q.url).searchParams.get("type");if(!w)return hQ({error:"type query parameter is required"},400);let $=A.entities.getEffectiveFrontmatterSchema(w);if(!$)return hQ({error:`Unknown entity type: ${w}`},404);let B=A.entities.getAdapter(w),X=Za(w),Y=X?[]:Object.entries($.shape).map(([Z,H])=>Ya(Z,H));return hQ({entityType:w,format:X?"raw":"frontmatter",isSingleton:B?.isSingleton===!0,hasBody:X||B?.hasBody!==!1,fields:Y})}async function ZOw(A,Q){let w=new URL(Q.url).searchParams,$=w.get("type");if(!$)return hQ({error:"type query parameter is required"},400);if(!A.entities.getEffectiveFrontmatterSchema($))return hQ({error:`Unknown entity type: ${$}`},404);let B=w.get("id");if(B){let Y=await A.entityService.getEntity({entityType:$,id:B});if(!Y)return hQ({error:`Entity not found: ${B}`},404);let{frontmatter:Z,body:H}=J0A($,Y.content);return hQ({entity:{id:Y.id,entityType:Y.entityType,frontmatter:Z,body:H,contentHash:Y.contentHash,created:Y.created,updated:Y.updated}})}let X=await A.entityService.listEntities({entityType:$});return hQ({entities:X.map((Y)=>({id:Y.id,entityType:Y.entityType,frontmatter:J0A($,Y.content).frontmatter,updated:Y.updated}))})}async function fOw(A,Q){let w;try{w=oMw.parse(await Q.json())}catch{return hQ({error:"Invalid update payload"},400)}let{entityType:$,id:B}=w,X=A.entities.getEffectiveFrontmatterSchema($);if(!X)return hQ({error:`Unknown entity type: ${$}`},404);let Y=P82(A,$,w.body);if(Y)return Y;let Z=Za($);if(Z&&Object.keys(w.frontmatter).length>0)return hQ({error:`Entity type ${$} is raw markdown without frontmatter`},400);let H=Z?{success:!0,data:{}}:X.safeParse(w.frontmatter);if(!H.success)return hQ({error:"Invalid frontmatter",issues:H.error.issues},400);let W=await A.entityService.getEntity({entityType:$,id:B});if(!W)return hQ({error:`Entity not found: ${B}`},404);if(w.baseContentHash!==void 0&&w.baseContentHash!==W.contentHash)return hQ({error:"This entry changed since it was opened \u2014 likely updated by "+"another writer (an agent, or a git import via directory-sync). Reload to review before saving again.",currentContentHash:W.contentHash},409);let K=w.body??J0A($,W.content).body,U=Z?K:m5(K,H.data),G=A.entities.getAdapter($)?.fromMarkdown(U),q={...W,...G,id:W.id,entityType:W.entityType,content:U},V=await A.entityService.updateEntity({entity:q});return hQ({entityId:V.entityId,jobId:V.jobId,skipped:V.skipped})}async function HOw(A,Q){let w;try{w=sMw.parse(await Q.json())}catch{return hQ({error:"Invalid create payload"},400)}let{entityType:$}=w,B=A.entities.getEffectiveFrontmatterSchema($);if(!B)return hQ({error:`Unknown entity type: ${$}`},404);let X=P82(A,$,w.body);if(X)return X;let Y=Za($);if(Y&&Object.keys(w.frontmatter).length>0)return hQ({error:`Entity type ${$} is raw markdown without frontmatter`},400);let Z=Y?{success:!0,data:{}}:B.safeParse(w.frontmatter);if(!Z.success)return hQ({error:"Invalid frontmatter",issues:Z.error.issues},400);let H=Y?w.body??"":m5(w.body??"",Z.data),W=A.entities.getAdapter($)?.fromMarkdown(H),K=await A.entityService.createEntity({entity:{...W,entityType:$,content:H,metadata:W?.metadata??{}}});return hQ({entityId:K.entityId,jobId:K.jobId},201)}async function WOw(A,Q){let w=new URL(Q.url).searchParams,$=w.get("type"),B=w.get("id");if(!$||!B)return hQ({error:"type and id query parameters are required"},400);if(!await A.entityService.getEntity({entityType:$,id:B}))return hQ({error:`Entity not found: ${B}`},404);let Y=await A.entityService.deleteEntity({entityType:$,id:B});return hQ({deleted:Y})}async function KOw(A,Q){let w;try{w=aMw.parse(await Q.json())}catch{return hQ({error:"Invalid assist payload or selection length"},400)}let $=A.entities.getEffectiveFrontmatterSchema(w.entityType);if(!$)return hQ({error:`Unknown entity type: ${w.entityType}`},404);if(w.variant==="summarise"||w.variant==="tag-suggest"){let Y=$.shape[w.targetField];if(!Y)return hQ({error:`Unknown frontmatter field: ${w.targetField}`},400);let Z=Ya(w.targetField,Y);if(!(w.variant==="summarise"?Z.widget==="string"||Z.widget==="text":Z.widget==="list"&&Z.field?.widget==="string"))return hQ({error:`Field ${w.targetField} is incompatible with ${w.variant}`},400);let W=["You are editing CMS frontmatter from an existing markdown body.",`Entity type: ${w.entityType}`,`Target field: ${w.targetField}`,`Existing frontmatter JSON: ${JSON.stringify(w.frontmatter)}`,"","Full markdown body:",w.body];if(w.variant==="summarise"){let{object:U}=await A.ai.generateObject(["Summarise the body for the target frontmatter field.","Return only the field value in the suggestion field.",...W].join(`
7972
7972
  `),_82);return hQ({variant:w.variant,targetField:w.targetField,suggestion:U.suggestion})}let{object:K}=await A.ai.generateObject(["Suggest tags for the target frontmatter field.","Return concise tag strings in the suggestions field without duplicates.",...W].join(`
7973
7973
  `),tMw);return hQ({variant:w.variant,targetField:w.targetField,suggestions:[...new Set(K.suggestions)]})}let B=["You are editing markdown for the CMS.","Rewrite only the selected text according to the instruction.","Return only replacement markdown in the suggestion field.","Do not include commentary, code fences, or unchanged surrounding body text.","",`Entity type: ${w.entityType}`,`Frontmatter JSON: ${JSON.stringify(w.frontmatter)}`,`Instruction: ${w.instruction}`,"","Selected markdown:",w.selection,"","Full body for context:",w.body].join(`
7974
- `),{object:X}=await A.ai.generateObject(B,_82);return hQ({suggestion:X.suggestion})}async function UOw(A){let Q=await A.messaging.send({type:"a2a:call:agents",payload:{}});if(!("success"in Q)||!Q.success)return hQ({agents:[]});let w=QOw.safeParse(Q.data);return hQ(w.success?w.data:{agents:[]})}async function GOw(A,Q){let w;try{w=eMw.parse(await Q.json())}catch{return hQ({error:"Invalid agent ask payload or selection length"},400)}let $=await A.messaging.send({type:"a2a:call:request",payload:w});if(!("success"in $)||!$.success){let X="error"in $&&typeof $.error==="string"?$.error:"Agent call failed",Y=X.startsWith("No handler found");return hQ({error:Y?"Agent asking is unavailable":X},Y?503:400)}if($.data===void 0)return hQ({error:"Agent asking is unavailable"},503);let B=AOw.safeParse($.data);if(!B.success)return hQ({error:"Invalid response from agent"},502);return hQ({agentId:w.agent,response:B.data.response})}async function DOw(A,Q,w){let $=Number(Q.headers.get("content-length"));if(Number.isFinite($)&&$>N82)return hQ({error:"Upload too large"},400);let B;try{B=await Q.formData()}catch{return hQ({error:"Invalid multipart upload"},400)}let X=B.get(wOw);if(!(X instanceof File))return hQ({error:"Missing upload file"},400);if(X.size>N82)return hQ({error:"Upload too large"},400);let Y=A.entities.getUploadSaveHandler(X.type);if(!Y)return hQ({error:`No handler accepts uploads of type ${X.type}`},415);let H=await A.uploads.scoped({namespace:"upload",refKind:"upload",routePath:w}).save({filename:X.name,mediaType:X.type,content:Buffer.from(await X.arrayBuffer())}),W=await Y.handler({upload:{kind:"upload",id:H.id}},{interfaceType:"cms",userId:"operator"});if(!W.success)return hQ({error:W.error},502);return hQ({entityId:W.data.entityId,jobId:W.data.jobId},201)}function P82(A,Q,w){if(w===void 0)return null;if(A.entities.getAdapter(Q)?.hasBody===!1)return hQ({error:`Entity type ${Q} does not have a body`},400);return null}function J0A(A,Q){if(Za(A))return{frontmatter:{},body:Q};try{let w=$Q(Q,f.record(f.string(),f.unknown()));return{frontmatter:w.metadata,body:w.content}}catch{return{frontmatter:{},body:Q}}}function hQ(A,Q=200){return new Response(JSON.stringify(A),{status:Q,headers:{"Content-Type":"application/json; charset=utf-8","Cache-Control":"no-store"}})}var M82={name:"@brains/cms",version:"0.2.0-alpha.158",description:"CMS plugin for config and browser authoring routes",dependencies:{"@brains/auth-service":"workspace:*","@brains/console-theme":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*","@codemirror/lang-markdown":"^6.5.0","@codemirror/language":"^6.12.4","@codemirror/state":"^6.7.1","@codemirror/view":"^6.43.6","@lezer/highlight":"^1.2.3",react:"^19.2.7","react-dom":"^19.2.7",streamdown:"^2.5.0"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14","@types/react":"^19.2.17","@types/react-dom":"^19.0.3","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{build:"bun scripts/build-ui.ts","build:ui":"bun scripts/build-ui.ts",lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit && tsc --noEmit -p ui-react/tsconfig.json"},type:"module"};var zOw=f.looseObject({label:f.string().optional(),pluralName:f.string().optional()}),VOw=f.object({entityDisplay:f.record(f.string(),zOw).optional(),routePath:f.string().default("/cms")});class I0A extends Kw{constructor(A={}){super("cms",M82,A,VOw)}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(){return j82({routePath:this.config.routePath,getContext:()=>this.getContext(),resolveOperatorSession:JOw,getEntityDisplay:()=>this.config.entityDisplay??this.getContext().entityDisplay})}}function IM(A={}){return new I0A(A)}async function JOw(A){return Boolean(await s7()?.getOperatorSession(A))}fA();C0();fA();C0();var _H0=["StatsWidget","ListWidget","CustomWidget","PipelineWidget","IdentityWidget","ProfileWidget","SystemWidget"],IOw=new Set(_H0),FOw=f.enum(["public","trusted","anchor"]);function F0A(A){return IOw.has(A)}var O82=f.object({label:f.string(),value:f.string(),tone:f.enum(["plain","good","warn"]).optional()}),x82=f.object({id:f.string(),pluginId:f.string(),title:f.string(),description:f.string().optional(),group:f.string().min(1),priority:f.number().default(50),section:f.enum(["primary","secondary","sidebar"]).default("primary"),rendererName:f.string(),visibility:FOw.default("public"),needsOperator:f.number().int().nonnegative().optional(),digest:f.array(O82).max(4).optional()});class NH0{widgets=new Map;logger;constructor(A){this.logger=A.child("DashboardWidgetRegistry")}register(A){let w={...x82.parse(A),dataProvider:A.dataProvider,...A.digestProvider?{digestProvider:A.digestProvider}:{},...A.component?{component:A.component}:{},...A.clientScript?{clientScript:A.clientScript}:{}},$=`${w.pluginId}:${w.id}`;this.widgets.set($,w),this.logger.debug("Dashboard widget registered",{key:$,title:w.title,rendererName:w.rendererName,group:w.group})}unregister(A,Q){if(Q){this.widgets.delete(`${A}:${Q}`);return}for(let w of this.widgets.keys())if(w.startsWith(`${A}:`))this.widgets.delete(w)}get(A,Q){return this.widgets.get(`${A}:${Q}`)}list(A={}){let Q=typeof A==="string"?{section:A}:A,w=Q.permissionLevel??"public";return Array.from(this.widgets.values()).filter(($)=>!Q.section||$.section===Q.section).filter(($)=>N9.hasPermission(w,$.visibility)).sort(($,B)=>$.priority-B.priority)}get size(){return this.widgets.size}}class jH0{id="dashboard:dashboard";name="Dashboard DataSource";description="Aggregates dashboard widgets from all plugins";registry;logger;constructor(A,Q){this.registry=A,this.logger=Q.child("DashboardDataSource")}async getDashboardData(A={}){let Q={},w=A.widgets??this.registry.list({...A.permissionLevel!==void 0&&{permissionLevel:A.permissionLevel}}),$=await Promise.allSettled(w.map(async(B)=>{let X=await B.dataProvider(),{dataProvider:Y,digestProvider:Z,component:H,clientScript:W,visibility:K="public",...U}=B;return{key:`${B.pluginId}:${B.id}`,widget:{...U,visibility:K,...this.deriveLiveDigest(B,X)},data:X}}));for(let B=0;B<$.length;B++){let X=$[B],Y=w[B];if(!X||!Y)continue;if(X.status==="fulfilled")Q[X.value.key]={widget:X.value.widget,data:X.value.data};else this.logger.error("Widget data provider failed",{widgetId:Y.id,pluginId:Y.pluginId,error:dA(X.reason)})}return{widgets:Q}}deriveLiveDigest(A,Q){if(!A.digestProvider)return{};try{let w=A.digestProvider(Q);return{...w.digest!==void 0&&{digest:w.digest},...w.needsOperator!==void 0&&{needsOperator:w.needsOperator}}}catch(w){return this.logger.error("Widget digest provider failed",{widgetId:A.id,pluginId:A.pluginId,error:dA(w)}),{}}}async fetch(A,Q,w){return await this.getDashboardData()}}import{render as Axw}from"preact-render-to-string";var R82=`* { margin: 0; padding: 0; box-sizing: border-box; }
7974
+ `),{object:X}=await A.ai.generateObject(B,_82);return hQ({suggestion:X.suggestion})}async function UOw(A){let Q=await A.messaging.send({type:"a2a:call:agents",payload:{}});if(!("success"in Q)||!Q.success)return hQ({agents:[]});let w=QOw.safeParse(Q.data);return hQ(w.success?w.data:{agents:[]})}async function GOw(A,Q){let w;try{w=eMw.parse(await Q.json())}catch{return hQ({error:"Invalid agent ask payload or selection length"},400)}let $=await A.messaging.send({type:"a2a:call:request",payload:w});if(!("success"in $)||!$.success){let X="error"in $&&typeof $.error==="string"?$.error:"Agent call failed",Y=X.startsWith("No handler found");return hQ({error:Y?"Agent asking is unavailable":X},Y?503:400)}if($.data===void 0)return hQ({error:"Agent asking is unavailable"},503);let B=AOw.safeParse($.data);if(!B.success)return hQ({error:"Invalid response from agent"},502);return hQ({agentId:w.agent,response:B.data.response})}async function DOw(A,Q,w){let $=Number(Q.headers.get("content-length"));if(Number.isFinite($)&&$>N82)return hQ({error:"Upload too large"},400);let B;try{B=await Q.formData()}catch{return hQ({error:"Invalid multipart upload"},400)}let X=B.get(wOw);if(!(X instanceof File))return hQ({error:"Missing upload file"},400);if(X.size>N82)return hQ({error:"Upload too large"},400);let Y=A.entities.getUploadSaveHandler(X.type);if(!Y)return hQ({error:`No handler accepts uploads of type ${X.type}`},415);let H=await A.uploads.scoped({namespace:"upload",refKind:"upload",routePath:w}).save({filename:X.name,mediaType:X.type,content:Buffer.from(await X.arrayBuffer())}),W=await Y.handler({upload:{kind:"upload",id:H.id}},{interfaceType:"cms",userId:"operator"});if(!W.success)return hQ({error:W.error},502);return hQ({entityId:W.data.entityId,jobId:W.data.jobId},201)}function P82(A,Q,w){if(w===void 0)return null;if(A.entities.getAdapter(Q)?.hasBody===!1)return hQ({error:`Entity type ${Q} does not have a body`},400);return null}function J0A(A,Q){if(Za(A))return{frontmatter:{},body:Q};try{let w=$Q(Q,f.record(f.string(),f.unknown()));return{frontmatter:w.metadata,body:w.content}}catch{return{frontmatter:{},body:Q}}}function hQ(A,Q=200){return new Response(JSON.stringify(A),{status:Q,headers:{"Content-Type":"application/json; charset=utf-8","Cache-Control":"no-store"}})}var M82={name:"@brains/cms",version:"0.2.0-alpha.159",description:"CMS plugin for config and browser authoring routes",dependencies:{"@brains/auth-service":"workspace:*","@brains/console-theme":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*","@codemirror/lang-markdown":"^6.5.0","@codemirror/language":"^6.12.4","@codemirror/state":"^6.7.1","@codemirror/view":"^6.43.6","@lezer/highlight":"^1.2.3",react:"^19.2.7","react-dom":"^19.2.7",streamdown:"^2.5.0"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14","@types/react":"^19.2.17","@types/react-dom":"^19.0.3","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{build:"bun scripts/build-ui.ts","build:ui":"bun scripts/build-ui.ts",lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit && tsc --noEmit -p ui-react/tsconfig.json"},type:"module"};var zOw=f.looseObject({label:f.string().optional(),pluralName:f.string().optional()}),VOw=f.object({entityDisplay:f.record(f.string(),zOw).optional(),routePath:f.string().default("/cms")});class I0A extends Kw{constructor(A={}){super("cms",M82,A,VOw)}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(){return j82({routePath:this.config.routePath,getContext:()=>this.getContext(),resolveOperatorSession:JOw,getEntityDisplay:()=>this.config.entityDisplay??this.getContext().entityDisplay})}}function IM(A={}){return new I0A(A)}async function JOw(A){return Boolean(await s7()?.getOperatorSession(A))}fA();C0();fA();C0();var _H0=["StatsWidget","ListWidget","CustomWidget","PipelineWidget","IdentityWidget","ProfileWidget","SystemWidget"],IOw=new Set(_H0),FOw=f.enum(["public","trusted","anchor"]);function F0A(A){return IOw.has(A)}var O82=f.object({label:f.string(),value:f.string(),tone:f.enum(["plain","good","warn"]).optional()}),x82=f.object({id:f.string(),pluginId:f.string(),title:f.string(),description:f.string().optional(),group:f.string().min(1),priority:f.number().default(50),section:f.enum(["primary","secondary","sidebar"]).default("primary"),rendererName:f.string(),visibility:FOw.default("public"),needsOperator:f.number().int().nonnegative().optional(),digest:f.array(O82).max(4).optional()});class NH0{widgets=new Map;logger;constructor(A){this.logger=A.child("DashboardWidgetRegistry")}register(A){let w={...x82.parse(A),dataProvider:A.dataProvider,...A.digestProvider?{digestProvider:A.digestProvider}:{},...A.component?{component:A.component}:{},...A.clientScript?{clientScript:A.clientScript}:{}},$=`${w.pluginId}:${w.id}`;this.widgets.set($,w),this.logger.debug("Dashboard widget registered",{key:$,title:w.title,rendererName:w.rendererName,group:w.group})}unregister(A,Q){if(Q){this.widgets.delete(`${A}:${Q}`);return}for(let w of this.widgets.keys())if(w.startsWith(`${A}:`))this.widgets.delete(w)}get(A,Q){return this.widgets.get(`${A}:${Q}`)}list(A={}){let Q=typeof A==="string"?{section:A}:A,w=Q.permissionLevel??"public";return Array.from(this.widgets.values()).filter(($)=>!Q.section||$.section===Q.section).filter(($)=>N9.hasPermission(w,$.visibility)).sort(($,B)=>$.priority-B.priority)}get size(){return this.widgets.size}}class jH0{id="dashboard:dashboard";name="Dashboard DataSource";description="Aggregates dashboard widgets from all plugins";registry;logger;constructor(A,Q){this.registry=A,this.logger=Q.child("DashboardDataSource")}async getDashboardData(A={}){let Q={},w=A.widgets??this.registry.list({...A.permissionLevel!==void 0&&{permissionLevel:A.permissionLevel}}),$=await Promise.allSettled(w.map(async(B)=>{let X=await B.dataProvider(),{dataProvider:Y,digestProvider:Z,component:H,clientScript:W,visibility:K="public",...U}=B;return{key:`${B.pluginId}:${B.id}`,widget:{...U,visibility:K,...this.deriveLiveDigest(B,X)},data:X}}));for(let B=0;B<$.length;B++){let X=$[B],Y=w[B];if(!X||!Y)continue;if(X.status==="fulfilled")Q[X.value.key]={widget:X.value.widget,data:X.value.data};else this.logger.error("Widget data provider failed",{widgetId:Y.id,pluginId:Y.pluginId,error:dA(X.reason)})}return{widgets:Q}}deriveLiveDigest(A,Q){if(!A.digestProvider)return{};try{let w=A.digestProvider(Q);return{...w.digest!==void 0&&{digest:w.digest},...w.needsOperator!==void 0&&{needsOperator:w.needsOperator}}}catch(w){return this.logger.error("Widget digest provider failed",{widgetId:A.id,pluginId:A.pluginId,error:dA(w)}),{}}}async fetch(A,Q,w){return await this.getDashboardData()}}import{render as Axw}from"preact-render-to-string";var R82=`* { margin: 0; padding: 0; box-sizing: border-box; }
7975
7975
  html, body { min-height: 100%; max-width: 100%; }
7976
7976
  body {
7977
7977
  font-family: var(--console-ui);
@@ -9613,7 +9613,7 @@ ${v82}`;import{jsxDEV as FM,Fragment as C82}from"preact/jsx-dev-runtime";functio
9613
9613
  activate(resolveId(window.location.hash), false);
9614
9614
  });
9615
9615
  })();`;function Zxw({hiddenWidgetCount:A,loginUrl:Q}){return LA("section",{class:"card operator-gate",children:[LA("div",{children:[LA("div",{class:"card-title",children:"Operator access"},void 0,!1,void 0,this),LA("p",{children:[A===1?"1 private console widget is hidden.":`${A} private console widgets are hidden.`," ","","Sign in with your passkey to unlock the restricted layer."]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),LA("a",{class:"operator-gate-link",href:Q,children:"Sign in"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function fxw({dashboardPath:A,surfaces:Q,operatorAccess:w}){let $=w?.isOperator?w.logoutUrl:w?.loginUrl??"/login",B=w?.isOperator?"Operator":"Visitor",X=w?.isOperator?"Sign out":"Sign in";return LA("header",{class:"console-strip","aria-label":"Operator surfaces",children:[LA("a",{class:"console-mark",href:A,"aria-label":"Dashboard home",children:[LA("span",{class:"pulse"},void 0,!1,void 0,this),LA("span",{children:["Brain"," ",LA("span",{class:"console-mark-long",children:["\xB7 ",LA("b",{children:"Console"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),LA("nav",{class:"surface-nav","aria-label":"Console surfaces",children:Q.map((Y)=>LA("a",{class:Y.isActive?"surface-nav-link is-active":"surface-nav-link",href:Y.href,children:Y.label},Y.id,!1,void 0,this))},void 0,!1,void 0,this),LA("button",{class:"command-chip",type:"button","aria-label":"Search or jump",children:[LA("span",{class:"command-chip-hint",children:"Search or jump\u2026"},void 0,!1,void 0,this),LA("kbd",{children:"\u2318K"},void 0,!1,void 0,this),LA("span",{class:"command-chip-icon","aria-hidden":"true",children:"\u2315"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),LA("button",{id:"climateToggle",class:"climate-chip",type:"button","aria-label":"Toggle climate",children:"\u25D0"},void 0,!1,void 0,this),LA("a",{class:w?.isOperator?"session-chip":"session-chip is-visitor",href:$,"aria-label":`${B} \xB7 ${X}`,children:[LA("span",{children:B},void 0,!1,void 0,this),LA("strong",{children:X},void 0,!1,void 0,this),LA("span",{class:"session-chip-avatar","aria-hidden":"true",children:w?.isOperator?"OP":"VI"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}function Hxw({tabs:A}){return LA("nav",{class:"dashboard-tabs","aria-label":"Dashboard sections",role:"tablist",children:[LA("a",{class:"dashboard-tab is-active",href:"#overview",role:"tab","aria-selected":"true","data-dashboard-tab-link":"overview",children:"Overview"},void 0,!1,void 0,this),A.map((Q)=>LA("a",{class:"dashboard-tab",href:`#${Q.id}`,role:"tab","aria-selected":"false","data-dashboard-tab-link":Q.id,children:[LA("span",{children:Q.label},void 0,!1,void 0,this),Q.needsOperator>0?LA("span",{class:"tab-badge tab-badge--needs",children:Q.needsOperator},void 0,!1,void 0,this):Q.widgetCount>0?LA("span",{class:"tab-badge tab-badge--muted",children:Q.widgetCount},void 0,!1,void 0,this):null]},Q.id,!0,void 0,this))]},void 0,!0,void 0,this)}function N0A(A){return A.indexStatus?.ready??A.indexReady??A.appInfo.embeddings>0}function Wxw({input:A}){let Q=N0A(A),w=A.activityLog?.[0],$=A.appInfo.entityCounts.length,B=A.appInfo.interactions.map((U)=>U.id).slice(0,3).join(" / "),X=A.indexStatus?.embeddedEntities??A.appInfo.embeddings,Y=A.indexStatus?.embeddableEntities,Z=A.indexStatus?(A.indexStatus.activeEmbeddingJobs??0)+(A.indexStatus.missingEmbeddings??0)+(A.indexStatus.staleEmbeddings??0):0,H=Y===void 0?`${X}`:`${X}/${Y}`,W=Z>0?`${H} embedded \xB7 ${Z} queued`:`${H} embedded`,K=(A.jobProgress??[]).some((U)=>U.status==="processing"||U.status==="pending");return LA("section",{class:"overview-vitals","aria-label":"Runtime vitals",children:[LA("article",{class:"vital-card",children:[LA("span",{class:"vital-label",children:"Entities"},void 0,!1,void 0,this),LA("strong",{class:"vital-num",children:A.appInfo.entities},void 0,!1,void 0,this),LA("span",{class:"vital-sub",children:$===1?"1 type":`${$} types`},void 0,!1,void 0,this)]},void 0,!0,void 0,this),LA("article",{class:"vital-card",children:[LA("span",{class:"vital-label",children:"Interactions"},void 0,!1,void 0,this),LA("strong",{class:"vital-num",children:A.appInfo.interactions.length},void 0,!1,void 0,this),LA("span",{class:"vital-sub",children:B||"no channels"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),LA("article",{class:`vital-card ${Q?"vital-card--ok":"vital-card--warm"}`,children:[LA("span",{class:"vital-label",children:"Semantic index"},void 0,!1,void 0,this),LA("strong",{class:"vital-num vital-num--text",children:Q?"Ready":"Pending"},void 0,!1,void 0,this),LA("span",{class:"vital-sub",children:W},void 0,!1,void 0,this)]},void 0,!0,void 0,this),LA("article",{class:`vital-card${K?" vital-card--warm":""}`,children:[LA("span",{class:"vital-label",children:"Last write"},void 0,!1,void 0,this),LA("strong",{class:"vital-num vital-num--text",children:w?j0A(w.timestamp):"\u2014"},void 0,!1,void 0,this),LA("span",{class:"vital-sub",children:w?`${w.entityType}/${w.entityId}`:"no writes observed"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}function Kxw({input:A}){let{role:Q,purpose:w,values:$}=A.character;if(!Q&&!w&&$.length===0)return null;return LA("aside",{class:"card identity-capsule",children:[LA("div",{class:"card-head",children:[LA("span",{class:"card-title",children:"Identity"},void 0,!1,void 0,this),LA("span",{class:"card-from",children:"identity"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),LA("div",{class:"identity-capsule-body",children:[Q&&LA("span",{class:"identity-role",children:["\u201C",Q,"\u201D"]},void 0,!0,void 0,this),$.length>0&&LA("span",{class:"values",children:$.map((B)=>LA("span",{class:"value",children:B},B,!1,void 0,this))},void 0,!1,void 0,this),w&&LA("span",{class:"identity-purpose",children:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}function Uxw({cards:A}){if(A.length===0)return LA("section",{class:"card overview-empty-digest",children:[LA("div",{class:"card-head",children:LA("span",{class:"card-title",children:"Group digests"},void 0,!1,void 0,this)},void 0,!1,void 0,this),LA("p",{class:"muted",children:"No plugin groups are visible yet."},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return LA("section",{class:"digests","aria-label":"Group digests",children:A.map((Q)=>LA("a",{class:"card digest-card",href:Q.href,children:[LA("div",{class:"digest-head",children:[LA("h4",{children:Q.label},void 0,!1,void 0,this),LA("span",{class:"digest-go",children:"open \u2192"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),LA("dl",{class:"digest-lines",children:Q.lines.map((w)=>LA("div",{class:`digest-line digest-line--${w.tone??"plain"}`,children:[LA("dt",{children:w.label},void 0,!1,void 0,this),LA("dd",{children:w.value},void 0,!1,void 0,this)]},`${w.label}:${w.value}`,!0,void 0,this))},void 0,!1,void 0,this)]},Q.id,!0,void 0,this))},void 0,!1,void 0,this)}function Gxw(A){let Q=new Date(A);if(Number.isNaN(Q.getTime()))return"\u2014";return Q.toLocaleString("en",{month:"short",day:"2-digit",hour:"2-digit",minute:"2-digit"})}function j0A(A){let Q=new Date(A);if(Number.isNaN(Q.getTime()))return"\u2014";return Q.toLocaleTimeString("en-GB",{hour:"2-digit",minute:"2-digit"})}var l82={created:{glyph:"\uFF0B",tone:""},updated:{glyph:"\u2713",tone:" ledger-glyph--ok"},deleted:{glyph:"\u2212",tone:" ledger-glyph--warn"}};function Dxw({events:A}){return LA("section",{class:"card activity-ledger",children:[LA("div",{class:"card-head",children:[LA("span",{class:"card-title",children:"Activity"},void 0,!1,void 0,this),LA("span",{class:"card-from",children:"entity events"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.length===0?LA("p",{class:"muted",children:"No entity activity has been observed this session."},void 0,!1,void 0,this):LA("ol",{class:"ledger",children:A.map((Q)=>LA("li",{class:"ledger-entry",children:[LA("time",{class:"ledger-time",dateTime:Q.timestamp,children:j0A(Q.timestamp)},void 0,!1,void 0,this),LA("span",{class:`ledger-glyph${l82[Q.action].tone}`,"aria-hidden":"true",children:l82[Q.action].glyph},void 0,!1,void 0,this),LA("span",{class:"ledger-what",children:[LA("b",{children:Q.entityType},void 0,!1,void 0,this)," ",Q.action," \u2014"," ",LA("code",{children:[Q.entityType,"/",Q.entityId]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},`${Q.timestamp}:${Q.action}:${Q.entityType}:${Q.entityId}`,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function qxw(A){let Q=(A.activeEmbeddingJobs??0)+(A.missingEmbeddings??0)+(A.staleEmbeddings??0);if(A.ready&&!A.degraded)return 100;if(A.ready)return 92;if(Q===0)return 50;return Math.max(8,Math.min(88,100-Q*12))}function zxw(A){return["Semantic index",A.ready?A.degraded?"ready, degraded":"ready":"pending",A.activeEmbeddingJobs!==void 0?`${A.activeEmbeddingJobs} active`:void 0,A.missingEmbeddings!==void 0?`${A.missingEmbeddings} missing`:void 0,A.staleEmbeddings!==void 0?`${A.staleEmbeddings} stale`:void 0,A.failedEmbeddings!==void 0?`${A.failedEmbeddings} failed`:void 0].filter(Boolean).join(" \xB7 ")}function Vxw({status:A}){let Q=qxw(A),w=A.ready?A.degraded?"Degraded":"Ready":"Indexing";return LA("div",{class:"index-gauge",style:`--index-percent: ${Q}%`,children:[LA("div",{class:"index-gauge-ring","aria-hidden":"true",children:LA("span",{children:[Q,"%"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),LA("div",{class:"index-gauge-copy",children:[LA("strong",{children:w},void 0,!1,void 0,this),LA("span",{children:zxw(A)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}function Jxw({input:A}){let Q=N0A(A);return LA("section",{class:"card semantic-index-card",children:[LA("div",{class:"card-head",children:[LA("span",{class:"card-title",children:"Semantic index"},void 0,!1,void 0,this),LA("span",{class:"card-from",children:"entity-service"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.indexStatus?LA(Vxw,{status:A.indexStatus},void 0,!1,void 0,this):LA("dl",{class:"kv",children:LA("div",{class:"kv-row",children:[LA("dt",{children:"Semantic index"},void 0,!1,void 0,this),LA("dd",{children:Q?"Ready":"Pending"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function Ixw({status:A}){let Q=A.totalFiles===void 0?"\u2014":A.totalFiles===1?"1 file":`${A.totalFiles} files`,w=A.byEntityType?Object.entries(A.byEntityType).sort(([,$],[,B])=>B-$).slice(0,2).map(([$,B])=>`${$} ${B}`).join(", "):void 0;return LA("section",{class:"card content-sync-card",children:[LA("div",{class:"card-head",children:[LA("span",{class:"card-title",children:"Content sync"},void 0,!1,void 0,this),LA("span",{class:"card-from",children:"directory-sync"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),LA("dl",{class:"kv",children:[LA("div",{class:"kv-row",children:[LA("dt",{children:"Path"},void 0,!1,void 0,this),LA("dd",{children:A.syncPath},void 0,!1,void 0,this)]},void 0,!0,void 0,this),LA("div",{class:"kv-row",children:[LA("dt",{children:"Files"},void 0,!1,void 0,this),LA("dd",{children:w?`${Q} \xB7 ${w}`:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this),LA("div",{class:"kv-row",children:[LA("dt",{children:"Watch"},void 0,!1,void 0,this),LA("dd",{children:A.watchEnabled?"Watching":A.isInitialized?"Manual":"Not initialized"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),LA("div",{class:"kv-row",children:[LA("dt",{children:"Last sync"},void 0,!1,void 0,this),LA("dd",{children:A.lastSync?`last sync ${Gxw(A.lastSync)}`:"\u2014"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),LA("div",{class:"pipeline-mini","aria-label":"Write pipeline",children:[LA("span",{class:`pipeline-step${A.isInitialized?" is-done":""}`,children:"entity db"},void 0,!1,void 0,this),LA("span",{class:"pipeline-track"},void 0,!1,void 0,this),LA("span",{class:`pipeline-step${(A.totalFiles??0)>0?" is-done":""}`,children:"exported"},void 0,!1,void 0,this),LA("span",{class:"pipeline-track"},void 0,!1,void 0,this),LA("span",{class:`pipeline-step${A.lastSync?" is-done":""}`,children:"committed"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}var Fxw={pending:"run",processing:"run",completed:"done",failed:"fail"},bxw={pending:"pending",processing:"running",completed:"done",failed:"failed"};function Lxw({jobs:A}){return LA("section",{class:"card widget-card--wide job-queue-card",children:[LA("div",{class:"card-head",children:[LA("span",{class:"card-title",children:"Job queue"},void 0,!1,void 0,this),LA("span",{class:"card-from",children:"job-queue"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.length===0?LA("p",{class:"muted",children:"No recent job progress observed."},void 0,!1,void 0,this):LA("table",{class:"jobs",children:[LA("thead",{children:LA("tr",{children:[LA("th",{children:"Job"},void 0,!1,void 0,this),LA("th",{children:"Type"},void 0,!1,void 0,this),LA("th",{children:"Updated"},void 0,!1,void 0,this),LA("th",{children:"Status"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),LA("tbody",{children:A.map((Q)=>LA("tr",{children:[LA("td",{class:"mono",children:Q.id.slice(0,8)},void 0,!1,void 0,this),LA("td",{children:Q.jobType??Q.kind},void 0,!1,void 0,this),LA("td",{class:"mono",children:j0A(Q.updatedAt)},void 0,!1,void 0,this),LA("td",{children:LA("span",{class:`status-pill status-pill--${Fxw[Q.status]}`,children:[bxw[Q.status],Q.progressLabel?` \xB7 ${Q.progressLabel}`:""]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},`${Q.kind}:${Q.id}`,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}function kxw({input:A,tabs:Q,showOperatorGate:w}){let $=$xw(Q,A),B=A.activityLog??[];return LA("section",{id:"overview",class:"dashboard-tab-panel is-active","data-dashboard-tab-panel":!0,"aria-labelledby":"dashboard-tab-overview",children:[LA(Wxw,{input:A},void 0,!1,void 0,this),LA(Kxw,{input:A},void 0,!1,void 0,this),w&&A.operatorAccess&&LA(Zxw,{hiddenWidgetCount:A.operatorAccess.hiddenWidgetCount,loginUrl:A.operatorAccess.loginUrl},void 0,!1,void 0,this),LA("div",{class:"overview-grid",children:[LA(Uxw,{cards:$},void 0,!1,void 0,this),LA(Dxw,{events:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}function _xw({tab:A,input:Q,now:w}){let $=[...A.widgets.primary,...A.widgets.secondary],B=A.group==="system",X=A.group==="knowledge",Y=A.widgets.sidebar.length>0||B;return LA("section",{id:A.id,class:"dashboard-tab-panel","data-dashboard-tab-panel":!0,"data-dashboard-group":A.group,children:[LA("header",{class:"tab-section-head",children:LA("h2",{children:A.label},void 0,!1,void 0,this)},void 0,!1,void 0,this),LA("div",{class:`layout tab-layout${Y?"":" tab-layout--main-only"}`,children:[LA("div",{class:"main-column",children:[X&&LA(y82,{total:Q.appInfo.entities,entityCounts:Q.appInfo.entityCounts},void 0,!1,void 0,this),B&&LA(p82,{children:[LA(Jxw,{input:Q},void 0,!1,void 0,this),Q.directorySyncStatus&&LA(Ixw,{status:Q.directorySyncStatus},void 0,!1,void 0,this),LA(Lxw,{jobs:Q.jobProgress??[]},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$.map((Z)=>LA(L0A,{widget:Z},`${Z.widget.pluginId}:${Z.widget.id}`,!1,void 0,this))]},void 0,!0,void 0,this),Y&&LA("div",{class:"sidebar-column",children:[B&&LA(p82,{children:[LA(E82,{endpoints:Q.appInfo.endpoints,baseUrl:Q.baseUrl},void 0,!1,void 0,this),LA(u82,{appInfo:Q.appInfo,now:w},void 0,!1,void 0,this),LA(T82,{interactions:Q.appInfo.interactions,baseUrl:Q.baseUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.widgets.sidebar.map((Z)=>LA(L0A,{widget:Z},`${Z.widget.pluginId}:${Z.widget.id}`,!1,void 0,this))]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}function Nxw({input:A}){let Q=Xxw(A.widgets),w=A.operatorAccess&&!A.operatorAccess.isOperator&&A.operatorAccess.hiddenWidgetCount>0,$=A.dashboardPath??"/dashboard",B=new Date;return LA("html",{lang:"en","data-climate":"instrument",children:[LA("head",{children:[LA("meta",{charSet:"utf-8"},void 0,!1,void 0,this),LA("meta",{name:"viewport",content:"width=device-width, initial-scale=1.0, viewport-fit=cover"},void 0,!1,void 0,this),LA("title",{children:A.title},void 0,!1,void 0,this),LA("link",{rel:"preconnect",href:"https://fonts.googleapis.com"},void 0,!1,void 0,this),LA("link",{rel:"preconnect",href:"https://fonts.gstatic.com",crossOrigin:"anonymous"},void 0,!1,void 0,this),LA("link",{href:Xr,rel:"stylesheet"},void 0,!1,void 0,this),A.themeCSS!==void 0&&LA("style",{"data-dashboard-theme":!0,dangerouslySetInnerHTML:{__html:A.themeCSS}},void 0,!1,void 0,this),LA("style",{"data-dashboard-styles":!0,dangerouslySetInnerHTML:{__html:h82}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),LA("body",{children:[LA(fxw,{dashboardPath:$,surfaces:A.surfaces??[{id:"dashboard",label:"Dashboard",href:$,isActive:!0}],operatorAccess:A.operatorAccess},void 0,!1,void 0,this),LA("main",{class:"console","data-component":"dashboard:dashboard",children:[LA("div",{class:"frame",children:[LA(g82,{title:A.title,tagline:A.profile.description},void 0,!1,void 0,this),LA(Hxw,{tabs:Q},void 0,!1,void 0,this),LA("div",{class:"canvas",children:LA("div",{class:"dashboard-tab-panels",children:[LA(kxw,{input:A,tabs:Q,showOperatorGate:Boolean(w)},void 0,!1,void 0,this),Q.map((X)=>LA(_xw,{tab:X,input:A,now:B},X.id,!1,void 0,this))]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),LA(c82,{title:A.title,appInfo:A.appInfo,baseUrl:A.baseUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this),LA("script",{dangerouslySetInnerHTML:{__html:BP}},void 0,!1,void 0,this),LA("script",{dangerouslySetInnerHTML:{__html:XP}},void 0,!1,void 0,this),LA("script",{dangerouslySetInnerHTML:{__html:Yxw}},void 0,!1,void 0,this),A.widgetScripts.map((X,Y)=>LA("script",{dangerouslySetInnerHTML:{__html:X}},`widget-script:${Y}`,!1,void 0,this))]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}function d82(A){return`<!doctype html>
9616
- ${Axw(LA(Nxw,{input:A},void 0,!1,void 0,this))}`}function jxw(A){return A.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"group"}function n82(A){let Q=A.query.trim().toLowerCase(),w=[];if(A.cmsPath!==void 0&&A.entities.length>0){let B=A.cmsPath;w.push({id:"entities",label:"Entities",items:A.entities.map((X)=>({id:`${X.entityType}/${X.id}`,title:X.title,sub:X.entityType,href:`${B}#/${encodeURIComponent(X.entityType)}/${encodeURIComponent(X.id)}`,tag:"edit in cms"}))})}let $=MH0([...new Set(A.groups)]).map((B)=>({group:B,label:mE(B)})).filter(({group:B,label:X})=>Q===""||X.toLowerCase().includes(Q)||B.toLowerCase().includes(Q)).map(({group:B,label:X})=>({id:`tab/${B}`,title:X,sub:"tab",href:`${A.dashboardPath}#${jxw(B)}`,tag:"dashboard"}));if($.length>0)w.push({id:"tabs",label:"Dashboard",items:$});return w}function r82(A,Q){let w={},$=new Set;for(let[B,X]of Object.entries(A)){let Y=Q?.get(X.widget.pluginId,X.widget.id);if(w[B]={...X,...Y?.component?{component:Y.component}:{}},Y?.clientScript)$.add(Y.clientScript)}return{widgets:w,widgetScripts:Array.from($)}}var o82={name:"@brains/dashboard",version:"0.2.0-alpha.158",description:"Dashboard plugin with extensible widget system",dependencies:{"@brains/auth-service":"workspace:*","@brains/console-theme":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2","preact-render-to-string":"^6.7.0"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var Mxw=f.object({version:f.string().default("1.0.0"),routePath:f.string().default("/dashboard"),themeCSS:f.string().optional()}),Oxw=f.object({id:f.string(),pluginId:f.string(),title:f.string(),description:f.string().optional(),group:f.string().min(1),priority:f.number().default(50),section:f.enum(["primary","secondary","sidebar"]).default("primary"),rendererName:f.string(),visibility:f.enum(["public","trusted","anchor"]).default("public"),needsOperator:f.number().int().nonnegative().optional(),digest:f.array(f.object({label:f.string(),value:f.string(),tone:f.enum(["plain","good","warn"]).optional()})).max(4).optional(),component:f.custom().optional(),clientScript:f.string().optional(),dataProvider:f.custom((A)=>typeof A==="function",{message:"Expected dashboard widget data provider function"}),digestProvider:f.custom((A)=>typeof A==="function",{message:"Expected dashboard widget digest provider function"}).optional()}).superRefine((A,Q)=>{if(!F0A(A.rendererName)&&!A.component)Q.addIssue({code:"custom",message:"Custom dashboard widgets must register a Preact component.",path:["component"]})}),xxw=f.object({pluginId:f.string(),widgetId:f.string().optional()}),Rxw=f.object({entityType:f.string(),entityId:f.string(),conversationId:f.string().optional()}),vxw=f.object({id:f.string(),type:f.enum(["job","batch"]),status:f.enum(["pending","processing","completed","failed"]),message:f.string().optional(),progress:f.object({current:f.number(),total:f.number(),percentage:f.number()}).optional(),jobDetails:f.object({jobType:f.string(),priority:f.number(),retryCount:f.number()}).optional()}),hxw=f.object({success:f.literal(!0),data:f.object({syncPath:f.string(),isInitialized:f.boolean(),watchEnabled:f.boolean(),lastSync:f.string().datetime().optional(),totalFiles:f.number().int().nonnegative().optional(),byEntityType:f.record(f.string(),f.number().int().nonnegative()).optional()})});function Cxw(A){return{id:A.id,pluginId:A.pluginId,title:A.title,...A.description?{description:A.description}:{},group:A.group,priority:A.priority,section:A.section,rendererName:A.rendererName,visibility:A.visibility,...A.needsOperator!==void 0&&{needsOperator:A.needsOperator},...A.digest?{digest:A.digest}:{},...A.component?{component:A.component}:{},...A.clientScript?{clientScript:A.clientScript}:{},dataProvider:A.dataProvider,...A.digestProvider?{digestProvider:A.digestProvider}:{}}}class P0A extends Kw{widgetRegistry=null;datasource=null;siteUrl;ctx;activityLog=[];jobProgress=[];constructor(A={}){super("dashboard",o82,A,Mxw)}recordActivity(A,Q){let w=Rxw.safeParse(Q);if(!w.success)return;this.activityLog=[{action:A,entityType:w.data.entityType,entityId:w.data.entityId,timestamp:new Date().toISOString(),...w.data.conversationId?{conversationId:w.data.conversationId}:{}},...this.activityLog].slice(0,12)}recordJobProgress(A){let Q=vxw.safeParse(A);if(!Q.success)return;let w=Q.data.progress?`${Q.data.progress.current}/${Q.data.progress.total}`:void 0,$={id:Q.data.id,kind:Q.data.type,status:Q.data.status,updatedAt:new Date().toISOString(),...Q.data.message?{message:Q.data.message}:{},...Q.data.jobDetails?.jobType?{jobType:Q.data.jobDetails.jobType}:{},...w?{progressLabel:w}:{}};this.jobProgress=[$,...this.jobProgress.filter((B)=>B.id!==$.id||B.kind!==$.kind)].slice(0,8)}async getIndexStatus(){if(!this.ctx)return;let A=this.ctx.entityService;try{if(typeof A.awaitIndexReady==="function")return await A.awaitIndexReady({timeoutMs:0,intervalMs:0});if(typeof A.isIndexReady==="function")return{ready:A.isIndexReady()}}catch(Q){this.logger.debug("Semantic index status unavailable",{error:dA(Q)})}return}async getDirectorySyncStatus(){if(!this.ctx)return;try{let A=await this.ctx.messaging.send({type:"sync:status:request",payload:{}}),Q=hxw.safeParse(A);return Q.success?Q.data.data:void 0}catch(A){this.logger.debug("Directory sync status unavailable",{error:dA(A)});return}}async onRegister(A){this.siteUrl=A.siteUrl,this.ctx=A,this.widgetRegistry=new NH0(this.logger),this.datasource=new jH0(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("entity:created",async(Q)=>{return this.recordActivity("created",Q.payload),{success:!0}}),A.messaging.subscribe("entity:updated",async(Q)=>{return this.recordActivity("updated",Q.payload),{success:!0}}),A.messaging.subscribe("entity:deleted",async(Q)=>{return this.recordActivity("deleted",Q.payload),{success:!0}}),A.messaging.subscribe("job-progress",async(Q)=>{return this.recordJobProgress(Q.payload),{success:!0}}),A.messaging.subscribe("dashboard:register-widget",async(Q)=>{try{let w=Oxw.parse(Q.payload),$=Cxw(w);return this.widgetRegistry?.register($),this.logger.debug("Widget registered via messaging",{widgetId:w.id,pluginId:w.pluginId,rendererName:w.rendererName,builtIn:_H0.includes(w.rendererName)}),{success:!0}}catch(w){return this.logger.error("Failed to register widget",{error:dA(w),payload:Q.payload}),{success:!1,error:"Widget registration failed"}}}),A.messaging.subscribe("dashboard:unregister-widget",async(Q)=>{try{let w=xxw.parse(Q.payload);return this.widgetRegistry?.unregister(w.pluginId,w.widgetId),this.logger.debug("Widget unregistered via messaging",{pluginId:w.pluginId,widgetId:w.widgetId}),{success:!0}}catch(w){return this.logger.error("Failed to unregister widget",{error:dA(w),payload:Q.payload}),{success:!1,error:"Widget unregistration failed"}}}),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,w=await s7()?.getOperatorSession(A),$=Boolean(w),B=$?"anchor":"public",X=this.widgetRegistry?.list({permissionLevel:"anchor"})??[],Y=X.filter((O)=>N9.hasPermission(B,O.visibility)),Z=X.length-Y.length,[H,W,K,U]=await Promise.all([this.datasource.getDashboardData({permissionLevel:B,widgets:Y}),Q.appInfo(),this.getDirectorySyncStatus(),this.getIndexStatus()]),G=Q.identity.get(),q=Q.identity.getProfile(),V=this.siteUrl??(()=>{try{return new URL(A.url).origin}catch{return}})(),I={...W,endpoints:W.endpoints.filter((O)=>N9.hasPermission(B,O.visibility)),interactions:W.interactions.filter((O)=>N9.hasPermission(B,O.visibility))},J=q.name||W.model||"Brain Dashboard",k=new URL(A.url),j=`${k.pathname}${k.search}`,_=encodeURIComponent(j),x=r82(H.widgets,this.widgetRegistry),v={title:J,baseUrl:V,widgets:x.widgets,widgetScripts:x.widgetScripts,dashboardPath:this.config.routePath,surfaces:Eb(Q.webRoutes.getRoutes(),{activeId:"dashboard",self:{id:"dashboard",href:this.config.routePath}}),character:G,profile:q,appInfo:I,activityLog:this.activityLog,jobProgress:this.jobProgress,...U!==void 0&&{indexStatus:U},...K!==void 0&&{directorySyncStatus:K},...this.config.themeCSS!==void 0&&{themeCSS:this.config.themeCSS},operatorAccess:{isOperator:$,hiddenWidgetCount:Z,loginUrl:`/login?return_to=${_}`,logoutUrl:`/logout?return_to=${_}`}};return new Response(d82(v),{headers:{"Content-Type":"text/html; charset=utf-8"}})}},{path:"/api/console/jump",method:"GET",public:!0,handler:async(A)=>{if(!await s7()?.getOperatorSession(A))return Response.json({error:"Operator session required"},{status:401});let w=this.ctx;if(!w)return Response.json({groups:[]});let $=new URL(A.url).searchParams.get("q")?.trim()??"",B=[];if($.length>=2)try{B=(await w.entityService.search({query:$,options:{limit:6}})).map((H)=>({entityType:H.entity.entityType,id:H.entity.id,title:H.entity.title??H.entity.id}))}catch{}let X=(this.widgetRegistry?.list({permissionLevel:"anchor"})??[]).map((Z)=>Z.group),Y=Eb(w.webRoutes.getRoutes(),{activeId:"dashboard"}).find((Z)=>Z.id==="cms")?.href;return Response.json({groups:n82({query:$,groups:[...X,"knowledge","system"],dashboardPath:this.config.routePath,cmsPath:Y,entities:B})})}}]}async getTools(){return[]}getWidgetRegistry(){return this.widgetRegistry}}function OL(A={}){return new P0A(A)}C0();var gxw=f.enum(["public","trusted","anchor"]),yxw=f.object({label:f.string(),value:f.string(),tone:f.enum(["plain","good","warn"]).optional()}),Exw=f.object({id:f.string(),pluginId:f.string(),title:f.string(),description:f.string().optional(),group:f.string().min(1),priority:f.number(),section:f.enum(["primary","secondary","sidebar"]),rendererName:f.string(),visibility:gxw,needsOperator:f.number().int().nonnegative().optional(),digest:f.array(yxw).max(4).optional(),component:f.custom().optional()}),Txw=f.object({widget:Exw,data:f.unknown()}),Sxw=f.object({widgets:f.record(f.string(),Txw)});fA();C0();fA();C0();import{h as $Rw}from"preact";fA();Xf();b2();C0();var OH0=f.enum(["generating","draft","queued","published","failed"]),mxw=f.enum(["generating","draft","queued","published","failed"]),xH0=f.object({subject:f.string(),status:OH0,entityIds:f.array(f.string()).optional(),scheduledFor:f.string().datetime().optional(),sentAt:f.string().datetime().optional(),buttondownId:f.string().optional(),sourceEntityType:f.string().optional()}),s82=f.object({subject:f.string(),status:OH0,entityIds:f.array(f.string()).optional(),scheduledFor:f.string().datetime().optional(),sentAt:f.string().datetime().optional(),buttondownId:f.string().optional(),sourceEntityType:f.string().optional(),error:f.string().optional()}),uxw=f.object({subject:f.string(),status:mxw,entityIds:f.array(f.string()).optional(),scheduledFor:f.string().datetime().optional(),sentAt:f.string().datetime().optional(),buttondownId:f.string().optional(),sourceEntityType:f.string().optional(),error:f.string().optional()}),uE=EQ.extend({entityType:f.literal("newsletter"),metadata:uxw});fA();class a82 extends d2{constructor(){super({entityType:"newsletter",purpose:"An email newsletter issue composed for subscribers.",schema:uE,frontmatterSchema:xH0})}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 t82=new a82;fA();fA();b2();C0();var cxw=f.looseObject({id:f.string().optional(),limit:f.number().optional(),page:f.number().optional(),pageSize:f.number().optional(),baseUrl:f.string().optional(),status:f.enum(["generating","draft","queued","published","failed"]).optional()}),lxw=f.looseObject({entityType:f.string().optional(),query:cxw.optional()});function e82(A){try{let{content:Q}=$Q(A.content,xH0);return Q}catch{return A.content}}class M0A extends c5{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=lxw.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}transformEntity(A){let Q=e82(A),w={id:A.id,subject:A.metadata.subject,status:A.metadata.status,excerpt:mX(Q,150),created:A.created,url:`/newsletters/${A.id}`};if(A.metadata.sentAt)w.sentAt=A.metadata.sentAt;return w}buildListResult(A,Q,w){return{newsletters:A,totalCount:Q?.totalItems??A.length,pagination:Q}}async fetch(A,Q,w){let{query:$}=this.parseQuery(A),B=w.entityService;if($.id)return this.fetchSingleNewsletter($.id,Q,B);let X=$.status,Y=X?{filter:{metadata:{status:X}}}:void 0,{items:Z,pagination:H}=await this.fetchList($,B,Y);return Q.parse(this.buildListResult(Z,H,$))}async fetchSingleNewsletter(A,Q,w){let $=await w.getEntity({entityType:this.config.entityType,id:A});if(!$)throw Error(`Newsletter not found: ${A}`);let B=await this.resolveNavigation($,w),X=[];if($.metadata.entityIds?.length){let H=$.metadata.sourceEntityType??"post";X=(await Promise.all($.metadata.entityIds.map(async(K)=>{let U=await w.getEntity({entityType:H,id:K});if(U){let G=U.metadata;return{id:K,title:G.title??K,url:`/${H}s/${G.slug??K}`}}return null}))).filter((K)=>K!==null)}let Y=e82($),Z={id:$.id,subject:$.metadata.subject,status:$.metadata.status,content:Y,created:$.created,updated:$.updated,sentAt:$.metadata.sentAt,scheduledFor:$.metadata.scheduledFor,newsletter:$,prevNewsletter:B.prev?{id:B.prev.id,subject:B.prev.subject,url:B.prev.url}:null,nextNewsletter:B.next?{id:B.next.id,subject:B.next.subject,url:B.next.url}:null,sourceEntities:X.length>0?X:void 0};return Q.parse(Z)}}fA();b2();C0();var pxw=f.object({prompt:f.string().optional().describe("AI generation prompt"),sourceEntityIds:f.array(f.string()).optional().describe("Entity IDs to include in newsletter (e.g., blog posts)"),sourceEntityType:f.enum(["post"]).optional().describe("Type of source entities"),content:f.string().optional().describe("Direct content (skip AI)"),subject:f.string().optional().describe("Newsletter subject (AI-generated if not provided)"),addToQueue:f.boolean().optional().describe("Create as queued (true) or draft (false)")});class O0A extends S4{constructor(A,Q){super(A,Q,{schema:pxw,jobTypeName:"newsletter:generation",entityType:"newsletter"})}async generate(A,Q){let w=A.addToQueue??!1,{prompt:$,sourceEntityIds:B,sourceEntityType:X}=A,{content:Y,subject:Z}=A;if(Y){if(!Z)this.failEarly("Subject is required when providing content directly");await this.reportProgress(Q,{progress:50,message:"Using provided content"})}else if(B&&B.length>0){let G=X??"post";await this.reportProgress(Q,{progress:10,message:`Fetching ${B.length} source entities`});let V=(await Promise.all(B.map((_)=>this.context.entityService.getEntity({entityType:G,id:_})))).filter((_)=>_!=null);if(V.length===0)this.failEarly(`No source entities found for IDs: ${B.join(", ")}`);await this.reportProgress(Q,{progress:30,message:`Generating newsletter from ${V.length} posts`});let J=`Create an engaging newsletter that highlights these blog posts:
9616
+ ${Axw(LA(Nxw,{input:A},void 0,!1,void 0,this))}`}function jxw(A){return A.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"group"}function n82(A){let Q=A.query.trim().toLowerCase(),w=[];if(A.cmsPath!==void 0&&A.entities.length>0){let B=A.cmsPath;w.push({id:"entities",label:"Entities",items:A.entities.map((X)=>({id:`${X.entityType}/${X.id}`,title:X.title,sub:X.entityType,href:`${B}#/${encodeURIComponent(X.entityType)}/${encodeURIComponent(X.id)}`,tag:"edit in cms"}))})}let $=MH0([...new Set(A.groups)]).map((B)=>({group:B,label:mE(B)})).filter(({group:B,label:X})=>Q===""||X.toLowerCase().includes(Q)||B.toLowerCase().includes(Q)).map(({group:B,label:X})=>({id:`tab/${B}`,title:X,sub:"tab",href:`${A.dashboardPath}#${jxw(B)}`,tag:"dashboard"}));if($.length>0)w.push({id:"tabs",label:"Dashboard",items:$});return w}function r82(A,Q){let w={},$=new Set;for(let[B,X]of Object.entries(A)){let Y=Q?.get(X.widget.pluginId,X.widget.id);if(w[B]={...X,...Y?.component?{component:Y.component}:{}},Y?.clientScript)$.add(Y.clientScript)}return{widgets:w,widgetScripts:Array.from($)}}var o82={name:"@brains/dashboard",version:"0.2.0-alpha.159",description:"Dashboard plugin with extensible widget system",dependencies:{"@brains/auth-service":"workspace:*","@brains/console-theme":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2","preact-render-to-string":"^6.7.0"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var Mxw=f.object({version:f.string().default("1.0.0"),routePath:f.string().default("/dashboard"),themeCSS:f.string().optional()}),Oxw=f.object({id:f.string(),pluginId:f.string(),title:f.string(),description:f.string().optional(),group:f.string().min(1),priority:f.number().default(50),section:f.enum(["primary","secondary","sidebar"]).default("primary"),rendererName:f.string(),visibility:f.enum(["public","trusted","anchor"]).default("public"),needsOperator:f.number().int().nonnegative().optional(),digest:f.array(f.object({label:f.string(),value:f.string(),tone:f.enum(["plain","good","warn"]).optional()})).max(4).optional(),component:f.custom().optional(),clientScript:f.string().optional(),dataProvider:f.custom((A)=>typeof A==="function",{message:"Expected dashboard widget data provider function"}),digestProvider:f.custom((A)=>typeof A==="function",{message:"Expected dashboard widget digest provider function"}).optional()}).superRefine((A,Q)=>{if(!F0A(A.rendererName)&&!A.component)Q.addIssue({code:"custom",message:"Custom dashboard widgets must register a Preact component.",path:["component"]})}),xxw=f.object({pluginId:f.string(),widgetId:f.string().optional()}),Rxw=f.object({entityType:f.string(),entityId:f.string(),conversationId:f.string().optional()}),vxw=f.object({id:f.string(),type:f.enum(["job","batch"]),status:f.enum(["pending","processing","completed","failed"]),message:f.string().optional(),progress:f.object({current:f.number(),total:f.number(),percentage:f.number()}).optional(),jobDetails:f.object({jobType:f.string(),priority:f.number(),retryCount:f.number()}).optional()}),hxw=f.object({success:f.literal(!0),data:f.object({syncPath:f.string(),isInitialized:f.boolean(),watchEnabled:f.boolean(),lastSync:f.string().datetime().optional(),totalFiles:f.number().int().nonnegative().optional(),byEntityType:f.record(f.string(),f.number().int().nonnegative()).optional()})});function Cxw(A){return{id:A.id,pluginId:A.pluginId,title:A.title,...A.description?{description:A.description}:{},group:A.group,priority:A.priority,section:A.section,rendererName:A.rendererName,visibility:A.visibility,...A.needsOperator!==void 0&&{needsOperator:A.needsOperator},...A.digest?{digest:A.digest}:{},...A.component?{component:A.component}:{},...A.clientScript?{clientScript:A.clientScript}:{},dataProvider:A.dataProvider,...A.digestProvider?{digestProvider:A.digestProvider}:{}}}class P0A extends Kw{widgetRegistry=null;datasource=null;siteUrl;ctx;activityLog=[];jobProgress=[];constructor(A={}){super("dashboard",o82,A,Mxw)}recordActivity(A,Q){let w=Rxw.safeParse(Q);if(!w.success)return;this.activityLog=[{action:A,entityType:w.data.entityType,entityId:w.data.entityId,timestamp:new Date().toISOString(),...w.data.conversationId?{conversationId:w.data.conversationId}:{}},...this.activityLog].slice(0,12)}recordJobProgress(A){let Q=vxw.safeParse(A);if(!Q.success)return;let w=Q.data.progress?`${Q.data.progress.current}/${Q.data.progress.total}`:void 0,$={id:Q.data.id,kind:Q.data.type,status:Q.data.status,updatedAt:new Date().toISOString(),...Q.data.message?{message:Q.data.message}:{},...Q.data.jobDetails?.jobType?{jobType:Q.data.jobDetails.jobType}:{},...w?{progressLabel:w}:{}};this.jobProgress=[$,...this.jobProgress.filter((B)=>B.id!==$.id||B.kind!==$.kind)].slice(0,8)}async getIndexStatus(){if(!this.ctx)return;let A=this.ctx.entityService;try{if(typeof A.awaitIndexReady==="function")return await A.awaitIndexReady({timeoutMs:0,intervalMs:0});if(typeof A.isIndexReady==="function")return{ready:A.isIndexReady()}}catch(Q){this.logger.debug("Semantic index status unavailable",{error:dA(Q)})}return}async getDirectorySyncStatus(){if(!this.ctx)return;try{let A=await this.ctx.messaging.send({type:"sync:status:request",payload:{}}),Q=hxw.safeParse(A);return Q.success?Q.data.data:void 0}catch(A){this.logger.debug("Directory sync status unavailable",{error:dA(A)});return}}async onRegister(A){this.siteUrl=A.siteUrl,this.ctx=A,this.widgetRegistry=new NH0(this.logger),this.datasource=new jH0(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("entity:created",async(Q)=>{return this.recordActivity("created",Q.payload),{success:!0}}),A.messaging.subscribe("entity:updated",async(Q)=>{return this.recordActivity("updated",Q.payload),{success:!0}}),A.messaging.subscribe("entity:deleted",async(Q)=>{return this.recordActivity("deleted",Q.payload),{success:!0}}),A.messaging.subscribe("job-progress",async(Q)=>{return this.recordJobProgress(Q.payload),{success:!0}}),A.messaging.subscribe("dashboard:register-widget",async(Q)=>{try{let w=Oxw.parse(Q.payload),$=Cxw(w);return this.widgetRegistry?.register($),this.logger.debug("Widget registered via messaging",{widgetId:w.id,pluginId:w.pluginId,rendererName:w.rendererName,builtIn:_H0.includes(w.rendererName)}),{success:!0}}catch(w){return this.logger.error("Failed to register widget",{error:dA(w),payload:Q.payload}),{success:!1,error:"Widget registration failed"}}}),A.messaging.subscribe("dashboard:unregister-widget",async(Q)=>{try{let w=xxw.parse(Q.payload);return this.widgetRegistry?.unregister(w.pluginId,w.widgetId),this.logger.debug("Widget unregistered via messaging",{pluginId:w.pluginId,widgetId:w.widgetId}),{success:!0}}catch(w){return this.logger.error("Failed to unregister widget",{error:dA(w),payload:Q.payload}),{success:!1,error:"Widget unregistration failed"}}}),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,w=await s7()?.getOperatorSession(A),$=Boolean(w),B=$?"anchor":"public",X=this.widgetRegistry?.list({permissionLevel:"anchor"})??[],Y=X.filter((O)=>N9.hasPermission(B,O.visibility)),Z=X.length-Y.length,[H,W,K,U]=await Promise.all([this.datasource.getDashboardData({permissionLevel:B,widgets:Y}),Q.appInfo(),this.getDirectorySyncStatus(),this.getIndexStatus()]),G=Q.identity.get(),q=Q.identity.getProfile(),V=this.siteUrl??(()=>{try{return new URL(A.url).origin}catch{return}})(),I={...W,endpoints:W.endpoints.filter((O)=>N9.hasPermission(B,O.visibility)),interactions:W.interactions.filter((O)=>N9.hasPermission(B,O.visibility))},J=q.name||W.model||"Brain Dashboard",k=new URL(A.url),j=`${k.pathname}${k.search}`,_=encodeURIComponent(j),x=r82(H.widgets,this.widgetRegistry),v={title:J,baseUrl:V,widgets:x.widgets,widgetScripts:x.widgetScripts,dashboardPath:this.config.routePath,surfaces:Eb(Q.webRoutes.getRoutes(),{activeId:"dashboard",self:{id:"dashboard",href:this.config.routePath}}),character:G,profile:q,appInfo:I,activityLog:this.activityLog,jobProgress:this.jobProgress,...U!==void 0&&{indexStatus:U},...K!==void 0&&{directorySyncStatus:K},...this.config.themeCSS!==void 0&&{themeCSS:this.config.themeCSS},operatorAccess:{isOperator:$,hiddenWidgetCount:Z,loginUrl:`/login?return_to=${_}`,logoutUrl:`/logout?return_to=${_}`}};return new Response(d82(v),{headers:{"Content-Type":"text/html; charset=utf-8"}})}},{path:"/api/console/jump",method:"GET",public:!0,handler:async(A)=>{if(!await s7()?.getOperatorSession(A))return Response.json({error:"Operator session required"},{status:401});let w=this.ctx;if(!w)return Response.json({groups:[]});let $=new URL(A.url).searchParams.get("q")?.trim()??"",B=[];if($.length>=2)try{B=(await w.entityService.search({query:$,options:{limit:6}})).map((H)=>({entityType:H.entity.entityType,id:H.entity.id,title:H.entity.title??H.entity.id}))}catch{}let X=(this.widgetRegistry?.list({permissionLevel:"anchor"})??[]).map((Z)=>Z.group),Y=Eb(w.webRoutes.getRoutes(),{activeId:"dashboard"}).find((Z)=>Z.id==="cms")?.href;return Response.json({groups:n82({query:$,groups:[...X,"knowledge","system"],dashboardPath:this.config.routePath,cmsPath:Y,entities:B})})}}]}async getTools(){return[]}getWidgetRegistry(){return this.widgetRegistry}}function OL(A={}){return new P0A(A)}C0();var gxw=f.enum(["public","trusted","anchor"]),yxw=f.object({label:f.string(),value:f.string(),tone:f.enum(["plain","good","warn"]).optional()}),Exw=f.object({id:f.string(),pluginId:f.string(),title:f.string(),description:f.string().optional(),group:f.string().min(1),priority:f.number(),section:f.enum(["primary","secondary","sidebar"]),rendererName:f.string(),visibility:gxw,needsOperator:f.number().int().nonnegative().optional(),digest:f.array(yxw).max(4).optional(),component:f.custom().optional()}),Txw=f.object({widget:Exw,data:f.unknown()}),Sxw=f.object({widgets:f.record(f.string(),Txw)});fA();C0();fA();C0();import{h as $Rw}from"preact";fA();Xf();b2();C0();var OH0=f.enum(["generating","draft","queued","published","failed"]),mxw=f.enum(["generating","draft","queued","published","failed"]),xH0=f.object({subject:f.string(),status:OH0,entityIds:f.array(f.string()).optional(),scheduledFor:f.string().datetime().optional(),sentAt:f.string().datetime().optional(),buttondownId:f.string().optional(),sourceEntityType:f.string().optional()}),s82=f.object({subject:f.string(),status:OH0,entityIds:f.array(f.string()).optional(),scheduledFor:f.string().datetime().optional(),sentAt:f.string().datetime().optional(),buttondownId:f.string().optional(),sourceEntityType:f.string().optional(),error:f.string().optional()}),uxw=f.object({subject:f.string(),status:mxw,entityIds:f.array(f.string()).optional(),scheduledFor:f.string().datetime().optional(),sentAt:f.string().datetime().optional(),buttondownId:f.string().optional(),sourceEntityType:f.string().optional(),error:f.string().optional()}),uE=EQ.extend({entityType:f.literal("newsletter"),metadata:uxw});fA();class a82 extends d2{constructor(){super({entityType:"newsletter",purpose:"An email newsletter issue composed for subscribers.",schema:uE,frontmatterSchema:xH0})}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 t82=new a82;fA();fA();b2();C0();var cxw=f.looseObject({id:f.string().optional(),limit:f.number().optional(),page:f.number().optional(),pageSize:f.number().optional(),baseUrl:f.string().optional(),status:f.enum(["generating","draft","queued","published","failed"]).optional()}),lxw=f.looseObject({entityType:f.string().optional(),query:cxw.optional()});function e82(A){try{let{content:Q}=$Q(A.content,xH0);return Q}catch{return A.content}}class M0A extends c5{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=lxw.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}transformEntity(A){let Q=e82(A),w={id:A.id,subject:A.metadata.subject,status:A.metadata.status,excerpt:mX(Q,150),created:A.created,url:`/newsletters/${A.id}`};if(A.metadata.sentAt)w.sentAt=A.metadata.sentAt;return w}buildListResult(A,Q,w){return{newsletters:A,totalCount:Q?.totalItems??A.length,pagination:Q}}async fetch(A,Q,w){let{query:$}=this.parseQuery(A),B=w.entityService;if($.id)return this.fetchSingleNewsletter($.id,Q,B);let X=$.status,Y=X?{filter:{metadata:{status:X}}}:void 0,{items:Z,pagination:H}=await this.fetchList($,B,Y);return Q.parse(this.buildListResult(Z,H,$))}async fetchSingleNewsletter(A,Q,w){let $=await w.getEntity({entityType:this.config.entityType,id:A});if(!$)throw Error(`Newsletter not found: ${A}`);let B=await this.resolveNavigation($,w),X=[];if($.metadata.entityIds?.length){let H=$.metadata.sourceEntityType??"post";X=(await Promise.all($.metadata.entityIds.map(async(K)=>{let U=await w.getEntity({entityType:H,id:K});if(U){let G=U.metadata;return{id:K,title:G.title??K,url:`/${H}s/${G.slug??K}`}}return null}))).filter((K)=>K!==null)}let Y=e82($),Z={id:$.id,subject:$.metadata.subject,status:$.metadata.status,content:Y,created:$.created,updated:$.updated,sentAt:$.metadata.sentAt,scheduledFor:$.metadata.scheduledFor,newsletter:$,prevNewsletter:B.prev?{id:B.prev.id,subject:B.prev.subject,url:B.prev.url}:null,nextNewsletter:B.next?{id:B.next.id,subject:B.next.subject,url:B.next.url}:null,sourceEntities:X.length>0?X:void 0};return Q.parse(Z)}}fA();b2();C0();var pxw=f.object({prompt:f.string().optional().describe("AI generation prompt"),sourceEntityIds:f.array(f.string()).optional().describe("Entity IDs to include in newsletter (e.g., blog posts)"),sourceEntityType:f.enum(["post"]).optional().describe("Type of source entities"),content:f.string().optional().describe("Direct content (skip AI)"),subject:f.string().optional().describe("Newsletter subject (AI-generated if not provided)"),addToQueue:f.boolean().optional().describe("Create as queued (true) or draft (false)")});class O0A extends S4{constructor(A,Q){super(A,Q,{schema:pxw,jobTypeName:"newsletter:generation",entityType:"newsletter"})}async generate(A,Q){let w=A.addToQueue??!1,{prompt:$,sourceEntityIds:B,sourceEntityType:X}=A,{content:Y,subject:Z}=A;if(Y){if(!Z)this.failEarly("Subject is required when providing content directly");await this.reportProgress(Q,{progress:50,message:"Using provided content"})}else if(B&&B.length>0){let G=X??"post";await this.reportProgress(Q,{progress:10,message:`Fetching ${B.length} source entities`});let V=(await Promise.all(B.map((_)=>this.context.entityService.getEntity({entityType:G,id:_})))).filter((_)=>_!=null);if(V.length===0)this.failEarly(`No source entities found for IDs: ${B.join(", ")}`);await this.reportProgress(Q,{progress:30,message:`Generating newsletter from ${V.length} posts`});let J=`Create an engaging newsletter that highlights these blog posts:
9617
9617
 
9618
9618
  ${V.map((_)=>`## ${_.metadata.title}
9619
9619
 
@@ -9682,17 +9682,17 @@ Newsletter-specific guidelines:
9682
9682
  - "Reply and let me know..."
9683
9683
  - "Until next time..."
9684
9684
 
9685
- The goal is to build a relationship with readers through valuable, authentic content.`});C0();fA();import{jsxDEV as bY,Fragment as sxw}from"preact/jsx-dev-runtime";var dxw=f.enum(["generating","draft","queued","published","failed"]),nxw=f.object({id:f.string(),subject:f.string(),status:dxw,excerpt:f.string(),created:f.string(),sentAt:f.string().optional(),url:f.string()}),rxw=f.object({newsletters:f.array(nxw),totalCount:f.number(),pagination:M20.nullable()}),oxw=({newsletters:A,totalCount:Q,pageTitle:w,pagination:$,baseUrl:B="/newsletters"})=>{let X=w??"Newsletters",Y=`Browse all ${Q} ${Q===1?"newsletter":"newsletters"}`;return bY(sxw,{children:[bY($w,{title:X,description:Y},void 0,!1,void 0,this),bY("div",{className:"newsletter-list bg-theme",children:bY("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[bY("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:X},void 0,!1,void 0,this),A.length===0?bY("p",{className:"text-theme-muted italic",children:"No newsletters yet."},void 0,!1,void 0,this):bY("div",{className:"space-y-4",children:A.map((Z)=>bY(O6,{href:Z.url,children:[bY(M7,{className:"text-lg",children:Z.subject},void 0,!1,void 0,this),bY($4,{children:bY("div",{className:"flex items-center gap-3",children:[bY(VZ,{status:Z.status},void 0,!1,void 0,this),bY("span",{className:"text-sm text-theme-muted",children:dB(Z.sentAt??Z.created,{style:"long"})},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Z.excerpt&&bY("p",{className:"text-theme-muted line-clamp-2",children:Z.excerpt},void 0,!1,void 0,this)]},Z.id,!0,void 0,this))},void 0,!1,void 0,this),$&&$.totalPages>1&&bY(CV,{currentPage:$.currentPage,totalPages:$.totalPages,baseUrl:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},QB2=e1({name:"newsletter-list",description:"Newsletter list page template",schema:rxw,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:oxw}});C0();fA();import{jsxDEV as z8,Fragment as QRw}from"preact/jsx-dev-runtime";var axw=f.enum(["generating","draft","queued","published","failed"]),txw=f.object({id:f.string(),title:f.string(),url:f.string()}),wB2=f.object({id:f.string(),subject:f.string(),url:f.string()}),exw=f.object({id:f.string(),subject:f.string(),status:axw,content:f.string(),created:f.string(),updated:f.string(),sentAt:f.string().optional(),scheduledFor:f.string().optional(),sourceEntities:f.array(txw).optional(),prevNewsletter:wB2.nullable().optional(),nextNewsletter:wB2.nullable().optional()}),ARw=({subject:A,status:Q,content:w,created:$,sentAt:B,scheduledFor:X,sourceEntities:Y,prevNewsletter:Z,nextNewsletter:H})=>{let W=[{label:"Home",href:"/"},{label:"Newsletters",href:"/newsletters"},{label:A}],K=B??$,U=B?"Sent":"Created";return z8(QRw,{children:[z8($w,{title:A,description:`Newsletter: ${A}`},void 0,!1,void 0,this),z8("section",{className:"newsletter-detail-section",children:z8("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:z8("div",{className:"max-w-3xl mx-auto",children:[z8(qq,{items:W},void 0,!1,void 0,this),z8("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),z8("div",{className:"flex flex-wrap items-center gap-3 mb-8 text-sm text-theme-muted",children:[z8(VZ,{status:Q},void 0,!1,void 0,this),z8("span",{children:[U,": ",dB(K,{style:"long"})]},void 0,!0,void 0,this),X&&Q==="queued"&&z8("span",{children:["Scheduled for: ",dB(X,{style:"long"})]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Y&&Y.length>0&&z8(O6,{variant:"compact",className:"mb-8",children:[z8("h3",{className:"text-sm font-medium text-heading mb-2",children:"Related Content"},void 0,!1,void 0,this),z8("ul",{className:"space-y-1",children:Y.map((G)=>z8("li",{children:z8("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),z8(l9,{markdown:w},void 0,!1,void 0,this),(Z??H)&&z8("nav",{className:"mt-12 pt-8 border-t border-theme",children:z8("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[Z?z8(O6,{href:Z.url,variant:"compact",children:[z8("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Newer"},void 0,!1,void 0,this),z8("span",{className:"block mt-1 font-medium text-heading group-hover:text-brand transition-colors truncate",children:Z.subject},void 0,!1,void 0,this)]},void 0,!0,void 0,this):z8("div",{},void 0,!1,void 0,this),H&&z8(O6,{href:H.url,variant:"compact",className:"md:text-right",children:[z8("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Older"},void 0,!1,void 0,this),z8("span",{className:"block mt-1 font-medium text-heading group-hover:text-brand transition-colors truncate",children:H.subject},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},$B2=e1({name:"newsletter-detail",description:"Individual newsletter detail template",schema:exw,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:ARw}});var RH0={name:"@brains/newsletter",version:"0.2.0-alpha.158",description:"Newsletter composite \u2014 bundles the newsletter entity with the buttondown service plugin",dependencies:{"@brains/contracts":"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":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts","./env-schema":"./src/env-schema.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var BRw=f.looseObject({}),XRw=f.object({prompt:f.string().optional(),content:f.string().optional()});class vH0 extends Zw{entityType="newsletter";schema=uE;adapter=t82;constructor(A={}){super("newsletter",RH0,A,BRw)}getEntityTypeConfig(){return{publish:{publishStatuses:["queued","published","failed"]}}}createGenerationHandler(A){return new O0A(this.logger,A)}getTemplates(){return{generation:AB2,"newsletter-list":QB2,"newsletter-detail":$B2}}getDataSources(){return[new M0A(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:()=>$Rw(Nr0,{variant:"inline"})}});return{success:!0}}),this.logger.debug("Newsletter plugin registered")}deferPublishRegistration(A){let Q={name:"internal",publish:async(w,$)=>{let B=typeof $.subject==="string"?$.subject:"",X=await A.messaging.send({type:"buttondown:send",payload:{entityId:"",subject:B,content:w}});return{id:!("noop"in X)&&X.data?.emailId?X.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 w=await A.entityService.listEntities({entityType:"post",options:{filter:{metadata:{status:"published"}},limit:10}});if(w.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:w.map(($)=>$.id),sourceEntityType:"post",addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}}),{success:!0}}catch(w){return await A.messaging.send({type:"generate:report:failure",payload:{entityType:"newsletter",error:dA(w)}}),{success:!0}}})}registerEvalHandlers(A){A.eval.registerHandler("generation",async(Q)=>{let w=XRw.parse(Q),$=w.content?`Create an engaging newsletter based on this content:
9685
+ The goal is to build a relationship with readers through valuable, authentic content.`});C0();fA();import{jsxDEV as bY,Fragment as sxw}from"preact/jsx-dev-runtime";var dxw=f.enum(["generating","draft","queued","published","failed"]),nxw=f.object({id:f.string(),subject:f.string(),status:dxw,excerpt:f.string(),created:f.string(),sentAt:f.string().optional(),url:f.string()}),rxw=f.object({newsletters:f.array(nxw),totalCount:f.number(),pagination:M20.nullable()}),oxw=({newsletters:A,totalCount:Q,pageTitle:w,pagination:$,baseUrl:B="/newsletters"})=>{let X=w??"Newsletters",Y=`Browse all ${Q} ${Q===1?"newsletter":"newsletters"}`;return bY(sxw,{children:[bY($w,{title:X,description:Y},void 0,!1,void 0,this),bY("div",{className:"newsletter-list bg-theme",children:bY("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[bY("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:X},void 0,!1,void 0,this),A.length===0?bY("p",{className:"text-theme-muted italic",children:"No newsletters yet."},void 0,!1,void 0,this):bY("div",{className:"space-y-4",children:A.map((Z)=>bY(O6,{href:Z.url,children:[bY(M7,{className:"text-lg",children:Z.subject},void 0,!1,void 0,this),bY($4,{children:bY("div",{className:"flex items-center gap-3",children:[bY(VZ,{status:Z.status},void 0,!1,void 0,this),bY("span",{className:"text-sm text-theme-muted",children:dB(Z.sentAt??Z.created,{style:"long"})},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Z.excerpt&&bY("p",{className:"text-theme-muted line-clamp-2",children:Z.excerpt},void 0,!1,void 0,this)]},Z.id,!0,void 0,this))},void 0,!1,void 0,this),$&&$.totalPages>1&&bY(CV,{currentPage:$.currentPage,totalPages:$.totalPages,baseUrl:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},QB2=e1({name:"newsletter-list",description:"Newsletter list page template",schema:rxw,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:oxw}});C0();fA();import{jsxDEV as z8,Fragment as QRw}from"preact/jsx-dev-runtime";var axw=f.enum(["generating","draft","queued","published","failed"]),txw=f.object({id:f.string(),title:f.string(),url:f.string()}),wB2=f.object({id:f.string(),subject:f.string(),url:f.string()}),exw=f.object({id:f.string(),subject:f.string(),status:axw,content:f.string(),created:f.string(),updated:f.string(),sentAt:f.string().optional(),scheduledFor:f.string().optional(),sourceEntities:f.array(txw).optional(),prevNewsletter:wB2.nullable().optional(),nextNewsletter:wB2.nullable().optional()}),ARw=({subject:A,status:Q,content:w,created:$,sentAt:B,scheduledFor:X,sourceEntities:Y,prevNewsletter:Z,nextNewsletter:H})=>{let W=[{label:"Home",href:"/"},{label:"Newsletters",href:"/newsletters"},{label:A}],K=B??$,U=B?"Sent":"Created";return z8(QRw,{children:[z8($w,{title:A,description:`Newsletter: ${A}`},void 0,!1,void 0,this),z8("section",{className:"newsletter-detail-section",children:z8("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:z8("div",{className:"max-w-3xl mx-auto",children:[z8(qq,{items:W},void 0,!1,void 0,this),z8("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),z8("div",{className:"flex flex-wrap items-center gap-3 mb-8 text-sm text-theme-muted",children:[z8(VZ,{status:Q},void 0,!1,void 0,this),z8("span",{children:[U,": ",dB(K,{style:"long"})]},void 0,!0,void 0,this),X&&Q==="queued"&&z8("span",{children:["Scheduled for: ",dB(X,{style:"long"})]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Y&&Y.length>0&&z8(O6,{variant:"compact",className:"mb-8",children:[z8("h3",{className:"text-sm font-medium text-heading mb-2",children:"Related Content"},void 0,!1,void 0,this),z8("ul",{className:"space-y-1",children:Y.map((G)=>z8("li",{children:z8("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),z8(l9,{markdown:w},void 0,!1,void 0,this),(Z??H)&&z8("nav",{className:"mt-12 pt-8 border-t border-theme",children:z8("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[Z?z8(O6,{href:Z.url,variant:"compact",children:[z8("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Newer"},void 0,!1,void 0,this),z8("span",{className:"block mt-1 font-medium text-heading group-hover:text-brand transition-colors truncate",children:Z.subject},void 0,!1,void 0,this)]},void 0,!0,void 0,this):z8("div",{},void 0,!1,void 0,this),H&&z8(O6,{href:H.url,variant:"compact",className:"md:text-right",children:[z8("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Older"},void 0,!1,void 0,this),z8("span",{className:"block mt-1 font-medium text-heading group-hover:text-brand transition-colors truncate",children:H.subject},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},$B2=e1({name:"newsletter-detail",description:"Individual newsletter detail template",schema:exw,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:ARw}});var RH0={name:"@brains/newsletter",version:"0.2.0-alpha.159",description:"Newsletter composite \u2014 bundles the newsletter entity with the buttondown service plugin",dependencies:{"@brains/contracts":"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":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts","./env-schema":"./src/env-schema.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var BRw=f.looseObject({}),XRw=f.object({prompt:f.string().optional(),content:f.string().optional()});class vH0 extends Zw{entityType="newsletter";schema=uE;adapter=t82;constructor(A={}){super("newsletter",RH0,A,BRw)}getEntityTypeConfig(){return{publish:{publishStatuses:["queued","published","failed"]}}}createGenerationHandler(A){return new O0A(this.logger,A)}getTemplates(){return{generation:AB2,"newsletter-list":QB2,"newsletter-detail":$B2}}getDataSources(){return[new M0A(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:()=>$Rw(Nr0,{variant:"inline"})}});return{success:!0}}),this.logger.debug("Newsletter plugin registered")}deferPublishRegistration(A){let Q={name:"internal",publish:async(w,$)=>{let B=typeof $.subject==="string"?$.subject:"",X=await A.messaging.send({type:"buttondown:send",payload:{entityId:"",subject:B,content:w}});return{id:!("noop"in X)&&X.data?.emailId?X.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 w=await A.entityService.listEntities({entityType:"post",options:{filter:{metadata:{status:"published"}},limit:10}});if(w.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:w.map(($)=>$.id),sourceEntityType:"post",addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}}),{success:!0}}catch(w){return await A.messaging.send({type:"generate:report:failure",payload:{entityType:"newsletter",error:dA(w)}}),{success:!0}}})}registerEvalHandlers(A){A.eval.registerHandler("generation",async(Q)=>{let w=XRw.parse(Q),$=w.content?`Create an engaging newsletter based on this content:
9686
9686
 
9687
9687
  ${w.content}`:w.prompt??"Write an engaging newsletter";return A.ai.generate({prompt:$,templateName:"newsletter:generation"})})}}function hH0(A={}){return new vH0(A)}fA();C0();C0();var ZRw="https://api.buttondown.email/v1",fRw=f.enum(["unactivated","regular","unsubscribed","already_subscribed"]),HRw=f.enum(["draft","about_to_send","scheduled","sent"]),x0A=f.looseObject({id:f.string(),email:f.string(),subscriber_type:fRw,metadata:f.record(f.string(),f.string()).optional()}),BB2=f.looseObject({id:f.string(),subject:f.string(),body:f.string().optional(),status:HRw,publish_date:f.string().optional()}),WRw=f.looseObject({results:f.array(x0A),count:f.number()}),KRw=f.looseObject({detail:f.string().optional(),message:f.string().optional(),code:f.string().optional()});class R0A extends Error{status;code;constructor(A,Q,w){super(A);this.name="ButtondownApiError",this.status=Q,this.code=w}}class bM{config;logger;constructor(A,Q){this.config=A,this.logger=Q}async request(A,Q={}){let w=`${ZRw}${A}`;this.logger.debug("Buttondown API request",{endpoint:A,method:Q.method??"GET"});let $=await fetch(w,{...Q,headers:{Authorization:`Token ${this.config.apiKey}`,"Content-Type":"application/json",...Q.headers}});if(!$.ok){let B=await $.json().catch(()=>({})),X=KRw.safeParse(B),Y=X.success?X.data.detail??X.data.message??`HTTP ${$.status}`:`HTTP ${$.status}`,Z=X.success?X.data.code:void 0;throw this.logger.error("Buttondown API error",{endpoint:A,status:$.status,code:Z,error:Y}),new R0A(`Buttondown API error: ${Y}`,$.status,Z)}return $.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 x0A.parse(await this.request("/subscribers",{method:"POST",body:JSON.stringify(Q)}))}catch(w){if(w instanceof R0A&&w.code==="email_already_exists")return this.logger.info("Subscriber already exists",{email:A.email}),{...await this.getSubscriberByEmail(A.email),subscriber_type:"already_subscribed"};throw w}}async getSubscriberByEmail(A){return x0A.parse(await this.request(`/subscribers/${encodeURIComponent(A)}`))}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 w=Q.toString(),$=w?`/subscribers?${w}`:"/subscribers";return WRw.parse(await this.request($))}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"}),BB2.parse(await this.request("/emails",{method:"POST",body:JSON.stringify(Q)}))}async getEmail(A){return BB2.parse(await this.request(`/emails/${A}`))}async validateCredentials(){try{return await this.request("/subscribers?page_size=1"),!0}catch{return!1}}}fA();C0();var XB2=f.string().email({pattern:f.regexes.html5Email}),URw=f.object({email:XB2.describe("Email address to subscribe"),name:f.string().optional().describe("Subscriber name (optional)"),tags:f.array(f.string()).optional().describe("Tags to apply to subscriber (optional)")}),GRw=f.object({email:XB2.describe("Email address to unsubscribe")}),DRw=f.object({type:f.enum(["unactivated","regular","unsubscribed"]).optional().describe("Filter by subscriber status"),limit:f.number().optional().describe("Maximum number of results")});function YB2(A,Q,w){let $=new bM(Q,w);return[p6(A,"subscribe","Subscribe an email address to the newsletter. Uses double opt-in by default.",URw,async(B)=>{try{let X=await $.createSubscriber({email:B.email,...B.name&&{name:B.name},...B.tags&&{tags:B.tags}}),Y=X.subscriber_type==="already_subscribed";return u5({subscriberId:X.id,email:X.email,status:X.subscriber_type,message:Y?"already_subscribed":"subscribed"},Y?`${B.email} is already subscribed`:`Subscribed ${B.email} successfully`)}catch(X){return d7(dA(X))}}),p6(A,"unsubscribe","Unsubscribe an email address from the newsletter.",GRw,async(B)=>{try{return await $.unsubscribe(B.email),u5({email:B.email},`Unsubscribed ${B.email} successfully`)}catch(X){return d7(dA(X))}}),p6(A,"list_subscribers","List newsletter subscribers with optional filtering by status.",DRw,async(B)=>{try{let X=await $.listSubscribers({...B.type&&{type:B.type},...B.limit&&{limit:B.limit}});return u5({subscribers:X.results.map((Y)=>({id:Y.id,email:Y.email,status:Y.subscriber_type})),count:X.count},`Found ${X.count} subscribers`)}catch(X){return d7(dA(X))}})]}async function ZB2(A,Q,w,$){if(A.entityType!=="post")return{success:!0,skipped:!0,reason:"Only post entity types trigger auto-send"};let B=await w.getEntity({entityType:"post",id:A.entityId});if(!B)return{success:!1,error:`Post ${A.entityId} not found`};$.info("Auto-sending newsletter for published post",{postId:B.id,title:B.metadata.title});try{let X=await Q.createEmail({subject:B.metadata.title,body:B.content,status:"about_to_send"});return $.info("Newsletter sent for post",{postId:B.id,emailId:X.id}),{success:!0,emailId:X.id}}catch(X){let Y=dA(X);return $.error("Failed to send newsletter for post",{postId:B.id,error:Y}),{success:!1,error:Y}}}var qRw=f.object({apiKey:f.string().optional().describe("Buttondown API key"),doubleOptIn:f.boolean().default(!0).describe("Require email confirmation for new subscribers"),autoSendOnPublish:f.boolean().default(!1).describe("Automatically send newsletter when a blog post is published")});class CH0 extends Kw{constructor(A={}){super("buttondown",RH0,A,qRw)}async onRegister(A){if(A.messaging.subscribe("buttondown:is-configured",async()=>{return{success:!!this.config.apiKey}}),this.config.apiKey){let Q=new bM({apiKey:this.config.apiKey,doubleOptIn:this.config.doubleOptIn},this.logger);if(A.messaging.subscribe("buttondown:send",async(w)=>{try{return{success:!0,data:{emailId:(await Q.createEmail({subject:w.payload.subject,body:w.payload.content,status:"about_to_send"})).id}}}catch($){return this.logger.error("Buttondown send failed",{error:dA($)}),{success:!1}}}),this.config.autoSendOnPublish)A.messaging.subscribe("publish:completed",async(w)=>{let $=await ZB2(w.payload,Q,A.entityService,this.logger);if(!$.success)return this.logger.error("Buttondown auto-send failed",{entityId:w.payload.entityId,error:$.error}),{success:!1,error:$.error};return{success:!0}}),this.logger.info("Buttondown auto-send on publish enabled")}}async getTools(){if(!this.config.apiKey)return[];return YB2(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 gH0(A={}){return new CH0(A)}var zRw=f.object({apiKey:f.string().optional().describe("Buttondown API key"),doubleOptIn:f.boolean().optional().describe("Require email confirmation for new subscribers"),autoSendOnPublish:f.boolean().optional().describe("Automatically send newsletter when a blog post is published")});function fB2(A={}){let Q=zRw.safeParse(A);if(!Q.success)throw new Sz("newsletter",Q.error.issues.map(($)=>({path:$.path.map(String).join("."),code:$.code,message:$.message})));let w=Q.data;return[hH0({}),gH0({...w.apiKey!==void 0&&{apiKey:w.apiKey},...w.doubleOptIn!==void 0&&{doubleOptIn:w.doubleOptIn},...w.autoSendOnPublish!==void 0&&{autoSendOnPublish:w.autoSendOnPublish}})]}fA();C0();import{existsSync as xRw,mkdirSync as RRw,writeFileSync as vRw}from"fs";import{join as AJ}from"path";C0();var v0A=f.object({baseFolder:f.string().default("_obsidian")});function h0A(A){return typeof A==="object"&&A!==null}function fa(A){if(!h0A(A))return;let Q=A.def;return h0A(Q)?Q:void 0}function HB2(A){let Q=fa(A)?.type;return typeof Q==="string"?Q:void 0}function VRw(A){return typeof A==="function"?A():A}function JRw(A){let Q=A,w=!0,$=void 0,B=!1,X=!0;while(X){X=!1;let Z=fa(Q),H=HB2(Q);if(H==="optional"||H==="nullable"){w=!1,Q=Z?.innerType,X=!0;continue}if(H==="default")w=!1,B=!0,$=VRw(Z?.defaultValue),Q=Z?.innerType,X=!0}let Y={inner:Q,required:w};if(B)Y.defaultValue=$;return Y}function IRw(A){let w=fa(A)?.entries;if(!h0A(w))return;let $=Object.values(w);if(!$.every((B)=>typeof B==="string"))return;return $}function FRw(A){let Q=fa(A),w=Q?.values;if(Array.isArray(w))return w[0];return Q?.value}function WB2(A){let Q=HB2(A);if(Q==="enum"){let w=IRw(A);return w?{type:"enum",enumValues:w}:{type:"enum"}}if(Q==="literal")return{type:"string",defaultValue:FRw(A)};if(Q==="string")return{type:"string"};if(Q==="number")return{type:"number"};if(Q==="boolean")return{type:"boolean"};if(Q==="array")return{type:"array"};if(Q==="date")return{type:"date"};if(Q==="pipeline"||Q==="pipe"){let w=fa(A);return WB2(w?.out)}return{type:"unknown"}}function KB2(A){let Q=[];for(let[w,$]of Object.entries(A.shape)){let{inner:B,required:X,defaultValue:Y}=JRw($),Z=WB2(B),H={name:w,type:Z.type,required:X},W=Y!==void 0?Y:Z.defaultValue;if(W!==void 0)H.defaultValue=W;if(Z.enumValues)H.enumValues=Z.enumValues;Q.push(H)}return Q}function bRw(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 UB2(A,Q,w=""){let $=["---"];for(let B of Q){let X=bRw(B,A);if(X==="")$.push(`${B.name}:`);else $.push(`${B.name}: ${X}`)}if($.push("---"),$.push(""),w)$.push(w);else $.push("<!-- Write your content here -->"),$.push("");return $.join(`
9688
9688
  `)}Fv();var LRw={string:"Input",number:"Number",boolean:"Boolean",date:"Date",enum:"Select",array:"Multi",unknown:"Input"};function kRw(A){let Q={name:A.name,id:A.name,type:LRw[A.type]};if(A.type==="enum"&&A.enumValues){let w={};A.enumValues.forEach(($,B)=>{w[String(B)]=$}),Q.options=w}return Q}function GB2(A,Q){let w={filesPaths:A,fields:Q.map(kRw)};return`---
9689
9689
  ${Iv(w)}---
9690
- `}b2();Fv();var _Rw=new Set(["entityType"]),NRw={base:"Notes"},jRw=new Set(["note"]);function PRw(A){let Q=["file.name"];for(let w of A)if(!_Rw.has(w.name))Q.push(w.name);return Q}function MRw(A){return A.some((Q)=>Q.name==="status"&&Q.type==="enum")}function DB2(A,Q){let w=NRw[A]??LfA(A),$=MRw(Q),B=PRw(Q),X=[{type:"table",name:`All ${w}`,order:B}];if($)X.push({type:"table",name:"By Status",groupBy:{property:"status",direction:"ASC"},order:B});let Z={filters:{and:[jRw.has(A)?'file.folder == "/"':`file.inFolder("${A}")`]},views:X};return{filename:`${w}.base`,content:Iv(Z),hasStatus:$}}function qB2(A){if(A.length===0)return null;let Q=A.map(($)=>`file.inFolder("${$}")`),w={filters:{and:[Q.length===1?Q[0]:{or:Q}]},views:[{type:"table",name:"Settings",order:["file.name","file.folder"]}]};return Iv(w)}function zB2(A){if(A.length===0)return null;let Q=A.map(($)=>`file.inFolder("${$.entityType}")`),w={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 Iv(w)}var VB2={name:"@brains/obsidian-vault",version:"0.2.0-alpha.158",description:"Obsidian vault integration \u2014 generates templates from entity schemas",dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var hRw={mkdir:RRw,writeFile:vRw,existsFile:xRw},CRw=f.object({entityTypes:f.array(f.string()).optional().describe("Entity types to generate templates for (default: all)")});class C0A extends Kw{deps;constructor(A={},Q={}){super("obsidian-vault",VB2,A,v0A);this.deps={...hRw,...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[p6(this.id,"sync-templates","Generate Obsidian templates, Metadata Menu fileClass definitions, and Bases views for all registered entity types.",CRw,async(Q)=>{return this.sync(A,Q.entityTypes)},{sideEffects:"external"})]}async sync(A,Q){try{let w=A.entityService.getEntityTypes(),$=Q?w.filter((J)=>Q.includes(J)):w,B=AJ(A.dataDir,this.config.baseFolder),X=AJ(B,"templates"),Y=AJ(B,"fileClasses"),Z=AJ(B,"bases");this.deps.mkdir(X,{recursive:!0}),this.deps.mkdir(Y,{recursive:!0}),this.deps.mkdir(Z,{recursive:!0});let H=[],W=[],K=[],U=[],G=[],q=[];for(let J of $){let k=A.entities.getEffectiveFrontmatterSchema(J);if(!k){this.logger.debug(`Skipping ${J}: no frontmatter schema`),W.push(J);continue}let j=KB2(k),_=A.entities.getAdapter(J),x=_?.isSingleton===!0,v=GB2(J,j);if(this.deps.writeFile(AJ(Y,`${J}.md`),v),K.push(J),x){G.push(J),this.logger.debug(`Generated fileClass (singleton): ${J}`);continue}let O=_?.getBodyTemplate()??"",M=UB2(J,j,O);this.deps.writeFile(AJ(X,`${J}.md`),M),H.push(J);let S=DB2(J,j),u=AJ(Z,S.filename);if(!this.deps.existsFile(u))this.deps.writeFile(u,S.content),U.push(J),this.logger.debug(`Generated base: ${S.filename}`);if(S.hasStatus)q.push({entityType:J,fields:j});this.logger.debug(`Generated template + fileClass: ${J}`)}let V=qB2(G);if(V){let J=AJ(Z,"Settings.base");if(!this.deps.existsFile(J))this.deps.writeFile(J,V),U.push("Settings"),this.logger.debug("Generated Settings.base")}let I=zB2(q);if(I){let J=AJ(Z,"Pipeline.base");if(!this.deps.existsFile(J))this.deps.writeFile(J,I),U.push("Pipeline"),this.logger.debug("Generated Pipeline.base")}return this.logger.info(`Synced ${H.length} templates, ${K.length} fileClasses, ${U.length} bases (${W.length} skipped)`),u5({generated:H,skipped:W,fileClasses:K,bases:U})}catch(w){return this.logger.error("Failed to sync",{error:w}),d7(w instanceof Error?w.message:"Unknown error")}}}function g0A(A={},Q){return new C0A(A,Q)}e6();fA();fA();b2();b9();fA();C0();var yH0=f.enum(["draft","active","archived"]),EH0=f.enum(["anchor","trusted","public"]),TH0=f.enum(["agent-confirmed","manual"]),gRw=f.enum(["draft","active","archived"]),yRw=f.enum(["anchor","trusted","public"]),ERw=f.enum(["agent-confirmed","manual"]),cq=f.preprocess((A)=>typeof A==="string"&&A.trim().length===0?void 0:A,f.string().min(1).optional()),QJ=f.preprocess((A)=>typeof A==="string"&&A.trim().length===0?void 0:A,f.string().min(1).optional()),y0A=f.object({event:f.string().min(1),target:f.string().min(1),operatorAction:f.boolean().optional(),label:QJ,description:QJ,operatorDescription:QJ}),E0A=f.object({id:f.string().min(1),title:f.string().min(1),prompt:QJ,requiredDetails:f.array(f.string().min(1)).default([]),instructions:f.array(f.string().min(1)).default([]),doneWhen:f.array(f.string().min(1)).default([]),transitions:f.array(y0A).default([])}),SH0=f.object({purpose:f.string().min(1),operatingRules:f.array(f.string().min(1)).default([]),initialState:f.string().min(1),states:f.array(E0A).min(1),finalStates:f.array(f.string().min(1)).min(1),nextPrompts:f.array(f.string().min(1)).default([])}),cE=f.object({title:f.string(),status:yH0.default("active"),audience:EH0.default("anchor"),trigger:cq.optional(),lifecycle:cq.optional(),once:f.boolean().optional(),starterText:cq.optional(),description:cq.optional(),starterPrompt:cq.optional(),completionMode:TH0.default("agent-confirmed")}),JB2=f.object({title:f.string(),status:yH0,audience:EH0,trigger:cq.optional(),lifecycle:cq.optional(),once:f.boolean().optional(),starterText:cq.optional(),description:cq.optional(),starterPrompt:cq.optional(),completionMode:TH0}),TRw=f.object({title:f.string(),status:gRw,audience:yRw,trigger:QJ.optional(),lifecycle:QJ.optional(),once:f.boolean().optional(),starterText:QJ.optional(),description:QJ.optional(),starterPrompt:QJ.optional(),completionMode:ERw}),lE=EQ.extend({entityType:f.literal("playbook"),metadata:TRw});class mH0 extends R6{constructor(){super(SH0,{title:"Playbook",mappings:[{key:"purpose",label:"Purpose",type:"string"},{key:"operatingRules",label:"Operating Rules",type:"array",itemType:"string"},{key:"initialState",label:"Initial State",type:"string"},{key:"states",label:"States",type:"array",itemType:"object",itemMappings:[{key:"id",label:"ID",type:"string"},{key:"title",label:"Title",type:"string"},{key:"prompt",label:"Prompt",type:"custom",formatter:T0A,parser:S0A},{key:"requiredDetails",label:"Required Details",type:"array",itemType:"string"},{key:"instructions",label:"Instructions",type:"array",itemType:"string"},{key:"doneWhen",label:"Done When",type:"array",itemType:"string"},{key:"transitions",label:"Transitions",type:"array",itemType:"object",itemMappings:[{key:"event",label:"Event",type:"string"},{key:"target",label:"Target",type:"string"},{key:"operatorAction",label:"User Choice",type:"custom",formatter:SRw,parser:mRw},{key:"label",label:"Label",type:"custom",formatter:T0A,parser:S0A},{key:"description",label:"Description",type:"string"},{key:"operatorDescription",label:"Operator Description",type:"custom",formatter:T0A,parser:S0A}]}]},{key:"finalStates",label:"Final States",type:"array",itemType:"string"},{key:"nextPrompts",label:"Next Prompts",type:"array",itemType:"string"}]})}}var Ha=new mH0;function T0A(A){return typeof A==="string"?A:""}function S0A(A){let Q=A.trim();return Q.length>0?Q:void 0}function SRw(A){return typeof A==="boolean"?String(A):""}function mRw(A){let Q=A.trim().toLowerCase();if(Q==="true")return!0;if(Q==="false")return!1;return}function m0A(A){let Q=[],w=new Set,$=new Set;for(let B of A.states){if(w.has(B.id))$.add(B.id);w.add(B.id)}if(!w.has(A.initialState))Q.push(`Playbook initial state '${A.initialState}' is not defined.`);for(let B of $)Q.push(`Duplicate playbook state id '${B}'.`);for(let B of A.finalStates)if(!w.has(B))Q.push(`Playbook final state '${B}' is not defined.`);for(let B of A.states)for(let X of B.transitions)if(!w.has(X.target))Q.push(`Playbook transition '${B.id}' -> '${X.target}' targets an undefined state.`);for(let B of uRw(A,w))Q.push(`Playbook state '${B}' is unreachable.`);return{valid:Q.length===0,errors:Q}}function pE(A){let Q=m0A(A);if(!Q.valid)throw Error(Q.errors.join(`
9690
+ `}b2();Fv();var _Rw=new Set(["entityType"]),NRw={base:"Notes"},jRw=new Set(["note"]);function PRw(A){let Q=["file.name"];for(let w of A)if(!_Rw.has(w.name))Q.push(w.name);return Q}function MRw(A){return A.some((Q)=>Q.name==="status"&&Q.type==="enum")}function DB2(A,Q){let w=NRw[A]??LfA(A),$=MRw(Q),B=PRw(Q),X=[{type:"table",name:`All ${w}`,order:B}];if($)X.push({type:"table",name:"By Status",groupBy:{property:"status",direction:"ASC"},order:B});let Z={filters:{and:[jRw.has(A)?'file.folder == "/"':`file.inFolder("${A}")`]},views:X};return{filename:`${w}.base`,content:Iv(Z),hasStatus:$}}function qB2(A){if(A.length===0)return null;let Q=A.map(($)=>`file.inFolder("${$}")`),w={filters:{and:[Q.length===1?Q[0]:{or:Q}]},views:[{type:"table",name:"Settings",order:["file.name","file.folder"]}]};return Iv(w)}function zB2(A){if(A.length===0)return null;let Q=A.map(($)=>`file.inFolder("${$.entityType}")`),w={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 Iv(w)}var VB2={name:"@brains/obsidian-vault",version:"0.2.0-alpha.159",description:"Obsidian vault integration \u2014 generates templates from entity schemas",dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var hRw={mkdir:RRw,writeFile:vRw,existsFile:xRw},CRw=f.object({entityTypes:f.array(f.string()).optional().describe("Entity types to generate templates for (default: all)")});class C0A extends Kw{deps;constructor(A={},Q={}){super("obsidian-vault",VB2,A,v0A);this.deps={...hRw,...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[p6(this.id,"sync-templates","Generate Obsidian templates, Metadata Menu fileClass definitions, and Bases views for all registered entity types.",CRw,async(Q)=>{return this.sync(A,Q.entityTypes)},{sideEffects:"external"})]}async sync(A,Q){try{let w=A.entityService.getEntityTypes(),$=Q?w.filter((J)=>Q.includes(J)):w,B=AJ(A.dataDir,this.config.baseFolder),X=AJ(B,"templates"),Y=AJ(B,"fileClasses"),Z=AJ(B,"bases");this.deps.mkdir(X,{recursive:!0}),this.deps.mkdir(Y,{recursive:!0}),this.deps.mkdir(Z,{recursive:!0});let H=[],W=[],K=[],U=[],G=[],q=[];for(let J of $){let k=A.entities.getEffectiveFrontmatterSchema(J);if(!k){this.logger.debug(`Skipping ${J}: no frontmatter schema`),W.push(J);continue}let j=KB2(k),_=A.entities.getAdapter(J),x=_?.isSingleton===!0,v=GB2(J,j);if(this.deps.writeFile(AJ(Y,`${J}.md`),v),K.push(J),x){G.push(J),this.logger.debug(`Generated fileClass (singleton): ${J}`);continue}let O=_?.getBodyTemplate()??"",M=UB2(J,j,O);this.deps.writeFile(AJ(X,`${J}.md`),M),H.push(J);let S=DB2(J,j),u=AJ(Z,S.filename);if(!this.deps.existsFile(u))this.deps.writeFile(u,S.content),U.push(J),this.logger.debug(`Generated base: ${S.filename}`);if(S.hasStatus)q.push({entityType:J,fields:j});this.logger.debug(`Generated template + fileClass: ${J}`)}let V=qB2(G);if(V){let J=AJ(Z,"Settings.base");if(!this.deps.existsFile(J))this.deps.writeFile(J,V),U.push("Settings"),this.logger.debug("Generated Settings.base")}let I=zB2(q);if(I){let J=AJ(Z,"Pipeline.base");if(!this.deps.existsFile(J))this.deps.writeFile(J,I),U.push("Pipeline"),this.logger.debug("Generated Pipeline.base")}return this.logger.info(`Synced ${H.length} templates, ${K.length} fileClasses, ${U.length} bases (${W.length} skipped)`),u5({generated:H,skipped:W,fileClasses:K,bases:U})}catch(w){return this.logger.error("Failed to sync",{error:w}),d7(w instanceof Error?w.message:"Unknown error")}}}function g0A(A={},Q){return new C0A(A,Q)}e6();fA();fA();b2();b9();fA();C0();var yH0=f.enum(["draft","active","archived"]),EH0=f.enum(["anchor","trusted","public"]),TH0=f.enum(["agent-confirmed","manual"]),gRw=f.enum(["draft","active","archived"]),yRw=f.enum(["anchor","trusted","public"]),ERw=f.enum(["agent-confirmed","manual"]),cq=f.preprocess((A)=>typeof A==="string"&&A.trim().length===0?void 0:A,f.string().min(1).optional()),QJ=f.preprocess((A)=>typeof A==="string"&&A.trim().length===0?void 0:A,f.string().min(1).optional()),y0A=f.object({event:f.string().min(1),target:f.string().min(1),operatorAction:f.boolean().optional(),label:QJ,description:QJ,operatorDescription:QJ}),E0A=f.object({id:f.string().min(1),title:f.string().min(1),prompt:QJ,requiredDetails:f.array(f.string().min(1)).default([]),instructions:f.array(f.string().min(1)).default([]),doneWhen:f.array(f.string().min(1)).default([]),transitions:f.array(y0A).default([])}),SH0=f.object({purpose:f.string().min(1),operatingRules:f.array(f.string().min(1)).default([]),initialState:f.string().min(1),states:f.array(E0A).min(1),finalStates:f.array(f.string().min(1)).min(1),nextPrompts:f.array(f.string().min(1)).default([])}),cE=f.object({title:f.string(),status:yH0.default("active"),audience:EH0.default("anchor"),trigger:cq.optional(),lifecycle:cq.optional(),once:f.boolean().optional(),starterText:cq.optional(),description:cq.optional(),starterPrompt:cq.optional(),completionMode:TH0.default("agent-confirmed")}),JB2=f.object({title:f.string(),status:yH0,audience:EH0,trigger:cq.optional(),lifecycle:cq.optional(),once:f.boolean().optional(),starterText:cq.optional(),description:cq.optional(),starterPrompt:cq.optional(),completionMode:TH0}),TRw=f.object({title:f.string(),status:gRw,audience:yRw,trigger:QJ.optional(),lifecycle:QJ.optional(),once:f.boolean().optional(),starterText:QJ.optional(),description:QJ.optional(),starterPrompt:QJ.optional(),completionMode:ERw}),lE=EQ.extend({entityType:f.literal("playbook"),metadata:TRw});class mH0 extends R6{constructor(){super(SH0,{title:"Playbook",mappings:[{key:"purpose",label:"Purpose",type:"string"},{key:"operatingRules",label:"Operating Rules",type:"array",itemType:"string"},{key:"initialState",label:"Initial State",type:"string"},{key:"states",label:"States",type:"array",itemType:"object",itemMappings:[{key:"id",label:"ID",type:"string"},{key:"title",label:"Title",type:"string"},{key:"prompt",label:"Prompt",type:"custom",formatter:T0A,parser:S0A},{key:"requiredDetails",label:"Required Details",type:"array",itemType:"string"},{key:"instructions",label:"Instructions",type:"array",itemType:"string"},{key:"doneWhen",label:"Done When",type:"array",itemType:"string"},{key:"transitions",label:"Transitions",type:"array",itemType:"object",itemMappings:[{key:"event",label:"Event",type:"string"},{key:"target",label:"Target",type:"string"},{key:"operatorAction",label:"User Choice",type:"custom",formatter:SRw,parser:mRw},{key:"label",label:"Label",type:"custom",formatter:T0A,parser:S0A},{key:"description",label:"Description",type:"string"},{key:"operatorDescription",label:"Operator Description",type:"custom",formatter:T0A,parser:S0A}]}]},{key:"finalStates",label:"Final States",type:"array",itemType:"string"},{key:"nextPrompts",label:"Next Prompts",type:"array",itemType:"string"}]})}}var Ha=new mH0;function T0A(A){return typeof A==="string"?A:""}function S0A(A){let Q=A.trim();return Q.length>0?Q:void 0}function SRw(A){return typeof A==="boolean"?String(A):""}function mRw(A){let Q=A.trim().toLowerCase();if(Q==="true")return!0;if(Q==="false")return!1;return}function m0A(A){let Q=[],w=new Set,$=new Set;for(let B of A.states){if(w.has(B.id))$.add(B.id);w.add(B.id)}if(!w.has(A.initialState))Q.push(`Playbook initial state '${A.initialState}' is not defined.`);for(let B of $)Q.push(`Duplicate playbook state id '${B}'.`);for(let B of A.finalStates)if(!w.has(B))Q.push(`Playbook final state '${B}' is not defined.`);for(let B of A.states)for(let X of B.transitions)if(!w.has(X.target))Q.push(`Playbook transition '${B.id}' -> '${X.target}' targets an undefined state.`);for(let B of uRw(A,w))Q.push(`Playbook state '${B}' is unreachable.`);return{valid:Q.length===0,errors:Q}}function pE(A){let Q=m0A(A);if(!Q.valid)throw Error(Q.errors.join(`
9691
9691
  `))}function uRw(A,Q){if(!Q.has(A.initialState))return[];let w=new Set,$=[A.initialState];while($.length>0){let B=$.shift();if(!B||w.has(B))continue;w.add(B);let X=A.states.find((Y)=>Y.id===B);if(!X)continue;for(let Y of X.transitions)if(Q.has(Y.target)&&!w.has(Y.target))$.push(Y.target)}return A.states.map((B)=>B.id).filter((B)=>!w.has(B))}class cH0 extends d2{constructor(){super({entityType:"playbook",purpose:"A guided multi-step workflow the assistant runs together with the user.",schema:lE,frontmatterSchema:cE})}createPlaybookContent(A,Q){return this.buildMarkdown(Ha.format(Q),A)}parsePlaybookContent(A){let Q=this.parseFrontMatter(A,cE),w=this.extractBody(A).trim(),$=cRw(w)?lRw(w):Ha.parse(w);return pE($),{frontmatter:cE.parse(Q),body:$,bodyMarkdown:w}}fromMarkdown(A){let{frontmatter:Q}=this.parsePlaybookContent(A);return{content:A,entityType:"playbook",metadata:{title:Q.title,status:Q.status,audience:Q.audience,...Q.trigger?{trigger:Q.trigger}:{},...Q.lifecycle?{lifecycle:Q.lifecycle}:{},...Q.once!==void 0?{once:Q.once}:{},...Q.starterText?{starterText:Q.starterText}:{},...Q.description?{description:Q.description}:{},...Q.starterPrompt?{starterPrompt:Q.starterPrompt}:{},completionMode:Q.completionMode}}}}var LM=new cH0;function cRw(A){return/^##\s+Steps\s*$/im.test(A)}function lRw(A){let Q=pRw(u0A(A,"Steps"));if(Q.length===0)throw Error("Playbook must declare at least one step.");let w=Q.map(($,B)=>{let X=B===Q.length-1;if(!X&&$.doneWhen.length===0&&$.choices.length===0&&!$.skip)throw Error(`Playbook step '${$.title}' must declare Done when, Choices, or Skip.`);return{id:$.id,title:$.title,...$.prompt?{prompt:$.prompt}:{},requiredDetails:$.requiredDetails,instructions:$.instructions,doneWhen:$.doneWhen,transitions:[...$.doneWhen.length>0&&!X?[{event:"NEXT",target:Q[B+1]?.id??$.id}]:[],...$.choices.map((Y,Z)=>({event:`CHOICE_${Z+1}`,target:q1(Y.target),operatorAction:!0,label:Y.label})),...$.skip?[{event:"SKIP",target:q1($.skip.target),operatorAction:!0,label:$.skip.label}]:[]]}});return{purpose:iRw(A,"Purpose"),operatingRules:IB2(A,"Operating Rules"),initialState:Q[0]?.id??"",states:w,finalStates:[Q.at(-1)?.id??""],nextPrompts:IB2(A,"Next Prompts")}}function pRw(A){let Q=[],w;for(let $ of A.split(/\r?\n/)){let B=/^###\s+(.+?)\s*$/.exec($);if(B){w={title:B[1]??"",content:[]},Q.push(w);continue}w?.content.push($)}return Q.map(($)=>{let B=$.content.join(`
9692
9692
  `);return{title:$.title,id:q1($.title),...FB2(B,"Say")?{prompt:FB2(B,"Say")}:{},requiredDetails:uH0(B,"Required details"),instructions:uH0(B,"To do"),doneWhen:uH0(B,"Done when"),choices:dRw(B,"Choices"),...bB2(B)?{skip:bB2(B)}:{}}})}function u0A(A,Q){let w=A.split(/\r?\n/),$=w.findIndex((X)=>X.trim().toLowerCase()===`## ${Q.toLowerCase()}`);if($===-1)return"";let B=[];for(let X of w.slice($+1)){if(/^##\s+/.test(X))break;B.push(X)}return B.join(`
9693
9693
  `).trim()}function iRw(A,Q){return u0A(A,Q).split(/\r?\n/).map((w)=>w.trim()).filter((w)=>w.length>0&&!w.startsWith("#")).join(`
9694
9694
  `).trim()}function IB2(A,Q){return LB2(u0A(A,Q))}function FB2(A,Q){return new RegExp(`^${rRw(Q)}:\\s*(.+?)\\s*$`,"im").exec(A)?.[1]?.trim()}function uH0(A,Q){let w=A.split(/\r?\n/),$=w.findIndex((X)=>X.trim().toLowerCase()===`${Q.toLowerCase()}:`);if($===-1)return[];let B=[];for(let X of w.slice($+1)){let Y=X.trim();if(Y.length===0)continue;if(/^[A-Za-z][A-Za-z ]+:/.test(Y)||/^#{1,6}\s+/.test(Y))break;B.push(X)}return LB2(B.join(`
9695
- `))}function dRw(A,Q){return uH0(A,Q).map(nRw)}function nRw(A){let Q=/^(.+?)\s*(?:\u2192|->)\s*(.+)$/.exec(A);if(!Q)throw Error(`Invalid playbook choice '${A}'. Expected "Label \u2192 Step".`);return{label:Q[1]?.trim()??"",target:Q[2]?.trim()??""}}function bB2(A){let Q=/^Skip:\s*(.+?)\s*(?:\u2192|->)\s*(.+?)\s*$/im.exec(A);if(!Q)return;return{label:Q[1]?.trim()??"",target:Q[2]?.trim()??""}}function LB2(A){return A.split(/\r?\n/).map((Q)=>/^-\s+(.+?)\s*$/.exec(Q)?.[1]?.trim()).filter((Q)=>Boolean(Q))}function rRw(A){return A.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}C0();var lH0=f.object({}).catchall(f.unknown()).transform(()=>({}));var pH0={name:"@brains/playbooks",version:"0.2.0-alpha.158",description:"Runtime orchestration for chat-native playbook runs",dependencies:{"@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/runtime-state":"workspace:*","@brains/utils":"workspace:*",xstate:"^5.32.1"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var sRw="playbook";class c0A extends Zw{entityType=sRw;schema=lE;adapter=LM;constructor(A={}){super("playbook",pH0,A,lH0)}async getInstructions(){return"Playbook entities describe durable, editable guided workflows for the agent. Use them as operating guidance when a playbook run is active; do not treat them as content to publish unless the user explicitly asks."}}function l0A(A={}){return new c0A(A)}e6();fA();C0();Xf();oc();function iH0(A,Q){return A.length===Q.length&&A.every((w,$)=>w===Q[$])}function p0A(A,Q){return Q==="NEXT"&&A.doneWhen.length>0}function dH0(A,Q){return Q.gateVerdicts.some((w)=>w.stateId===A.id&&iH0(w.goal,A.doneWhen)&&w.met)}function aRw(A,Q,w){return Q2.createMachine({id:A,initial:Q.initialState,states:Object.fromEntries(Q.states.map(($)=>{let B=Q.finalStates.includes($.id);return[$.id,{...B?{type:"final"}:{},...B?{}:{on:Object.fromEntries($.transitions.map((X)=>[X.event,{target:X.target,...p0A($,X.event)?{guard:()=>dH0($,w)}:{}}]))}}]}))})}function i0A(A,Q){let w=aRw(Q.playbookId,A,Q);return Q2.createActor(w,{snapshot:w.resolveState({value:Q.currentState})})}function tRw(A,Q,w){let $=i0A(Q,A);$.start();let B=$.getSnapshot().can({type:w});return $.stop(),B}function iE(A,Q,w){return w.transitions.filter(($)=>tRw(A,Q,$.event))}function Wa(A,Q,w){let $=new Set(iE(A,Q,w).map((B)=>`${B.event}\x00${B.target}`));return w.transitions.filter((B)=>!$.has(`${B.event}\x00${B.target}`))}function kB2(A,Q){return A.evidence.filter((w)=>!w.stateId||w.stateId===Q)}function kM(A,Q){return A.states.find((w)=>w.id===Q)}function _M(A){let Q=A.operatorDescription??A.description??A.label;return Q?`- ${A.event} -> ${A.target}: ${Q}`:`- ${A.event} -> ${A.target}`}function _B2(A,Q){if(Q.doneWhen.length===0)return"- no gated Done When conditions";let w=A.gateVerdicts.find(($)=>$.stateId===Q.id&&iH0($.goal,Q.doneWhen));if(!w)return`- Not yet met: ${Q.doneWhen.join("; ")}`;return w.met?`- Met: ${w.reason}`:`- Not yet met: ${w.reason}`}function NB2(A,Q,w){let $=iE(A,Q,w),B=$.filter((H)=>H.operatorAction!==!0),X=$.filter((H)=>H.operatorAction===!0),Y=Wa(A,Q,w),Z=A.gateVerdicts.find((H)=>H.stateId===w.id&&iH0(H.goal,w.doneWhen));return[`Current state: ${w.id} (${w.title})`,"Instructions:",...w.instructions.map((H)=>`- ${H}`),"Done When:",...w.doneWhen.length>0?w.doneWhen.map((H)=>`- ${H}`):["- none"],"Goal status:",Z?`- ${Z.met?"Met":"Not yet met"}: ${Z.reason}`:"- Not checked yet.","Current-state information rules:","- If this state asks the operator for information, ask the operator for the missing current-run information.","- If the current operator message partially answers the state's prompt, do not repeat the original prompt; ask only for the next missing detail required by the state instructions.","- Do not answer the state's operator-facing prompt from memory, existing durable records, profile data, search, or retrieval tools.","- Setup facts must come from current-run evidence or current operator input, not ambient records.","Event selection rules:","- Blocked events are not valid events; do not call playbook_send_event with a blocked event.","- For gated durable states, operator-provided details are not enough to send NEXT; first complete the required system_create/system_update/system_delete action or use existing current-run evidence that the Done When condition has already been met.","- If the operator explicitly says they have not chosen, selected, asked for, or used one of the available actions, do not send any event.",'- Operator actions and choices are not generic continuation events; even if only one operator action is available, generic continuation like "yes", "next", or "continue" is not a valid selection.',"- If multiple events are available, ask the operator to pick one labeled action.","- A Skip-style operator action is never a default continuation; send it only when the operator positively selects or asks to skip.","Valid continuation events:",...B.length>0?B.map((H)=>_M(H)):["- none"],"Available operator actions:",...X.length>0?X.map((H)=>_M(H)):["- none"],"Blocked events:",...Y.length>0?Y.map((H)=>_M(H)):["- none"]].join(`
9695
+ `))}function dRw(A,Q){return uH0(A,Q).map(nRw)}function nRw(A){let Q=/^(.+?)\s*(?:\u2192|->)\s*(.+)$/.exec(A);if(!Q)throw Error(`Invalid playbook choice '${A}'. Expected "Label \u2192 Step".`);return{label:Q[1]?.trim()??"",target:Q[2]?.trim()??""}}function bB2(A){let Q=/^Skip:\s*(.+?)\s*(?:\u2192|->)\s*(.+?)\s*$/im.exec(A);if(!Q)return;return{label:Q[1]?.trim()??"",target:Q[2]?.trim()??""}}function LB2(A){return A.split(/\r?\n/).map((Q)=>/^-\s+(.+?)\s*$/.exec(Q)?.[1]?.trim()).filter((Q)=>Boolean(Q))}function rRw(A){return A.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}C0();var lH0=f.object({}).catchall(f.unknown()).transform(()=>({}));var pH0={name:"@brains/playbooks",version:"0.2.0-alpha.159",description:"Runtime orchestration for chat-native playbook runs",dependencies:{"@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/runtime-state":"workspace:*","@brains/utils":"workspace:*",xstate:"^5.32.1"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var sRw="playbook";class c0A extends Zw{entityType=sRw;schema=lE;adapter=LM;constructor(A={}){super("playbook",pH0,A,lH0)}async getInstructions(){return"Playbook entities describe durable, editable guided workflows for the agent. Use them as operating guidance when a playbook run is active; do not treat them as content to publish unless the user explicitly asks."}}function l0A(A={}){return new c0A(A)}e6();fA();C0();Xf();oc();function iH0(A,Q){return A.length===Q.length&&A.every((w,$)=>w===Q[$])}function p0A(A,Q){return Q==="NEXT"&&A.doneWhen.length>0}function dH0(A,Q){return Q.gateVerdicts.some((w)=>w.stateId===A.id&&iH0(w.goal,A.doneWhen)&&w.met)}function aRw(A,Q,w){return Q2.createMachine({id:A,initial:Q.initialState,states:Object.fromEntries(Q.states.map(($)=>{let B=Q.finalStates.includes($.id);return[$.id,{...B?{type:"final"}:{},...B?{}:{on:Object.fromEntries($.transitions.map((X)=>[X.event,{target:X.target,...p0A($,X.event)?{guard:()=>dH0($,w)}:{}}]))}}]}))})}function i0A(A,Q){let w=aRw(Q.playbookId,A,Q);return Q2.createActor(w,{snapshot:w.resolveState({value:Q.currentState})})}function tRw(A,Q,w){let $=i0A(Q,A);$.start();let B=$.getSnapshot().can({type:w});return $.stop(),B}function iE(A,Q,w){return w.transitions.filter(($)=>tRw(A,Q,$.event))}function Wa(A,Q,w){let $=new Set(iE(A,Q,w).map((B)=>`${B.event}\x00${B.target}`));return w.transitions.filter((B)=>!$.has(`${B.event}\x00${B.target}`))}function kB2(A,Q){return A.evidence.filter((w)=>!w.stateId||w.stateId===Q)}function kM(A,Q){return A.states.find((w)=>w.id===Q)}function _M(A){let Q=A.operatorDescription??A.description??A.label;return Q?`- ${A.event} -> ${A.target}: ${Q}`:`- ${A.event} -> ${A.target}`}function _B2(A,Q){if(Q.doneWhen.length===0)return"- no gated Done When conditions";let w=A.gateVerdicts.find(($)=>$.stateId===Q.id&&iH0($.goal,Q.doneWhen));if(!w)return`- Not yet met: ${Q.doneWhen.join("; ")}`;return w.met?`- Met: ${w.reason}`:`- Not yet met: ${w.reason}`}function NB2(A,Q,w){let $=iE(A,Q,w),B=$.filter((H)=>H.operatorAction!==!0),X=$.filter((H)=>H.operatorAction===!0),Y=Wa(A,Q,w),Z=A.gateVerdicts.find((H)=>H.stateId===w.id&&iH0(H.goal,w.doneWhen));return[`Current state: ${w.id} (${w.title})`,"Instructions:",...w.instructions.map((H)=>`- ${H}`),"Done When:",...w.doneWhen.length>0?w.doneWhen.map((H)=>`- ${H}`):["- none"],"Goal status:",Z?`- ${Z.met?"Met":"Not yet met"}: ${Z.reason}`:"- Not checked yet.","Current-state information rules:","- If this state asks the operator for information, ask the operator for the missing current-run information.","- If the current operator message partially answers the state's prompt, do not repeat the original prompt; ask only for the next missing detail required by the state instructions.","- Do not answer the state's operator-facing prompt from memory, existing durable records, profile data, search, or retrieval tools.","- Setup facts must come from current-run evidence or current operator input, not ambient records.","Event selection rules:","- Blocked events are not valid events; do not call playbook_send_event with a blocked event.","- For gated durable states, operator-provided details are not enough to send NEXT; first complete the required system_create/system_update/system_delete action or use existing current-run evidence that the Done When condition has already been met.","- If the operator explicitly says they have not chosen, selected, asked for, or used one of the available actions, do not send any event.",'- Operator actions and choices are not generic continuation events; even if only one operator action is available, generic continuation like "yes", "next", or "continue" is not a valid selection.',"- If multiple events are available, ask the operator to pick one labeled action.","- A Skip-style operator action is never a default continuation; send it only when the operator positively selects or asks to skip.","Valid continuation events:",...B.length>0?B.map((H)=>_M(H)):["- none"],"Available operator actions:",...X.length>0?X.map((H)=>_M(H)):["- none"],"Blocked events:",...Y.length>0?Y.map((H)=>_M(H)):["- none"]].join(`
9696
9696
  `)}function jB2(A){let{run:Q,body:w,state:$,playbookTitle:B}=A,X=iE(Q,w,$),Y=X.filter((J)=>J.operatorAction!==!0),Z=X.filter((J)=>J.operatorAction===!0),H=Wa(Q,w,$),W=Y.map((J)=>_M(J)).join(`
9697
9697
  `),K=Z.map((J)=>_M(J)).join(`
9698
9698
  `),U=H.map((J)=>_M(J)).join(`
@@ -9766,9 +9766,9 @@ ${Object.entries(A).map(([w,$])=>`- ${w}: playbookId=${$.playbookId}, trigger=${
9766
9766
  ${A.guidance}`:B}}function TB2(A){return{...A,evidence:A.evidence.map((Q)=>({...Q,data:Gvw(Q.data)}))}}function Gvw(A){return Object.fromEntries(["entityType","entityId","operation"].flatMap((Q)=>A[Q]!==void 0?[[Q,A[Q]]]:[]))}function Dvw(A){return{kind:"actions",id:`actions:playbook:${A.run.id}`,title:A.title,defaultOpen:!0,actions:A.transitions.map((Q)=>({type:"event",id:`playbook:${A.run.id}:${Q.event}`,label:Q.label??Q.operatorDescription??Q.description??Q.event,event:Q.event,fromState:A.run.currentState,...Q.operatorDescription??Q.description?{description:Q.operatorDescription??Q.description}:{}}))}}function qvw(A){if(!A)return"Continuing.";return A.prompt??`Continuing to ${A.title}.`}function SB2(){return{promptTokens:0,completionTokens:0,totalTokens:0}}function mB2(A,Q){let w=A.filter(Q),$=w.filter((B)=>B.status==="active"||B.status==="offered");return a0A($)??a0A(w)}function a0A(A){return[...A].sort((Q,w)=>(w.completedAt??w.updatedAt).localeCompare(Q.completedAt??Q.updatedAt))[0]}function zvw(A){return{async evaluate(Q){let w=Q.goal.join(`
9767
9767
  `),$=await A.entityService.search({query:w,options:{limit:8,excludeTypes:["playbook"],visibilityScope:_8("anchor")}}),B=Vvw(Q,$),{verdict:X}=await A.judge({instruction:"Decide whether the playbook goal is satisfied by the supplied current-run runtime evidence and KB excerpts. Current-run runtime evidence is authoritative for playbook completion; use KB excerpts as supporting context, not to override clear runtime evidence from this run. Return met=true only when the outcome clearly holds. If evidence is missing or ambiguous, return met=false with a short reason.",material:B,schema:fvw});return X}}}function Vvw(A,Q){return["## Playbook run",`runId: ${A.run.id}`,`playbookId: ${A.run.playbookId}`,`currentState: ${A.state.id} (${A.state.title})`,"","## State instructions",...A.state.instructions.map((w)=>`- ${w}`),"","## Done When goal",...A.goal.map((w)=>`- ${w}`),"","## Runtime evidence",...A.evidence.length>0?A.evidence.map((w,$)=>Jvw($+1,w)):["No runtime evidence collected for this state."],"","## KB excerpts",...Q.length>0?Q.map((w,$)=>Ivw($+1,w)):["No relevant KB excerpts found."]].join(`
9768
9768
  `)}function Jvw(A,Q){return`${A}. ${Q.kind} at ${Q.observedAt}: ${cB2(Q.data)}`}function Ivw(A,Q){return[`${A}. ${Q.entity.entityType}/${Q.entity.id} (score ${Q.score})`,`Excerpt: ${Q.excerpt}`,`Content: ${lB2(Q.entity.content,1200)}`,`Metadata: ${cB2(Q.entity.metadata)}`].join(`
9769
- `)}function cB2(A){try{return lB2(JSON.stringify(A),1200)}catch{return"[unserializable]"}}function lB2(A,Q){return A.length>Q?`${A.slice(0,Q)}\u2026`:A}var Fvw={async evaluate(){return{met:!1,reason:"No playbook goal check is configured."}}};function e0A(A={},Q={}){return new t0A(A,Q)}e6();fA();C0();import{readFile as Lvw}from"fs/promises";import{join as kvw}from"path";var pB2={name:"@brains/rover-onboarding",version:"0.2.0-alpha.158",description:"Rover onboarding playbook bundle and activation plugin",dependencies:{"@brains/contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/playbooks":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var _vw=f.object({enabled:f.boolean().default(!1)}).strict(),iB2=[{id:"rover-onboarding",fileName:"rover-onboarding.md",starter:{id:"onboarding",trigger:"first-anchor-web-chat",playbookId:"rover-onboarding",once:!0,starterText:"Set up Rover",description:"Tune Rover's identity and anchor profile before using the knowledge loop.",starterPrompt:"Start playbook rover-onboarding."}},{id:"rover-first-knowledge-loop",fileName:"rover-first-knowledge-loop.md"}];class dB2 extends Kw{dependencies=["playbook","playbooks"];constructor(A={}){super("rover-onboarding",pB2,A,_vw)}async onReady(A){if(!this.config.enabled)return;for(let Q of iB2)await this.seedPlaybookIfMissing(A,Q);for(let Q of iB2){if(!Q.starter)continue;await A.messaging.send({type:zx,payload:Q.starter})}}async seedPlaybookIfMissing(A,Q){if(await A.entityService.getEntity({entityType:"playbook",id:Q.id,visibilityScope:"restricted"}))return;let $=await Lvw(kvw(import.meta.dir,"..","content","playbook",Q.fileName),"utf8");await A.entityService.createEntityFromMarkdown({input:{entityType:"playbook",id:Q.id,markdown:$}})}}function nB2(A={}){return new dB2(A)}fA();C0();C0();fA();var AAA=f.enum(["new","planned","in-progress","done","declined"]),QAA=f.enum(["low","medium","high","critical"]),Nvw=f.enum(["new","planned","in-progress","done","declined"]),jvw=f.enum(["low","medium","high","critical"]),Ka=f.object({title:f.string(),status:AAA,priority:QAA.default("medium"),requested:f.number().int().default(1),declinedReason:f.string().optional()}),Pvw=f.object({title:f.string(),status:AAA,priority:QAA,requested:f.number().int(),slug:f.string()}),Mvw=f.object({title:f.string(),status:Nvw,priority:jvw,requested:f.number().int(),slug:f.string()}),Ua=EQ.extend({entityType:f.literal("wish"),metadata:Mvw});C0();var wAA=f.object({}).catchall(f.unknown()).transform(()=>({}));fA();b2();class Ga extends d2{constructor(){super({entityType:"wish",purpose:"An explicitly recorded capability or outcome the assistant cannot currently fulfill, kept for future planning.",schema:Ua,frontmatterSchema:Ka})}createWishContent(A,Q){return this.buildMarkdown(Q,A)}parseWishContent(A){let Q=this.parseFrontMatter(A,Ka);return{frontmatter:Ka.parse(Q),description:this.extractBody(A).trim()}}fromMarkdown(A){let{frontmatter:Q}=this.parseWishContent(A),w=q1(Q.title);return{content:A,entityType:"wish",metadata:{title:Q.title,status:Q.status,priority:Q.priority,requested:Q.requested,slug:w}}}}var rB2=new Ga;b2();b2();async function oB2(A,Q){let w=`${Q.title}: ${Q.description}`,B=(await A.search({query:w,options:{types:["wish"],limit:1}}))[0];if(B&&B.score>=A.similarityThreshold)return B.entity;let X=q1(Q.title);return A.getEntity({entityType:"wish",id:X})}class sH0{logger;context;adapter=new Ga;constructor(A,Q){this.logger=A,this.context=Q}async process(A,Q,w){let $=A.title??A.prompt??"Untitled wish",B=A.content??A.prompt??"",X=await oB2({search:(W)=>this.context.entityService.search(W),getEntity:(W)=>this.context.entityService.getEntity(W),similarityThreshold:0.85},{title:$,description:B});if(X){let{frontmatter:W,description:K}=this.adapter.parseWishContent(X.content),U=W.requested+1,G=this.adapter.createWishContent({...W,requested:U},K);return await this.context.entityService.updateEntity({entity:{...X,content:G,metadata:{...X.metadata,requested:U}}}),this.logger.info("Incremented wish request count",{id:X.id,requested:U}),{success:!0,entityId:X.id,existed:!0,requested:U}}let Y=q1($),Z=A.options?.priority??"medium",H=this.adapter.createWishContent({title:$,status:"new",priority:Z,requested:1},B);return await this.context.entityService.createEntity({entity:{id:Y,entityType:"wish",content:H,metadata:{title:$,status:"new",priority:Z,requested:1,slug:Y}}}),this.logger.info("Created new wish",{id:Y,title:$}),{success:!0,entityId:Y,existed:!1,requested:1}}}var sB2={critical:0,high:1,medium:2,low:3};function aB2(A){A.sort((Q,w)=>{let $=w.metadata.requested-Q.metadata.requested;if($!==0)return $;return sB2[Q.metadata.priority]-sB2[w.metadata.priority]})}var tB2={name:"@brains/wishlist",version:"0.2.0-alpha.158",description:"Wishlist plugin for tracking unfulfilled user requests",dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var xvw=f.object({items:f.array(f.object({name:f.string(),count:f.number()}))}),Rvw="wish";class eB2 extends Zw{entityType=Rvw;schema=Ua;adapter=rB2;constructor(A={}){super("wishlist",tB2,A,wAA)}async interceptCreate(A,Q,w){let $=await new sH0(this.logger,w).process({...A.title?{title:A.title}:{},...A.prompt?{prompt:A.prompt}:{},...A.content?{content:A.content}:{}},`wish-create-${Date.now()}`,{});if(!$.success)return{kind:"handled",result:{success:!1,error:$.error??"Failed to create wish"}};return{kind:"handled",result:{success:!0,data:{...$.entityId?{entityId:$.entityId}:{},status:$.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",group:"knowledge",section:"secondary",priority:30,rendererName:"ListWidget",digestProvider:(w)=>{let{items:$}=xvw.parse(w),B=$[0];return{digest:B?[{label:"Top wish",value:`${B.name} \xB7 \xD7${B.count}`}]:[{label:"Wishes",value:"none yet"}]}},dataProvider:async()=>{let w=await A.entityService.listEntities({entityType:"wish",options:{limit:10}});return aB2(w),{items:w.map(($)=>({id:$.id,name:$.metadata.title,count:$.metadata.requested,priority:$.metadata.priority,status:$.metadata.status}))}}}}),{success:!0}});let Q=new sH0(this.logger,A);A.jobs.registerHandler("wish:create",{process:Q.process.bind(Q),validateAndParse:(w)=>w})}async getInstructions(){return"Wish entities record explicitly requested capabilities or desired end states whose literal completion is outside the available toolset. They may capture outcomes the assistant can advise about but cannot directly perform. They track demand, priority, and status for future capability planning; they are not a substitute for first-class entities that already support the requested action. To show the whole wishlist, call system_list once with entityType wish and omit status; only include status when the user asks for a specific wish status."}}function vvw(A={}){return new eB2(A)}var aH0=vvw;fA();fA();C0();var Da=f.object({title:f.string(),target:f.string()}),A52=f.object({title:f.string(),target:f.string(),slug:f.string().optional()}),qa=EQ.extend({entityType:f.literal("prompt"),metadata:A52});fA();b2();class $AA extends d2{constructor(){super({entityType:"prompt",purpose:"A reusable prompt or instruction template.",schema:qa,frontmatterSchema:Da})}toMarkdown(A){let Q=this.extractBody(A.content),w=this.parseFrontMatter(A.content,Da);return this.buildMarkdown(Q,w)}fromMarkdown(A){let Q=this.parseFrontMatter(A,Da),w=q1(Q.target.replace(/:/g,"-"));return{content:A,entityType:"prompt",metadata:{title:Q.title,target:Q.target,slug:w}}}}var BAA=new $AA;var Q52={name:"@brains/prompt",version:"0.2.0-alpha.158",description:"Prompt entity type \u2014 AI prompts as editable markdown entities",dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","bun-types":"^1.3.14",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var Cvw="prompt";class XAA extends Zw{entityType=Cvw;schema=qa;adapter=BAA;constructor(){super("prompt",Q52,{},i7)}getEntityTypeConfig(){return{embeddable:!1}}}function jM(){return new XAA}fA();C0();C0();class tH0{apiKey;fetchFn;baseUrl="https://api.unsplash.com";constructor(A,Q){this.apiKey=A,this.fetchFn=Q}async searchPhotos(A,Q){let w=new URL(`${this.baseUrl}/search/photos`);w.searchParams.set("query",A),w.searchParams.set("page",String(Q.page)),w.searchParams.set("per_page",String(Q.perPage));let $=await this.fetchFn(w.toString(),{headers:{Authorization:`Client-ID ${this.apiKey}`}});if(!$.ok)throw Error(`Unsplash API error: ${$.status} ${$.statusText}`);let B=yvw.parse(await $.json());return{photos:B.results.map(Evw),total:B.total,totalPages:B.total_pages,page:Q.page}}async triggerDownload(A){try{await this.fetchFn(A,{headers:{Authorization:`Client-ID ${this.apiKey}`}})}catch{}}}var gvw=f.looseObject({id:f.string(),description:f.string().nullable(),alt_description:f.string().nullable(),urls:f.looseObject({raw:f.url(),full:f.url(),regular:f.url(),small:f.url(),thumb:f.url()}),links:f.looseObject({html:f.url(),download_location:f.url()}),user:f.looseObject({name:f.string(),links:f.looseObject({html:f.url()})}),width:f.number().int().nonnegative(),height:f.number().int().nonnegative()}),yvw=f.looseObject({total:f.number().int().nonnegative(),total_pages:f.number().int().nonnegative(),results:f.array(gvw)});function Evw(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}}C0();async function eH0(A,Q,w,$){let B=await A.getEntity({entityType:Q,id:w});if(!B)return!1;return await A.updateEntity({entity:{...B,metadata:{...B.metadata,coverImageId:$}}}),!0}var Tvw={query:f.string().describe("Search terms for stock photos"),perPage:f.number().min(1).max(30).default(10).describe("Results per page (1-30)"),page:f.number().min(1).default(1).describe("Page number")},Svw={photoId:f.string().describe("Photo ID from search results"),downloadLocation:f.url().describe("Download tracking URL (required by provider ToS)"),photographerName:f.string().describe("Photographer name for attribution"),photographerUrl:f.url().describe("Photographer profile URL for attribution"),sourceUrl:f.url().describe("Photo page URL on provider"),imageUrl:f.url().describe("Image URL to download"),title:f.string().optional().describe("Image entity title"),alt:f.string().optional().describe("Alt text for the image"),targetEntityType:f.string().optional().describe("Entity type to set cover image on"),targetEntityId:f.string().optional().describe("Entity ID to set cover image on")},mvw=f.object({query:f.string(),perPage:f.number().min(1).max(30).default(10),page:f.number().min(1).default(1)}),uvw=f.object({photoId:f.string(),downloadLocation:f.url(),photographerName:f.string(),photographerUrl:f.url(),sourceUrl:f.url(),imageUrl:f.url(),title:f.string().optional(),alt:f.string().optional(),targetEntityType:f.string().optional(),targetEntityId:f.string().optional()});function w52(A,Q){return[cvw(A,Q),lvw(A,Q)]}function cvw(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:Tvw,visibility:"anchor",sideEffects:"none",handler:async(w)=>{let $=mvw.safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};try{return{success:!0,data:await Q.provider.searchPhotos($.data.query,{page:$.data.page,perPage:$.data.perPage})}}catch(B){return{success:!1,error:B instanceof Error?B.message:"Search failed"}}}}}function lvw(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:Svw,visibility:"anchor",sideEffects:"external",handler:async(w)=>{let $=uvw.safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};let{photoId:B,downloadLocation:X,photographerName:Y,photographerUrl:Z,sourceUrl:H,imageUrl:W,title:K,alt:U,targetEntityType:G,targetEntityId:q}=$.data,V={photographerName:Y,photographerUrl:Z,sourceUrl:H},I=await Q.entityService.listEntities({entityType:"image",options:{limit:1,filter:{metadata:{sourceUrl:W}}}});if(I[0]){let j={imageEntityId:I[0].id,alreadyExisted:!0,attribution:V};if(G&&q)j.coverSet=await eH0(Q.entityService,G,q,I[0].id);return{success:!0,data:j}}let J=await Q.jobs.enqueue({type:"select-photo",data:{photoId:B,downloadLocation:X,photographerName:Y,photographerUrl:Z,sourceUrl:H,imageUrl:W,...K!==void 0?{title:K}:{},...U!==void 0?{alt:U}:{},...G!==void 0?{targetEntityType:G}:{},...q!==void 0?{targetEntityId:q}:{}}}),k={imageEntityId:B,alreadyExisted:!1,attribution:V,jobId:J,status:"generating"};if(G&&q)k.coverSet=!1;return{success:!0,data:k}}}}fA();C0();p4();var pvw=f.object({photoId:f.string(),downloadLocation:f.url(),photographerName:f.string(),photographerUrl:f.url(),sourceUrl:f.url(),imageUrl:f.url(),title:f.string().optional(),alt:f.string().optional(),targetEntityType:f.string().optional(),targetEntityId:f.string().optional()});class YAA extends D6{deps;constructor(A,Q){super(A,{schema:pvw,jobTypeName:"select-photo"});this.deps=Q}async process(A,Q,w){await this.reportProgress(w,{progress:10,message:"Tracking stock photo download"}),await this.deps.provider.triggerDownload(A.downloadLocation),await this.reportProgress(w,{progress:35,message:"Downloading stock photo"});let $=await this.deps.fetchImage(A.imageUrl),B=A.title??`Stock photo ${A.photoId}`,X=qf.createImageEntity({dataUrl:$,title:B,alt:A.alt??B});await this.reportProgress(w,{progress:75,message:"Saving stock photo"});let{entityId:Y}=await this.deps.entityService.createEntity({entity:{id:A.photoId,...X,metadata:{...X.metadata,sourceUrl:A.imageUrl}}}),Z={imageEntityId:Y,alreadyExisted:!1};if(A.targetEntityType&&A.targetEntityId){if(Z.coverSet=await eH0(this.deps.entityService,A.targetEntityType,A.targetEntityId,Y),!Z.coverSet)Z.warning=`Target entity ${A.targetEntityType}:${A.targetEntityId} not found; cover image not set`}return await this.reportProgress(w,{progress:100,message:"Stock photo selected"}),Z}summarizeDataForLog(A){return{photoId:A.photoId,hasTarget:A.targetEntityType!==void 0}}}p4();var $52={name:"@brains/stock-photo",version:"0.2.0-alpha.158",description:"Stock photo search and selection \u2014 Unsplash provider",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":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts","./env-schema":"./src/env-schema.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var dvw=f.object({provider:f.enum(["unsplash"]).default("unsplash"),apiKey:f.string().optional().describe("Stock photo provider API key")});class ZAA extends Kw{deps;cachedTools=null;constructor(A={},Q={}){super("stock-photo",$52,A,dvw);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=w52(this.id,{provider:Q,entityService:A.entityService,fetchImage:this.deps.fetchImage??JW,jobs:A.jobs}),this.cachedTools}async registerJobHandlers(){if(!this.config.apiKey)return;let A=this.getContext();A.jobs.registerHandler("select-photo",new YAA(this.logger.child("SelectPhotoJobHandler"),{provider:this.createProvider(),entityService:A.entityService,fetchImage:this.deps.fetchImage??JW}))}createProvider(){return new tH0(this.config.apiKey??"",this.deps.fetch??globalThis.fetch)}}function fAA(A={},Q={}){return new ZAA(A,Q)}fA();C0();fA();fA();C0();var B52=f.enum(["ai","foundation","work"]),X52=f.object({suffix:B52,title:f.string(),body:f.string(),linkLabel:f.string(),linkHref:f.string()}),za=f.object({eyebrow:f.string(),headline:f.string(),cards:f.array(X52).min(1)}),HAA=f.object({title:f.string(),slug:f.string(),status:f.enum(["draft","published"])}),nvw=f.object({title:f.string(),slug:f.string(),status:f.enum(["draft","published"])}),Va=EQ.extend({entityType:f.literal("ecosystem-section"),metadata:nvw});class Y52 extends d2{constructor(){super({entityType:"ecosystem-section",purpose:"A section of the Rizom ecosystem overview.",schema:Va,frontmatterSchema:HAA})}fromMarkdown(A){return{content:A,entityType:"ecosystem-section",metadata:this.parseFrontmatter(A)}}}var WAA=new Y52;C0();function rvw(A){return A.replace(/^---\n[\s\S]*?\n---\n?/,"")}function KAA(A,Q){return new RegExp(`(?:^|\\n)## ${Q}\\s*\\n([\\s\\S]*?)(?=\\n## |$)`).exec(A)?.[1]?.trim()??""}function Ja(A,Q){return new RegExp(`(?:^|\\n)#### ${Q}\\s*\\n([\\s\\S]*?)(?=\\n#### |\\n### |$)`).exec(A)?.[1]?.trim()??""}function AW0(A){let Q=rvw(A),$=KAA(Q,"Cards").split(/^### Card \d+\s*$/m).map((B)=>B.trim()).filter(Boolean);return za.parse({eyebrow:KAA(Q,"Eyebrow"),headline:KAA(Q,"Headline"),cards:$.map((B)=>({suffix:Ja(B,"Suffix"),title:Ja(B,"Title"),body:Ja(B,"Body"),linkLabel:Ja(B,"Link Label"),linkHref:Ja(B,"Link Href")}))})}function Z52(A){return["# Ecosystem Section","","## Eyebrow",A.eyebrow,"","## Headline",A.headline,"","## Cards","",...A.cards.flatMap((Q,w)=>[`### Card ${w+1}`,"","#### Suffix",Q.suffix,"","#### Title",Q.title,"","#### Body",Q.body,"","#### Link Label",Q.linkLabel,"","#### Link Href",Q.linkHref,""])].join(`
9769
+ `)}function cB2(A){try{return lB2(JSON.stringify(A),1200)}catch{return"[unserializable]"}}function lB2(A,Q){return A.length>Q?`${A.slice(0,Q)}\u2026`:A}var Fvw={async evaluate(){return{met:!1,reason:"No playbook goal check is configured."}}};function e0A(A={},Q={}){return new t0A(A,Q)}e6();fA();C0();import{readFile as Lvw}from"fs/promises";import{join as kvw}from"path";var pB2={name:"@brains/rover-onboarding",version:"0.2.0-alpha.159",description:"Rover onboarding playbook bundle and activation plugin",dependencies:{"@brains/contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/playbooks":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var _vw=f.object({enabled:f.boolean().default(!1)}).strict(),iB2=[{id:"rover-onboarding",fileName:"rover-onboarding.md",starter:{id:"onboarding",trigger:"first-anchor-web-chat",playbookId:"rover-onboarding",once:!0,starterText:"Set up Rover",description:"Tune Rover's identity and anchor profile before using the knowledge loop.",starterPrompt:"Start playbook rover-onboarding."}},{id:"rover-first-knowledge-loop",fileName:"rover-first-knowledge-loop.md"}];class dB2 extends Kw{dependencies=["playbook","playbooks"];constructor(A={}){super("rover-onboarding",pB2,A,_vw)}async onReady(A){if(!this.config.enabled)return;for(let Q of iB2)await this.seedPlaybookIfMissing(A,Q);for(let Q of iB2){if(!Q.starter)continue;await A.messaging.send({type:zx,payload:Q.starter})}}async seedPlaybookIfMissing(A,Q){if(await A.entityService.getEntity({entityType:"playbook",id:Q.id,visibilityScope:"restricted"}))return;let $=await Lvw(kvw(import.meta.dir,"..","content","playbook",Q.fileName),"utf8");await A.entityService.createEntityFromMarkdown({input:{entityType:"playbook",id:Q.id,markdown:$}})}}function nB2(A={}){return new dB2(A)}fA();C0();C0();fA();var AAA=f.enum(["new","planned","in-progress","done","declined"]),QAA=f.enum(["low","medium","high","critical"]),Nvw=f.enum(["new","planned","in-progress","done","declined"]),jvw=f.enum(["low","medium","high","critical"]),Ka=f.object({title:f.string(),status:AAA,priority:QAA.default("medium"),requested:f.number().int().default(1),declinedReason:f.string().optional()}),Pvw=f.object({title:f.string(),status:AAA,priority:QAA,requested:f.number().int(),slug:f.string()}),Mvw=f.object({title:f.string(),status:Nvw,priority:jvw,requested:f.number().int(),slug:f.string()}),Ua=EQ.extend({entityType:f.literal("wish"),metadata:Mvw});C0();var wAA=f.object({}).catchall(f.unknown()).transform(()=>({}));fA();b2();class Ga extends d2{constructor(){super({entityType:"wish",purpose:"An explicitly recorded capability or outcome the assistant cannot currently fulfill, kept for future planning.",schema:Ua,frontmatterSchema:Ka})}createWishContent(A,Q){return this.buildMarkdown(Q,A)}parseWishContent(A){let Q=this.parseFrontMatter(A,Ka);return{frontmatter:Ka.parse(Q),description:this.extractBody(A).trim()}}fromMarkdown(A){let{frontmatter:Q}=this.parseWishContent(A),w=q1(Q.title);return{content:A,entityType:"wish",metadata:{title:Q.title,status:Q.status,priority:Q.priority,requested:Q.requested,slug:w}}}}var rB2=new Ga;b2();b2();async function oB2(A,Q){let w=`${Q.title}: ${Q.description}`,B=(await A.search({query:w,options:{types:["wish"],limit:1}}))[0];if(B&&B.score>=A.similarityThreshold)return B.entity;let X=q1(Q.title);return A.getEntity({entityType:"wish",id:X})}class sH0{logger;context;adapter=new Ga;constructor(A,Q){this.logger=A,this.context=Q}async process(A,Q,w){let $=A.title??A.prompt??"Untitled wish",B=A.content??A.prompt??"",X=await oB2({search:(W)=>this.context.entityService.search(W),getEntity:(W)=>this.context.entityService.getEntity(W),similarityThreshold:0.85},{title:$,description:B});if(X){let{frontmatter:W,description:K}=this.adapter.parseWishContent(X.content),U=W.requested+1,G=this.adapter.createWishContent({...W,requested:U},K);return await this.context.entityService.updateEntity({entity:{...X,content:G,metadata:{...X.metadata,requested:U}}}),this.logger.info("Incremented wish request count",{id:X.id,requested:U}),{success:!0,entityId:X.id,existed:!0,requested:U}}let Y=q1($),Z=A.options?.priority??"medium",H=this.adapter.createWishContent({title:$,status:"new",priority:Z,requested:1},B);return await this.context.entityService.createEntity({entity:{id:Y,entityType:"wish",content:H,metadata:{title:$,status:"new",priority:Z,requested:1,slug:Y}}}),this.logger.info("Created new wish",{id:Y,title:$}),{success:!0,entityId:Y,existed:!1,requested:1}}}var sB2={critical:0,high:1,medium:2,low:3};function aB2(A){A.sort((Q,w)=>{let $=w.metadata.requested-Q.metadata.requested;if($!==0)return $;return sB2[Q.metadata.priority]-sB2[w.metadata.priority]})}var tB2={name:"@brains/wishlist",version:"0.2.0-alpha.159",description:"Wishlist plugin for tracking unfulfilled user requests",dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var xvw=f.object({items:f.array(f.object({name:f.string(),count:f.number()}))}),Rvw="wish";class eB2 extends Zw{entityType=Rvw;schema=Ua;adapter=rB2;constructor(A={}){super("wishlist",tB2,A,wAA)}async interceptCreate(A,Q,w){let $=await new sH0(this.logger,w).process({...A.title?{title:A.title}:{},...A.prompt?{prompt:A.prompt}:{},...A.content?{content:A.content}:{}},`wish-create-${Date.now()}`,{});if(!$.success)return{kind:"handled",result:{success:!1,error:$.error??"Failed to create wish"}};return{kind:"handled",result:{success:!0,data:{...$.entityId?{entityId:$.entityId}:{},status:$.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",group:"knowledge",section:"secondary",priority:30,rendererName:"ListWidget",digestProvider:(w)=>{let{items:$}=xvw.parse(w),B=$[0];return{digest:B?[{label:"Top wish",value:`${B.name} \xB7 \xD7${B.count}`}]:[{label:"Wishes",value:"none yet"}]}},dataProvider:async()=>{let w=await A.entityService.listEntities({entityType:"wish",options:{limit:10}});return aB2(w),{items:w.map(($)=>({id:$.id,name:$.metadata.title,count:$.metadata.requested,priority:$.metadata.priority,status:$.metadata.status}))}}}}),{success:!0}});let Q=new sH0(this.logger,A);A.jobs.registerHandler("wish:create",{process:Q.process.bind(Q),validateAndParse:(w)=>w})}async getInstructions(){return"Wish entities record explicitly requested capabilities or desired end states whose literal completion is outside the available toolset. They may capture outcomes the assistant can advise about but cannot directly perform. They track demand, priority, and status for future capability planning; they are not a substitute for first-class entities that already support the requested action. To show the whole wishlist, call system_list once with entityType wish and omit status; only include status when the user asks for a specific wish status."}}function vvw(A={}){return new eB2(A)}var aH0=vvw;fA();fA();C0();var Da=f.object({title:f.string(),target:f.string()}),A52=f.object({title:f.string(),target:f.string(),slug:f.string().optional()}),qa=EQ.extend({entityType:f.literal("prompt"),metadata:A52});fA();b2();class $AA extends d2{constructor(){super({entityType:"prompt",purpose:"A reusable prompt or instruction template.",schema:qa,frontmatterSchema:Da})}toMarkdown(A){let Q=this.extractBody(A.content),w=this.parseFrontMatter(A.content,Da);return this.buildMarkdown(Q,w)}fromMarkdown(A){let Q=this.parseFrontMatter(A,Da),w=q1(Q.target.replace(/:/g,"-"));return{content:A,entityType:"prompt",metadata:{title:Q.title,target:Q.target,slug:w}}}}var BAA=new $AA;var Q52={name:"@brains/prompt",version:"0.2.0-alpha.159",description:"Prompt entity type \u2014 AI prompts as editable markdown entities",dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","bun-types":"^1.3.14",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var Cvw="prompt";class XAA extends Zw{entityType=Cvw;schema=qa;adapter=BAA;constructor(){super("prompt",Q52,{},i7)}getEntityTypeConfig(){return{embeddable:!1}}}function jM(){return new XAA}fA();C0();C0();class tH0{apiKey;fetchFn;baseUrl="https://api.unsplash.com";constructor(A,Q){this.apiKey=A,this.fetchFn=Q}async searchPhotos(A,Q){let w=new URL(`${this.baseUrl}/search/photos`);w.searchParams.set("query",A),w.searchParams.set("page",String(Q.page)),w.searchParams.set("per_page",String(Q.perPage));let $=await this.fetchFn(w.toString(),{headers:{Authorization:`Client-ID ${this.apiKey}`}});if(!$.ok)throw Error(`Unsplash API error: ${$.status} ${$.statusText}`);let B=yvw.parse(await $.json());return{photos:B.results.map(Evw),total:B.total,totalPages:B.total_pages,page:Q.page}}async triggerDownload(A){try{await this.fetchFn(A,{headers:{Authorization:`Client-ID ${this.apiKey}`}})}catch{}}}var gvw=f.looseObject({id:f.string(),description:f.string().nullable(),alt_description:f.string().nullable(),urls:f.looseObject({raw:f.url(),full:f.url(),regular:f.url(),small:f.url(),thumb:f.url()}),links:f.looseObject({html:f.url(),download_location:f.url()}),user:f.looseObject({name:f.string(),links:f.looseObject({html:f.url()})}),width:f.number().int().nonnegative(),height:f.number().int().nonnegative()}),yvw=f.looseObject({total:f.number().int().nonnegative(),total_pages:f.number().int().nonnegative(),results:f.array(gvw)});function Evw(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}}C0();async function eH0(A,Q,w,$){let B=await A.getEntity({entityType:Q,id:w});if(!B)return!1;return await A.updateEntity({entity:{...B,metadata:{...B.metadata,coverImageId:$}}}),!0}var Tvw={query:f.string().describe("Search terms for stock photos"),perPage:f.number().min(1).max(30).default(10).describe("Results per page (1-30)"),page:f.number().min(1).default(1).describe("Page number")},Svw={photoId:f.string().describe("Photo ID from search results"),downloadLocation:f.url().describe("Download tracking URL (required by provider ToS)"),photographerName:f.string().describe("Photographer name for attribution"),photographerUrl:f.url().describe("Photographer profile URL for attribution"),sourceUrl:f.url().describe("Photo page URL on provider"),imageUrl:f.url().describe("Image URL to download"),title:f.string().optional().describe("Image entity title"),alt:f.string().optional().describe("Alt text for the image"),targetEntityType:f.string().optional().describe("Entity type to set cover image on"),targetEntityId:f.string().optional().describe("Entity ID to set cover image on")},mvw=f.object({query:f.string(),perPage:f.number().min(1).max(30).default(10),page:f.number().min(1).default(1)}),uvw=f.object({photoId:f.string(),downloadLocation:f.url(),photographerName:f.string(),photographerUrl:f.url(),sourceUrl:f.url(),imageUrl:f.url(),title:f.string().optional(),alt:f.string().optional(),targetEntityType:f.string().optional(),targetEntityId:f.string().optional()});function w52(A,Q){return[cvw(A,Q),lvw(A,Q)]}function cvw(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:Tvw,visibility:"anchor",sideEffects:"none",handler:async(w)=>{let $=mvw.safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};try{return{success:!0,data:await Q.provider.searchPhotos($.data.query,{page:$.data.page,perPage:$.data.perPage})}}catch(B){return{success:!1,error:B instanceof Error?B.message:"Search failed"}}}}}function lvw(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:Svw,visibility:"anchor",sideEffects:"external",handler:async(w)=>{let $=uvw.safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};let{photoId:B,downloadLocation:X,photographerName:Y,photographerUrl:Z,sourceUrl:H,imageUrl:W,title:K,alt:U,targetEntityType:G,targetEntityId:q}=$.data,V={photographerName:Y,photographerUrl:Z,sourceUrl:H},I=await Q.entityService.listEntities({entityType:"image",options:{limit:1,filter:{metadata:{sourceUrl:W}}}});if(I[0]){let j={imageEntityId:I[0].id,alreadyExisted:!0,attribution:V};if(G&&q)j.coverSet=await eH0(Q.entityService,G,q,I[0].id);return{success:!0,data:j}}let J=await Q.jobs.enqueue({type:"select-photo",data:{photoId:B,downloadLocation:X,photographerName:Y,photographerUrl:Z,sourceUrl:H,imageUrl:W,...K!==void 0?{title:K}:{},...U!==void 0?{alt:U}:{},...G!==void 0?{targetEntityType:G}:{},...q!==void 0?{targetEntityId:q}:{}}}),k={imageEntityId:B,alreadyExisted:!1,attribution:V,jobId:J,status:"generating"};if(G&&q)k.coverSet=!1;return{success:!0,data:k}}}}fA();C0();p4();var pvw=f.object({photoId:f.string(),downloadLocation:f.url(),photographerName:f.string(),photographerUrl:f.url(),sourceUrl:f.url(),imageUrl:f.url(),title:f.string().optional(),alt:f.string().optional(),targetEntityType:f.string().optional(),targetEntityId:f.string().optional()});class YAA extends D6{deps;constructor(A,Q){super(A,{schema:pvw,jobTypeName:"select-photo"});this.deps=Q}async process(A,Q,w){await this.reportProgress(w,{progress:10,message:"Tracking stock photo download"}),await this.deps.provider.triggerDownload(A.downloadLocation),await this.reportProgress(w,{progress:35,message:"Downloading stock photo"});let $=await this.deps.fetchImage(A.imageUrl),B=A.title??`Stock photo ${A.photoId}`,X=qf.createImageEntity({dataUrl:$,title:B,alt:A.alt??B});await this.reportProgress(w,{progress:75,message:"Saving stock photo"});let{entityId:Y}=await this.deps.entityService.createEntity({entity:{id:A.photoId,...X,metadata:{...X.metadata,sourceUrl:A.imageUrl}}}),Z={imageEntityId:Y,alreadyExisted:!1};if(A.targetEntityType&&A.targetEntityId){if(Z.coverSet=await eH0(this.deps.entityService,A.targetEntityType,A.targetEntityId,Y),!Z.coverSet)Z.warning=`Target entity ${A.targetEntityType}:${A.targetEntityId} not found; cover image not set`}return await this.reportProgress(w,{progress:100,message:"Stock photo selected"}),Z}summarizeDataForLog(A){return{photoId:A.photoId,hasTarget:A.targetEntityType!==void 0}}}p4();var $52={name:"@brains/stock-photo",version:"0.2.0-alpha.159",description:"Stock photo search and selection \u2014 Unsplash provider",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":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts","./env-schema":"./src/env-schema.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var dvw=f.object({provider:f.enum(["unsplash"]).default("unsplash"),apiKey:f.string().optional().describe("Stock photo provider API key")});class ZAA extends Kw{deps;cachedTools=null;constructor(A={},Q={}){super("stock-photo",$52,A,dvw);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=w52(this.id,{provider:Q,entityService:A.entityService,fetchImage:this.deps.fetchImage??JW,jobs:A.jobs}),this.cachedTools}async registerJobHandlers(){if(!this.config.apiKey)return;let A=this.getContext();A.jobs.registerHandler("select-photo",new YAA(this.logger.child("SelectPhotoJobHandler"),{provider:this.createProvider(),entityService:A.entityService,fetchImage:this.deps.fetchImage??JW}))}createProvider(){return new tH0(this.config.apiKey??"",this.deps.fetch??globalThis.fetch)}}function fAA(A={},Q={}){return new ZAA(A,Q)}fA();C0();fA();fA();C0();var B52=f.enum(["ai","foundation","work"]),X52=f.object({suffix:B52,title:f.string(),body:f.string(),linkLabel:f.string(),linkHref:f.string()}),za=f.object({eyebrow:f.string(),headline:f.string(),cards:f.array(X52).min(1)}),HAA=f.object({title:f.string(),slug:f.string(),status:f.enum(["draft","published"])}),nvw=f.object({title:f.string(),slug:f.string(),status:f.enum(["draft","published"])}),Va=EQ.extend({entityType:f.literal("ecosystem-section"),metadata:nvw});class Y52 extends d2{constructor(){super({entityType:"ecosystem-section",purpose:"A section of the Rizom ecosystem overview.",schema:Va,frontmatterSchema:HAA})}fromMarkdown(A){return{content:A,entityType:"ecosystem-section",metadata:this.parseFrontmatter(A)}}}var WAA=new Y52;C0();function rvw(A){return A.replace(/^---\n[\s\S]*?\n---\n?/,"")}function KAA(A,Q){return new RegExp(`(?:^|\\n)## ${Q}\\s*\\n([\\s\\S]*?)(?=\\n## |$)`).exec(A)?.[1]?.trim()??""}function Ja(A,Q){return new RegExp(`(?:^|\\n)#### ${Q}\\s*\\n([\\s\\S]*?)(?=\\n#### |\\n### |$)`).exec(A)?.[1]?.trim()??""}function AW0(A){let Q=rvw(A),$=KAA(Q,"Cards").split(/^### Card \d+\s*$/m).map((B)=>B.trim()).filter(Boolean);return za.parse({eyebrow:KAA(Q,"Eyebrow"),headline:KAA(Q,"Headline"),cards:$.map((B)=>({suffix:Ja(B,"Suffix"),title:Ja(B,"Title"),body:Ja(B,"Body"),linkLabel:Ja(B,"Link Label"),linkHref:Ja(B,"Link Href")}))})}function Z52(A){return["# Ecosystem Section","","## Eyebrow",A.eyebrow,"","## Headline",A.headline,"","## Cards","",...A.cards.flatMap((Q,w)=>[`### Card ${w+1}`,"","#### Suffix",Q.suffix,"","#### Title",Q.title,"","#### Body",Q.body,"","#### Link Label",Q.linkLabel,"","#### Link Href",Q.linkHref,""])].join(`
9770
9770
  `)}var ovw=f.looseObject({query:f.object({id:f.string().optional()}).optional()});class QW0{id="rizom-ecosystem:entities";name="Rizom Ecosystem";description="Fetches an ecosystem-section entity for rendering";async fetch(A,Q,w){let B=ovw.parse(A??{}).query?.id??"rizom-ecosystem",X=await w.entityService.getEntity({entityType:"ecosystem-section",id:B});if(!X)throw Error(`Ecosystem section not found: ${B}`);return Q.parse(AW0(X.content))}}import{jsxDEV as tvw}from"preact/jsx-dev-runtime";var svw="px-6 md:px-10 xl:px-20",avw=`${svw} relative z-[1]`,f52=({id:A,className:Q,children:w})=>tvw("section",{id:A,className:C2(avw,Q),children:w},void 0,!1,void 0,this);import{jsxDEV as wW0}from"preact/jsx-dev-runtime";var evw=new Map([["work","text-accent"],["foundation","text-secondary"],["ai","text-accent-bright"]]),H52=({name:A="rizom",brandSuffix:Q,className:w,dotClassName:$,suffixClassName:B})=>{let X=evw.get(Q);return wW0("span",{className:C2("inline-flex items-baseline gap-0 font-display font-medium tracking-[-0.015em] [font-variation-settings:'opsz'_24]",w),children:[wW0("span",{className:"text-theme",children:A},void 0,!1,void 0,this),wW0("span",{className:C2(X??"text-accent",$),children:"."},void 0,!1,void 0,this),wW0("span",{className:C2("italic font-normal text-theme-muted",B),children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{Fragment as UAA}from"preact";import{jsxDEV as Ia}from"preact/jsx-dev-runtime";var Ahw=/(\*[^*]+\*)/;function W52(A,Q){let w=A.split(`
9771
- `);return Ia(UAA,{children:w.map(($,B)=>Ia(UAA,{children:[B>0&&Ia("br",{},void 0,!1,void 0,this),$.split(Ahw).map((X,Y)=>{if(X.length>=3&&X.startsWith("*")&&X.endsWith("*"))return Ia("span",{className:Q,children:X.slice(1,-1)},Y,!1,void 0,this);return Ia(UAA,{children:X},Y,!1,void 0,this)})]},B,!0,void 0,this))},void 0,!1,void 0,this)}import{jsxDEV as kZ,Fragment as Khw}from"preact/jsx-dev-runtime";var Qhw="italic text-accent font-normal",whw="You are here",$hw={work:"text-accent",foundation:"text-secondary",ai:"text-accent-bright"},Bhw={work:"border-t-accent/60",foundation:"border-t-secondary/60",ai:"border-t-accent-bright/60"},Xhw={work:"hover:border-t-accent",foundation:"hover:border-t-secondary",ai:"hover:border-t-accent-bright"},Yhw="font-label text-[10.5px] uppercase tracking-[0.26em] mt-1",Zhw="font-body text-[15px] leading-[1.6] text-theme-muted mt-2",fhw="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",Hhw="font-label text-[10.5px] uppercase tracking-[0.22em] text-accent self-start mt-[18px] pb-1",Whw=({card:A})=>{let Q=A.linkLabel===whw,w=A.linkHref.trim().length===0,$=kZ(Khw,{children:[kZ(H52,{brandSuffix:A.suffix,className:"text-[clamp(28px,3vw,40px)] [font-variation-settings:'opsz'_96]"},void 0,!1,void 0,this),kZ("span",{className:`${Yhw} ${$hw[A.suffix]}`,children:A.title},void 0,!1,void 0,this),kZ("p",{className:Zhw,children:A.body},void 0,!1,void 0,this),Q?kZ("span",{className:Hhw,children:A.linkLabel},void 0,!1,void 0,this):kZ("span",{className:fhw,children:A.linkLabel},void 0,!1,void 0,this)]},void 0,!0,void 0,this),B=`flex flex-col gap-[14px] border-t pt-7 ${Q?Bhw[A.suffix]:"border-white/10"}`;return Q||w?kZ("div",{className:B,children:$},void 0,!1,void 0,this):kZ("a",{href:A.linkHref,className:`${B} text-inherit no-underline transition-colors ${Xhw[A.suffix]}`,children:$},void 0,!1,void 0,this)},K52=({eyebrow:A,headline:Q,cards:w})=>kZ(f52,{id:"ecosystem",className:"pt-[112px] pb-[144px] border-t border-white/5",children:[kZ("div",{className:"mx-auto mb-[88px] max-w-[1180px] text-center",children:[kZ("span",{className:"font-label text-[11px] font-semibold uppercase tracking-[0.24em] text-accent",children:A},void 0,!1,void 0,this),kZ("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:W52(Q,Qhw)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),kZ("div",{className:"mx-auto grid max-w-[1180px] grid-cols-3 gap-16 max-[768px]:grid-cols-1 max-[768px]:gap-7",children:w.map(($)=>kZ(Whw,{card:$},$.suffix,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this);fA();var GAA=e1({name:"ecosystem",description:"Rizom ecosystem sibling-site section",schema:za,formatter:{parse:AW0,format:Z52},dataSourceId:"rizom-ecosystem:entities",requiredPermission:"public",layout:{component:K52}});var U52={name:"@brains/rizom-ecosystem",version:"0.2.0-alpha.158",description:"Entity-backed Rizom ecosystem section",dependencies:{"@brains/plugins":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var Ghw=f.object({}).catchall(f.unknown()).transform(()=>({})),Dhw="ecosystem-section";class DAA extends Zw{entityType=Dhw;schema=Va;adapter=WAA;constructor(A={}){super("rizom-ecosystem",U52,A,Ghw)}getTemplates(){return{ecosystem:GAA}}getDataSources(){return[new QW0]}}function PM(A={}){return new DAA(A)}C0();fA();fA();b2();C0();b9();C0();fA();var BB="agent",G52="agent-discovery";var D52="agent-network",q52="AgentNetworkWidget",Fa="agent-discovery:entities",qAA="agent-list",zAA="agent-detail",rB="skill",z52="skill",$W0="skill-derivation",V52="skill:project",J52="skill-derivation",I52="skill:skill-derivation",F52="skills";var BW0=f.object({name:f.string(),description:f.string(),tags:f.array(f.string())}),nE=f.enum(["discovered","approved"]).describe("Discovered for review or approved for calling"),b52=f.enum(["discovered","approved"]).describe("Discovered for review or approved for calling"),qhw=f.enum(["professional","team","collective"]),wJ=f.object({name:f.string(),kind:qhw,organization:f.string().optional(),brainName:f.string().describe("Name of the brain instance"),url:f.string().url().describe("Brain endpoint URL"),did:f.string().optional().describe("Decentralized identifier (public)"),repoDid:f.string().optional().describe("ATProto repo DID"),brainDid:f.string().optional().describe("ATProto brain DID"),anchorDid:f.string().optional().describe("ATProto anchor DID"),cardUri:f.string().optional().describe("ATProto brain card URI"),cardCid:f.string().optional().describe("ATProto brain card CID"),a2aEndpoint:f.string().url().optional().describe("A2A endpoint URL"),status:nE,discoveredAt:f.string().datetime().describe("When this agent was first discovered")}),L52=f.object({name:f.string(),url:f.string().url(),status:nE,discoveredAt:f.string().datetime().optional(),slug:f.string(),repoDid:f.string().optional(),brainDid:f.string().optional(),anchorDid:f.string().optional(),cardUri:f.string().optional(),cardCid:f.string().optional(),a2aEndpoint:f.string().url().optional()}),zhw=f.object({name:f.string(),kind:f.enum(["professional","team","collective"]),organization:f.string().optional(),brainName:f.string(),url:f.string().url(),did:f.string().optional(),repoDid:f.string().optional(),brainDid:f.string().optional(),anchorDid:f.string().optional(),cardUri:f.string().optional(),cardCid:f.string().optional(),a2aEndpoint:f.string().url().optional(),status:b52,discoveredAt:f.string().datetime()}),Vhw=f.object({name:f.string(),url:f.string().url(),status:b52,discoveredAt:f.string().datetime().optional(),slug:f.string(),repoDid:f.string().optional(),brainDid:f.string().optional(),anchorDid:f.string().optional(),cardUri:f.string().optional(),cardCid:f.string().optional(),a2aEndpoint:f.string().url().optional()}),ba=l8.extend({entityType:f.literal(BB),metadata:L52}),Jhw=EQ.extend({entityType:f.literal(BB),metadata:Vhw}),La=Jhw.extend({frontmatter:zhw,about:f.string(),skills:f.array(BW0),notes:f.string()}),Ihw=La.extend({url:f.string().optional(),typeLabel:f.string().optional()}),Fhw=La.extend({url:f.string(),typeLabel:f.string()});C0();var bhw=f.array(BW0);function k52(A){let Q=bhw.safeParse(A);if(!Q.success||Q.data.length===0)return"";return Q.data.map((w)=>{let $=w.tags.length>0?` [${w.tags.join(", ")}]`:"";return`- ${w.name}: ${w.description}${$}`}).join(`
9771
+ `);return Ia(UAA,{children:w.map(($,B)=>Ia(UAA,{children:[B>0&&Ia("br",{},void 0,!1,void 0,this),$.split(Ahw).map((X,Y)=>{if(X.length>=3&&X.startsWith("*")&&X.endsWith("*"))return Ia("span",{className:Q,children:X.slice(1,-1)},Y,!1,void 0,this);return Ia(UAA,{children:X},Y,!1,void 0,this)})]},B,!0,void 0,this))},void 0,!1,void 0,this)}import{jsxDEV as kZ,Fragment as Khw}from"preact/jsx-dev-runtime";var Qhw="italic text-accent font-normal",whw="You are here",$hw={work:"text-accent",foundation:"text-secondary",ai:"text-accent-bright"},Bhw={work:"border-t-accent/60",foundation:"border-t-secondary/60",ai:"border-t-accent-bright/60"},Xhw={work:"hover:border-t-accent",foundation:"hover:border-t-secondary",ai:"hover:border-t-accent-bright"},Yhw="font-label text-[10.5px] uppercase tracking-[0.26em] mt-1",Zhw="font-body text-[15px] leading-[1.6] text-theme-muted mt-2",fhw="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",Hhw="font-label text-[10.5px] uppercase tracking-[0.22em] text-accent self-start mt-[18px] pb-1",Whw=({card:A})=>{let Q=A.linkLabel===whw,w=A.linkHref.trim().length===0,$=kZ(Khw,{children:[kZ(H52,{brandSuffix:A.suffix,className:"text-[clamp(28px,3vw,40px)] [font-variation-settings:'opsz'_96]"},void 0,!1,void 0,this),kZ("span",{className:`${Yhw} ${$hw[A.suffix]}`,children:A.title},void 0,!1,void 0,this),kZ("p",{className:Zhw,children:A.body},void 0,!1,void 0,this),Q?kZ("span",{className:Hhw,children:A.linkLabel},void 0,!1,void 0,this):kZ("span",{className:fhw,children:A.linkLabel},void 0,!1,void 0,this)]},void 0,!0,void 0,this),B=`flex flex-col gap-[14px] border-t pt-7 ${Q?Bhw[A.suffix]:"border-white/10"}`;return Q||w?kZ("div",{className:B,children:$},void 0,!1,void 0,this):kZ("a",{href:A.linkHref,className:`${B} text-inherit no-underline transition-colors ${Xhw[A.suffix]}`,children:$},void 0,!1,void 0,this)},K52=({eyebrow:A,headline:Q,cards:w})=>kZ(f52,{id:"ecosystem",className:"pt-[112px] pb-[144px] border-t border-white/5",children:[kZ("div",{className:"mx-auto mb-[88px] max-w-[1180px] text-center",children:[kZ("span",{className:"font-label text-[11px] font-semibold uppercase tracking-[0.24em] text-accent",children:A},void 0,!1,void 0,this),kZ("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:W52(Q,Qhw)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),kZ("div",{className:"mx-auto grid max-w-[1180px] grid-cols-3 gap-16 max-[768px]:grid-cols-1 max-[768px]:gap-7",children:w.map(($)=>kZ(Whw,{card:$},$.suffix,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this);fA();var GAA=e1({name:"ecosystem",description:"Rizom ecosystem sibling-site section",schema:za,formatter:{parse:AW0,format:Z52},dataSourceId:"rizom-ecosystem:entities",requiredPermission:"public",layout:{component:K52}});var U52={name:"@brains/rizom-ecosystem",version:"0.2.0-alpha.159",description:"Entity-backed Rizom ecosystem section",dependencies:{"@brains/plugins":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var Ghw=f.object({}).catchall(f.unknown()).transform(()=>({})),Dhw="ecosystem-section";class DAA extends Zw{entityType=Dhw;schema=Va;adapter=WAA;constructor(A={}){super("rizom-ecosystem",U52,A,Ghw)}getTemplates(){return{ecosystem:GAA}}getDataSources(){return[new QW0]}}function PM(A={}){return new DAA(A)}C0();fA();fA();b2();C0();b9();C0();fA();var BB="agent",G52="agent-discovery";var D52="agent-network",q52="AgentNetworkWidget",Fa="agent-discovery:entities",qAA="agent-list",zAA="agent-detail",rB="skill",z52="skill",$W0="skill-derivation",V52="skill:project",J52="skill-derivation",I52="skill:skill-derivation",F52="skills";var BW0=f.object({name:f.string(),description:f.string(),tags:f.array(f.string())}),nE=f.enum(["discovered","approved"]).describe("Discovered for review or approved for calling"),b52=f.enum(["discovered","approved"]).describe("Discovered for review or approved for calling"),qhw=f.enum(["professional","team","collective"]),wJ=f.object({name:f.string(),kind:qhw,organization:f.string().optional(),brainName:f.string().describe("Name of the brain instance"),url:f.string().url().describe("Brain endpoint URL"),did:f.string().optional().describe("Decentralized identifier (public)"),repoDid:f.string().optional().describe("ATProto repo DID"),brainDid:f.string().optional().describe("ATProto brain DID"),anchorDid:f.string().optional().describe("ATProto anchor DID"),cardUri:f.string().optional().describe("ATProto brain card URI"),cardCid:f.string().optional().describe("ATProto brain card CID"),a2aEndpoint:f.string().url().optional().describe("A2A endpoint URL"),status:nE,discoveredAt:f.string().datetime().describe("When this agent was first discovered")}),L52=f.object({name:f.string(),url:f.string().url(),status:nE,discoveredAt:f.string().datetime().optional(),slug:f.string(),repoDid:f.string().optional(),brainDid:f.string().optional(),anchorDid:f.string().optional(),cardUri:f.string().optional(),cardCid:f.string().optional(),a2aEndpoint:f.string().url().optional()}),zhw=f.object({name:f.string(),kind:f.enum(["professional","team","collective"]),organization:f.string().optional(),brainName:f.string(),url:f.string().url(),did:f.string().optional(),repoDid:f.string().optional(),brainDid:f.string().optional(),anchorDid:f.string().optional(),cardUri:f.string().optional(),cardCid:f.string().optional(),a2aEndpoint:f.string().url().optional(),status:b52,discoveredAt:f.string().datetime()}),Vhw=f.object({name:f.string(),url:f.string().url(),status:b52,discoveredAt:f.string().datetime().optional(),slug:f.string(),repoDid:f.string().optional(),brainDid:f.string().optional(),anchorDid:f.string().optional(),cardUri:f.string().optional(),cardCid:f.string().optional(),a2aEndpoint:f.string().url().optional()}),ba=l8.extend({entityType:f.literal(BB),metadata:L52}),Jhw=EQ.extend({entityType:f.literal(BB),metadata:Vhw}),La=Jhw.extend({frontmatter:zhw,about:f.string(),skills:f.array(BW0),notes:f.string()}),Ihw=La.extend({url:f.string().optional(),typeLabel:f.string().optional()}),Fhw=La.extend({url:f.string(),typeLabel:f.string()});C0();var bhw=f.array(BW0);function k52(A){let Q=bhw.safeParse(A);if(!Q.success||Q.data.length===0)return"";return Q.data.map((w)=>{let $=w.tags.length>0?` [${w.tags.join(", ")}]`:"";return`- ${w.name}: ${w.description}${$}`}).join(`
9772
9772
  `)}function _52(A){if(!A.trim())return[];let Q=[];for(let w of A.split(`
9773
9773
  `)){let $=w.match(/^- (.+?): (.+?)(?:\s+\[(.+?)\])?$/);if(!$)continue;let B=$[1]??"",X=$[2]??"",Y=$[3],Z=Y?Y.split(",").map((H)=>H.trim()).filter(Boolean):[];Q.push({name:B,description:X,tags:Z})}return Q}var Lhw=f.object({name:f.string(),description:f.string(),tags:f.array(f.string())}),khw=f.object({about:f.string(),skills:f.array(Lhw),notes:f.string()}),N52=new R6(khw,{title:"Agent",mappings:[{key:"about",label:"About",type:"string"},{key:"skills",label:"Skills",type:"custom",formatter:k52,parser:_52},{key:"notes",label:"Notes",type:"string"}]});class DX extends d2{constructor(){super({entityType:BB,purpose:"A saved remote peer-brain contact in the local agent directory.",schema:ba,frontmatterSchema:wJ})}fromMarkdown(A){let Q=this.parseFrontMatter(A,wJ),w=xx(Q.url);return{content:A,entityType:BB,metadata:{name:Q.name,url:Q.url,status:Q.status,discoveredAt:Q.discoveredAt,slug:w,...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:nE.parse(A.status),discoveredAt:A.discoveredAt},w=N52.format({about:A.about,skills:A.skills,notes:A.notes});return this.buildMarkdown(w,Q)}parseAgentContent(A){let Q=this.extractBody(A);if(!Q.trim())return{about:"",skills:[],notes:""};try{let w=N52.parse(Q);return{about:w.about,skills:w.skills,notes:w.notes}}catch{return{about:"",skills:[],notes:""}}}parseEntity(A){return{frontmatter:this.parseFrontMatter(A.content,wJ),body:this.parseAgentContent(A.content)}}}fA();C0();var _hw=new DX,j52=f.enum(["discovered","approved"]),Nhw=f.looseObject({id:f.string().optional(),limit:f.number().optional(),page:f.number().optional(),pageSize:f.number().optional(),baseUrl:f.string().optional(),status:j52.optional()}),jhw=f.looseObject({entityType:f.string().optional(),query:Nhw.optional()});function Phw(A){let Q=$Q(A.content,wJ),w=_hw.parseAgentContent(A.content);return La.parse({...A,frontmatter:Q.metadata,about:w.about,skills:w.skills,notes:w.notes})}class XW0 extends c5{id=Fa;name="Agent Directory DataSource";description="Fetches and transforms agent entities for rendering";config={entityType:BB,defaultSort:[{field:"discoveredAt",direction:"desc"}],defaultLimit:50,lookupField:"slug",enableNavigation:!0};constructor(A){super(A)}transformEntity(A){return Phw(A)}buildDetailResult(A,Q){return{agent:A,prevAgent:Q?.prev??null,nextAgent:Q?.next??null}}parseQuery(A){let Q=jhw.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}buildListResult(A,Q,w){let $=j52.safeParse(w.status);return{agents:A,pagination:Q,baseUrl:w.baseUrl,selectedStatus:$.success?$.data:"all"}}async fetch(A,Q,w){let{query:$}=this.parseQuery(A);if($.id)return super.fetch(A,Q,w);let{items:B,pagination:X}=await this.fetchList($,w.entityService,$.status?{filter:{metadata:{status:$.status}}}:void 0);return Q.parse(this.buildListResult(B,X,$))}}fA();C0();e6();fA();async function YW0(A,Q){let $=`${(A.startsWith("http")?A:`https://${A}`).replace(/\/$/,"")}/.well-known/agent-card.json`;try{let B=await Q($);if(!B.ok)return null;let X=await B.json();return pu(X)}catch{return null}}function MM(A){let Q=A.trim();if(Q.startsWith("http://")||Q.startsWith("https://"))try{return new URL(Q).hostname}catch{return Q}let w=Q.match(/https?:\/\/[^\s]+?(?=[.,;:!?)]*(?:\s|$))/);if(w)try{return new URL(w[0]).hostname}catch{return w[0]}if(/^[^\s]+\.[^\s]+$/.test(Q))return Q;return""}b2();var Mhw=new DX;function P52(A){return A.trim().toLowerCase().replace(/[_\s]+/g,"-")}function xL(A){let Q=new Set,w=[];for(let $ of A){let B=P52($);if(!B||Q.has(B))continue;Q.add(B),w.push(B)}return w}function Ohw(A,Q){if(Q.count!==A.count)return Q.count-A.count;return A.tag.localeCompare(Q.tag)}async function M52(A,Q={}){let w=Q.minCount??1,$=Q.topN??12,B=Q.visibilityScope??"public",X=new Map,[Y,Z]=await Promise.all([A.entityService.listEntities({entityType:rB,options:{filter:{visibilityScope:B}}}),A.entityService.listEntities({entityType:BB,options:{filter:{visibilityScope:B}}})]),H=(W)=>{for(let K of xL(W))X.set(K,(X.get(K)??0)+1)};for(let W of Y)H(W.metadata.tags);for(let W of Z){let K=Mhw.parseAgentContent(W.content);H(K.skills.flatMap((U)=>U.tags))}return Array.from(X.entries()).map(([W,K])=>({tag:W,count:K})).filter((W)=>W.count>=w).sort(Ohw).slice(0,$)}function O52(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:w})=>`- ${Q} (${w})`)].join(`
9774
9774
  `)}var xhw=new DX;function ZW0(A,Q={}){let w=A.anchor?.name??A.brainName,$=A.anchor?.kind??"professional",B=[];if(A.anchor?.description)B.push(A.anchor.description);if(A.description)B.push(A.description);let X=Q.status??"discovered",Y=new Date().toISOString();return{content:xhw.createAgentContent({name:w,kind:$,...A.anchor?.organization&&{organization:A.anchor.organization},brainName:A.brainName,url:A.url,status:X,discoveredAt:Y,about:B.join(`
@@ -9869,7 +9869,7 @@ ${A.guidance}`:B}}function TB2(A){return{...A,evidence:A.evidence.map((Q)=>({...
9869
9869
  setTagFilter("all");
9870
9870
  });
9871
9871
  })();`;import{jsxDEV as yw}from"preact/jsx-dev-runtime";function Shw({item:A}){return yw("li",{class:"list-item",children:[yw("div",{class:"list-main",children:[yw("span",{class:"list-name",children:A.name},void 0,!1,void 0,this),yw("span",{class:"list-desc",children:A.description},void 0,!1,void 0,this),A.tags.length>0&&yw("div",{class:"list-tags",children:A.tags.map((Q)=>yw("span",{class:"tag",children:Q},`${A.id}:${Q}`,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),yw("div",{class:"list-meta",children:A.status==="discovered"&&yw("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 mhw({item:A}){return yw("li",{class:"list-item agent-network-skill-row","data-agent-network-skill-row":!0,"data-agent-network-tags":JSON.stringify(A.tags),children:[yw("div",{class:"list-main",children:yw("span",{class:"list-name",children:A.name},void 0,!1,void 0,this)},void 0,!1,void 0,this),yw("div",{class:"list-meta",children:yw("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 uhw({kind:A,items:Q,active:w}){return yw("div",{class:`agent-network-panel${w?" is-active":""}`,"data-agent-network-panel":A,children:Q.length>0?yw("ul",{class:"list agent-network-list",children:Q.map(($)=>yw(Shw,{item:$},$.id,!1,void 0,this))},void 0,!1,void 0,this):yw("p",{class:"agent-network-empty",children:"Nothing to show yet."},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function chw({skills:A,count:Q,filters:w}){return yw("div",{class:"agent-network-panel","data-agent-network-panel":"skills",children:[yw("div",{class:"agent-network-filter-row",role:"tablist","aria-label":"Filter skills by tag",children:[yw("button",{class:"agent-network-filter is-active",type:"button","data-agent-network-tag-filter":"all","aria-pressed":"true",children:[yw("span",{class:"count",children:Q},void 0,!1,void 0,this),yw("span",{class:"label",children:"all"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),w.map(($)=>yw("button",{class:`agent-network-filter${$.variant==="gap"?" is-gap":""}`,type:"button","data-agent-network-tag-filter":$.tag,"aria-pressed":"false",children:[yw("span",{class:"count",children:$.count},void 0,!1,void 0,this),yw("span",{class:"label",children:$.tag},void 0,!1,void 0,this)]},$.tag,!0,void 0,this))]},void 0,!0,void 0,this),A.length>0?yw("ul",{class:"list agent-network-list agent-network-skills-list",children:A.map(($)=>yw(mhw,{item:$},$.id,!1,void 0,this))},void 0,!1,void 0,this):yw("p",{class:"agent-network-empty",children:"Nothing to show yet."},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function IAA({data:A}){let Q=JAA.safeParse(A);if(!Q.success)return yw("p",{class:"muted",children:"Nothing to show yet."},void 0,!1,void 0,this);let w=Q.data;return yw("div",{"data-agent-network-widget":!0,"data-agent-network-view":"agents",children:[yw("div",{class:"agent-network-view-tabs",role:"tablist","aria-label":"Browse the agent network",children:[yw("button",{class:"agent-network-view-tab is-active",type:"button","data-agent-network-view-tab":"agents","aria-pressed":"true",children:["Agents",yw("span",{class:"agent-network-view-count",children:w.counts.agents},void 0,!1,void 0,this)]},void 0,!0,void 0,this),yw("button",{class:"agent-network-view-tab",type:"button","data-agent-network-view-tab":"skills","aria-pressed":"false",children:["Skills",yw("span",{class:"agent-network-view-count",children:w.counts.skills},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),yw("div",{class:"agent-network-kind-tabs",role:"tablist","aria-label":"Filter agents by kind",children:fW0.map(($)=>{let B=$==="all";return yw("button",{class:`agent-network-kind-tab${B?" is-active":""}`,type:"button","data-agent-network-kind-tab":$,"aria-pressed":B?"true":"false",children:[yw("span",{class:"agent-network-kind-count",children:w.agents[$].length},void 0,!1,void 0,this),yw("span",{class:"agent-network-kind-label",children:$},void 0,!1,void 0,this)]},$,!0,void 0,this)})},void 0,!1,void 0,this),fW0.map(($)=>yw(uhw,{kind:$,items:w.agents[$],active:$==="all"},$,!1,void 0,this)),yw(chw,{skills:w.skills,count:w.counts.skills,filters:w.skillFilters},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}var lhw=f.object({counts:f.object({agents:f.number(),skills:f.number()})});function y52(A,Q){A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"dashboard:register-widget",payload:{id:D52,pluginId:Q,title:"Agent Network",group:"network",section:"secondary",priority:15,rendererName:q52,component:IAA,clientScript:HW0,dataProvider:async()=>g52(A),digestProvider:(w)=>{let{counts:$}=lhw.parse(w);return{digest:[{label:"Agents",value:String($.agents)},{label:"Skills",value:String($.skills)}]}}}}),{success:!0}})}b2();var E52=new DX;function phw(A){return A.skills.map((Q)=>({name:Q.name,description:Q.description,tags:Q.tags??[]}))}function ihw(A){return new URL(A).hostname}function dhw(A){return[`ATProto card: ${A.uri}`,`ATProto card CID: ${A.cid}`,`ATProto repo DID: ${A.repoDid}`].join(`
9872
- `)}function nhw(A){let Q=A.record.brain.did,w=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},...w&&{anchorDid:w},cardUri:A.uri,cardCid:A.cid}}async function rhw(A,Q,w){await A.messaging.send({type:Q,payload:w,broadcast:!0})}async function ohw(A,Q,w=new Date().toISOString()){let{record:$}=Q,B=ihw($.siteUrl),X=await A.entityService.getEntity({entityType:"agent",id:B}),Y=X?E52.parseEntity(X):void 0,Z=$.brain.did,H=$.anchor.did,W=phw($),K=X?.metadata.status??"discovered",U=X?.metadata.url??$.siteUrl,G=X?.metadata.slug??xx(U),q=X?.metadata.name??$.anchor.name,V=Y?.frontmatter.kind??$.anchor.kind,I=X?.metadata.discoveredAt??w,J=$.brain.purpose.length>0?$.brain.purpose:Y?.body.about??"",k=W.length>0?W:Y?.body.skills??[],j={...X?.metadata??{},name:q,url:U,status:K,discoveredAt:I,slug:G,repoDid:Q.repoDid,...Z&&{brainDid:Z},...H&&{anchorDid:H},cardUri:Q.uri,cardCid:Q.cid},_=E52.createAgentContent({name:q,kind:V,...Y?.frontmatter.organization&&{organization:Y.frontmatter.organization},brainName:$.brain.name,url:U,...Z&&{did:Z,brainDid:Z},...H&&{anchorDid:H},repoDid:Q.repoDid,cardUri:Q.uri,cardCid:Q.cid,...Y?.frontmatter.a2aEndpoint&&{a2aEndpoint:Y.frontmatter.a2aEndpoint},status:K,discoveredAt:I,about:J,skills:k,notes:dhw({repoDid:Q.repoDid,uri:Q.uri,cid:Q.cid})});if(X){let v={...X,content:_,metadata:j,updated:w};return await A.entityService.updateEntity({entity:v}),{agent:v,created:!1}}let x={id:B,entityType:"agent",content:_,metadata:j,contentHash:"",visibility:"public",created:w,updated:w};return await A.entityService.createEntity({entity:x}),{agent:x,created:!0}}function T52(A){A.messaging.subscribe(Hr,async(Q)=>{let w=cp0.parse(Q.payload),$=await ohw(A,w),B=nhw({agent:$.agent,repoDid:w.repoDid,uri:w.uri,cid:w.cid,record:w.record});return await rhw(A,$.created?mp0:up0,B),{success:!0,data:B}})}function S52(){return["Agent entities are saved peer contacts. List them with system_list on entityType agent.","For an expertise match or recommendation, immediately run one system_search scoped to entityType agent using the requested topic. Suggest only clear matches, naming the contact and exact callable id/domain with brief supporting evidence. Prefer approved contacts; label discovered contacts as unverified. If none qualifies, say \u201CI couldn't find a clear match in your saved agent network for <topic>\u201D rather than suggesting a generic role. A short affirmative reply to an offer to search means run that search using the prior topic.","Route contact changes by intent: agent_connect verifies and saves a new domain/URL as an approved outbound contact; system_update changes the lifecycle status of an existing contact; agent_set_trust_level is the only tool for granting or revoking inbound A2A trust. Revocation uses level public and needs no key fingerprint or preliminary entity lookup.","If agent_call cannot reach an unsaved exact domain, offer to connect it; a short affirmative follow-up should call agent_connect for that domain. Only approved contacts can be called.","To call a contact named by person, anchor, or display name, first resolve it with one system_search scoped to entityType agent, then call agent_call with the returned entity id/domain\u2014not the display, anchor, or brain name. Skip search only when the user supplied an exact domain-like id."].join(" ")}p$();C0();import{jsxDEV as m52}from"preact/jsx-dev-runtime";function WW0(A){try{return new URL(A).hostname}catch{return A}}var KW0=({name:A,className:Q=""})=>{let w=A.charAt(0).toUpperCase(),$=0;for(let X=0;X<A.length;X++)$=A.charCodeAt(X)+(($<<5)-$);let B=Math.abs($)%360;return m52("div",{className:`flex items-center justify-center rounded-full text-white font-bold flex-shrink-0 ${Q}`,style:{backgroundColor:`hsl(${B}, 55%, 45%)`},children:w},void 0,!1,void 0,this)},UW0=({kind:A,size:Q="md"})=>{let $={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 m52("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]"} ${$}`,children:A},void 0,!1,void 0,this)};import{jsxDEV as e2,Fragment as thw}from"preact/jsx-dev-runtime";var shw=({skills:A})=>{if(A.length===0)return null;return e2("div",{className:"flex gap-1.5 flex-wrap mt-2",children:A.map((Q)=>e2("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 ahw(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric"})}function u52(A,Q,w){let $=new URLSearchParams({status:Q});if(w>1)$.set("page",String(w));return`${A}?${$.toString()}`}var FAA=({agent:A})=>{let{frontmatter:Q,about:w,skills:$,url:B}=A,X=Q.status==="approved";return e2("a",{href:B,className:`flex items-start gap-5 p-6 rounded-xl border border-theme bg-theme-subtle hover:shadow-lg transition-shadow ${X?"":"opacity-70"}`,children:[e2(KW0,{name:Q.name,className:"w-12 h-12 text-lg"},void 0,!1,void 0,this),e2("div",{className:"flex-1 min-w-0",children:[e2("div",{className:"flex items-center gap-2 mb-1 flex-wrap",children:[e2("span",{className:"text-lg font-semibold text-heading",children:Q.name},void 0,!1,void 0,this),e2(UW0,{kind:Q.kind,size:"sm"},void 0,!1,void 0,this),Q.organization&&e2("span",{className:"text-xs text-theme-muted",children:["\xB7 ",Q.organization]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),e2("div",{className:"text-sm text-theme-muted mb-1",children:Q.brainName},void 0,!1,void 0,this),w&&e2("p",{className:"text-sm text-theme-muted line-clamp-2 mb-0",children:w},void 0,!1,void 0,this),X&&e2(shw,{skills:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this),e2("div",{className:"flex flex-col items-end gap-1 flex-shrink-0 text-right",children:[e2("span",{className:"text-xs text-theme-muted",children:WW0(Q.url)},void 0,!1,void 0,this),e2("span",{className:"text-[11px] text-theme-muted opacity-60",children:X?`Discovered ${ahw(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)},c52=({agents:A,pageTitle:Q,pagination:w,baseUrl:$="/agents",selectedStatus:B})=>{let X=Q??"Agent Directory",Y=w?.totalItems??A.length,Z=A.filter((G)=>G.frontmatter.status==="approved"),H=A.filter((G)=>G.frontmatter.status==="discovered"),W=Z.length,K=H.length,U=`Your network of ${Y} ${Y===1?"brain":"brains"} and their anchors`;return e2(thw,{children:[e2($w,{title:X,description:U},void 0,!1,void 0,this),e2("div",{className:"agent-list bg-theme",children:e2("div",{className:"container mx-auto px-6 md:px-12 max-w-5xl py-16 md:py-24",children:[e2("div",{className:"mb-8 pb-6 border-b border-theme",children:[e2("h1",{className:"text-4xl font-bold text-heading mb-2",children:X},void 0,!1,void 0,this),e2("p",{className:"text-theme-muted mb-4",children:U},void 0,!1,void 0,this),e2("div",{className:"flex flex-wrap gap-2 text-sm mb-4",children:[e2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-heading",children:[Y," total"]},void 0,!0,void 0,this),e2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-status-success",children:[W," approved"]},void 0,!0,void 0,this),e2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-theme-muted",children:[K," discovered"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),e2("div",{className:"flex flex-wrap gap-2 text-sm",children:[e2("a",{href:$,className:`px-3 py-1 rounded-full border transition-colors ${B==="all"?"border-theme text-heading bg-theme-subtle":"border-theme text-theme-muted hover:text-heading"}`,children:"All"},void 0,!1,void 0,this),e2("a",{href:`${$}?status=approved`,className:`px-3 py-1 rounded-full border transition-colors ${B==="approved"?"border-theme text-heading bg-theme-subtle":"border-theme text-theme-muted hover:text-heading"}`,children:"Approved"},void 0,!1,void 0,this),e2("a",{href:`${$}?status=discovered`,className:`px-3 py-1 rounded-full border transition-colors ${B==="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),B==="all"&&Z.length>0&&e2("section",{className:"mb-10",children:[e2("div",{className:"flex items-center justify-between mb-4",children:[e2("h2",{className:"text-lg font-semibold text-heading",children:"Approved brains"},void 0,!1,void 0,this),e2("span",{className:"text-sm text-theme-muted",children:Z.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),e2("div",{className:"flex flex-col gap-4",children:Z.map((G)=>e2(FAA,{agent:G},G.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),B==="all"&&H.length>0&&e2("section",{children:[e2("div",{className:"flex items-center justify-between mb-4",children:[e2("div",{children:[e2("h2",{className:"text-lg font-semibold text-heading",children:"Discovered brains"},void 0,!1,void 0,this),e2("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),e2("span",{className:"text-sm text-theme-muted",children:H.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),e2("div",{className:"flex flex-col gap-4",children:H.map((G)=>e2(FAA,{agent:G},G.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),B!=="all"&&A.length>0&&e2("section",{children:[e2("div",{className:"flex items-center justify-between mb-4",children:[e2("h2",{className:"text-lg font-semibold text-heading",children:B==="approved"?"Approved brains":"Discovered brains"},void 0,!1,void 0,this),e2("span",{className:"text-sm text-theme-muted",children:A.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),e2("div",{className:"flex flex-col gap-4",children:A.map((G)=>e2(FAA,{agent:G},G.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.length===0&&e2("p",{className:"text-center text-theme-muted py-16",children:"No agents in your directory yet."},void 0,!1,void 0,this),w&&w.totalPages>1&&B==="all"&&e2("div",{className:"mt-12",children:e2(CV,{currentPage:w.currentPage,totalPages:w.totalPages,baseUrl:$},void 0,!1,void 0,this)},void 0,!1,void 0,this),w&&w.totalPages>1&&B!=="all"&&e2("nav",{"aria-label":"Pagination",className:"flex items-center justify-center gap-3 mt-12",children:[w.hasPrevPage?e2("a",{href:u52($,B,w.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):e2("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),e2("span",{className:"text-sm text-theme-muted",children:["Page ",w.currentPage," of ",w.totalPages]},void 0,!0,void 0,this),w.hasNextPage?e2("a",{href:u52($,B,w.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):e2("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 E2,Fragment as wCw}from"preact/jsx-dev-runtime";function ehw(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"})}var _a=({children:A})=>E2("h2",{className:"text-sm font-semibold text-theme-muted uppercase tracking-wide mb-3",children:A},void 0,!1,void 0,this),ACw=({skill:A})=>E2("div",{className:"flex items-start gap-3 px-4 py-3 bg-theme-subtle rounded-lg",children:[E2("div",{className:"flex-1",children:[E2("div",{className:"text-sm font-semibold text-heading",children:A.name},void 0,!1,void 0,this),E2("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&&E2("div",{className:"flex gap-1 flex-shrink-0",children:A.tags.map((Q)=>E2("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),QCw=({label:A,value:Q,valueClassName:w})=>E2("div",{className:"flex justify-between text-[13px]",children:[E2("span",{className:"text-theme-muted",children:A},void 0,!1,void 0,this),E2("span",{className:w??"text-heading",children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this),l52=({agent:A,prevAgent:Q,nextAgent:w})=>{let{frontmatter:$,about:B,skills:X,notes:Y}=A,Z=WW0($.url),H=$.status==="approved";return E2(wCw,{children:[E2($w,{title:$.name,description:B||`Agent profile for ${$.name}`},void 0,!1,void 0,this),E2("article",{className:"agent-detail",children:E2("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:[E2("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),E2("div",{className:"flex items-start gap-6 mb-8",children:[E2(KW0,{name:$.name,className:"w-[72px] h-[72px] text-3xl"},void 0,!1,void 0,this),E2("div",{children:[E2("div",{className:"flex items-center gap-3 mb-1",children:[E2("h1",{className:"text-3xl md:text-4xl font-bold text-heading",children:$.name},void 0,!1,void 0,this),E2(UW0,{kind:$.kind},void 0,!1,void 0,this)]},void 0,!0,void 0,this),E2("div",{className:"text-base text-theme-muted mb-2",children:$.brainName},void 0,!1,void 0,this),E2("div",{className:"flex items-center gap-3 text-theme-muted",children:[$.organization&&E2("span",{className:"text-[15px]",children:$.organization},void 0,!1,void 0,this),$.organization&&E2("span",{className:"text-theme-muted opacity-40",children:"\xB7"},void 0,!1,void 0,this),E2("span",{className:"text-sm",children:["Discovered ",ehw($.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),E2("div",{className:"border-b border-theme mb-8"},void 0,!1,void 0,this),!H&&E2("div",{className:"mb-8 rounded-xl border border-theme bg-theme-subtle px-5 py-4",children:[E2("div",{className:"text-sm font-semibold text-heading mb-1",children:"Saved for review"},void 0,!1,void 0,this),E2("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),E2("div",{className:"flex flex-col md:flex-row gap-12",children:[E2("div",{className:"flex-[2] min-w-0",children:[B&&E2("section",{className:"mb-8",children:[E2(_a,{children:"About"},void 0,!1,void 0,this),E2("p",{className:"text-[15px] text-theme leading-relaxed",children:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this),X.length>0&&E2("section",{className:"mb-8",children:[E2(_a,{children:"Skills"},void 0,!1,void 0,this),E2("div",{className:"flex flex-col gap-2.5",children:X.map((W)=>E2(ACw,{skill:W},W.name,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Y&&E2("section",{className:"mb-8",children:[E2(_a,{children:"Notes"},void 0,!1,void 0,this),E2("p",{className:"text-[15px] text-theme leading-relaxed",children:Y},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),E2("aside",{className:"flex-1 md:pl-8 md:border-l border-theme-muted/20",children:[E2("section",{className:"mb-8",children:[E2(_a,{children:"Brain"},void 0,!1,void 0,this),E2("div",{className:"p-4 bg-theme-subtle rounded-xl",children:[E2("div",{className:"text-[15px] font-semibold text-heading mb-1",children:$.brainName},void 0,!1,void 0,this),$.did&&E2("div",{className:"text-xs text-theme-muted font-mono",children:$.did},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),E2("section",{className:"mb-8",children:[E2(_a,{children:"Connection"},void 0,!1,void 0,this),E2("div",{className:"flex flex-col gap-3",children:[E2("div",{children:[E2("div",{className:"text-[13px] text-theme-muted mb-0.5",children:"Endpoint"},void 0,!1,void 0,this),E2("div",{className:"text-xs text-heading font-mono",children:$.url},void 0,!1,void 0,this)]},void 0,!0,void 0,this),E2(QCw,{label:"Status",value:$.status==="approved"?"Approved":"Discovered",valueClassName:$.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),E2("a",{href:$.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 ",Z," \u2197"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),(Q??w)&&E2("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:[E2("div",{className:"min-h-[1px]",children:Q&&E2("a",{href:Q.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[E2("span",{children:"\u2190 Previous"},void 0,!1,void 0,this),E2("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),E2("div",{className:"min-h-[1px] md:text-right",children:w&&E2("a",{href:w.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[E2("span",{children:"Next \u2192"},void 0,!1,void 0,this),E2("span",{className:"text-heading font-medium",children:w.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 $Cw=f.union([f.enum(["public","shared","restricted"]),f.literal("private")]).optional().transform((A)=>{if(A===void 0)return"public";if(A==="private")return"restricted";return A}),BCw=f.object({currentPage:f.number(),totalPages:f.number(),totalItems:f.number(),pageSize:f.number(),hasNextPage:f.boolean(),hasPrevPage:f.boolean()}),XCw=f.object({name:f.string(),description:f.string(),tags:f.array(f.string())}),bAA=f.enum(["discovered","approved"]),YCw=f.enum(["professional","team","collective"]),ZCw=f.object({name:f.string(),kind:YCw,organization:f.string().optional(),brainName:f.string(),url:f.url(),did:f.string().optional(),repoDid:f.string().optional(),brainDid:f.string().optional(),anchorDid:f.string().optional(),cardUri:f.string().optional(),cardCid:f.string().optional(),a2aEndpoint:f.url().optional(),status:bAA,discoveredAt:f.string()}),fCw=f.object({name:f.string(),url:f.url(),status:bAA,discoveredAt:f.string().optional(),slug:f.string(),repoDid:f.string().optional(),brainDid:f.string().optional(),anchorDid:f.string().optional(),cardUri:f.string().optional(),cardCid:f.string().optional(),a2aEndpoint:f.url().optional()}),GW0=f.object({id:f.string(),entityType:f.literal(BB),content:f.string(),created:f.string(),updated:f.string(),visibility:$Cw,metadata:fCw,contentHash:f.string(),frontmatter:ZCw,about:f.string(),skills:f.array(XCw),notes:f.string(),url:f.string().optional(),typeLabel:f.string().optional()}),HCw=f.object({agents:f.array(GW0),pageTitle:f.string().optional(),pagination:BCw.nullable(),baseUrl:f.string().optional(),selectedStatus:f.union([f.literal("all"),bAA])});function p52(){return{[qAA]:e1({name:qAA,description:"Agent directory list page template",schema:HCw,dataSourceId:Fa,requiredPermission:"public",layout:{component:c52}}),[zAA]:e1({name:zAA,description:"Individual agent profile template",schema:f.object({agent:GW0,prevAgent:GW0.nullable(),nextAgent:GW0.nullable()}),dataSourceId:Fa,requiredPermission:"public",layout:{component:l52}})}}var rE={name:"@brains/agent-discovery",version:"0.2.0-alpha.158",description:"Agent discovery \u2014 brain+anchor contacts and skills",dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/auth-service":"workspace:*","@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/dashboard":"workspace:*","@brains/http-signatures":"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":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var KCw=new DX;class LAA extends Zw{entityType=BB;schema=ba;adapter=KCw;constructor(){super(G52,rE,{},i7)}createGenerationHandler(A){return new VAA(this.logger.child("AgentGenerationJobHandler"),A)}getTemplates(){return p52()}getDataSources(){return[new XW0(this.logger.child("AgentDataSource"))]}async onRegister(A){T52(A),y52(A,this.id)}async getInstructions(){return S52()}}function kAA(){return new LAA}fA();C0();j9();C0();var i52=f.object({source:f.object({kind:f.literal("url"),url:f.string().min(1).describe("Remote agent domain or URL to verify and connect. Preserve bare domains as bare domains.")}),confirmed:f.boolean().optional(),confirmationToken:f.string().optional()}),UCw=new DX;function GCw(A){let Q=MM(A);if(!Q)return null;return{domain:Q,fetchTarget:A.trim().startsWith("http")?A.trim():Q}}function DCw(A,Q){return(MM(Q)||A).toLowerCase()}async function qCw(A){let{context:Q,entityId:w,card:$}=A,B=new Date().toISOString(),X=await Q.entityService.getEntity({entityType:BB,id:w}),Y=ZW0($,{status:"approved"}),H={...UCw.fromMarkdown(Y.content).metadata,...Y.metadata,a2aEndpoint:$.url};if(X){let K={...X,content:Y.content,metadata:H,updated:B};return await Q.entityService.updateEntity({entity:K}),{entity:K,created:!1}}let W={id:w,entityType:BB,content:Y.content,metadata:H,contentHash:"",visibility:"public",created:B,updated:B};return await Q.entityService.createEntity({entity:W}),{entity:W,created:!0}}function d52(A,Q=globalThis.fetch){let $=new Zf;return{name:"agent_connect",description:"Verify and connect a remote A2A agent by fetching its Agent Card from /.well-known/agent-card.json, then save the verified contact in the local agent directory as approved for future outbound calls. This adds a directory contact; it does not message the remote agent or grant it inbound trusted access. Requires confirmation before verification and persistence. Call this tool without confirmed on the initial request; the tool returns confirmation args for the user to approve.",inputSchema:i52.shape,visibility:"trusted",sideEffects:"external",handler:async(B,X)=>{let Y=i52.safeParse(B);if(!Y.success)return{success:!1,error:`Invalid input: ${Y.error.issues.map((K)=>`${K.path.join(".")}: ${K.message}`).join(", ")}`};let Z=Y.data,H=GCw(Z.source.url);if(!H)return{success:!1,error:"Provide a valid remote agent domain or URL to connect.",code:"invalid_agent_url"};try{A.permissions.assertEntityActionAllowed(BB,"create",X)}catch(K){return{success:!1,error:K instanceof Error?K.message:String(K)}}if(Z.confirmed){let K=Z.confirmationToken,U=$.validate(K,Z);if(U.status==="missing")return{success:!1,error:"No pending agent connection confirmation found. Please request connection again and confirm the new approval."};if(U.status==="mismatch")return{success:!1,error:"Confirmed agent connection arguments do not match the pending approval. Please request connection again and confirm the new approval."};let G=await YW0(H.fetchTarget,Q);if(!G)return{success:!1,error:`Could not verify an A2A Agent Card for ${H.domain}.`,code:"not_an_agent"};let q=DCw(H.domain,G.url),{entity:V,created:I}=await qCw({context:A,entityId:q,sourceUrl:Z.source.url,card:G});return{success:!0,data:{status:V.metadata.status,entityId:V.id,connected:!0,created:I,a2aEndpoint:G.url,skills:G.skills.map((J)=>({name:J.name,description:J.description,tags:J.tags}))}}}let W=$.create((K)=>({source:Z.source,confirmed:!0,confirmationToken:K}));return{needsConfirmation:!0,toolName:"agent_connect",summary:`Verify and connect agent ${H.domain}?`,preview:`This will fetch and validate ${H.domain}'s A2A Agent Card, then save the verified contact as approved for future outbound calls. It will not message the remote agent or grant it inbound trusted access.`,args:W}}}}j9();C0();var zCw=f.enum(["public","trusted"]),n52=f.object({agent:f.string().min(1).describe("Saved agent id, domain, or URL whose inbound A2A trust to set."),level:zCw.describe("Inbound A2A trust level. Use trusted to grant trusted inbound access, public to revoke it."),confirmed:f.boolean().optional(),confirmationToken:f.string().optional(),keyFingerprint:f.string().optional()}),VCw=f.object({keys:f.array(f.unknown())}),JCw=f.object({kty:f.literal("OKP"),crv:f.literal("Ed25519"),x:f.string(),kid:f.string().optional(),alg:f.literal("EdDSA").optional()}).passthrough();function r52(A){return(MM(A)||A.trim()).toLowerCase()}async function ICw(A,Q){let w=r52(Q),$=await A.entityService.getEntity({entityType:BB,id:w});if(!$)return null;let B=r52($.metadata.a2aEndpoint??$.metadata.url);if(!B)return null;return{domain:B}}async function FCw(A,Q){try{let w=await Q(`https://${A}/.well-known/jwks.json`);if(!w.ok)return null;let $=VCw.safeParse(await w.json());if(!$.success)return null;let B=$.data.keys.map((X)=>JCw.safeParse(X)).find((X)=>X.success);if(!B?.success)return null;return hp0(B.data)}catch{return null}}function o52(A,Q=globalThis.fetch){let $=new Zf;return{name:"agent_set_trust_level",description:"Grant or revoke inbound A2A trust for a saved contact; this is the only tool for inbound trust changes. To revoke, call directly with level public\u2014no key fingerprint or preliminary lookup is needed. To grant, use level trusted; the tool resolves and pins the peer key. This does not add or remove directory contacts or change outbound calling. Requires confirmation.",inputSchema:n52.shape,visibility:"anchor",sideEffects:"external",handler:async(B)=>{let X=n52.safeParse(B);if(!X.success)return{success:!1,error:`Invalid input: ${X.error.issues.map((G)=>`${G.path.join(".")}: ${G.message}`).join(", ")}`};let Y=s7();if(!Y)return{success:!1,error:"Auth service is required to set inbound A2A trust.",code:"auth_service_unavailable"};let Z=await ICw(A,X.data.agent);if(!Z)return{success:!1,error:`No saved agent contact found for ${X.data.agent}. Connect the agent before setting inbound trust.`,code:"agent_not_found"};let H=X.data;if(H.confirmed){let G=$.validate(H.confirmationToken,H);if(G.status==="missing")return{success:!1,error:"No pending agent trust confirmation found. Please request the trust change again and confirm the new approval."};if(G.status==="mismatch")return{success:!1,error:"Confirmed agent trust arguments do not match the pending approval. Please request the trust change again and confirm the new approval."};if(H.level==="trusted"){if(!H.keyFingerprint)return{success:!1,error:"Missing key fingerprint for trusted A2A grant."};let q=await Y.grantA2APeerTrust({domain:Z.domain,keyFingerprint:H.keyFingerprint,grantedLevel:"trusted"});return{success:!0,data:{agent:Z.domain,level:q.grantedLevel,keyFingerprint:q.keyFingerprint}}}return await Y.revokeA2APeerTrust(Z.domain),{success:!0,data:{agent:Z.domain,level:"public"}}}let W=H.level==="trusted"?await FCw(Z.domain,Q):void 0;if(H.level==="trusted"&&!W)return{success:!1,error:`Could not fetch an A2A signing key from ${Z.domain}.`,code:"jwks_unavailable"};let K=$.create((G)=>({agent:Z.domain,level:H.level,confirmed:!0,confirmationToken:G,...W?{keyFingerprint:W}:{}})),U=H.level==="trusted";return{needsConfirmation:!0,toolName:"agent_set_trust_level",summary:U?`Grant inbound trusted A2A access to ${Z.domain}?`:`Revoke inbound trusted A2A access from ${Z.domain}?`,preview:U?`This will grant inbound trusted A2A access to ${Z.domain} and pin key fingerprint ${W}. It will not add or remove the directory contact.`:`This will revoke inbound trusted A2A access from ${Z.domain}. The directory contact remains saved for outbound calls.`,args:K}}}}var bCw=f.object({}).strict();class _AA extends Kw{fetchFn;constructor(A){super("agent",rE,{},bCw);this.fetchFn=A}async getTools(){return[d52(this.getContext(),this.fetchFn),o52(this.getContext(),this.fetchFn)]}}function NAA(){return new _AA}fA();fA();C0();var OM=f.object({name:f.string(),description:f.string(),tags:f.array(f.string()),examples:f.array(f.string())}),s52=OM,Na=l8.extend({entityType:f.literal(rB),metadata:s52});fA();class oE extends d2{constructor(){super({entityType:rB,purpose:"A capability advertised by a remote agent.",schema:Na,frontmatterSchema:OM})}fromMarkdown(A){let Q=this.parseFrontMatter(A,OM);return{content:A,entityType:rB,metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}fA();C0();var LCw=f.object({skills:f.array(OM).max(8)}),a52=e1({name:"skill:skill-derivation",description:"Derive skills from topic titles and brain capabilities",dataSourceId:"shell:ai-content",schema:LCw,useKnowledgeContext:!0,basePrompt:`You are analyzing a brain's content to identify its high-level capabilities.
9872
+ `)}function nhw(A){let Q=A.record.brain.did,w=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},...w&&{anchorDid:w},cardUri:A.uri,cardCid:A.cid}}async function rhw(A,Q,w){await A.messaging.send({type:Q,payload:w,broadcast:!0})}async function ohw(A,Q,w=new Date().toISOString()){let{record:$}=Q,B=ihw($.siteUrl),X=await A.entityService.getEntity({entityType:"agent",id:B}),Y=X?E52.parseEntity(X):void 0,Z=$.brain.did,H=$.anchor.did,W=phw($),K=X?.metadata.status??"discovered",U=X?.metadata.url??$.siteUrl,G=X?.metadata.slug??xx(U),q=X?.metadata.name??$.anchor.name,V=Y?.frontmatter.kind??$.anchor.kind,I=X?.metadata.discoveredAt??w,J=$.brain.purpose.length>0?$.brain.purpose:Y?.body.about??"",k=W.length>0?W:Y?.body.skills??[],j={...X?.metadata??{},name:q,url:U,status:K,discoveredAt:I,slug:G,repoDid:Q.repoDid,...Z&&{brainDid:Z},...H&&{anchorDid:H},cardUri:Q.uri,cardCid:Q.cid},_=E52.createAgentContent({name:q,kind:V,...Y?.frontmatter.organization&&{organization:Y.frontmatter.organization},brainName:$.brain.name,url:U,...Z&&{did:Z,brainDid:Z},...H&&{anchorDid:H},repoDid:Q.repoDid,cardUri:Q.uri,cardCid:Q.cid,...Y?.frontmatter.a2aEndpoint&&{a2aEndpoint:Y.frontmatter.a2aEndpoint},status:K,discoveredAt:I,about:J,skills:k,notes:dhw({repoDid:Q.repoDid,uri:Q.uri,cid:Q.cid})});if(X){let v={...X,content:_,metadata:j,updated:w};return await A.entityService.updateEntity({entity:v}),{agent:v,created:!1}}let x={id:B,entityType:"agent",content:_,metadata:j,contentHash:"",visibility:"public",created:w,updated:w};return await A.entityService.createEntity({entity:x}),{agent:x,created:!0}}function T52(A){A.messaging.subscribe(Hr,async(Q)=>{let w=cp0.parse(Q.payload),$=await ohw(A,w),B=nhw({agent:$.agent,repoDid:w.repoDid,uri:w.uri,cid:w.cid,record:w.record});return await rhw(A,$.created?mp0:up0,B),{success:!0,data:B}})}function S52(){return["Agent entities are saved peer contacts. List them with system_list on entityType agent.","For an expertise match or recommendation, immediately run one system_search scoped to entityType agent using the requested topic. Suggest only clear matches, naming the contact and exact callable id/domain with brief supporting evidence. Prefer approved contacts; label discovered contacts as unverified. If none qualifies, say \u201CI couldn't find a clear match in your saved agent network for <topic>\u201D rather than suggesting a generic role. A short affirmative reply to an offer to search means run that search using the prior topic.","Route contact changes by intent: agent_connect verifies and saves a new domain/URL as an approved outbound contact; system_update changes the lifecycle status of an existing contact; agent_set_trust_level is the only tool for granting or revoking inbound A2A trust. Revocation uses level public and needs no key fingerprint or preliminary entity lookup.","If agent_call cannot reach an unsaved exact domain, offer to connect it; a short affirmative follow-up should call agent_connect for that domain. Only approved contacts can be called.","To call a contact named by person, anchor, or display name, first resolve it with one system_search scoped to entityType agent, then call agent_call with the returned entity id/domain\u2014not the display, anchor, or brain name. Skip search only when the user supplied an exact domain-like id."].join(" ")}p$();C0();import{jsxDEV as m52}from"preact/jsx-dev-runtime";function WW0(A){try{return new URL(A).hostname}catch{return A}}var KW0=({name:A,className:Q=""})=>{let w=A.charAt(0).toUpperCase(),$=0;for(let X=0;X<A.length;X++)$=A.charCodeAt(X)+(($<<5)-$);let B=Math.abs($)%360;return m52("div",{className:`flex items-center justify-center rounded-full text-white font-bold flex-shrink-0 ${Q}`,style:{backgroundColor:`hsl(${B}, 55%, 45%)`},children:w},void 0,!1,void 0,this)},UW0=({kind:A,size:Q="md"})=>{let $={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 m52("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]"} ${$}`,children:A},void 0,!1,void 0,this)};import{jsxDEV as e2,Fragment as thw}from"preact/jsx-dev-runtime";var shw=({skills:A})=>{if(A.length===0)return null;return e2("div",{className:"flex gap-1.5 flex-wrap mt-2",children:A.map((Q)=>e2("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 ahw(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric"})}function u52(A,Q,w){let $=new URLSearchParams({status:Q});if(w>1)$.set("page",String(w));return`${A}?${$.toString()}`}var FAA=({agent:A})=>{let{frontmatter:Q,about:w,skills:$,url:B}=A,X=Q.status==="approved";return e2("a",{href:B,className:`flex items-start gap-5 p-6 rounded-xl border border-theme bg-theme-subtle hover:shadow-lg transition-shadow ${X?"":"opacity-70"}`,children:[e2(KW0,{name:Q.name,className:"w-12 h-12 text-lg"},void 0,!1,void 0,this),e2("div",{className:"flex-1 min-w-0",children:[e2("div",{className:"flex items-center gap-2 mb-1 flex-wrap",children:[e2("span",{className:"text-lg font-semibold text-heading",children:Q.name},void 0,!1,void 0,this),e2(UW0,{kind:Q.kind,size:"sm"},void 0,!1,void 0,this),Q.organization&&e2("span",{className:"text-xs text-theme-muted",children:["\xB7 ",Q.organization]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),e2("div",{className:"text-sm text-theme-muted mb-1",children:Q.brainName},void 0,!1,void 0,this),w&&e2("p",{className:"text-sm text-theme-muted line-clamp-2 mb-0",children:w},void 0,!1,void 0,this),X&&e2(shw,{skills:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this),e2("div",{className:"flex flex-col items-end gap-1 flex-shrink-0 text-right",children:[e2("span",{className:"text-xs text-theme-muted",children:WW0(Q.url)},void 0,!1,void 0,this),e2("span",{className:"text-[11px] text-theme-muted opacity-60",children:X?`Discovered ${ahw(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)},c52=({agents:A,pageTitle:Q,pagination:w,baseUrl:$="/agents",selectedStatus:B})=>{let X=Q??"Agent Directory",Y=w?.totalItems??A.length,Z=A.filter((G)=>G.frontmatter.status==="approved"),H=A.filter((G)=>G.frontmatter.status==="discovered"),W=Z.length,K=H.length,U=`Your network of ${Y} ${Y===1?"brain":"brains"} and their anchors`;return e2(thw,{children:[e2($w,{title:X,description:U},void 0,!1,void 0,this),e2("div",{className:"agent-list bg-theme",children:e2("div",{className:"container mx-auto px-6 md:px-12 max-w-5xl py-16 md:py-24",children:[e2("div",{className:"mb-8 pb-6 border-b border-theme",children:[e2("h1",{className:"text-4xl font-bold text-heading mb-2",children:X},void 0,!1,void 0,this),e2("p",{className:"text-theme-muted mb-4",children:U},void 0,!1,void 0,this),e2("div",{className:"flex flex-wrap gap-2 text-sm mb-4",children:[e2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-heading",children:[Y," total"]},void 0,!0,void 0,this),e2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-status-success",children:[W," approved"]},void 0,!0,void 0,this),e2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-theme-muted",children:[K," discovered"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),e2("div",{className:"flex flex-wrap gap-2 text-sm",children:[e2("a",{href:$,className:`px-3 py-1 rounded-full border transition-colors ${B==="all"?"border-theme text-heading bg-theme-subtle":"border-theme text-theme-muted hover:text-heading"}`,children:"All"},void 0,!1,void 0,this),e2("a",{href:`${$}?status=approved`,className:`px-3 py-1 rounded-full border transition-colors ${B==="approved"?"border-theme text-heading bg-theme-subtle":"border-theme text-theme-muted hover:text-heading"}`,children:"Approved"},void 0,!1,void 0,this),e2("a",{href:`${$}?status=discovered`,className:`px-3 py-1 rounded-full border transition-colors ${B==="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),B==="all"&&Z.length>0&&e2("section",{className:"mb-10",children:[e2("div",{className:"flex items-center justify-between mb-4",children:[e2("h2",{className:"text-lg font-semibold text-heading",children:"Approved brains"},void 0,!1,void 0,this),e2("span",{className:"text-sm text-theme-muted",children:Z.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),e2("div",{className:"flex flex-col gap-4",children:Z.map((G)=>e2(FAA,{agent:G},G.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),B==="all"&&H.length>0&&e2("section",{children:[e2("div",{className:"flex items-center justify-between mb-4",children:[e2("div",{children:[e2("h2",{className:"text-lg font-semibold text-heading",children:"Discovered brains"},void 0,!1,void 0,this),e2("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),e2("span",{className:"text-sm text-theme-muted",children:H.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),e2("div",{className:"flex flex-col gap-4",children:H.map((G)=>e2(FAA,{agent:G},G.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),B!=="all"&&A.length>0&&e2("section",{children:[e2("div",{className:"flex items-center justify-between mb-4",children:[e2("h2",{className:"text-lg font-semibold text-heading",children:B==="approved"?"Approved brains":"Discovered brains"},void 0,!1,void 0,this),e2("span",{className:"text-sm text-theme-muted",children:A.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),e2("div",{className:"flex flex-col gap-4",children:A.map((G)=>e2(FAA,{agent:G},G.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.length===0&&e2("p",{className:"text-center text-theme-muted py-16",children:"No agents in your directory yet."},void 0,!1,void 0,this),w&&w.totalPages>1&&B==="all"&&e2("div",{className:"mt-12",children:e2(CV,{currentPage:w.currentPage,totalPages:w.totalPages,baseUrl:$},void 0,!1,void 0,this)},void 0,!1,void 0,this),w&&w.totalPages>1&&B!=="all"&&e2("nav",{"aria-label":"Pagination",className:"flex items-center justify-center gap-3 mt-12",children:[w.hasPrevPage?e2("a",{href:u52($,B,w.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):e2("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),e2("span",{className:"text-sm text-theme-muted",children:["Page ",w.currentPage," of ",w.totalPages]},void 0,!0,void 0,this),w.hasNextPage?e2("a",{href:u52($,B,w.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):e2("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 E2,Fragment as wCw}from"preact/jsx-dev-runtime";function ehw(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"})}var _a=({children:A})=>E2("h2",{className:"text-sm font-semibold text-theme-muted uppercase tracking-wide mb-3",children:A},void 0,!1,void 0,this),ACw=({skill:A})=>E2("div",{className:"flex items-start gap-3 px-4 py-3 bg-theme-subtle rounded-lg",children:[E2("div",{className:"flex-1",children:[E2("div",{className:"text-sm font-semibold text-heading",children:A.name},void 0,!1,void 0,this),E2("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&&E2("div",{className:"flex gap-1 flex-shrink-0",children:A.tags.map((Q)=>E2("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),QCw=({label:A,value:Q,valueClassName:w})=>E2("div",{className:"flex justify-between text-[13px]",children:[E2("span",{className:"text-theme-muted",children:A},void 0,!1,void 0,this),E2("span",{className:w??"text-heading",children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this),l52=({agent:A,prevAgent:Q,nextAgent:w})=>{let{frontmatter:$,about:B,skills:X,notes:Y}=A,Z=WW0($.url),H=$.status==="approved";return E2(wCw,{children:[E2($w,{title:$.name,description:B||`Agent profile for ${$.name}`},void 0,!1,void 0,this),E2("article",{className:"agent-detail",children:E2("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:[E2("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),E2("div",{className:"flex items-start gap-6 mb-8",children:[E2(KW0,{name:$.name,className:"w-[72px] h-[72px] text-3xl"},void 0,!1,void 0,this),E2("div",{children:[E2("div",{className:"flex items-center gap-3 mb-1",children:[E2("h1",{className:"text-3xl md:text-4xl font-bold text-heading",children:$.name},void 0,!1,void 0,this),E2(UW0,{kind:$.kind},void 0,!1,void 0,this)]},void 0,!0,void 0,this),E2("div",{className:"text-base text-theme-muted mb-2",children:$.brainName},void 0,!1,void 0,this),E2("div",{className:"flex items-center gap-3 text-theme-muted",children:[$.organization&&E2("span",{className:"text-[15px]",children:$.organization},void 0,!1,void 0,this),$.organization&&E2("span",{className:"text-theme-muted opacity-40",children:"\xB7"},void 0,!1,void 0,this),E2("span",{className:"text-sm",children:["Discovered ",ehw($.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),E2("div",{className:"border-b border-theme mb-8"},void 0,!1,void 0,this),!H&&E2("div",{className:"mb-8 rounded-xl border border-theme bg-theme-subtle px-5 py-4",children:[E2("div",{className:"text-sm font-semibold text-heading mb-1",children:"Saved for review"},void 0,!1,void 0,this),E2("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),E2("div",{className:"flex flex-col md:flex-row gap-12",children:[E2("div",{className:"flex-[2] min-w-0",children:[B&&E2("section",{className:"mb-8",children:[E2(_a,{children:"About"},void 0,!1,void 0,this),E2("p",{className:"text-[15px] text-theme leading-relaxed",children:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this),X.length>0&&E2("section",{className:"mb-8",children:[E2(_a,{children:"Skills"},void 0,!1,void 0,this),E2("div",{className:"flex flex-col gap-2.5",children:X.map((W)=>E2(ACw,{skill:W},W.name,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Y&&E2("section",{className:"mb-8",children:[E2(_a,{children:"Notes"},void 0,!1,void 0,this),E2("p",{className:"text-[15px] text-theme leading-relaxed",children:Y},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),E2("aside",{className:"flex-1 md:pl-8 md:border-l border-theme-muted/20",children:[E2("section",{className:"mb-8",children:[E2(_a,{children:"Brain"},void 0,!1,void 0,this),E2("div",{className:"p-4 bg-theme-subtle rounded-xl",children:[E2("div",{className:"text-[15px] font-semibold text-heading mb-1",children:$.brainName},void 0,!1,void 0,this),$.did&&E2("div",{className:"text-xs text-theme-muted font-mono",children:$.did},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),E2("section",{className:"mb-8",children:[E2(_a,{children:"Connection"},void 0,!1,void 0,this),E2("div",{className:"flex flex-col gap-3",children:[E2("div",{children:[E2("div",{className:"text-[13px] text-theme-muted mb-0.5",children:"Endpoint"},void 0,!1,void 0,this),E2("div",{className:"text-xs text-heading font-mono",children:$.url},void 0,!1,void 0,this)]},void 0,!0,void 0,this),E2(QCw,{label:"Status",value:$.status==="approved"?"Approved":"Discovered",valueClassName:$.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),E2("a",{href:$.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 ",Z," \u2197"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),(Q??w)&&E2("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:[E2("div",{className:"min-h-[1px]",children:Q&&E2("a",{href:Q.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[E2("span",{children:"\u2190 Previous"},void 0,!1,void 0,this),E2("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),E2("div",{className:"min-h-[1px] md:text-right",children:w&&E2("a",{href:w.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[E2("span",{children:"Next \u2192"},void 0,!1,void 0,this),E2("span",{className:"text-heading font-medium",children:w.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 $Cw=f.union([f.enum(["public","shared","restricted"]),f.literal("private")]).optional().transform((A)=>{if(A===void 0)return"public";if(A==="private")return"restricted";return A}),BCw=f.object({currentPage:f.number(),totalPages:f.number(),totalItems:f.number(),pageSize:f.number(),hasNextPage:f.boolean(),hasPrevPage:f.boolean()}),XCw=f.object({name:f.string(),description:f.string(),tags:f.array(f.string())}),bAA=f.enum(["discovered","approved"]),YCw=f.enum(["professional","team","collective"]),ZCw=f.object({name:f.string(),kind:YCw,organization:f.string().optional(),brainName:f.string(),url:f.url(),did:f.string().optional(),repoDid:f.string().optional(),brainDid:f.string().optional(),anchorDid:f.string().optional(),cardUri:f.string().optional(),cardCid:f.string().optional(),a2aEndpoint:f.url().optional(),status:bAA,discoveredAt:f.string()}),fCw=f.object({name:f.string(),url:f.url(),status:bAA,discoveredAt:f.string().optional(),slug:f.string(),repoDid:f.string().optional(),brainDid:f.string().optional(),anchorDid:f.string().optional(),cardUri:f.string().optional(),cardCid:f.string().optional(),a2aEndpoint:f.url().optional()}),GW0=f.object({id:f.string(),entityType:f.literal(BB),content:f.string(),created:f.string(),updated:f.string(),visibility:$Cw,metadata:fCw,contentHash:f.string(),frontmatter:ZCw,about:f.string(),skills:f.array(XCw),notes:f.string(),url:f.string().optional(),typeLabel:f.string().optional()}),HCw=f.object({agents:f.array(GW0),pageTitle:f.string().optional(),pagination:BCw.nullable(),baseUrl:f.string().optional(),selectedStatus:f.union([f.literal("all"),bAA])});function p52(){return{[qAA]:e1({name:qAA,description:"Agent directory list page template",schema:HCw,dataSourceId:Fa,requiredPermission:"public",layout:{component:c52}}),[zAA]:e1({name:zAA,description:"Individual agent profile template",schema:f.object({agent:GW0,prevAgent:GW0.nullable(),nextAgent:GW0.nullable()}),dataSourceId:Fa,requiredPermission:"public",layout:{component:l52}})}}var rE={name:"@brains/agent-discovery",version:"0.2.0-alpha.159",description:"Agent discovery \u2014 brain+anchor contacts and skills",dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/auth-service":"workspace:*","@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/dashboard":"workspace:*","@brains/http-signatures":"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":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var KCw=new DX;class LAA extends Zw{entityType=BB;schema=ba;adapter=KCw;constructor(){super(G52,rE,{},i7)}createGenerationHandler(A){return new VAA(this.logger.child("AgentGenerationJobHandler"),A)}getTemplates(){return p52()}getDataSources(){return[new XW0(this.logger.child("AgentDataSource"))]}async onRegister(A){T52(A),y52(A,this.id)}async getInstructions(){return S52()}}function kAA(){return new LAA}fA();C0();j9();C0();var i52=f.object({source:f.object({kind:f.literal("url"),url:f.string().min(1).describe("Remote agent domain or URL to verify and connect. Preserve bare domains as bare domains.")}),confirmed:f.boolean().optional(),confirmationToken:f.string().optional()}),UCw=new DX;function GCw(A){let Q=MM(A);if(!Q)return null;return{domain:Q,fetchTarget:A.trim().startsWith("http")?A.trim():Q}}function DCw(A,Q){return(MM(Q)||A).toLowerCase()}async function qCw(A){let{context:Q,entityId:w,card:$}=A,B=new Date().toISOString(),X=await Q.entityService.getEntity({entityType:BB,id:w}),Y=ZW0($,{status:"approved"}),H={...UCw.fromMarkdown(Y.content).metadata,...Y.metadata,a2aEndpoint:$.url};if(X){let K={...X,content:Y.content,metadata:H,updated:B};return await Q.entityService.updateEntity({entity:K}),{entity:K,created:!1}}let W={id:w,entityType:BB,content:Y.content,metadata:H,contentHash:"",visibility:"public",created:B,updated:B};return await Q.entityService.createEntity({entity:W}),{entity:W,created:!0}}function d52(A,Q=globalThis.fetch){let $=new Zf;return{name:"agent_connect",description:"Verify and connect a remote A2A agent by fetching its Agent Card from /.well-known/agent-card.json, then save the verified contact in the local agent directory as approved for future outbound calls. This adds a directory contact; it does not message the remote agent or grant it inbound trusted access. Requires confirmation before verification and persistence. Call this tool without confirmed on the initial request; the tool returns confirmation args for the user to approve.",inputSchema:i52.shape,visibility:"trusted",sideEffects:"external",handler:async(B,X)=>{let Y=i52.safeParse(B);if(!Y.success)return{success:!1,error:`Invalid input: ${Y.error.issues.map((K)=>`${K.path.join(".")}: ${K.message}`).join(", ")}`};let Z=Y.data,H=GCw(Z.source.url);if(!H)return{success:!1,error:"Provide a valid remote agent domain or URL to connect.",code:"invalid_agent_url"};try{A.permissions.assertEntityActionAllowed(BB,"create",X)}catch(K){return{success:!1,error:K instanceof Error?K.message:String(K)}}if(Z.confirmed){let K=Z.confirmationToken,U=$.validate(K,Z);if(U.status==="missing")return{success:!1,error:"No pending agent connection confirmation found. Please request connection again and confirm the new approval."};if(U.status==="mismatch")return{success:!1,error:"Confirmed agent connection arguments do not match the pending approval. Please request connection again and confirm the new approval."};let G=await YW0(H.fetchTarget,Q);if(!G)return{success:!1,error:`Could not verify an A2A Agent Card for ${H.domain}.`,code:"not_an_agent"};let q=DCw(H.domain,G.url),{entity:V,created:I}=await qCw({context:A,entityId:q,sourceUrl:Z.source.url,card:G});return{success:!0,data:{status:V.metadata.status,entityId:V.id,connected:!0,created:I,a2aEndpoint:G.url,skills:G.skills.map((J)=>({name:J.name,description:J.description,tags:J.tags}))}}}let W=$.create((K)=>({source:Z.source,confirmed:!0,confirmationToken:K}));return{needsConfirmation:!0,toolName:"agent_connect",summary:`Verify and connect agent ${H.domain}?`,preview:`This will fetch and validate ${H.domain}'s A2A Agent Card, then save the verified contact as approved for future outbound calls. It will not message the remote agent or grant it inbound trusted access.`,args:W}}}}j9();C0();var zCw=f.enum(["public","trusted"]),n52=f.object({agent:f.string().min(1).describe("Saved agent id, domain, or URL whose inbound A2A trust to set."),level:zCw.describe("Inbound A2A trust level. Use trusted to grant trusted inbound access, public to revoke it."),confirmed:f.boolean().optional(),confirmationToken:f.string().optional(),keyFingerprint:f.string().optional()}),VCw=f.object({keys:f.array(f.unknown())}),JCw=f.object({kty:f.literal("OKP"),crv:f.literal("Ed25519"),x:f.string(),kid:f.string().optional(),alg:f.literal("EdDSA").optional()}).passthrough();function r52(A){return(MM(A)||A.trim()).toLowerCase()}async function ICw(A,Q){let w=r52(Q),$=await A.entityService.getEntity({entityType:BB,id:w});if(!$)return null;let B=r52($.metadata.a2aEndpoint??$.metadata.url);if(!B)return null;return{domain:B}}async function FCw(A,Q){try{let w=await Q(`https://${A}/.well-known/jwks.json`);if(!w.ok)return null;let $=VCw.safeParse(await w.json());if(!$.success)return null;let B=$.data.keys.map((X)=>JCw.safeParse(X)).find((X)=>X.success);if(!B?.success)return null;return hp0(B.data)}catch{return null}}function o52(A,Q=globalThis.fetch){let $=new Zf;return{name:"agent_set_trust_level",description:"Grant or revoke inbound A2A trust for a saved contact; this is the only tool for inbound trust changes. To revoke, call directly with level public\u2014no key fingerprint or preliminary lookup is needed. To grant, use level trusted; the tool resolves and pins the peer key. This does not add or remove directory contacts or change outbound calling. Requires confirmation.",inputSchema:n52.shape,visibility:"anchor",sideEffects:"external",handler:async(B)=>{let X=n52.safeParse(B);if(!X.success)return{success:!1,error:`Invalid input: ${X.error.issues.map((G)=>`${G.path.join(".")}: ${G.message}`).join(", ")}`};let Y=s7();if(!Y)return{success:!1,error:"Auth service is required to set inbound A2A trust.",code:"auth_service_unavailable"};let Z=await ICw(A,X.data.agent);if(!Z)return{success:!1,error:`No saved agent contact found for ${X.data.agent}. Connect the agent before setting inbound trust.`,code:"agent_not_found"};let H=X.data;if(H.confirmed){let G=$.validate(H.confirmationToken,H);if(G.status==="missing")return{success:!1,error:"No pending agent trust confirmation found. Please request the trust change again and confirm the new approval."};if(G.status==="mismatch")return{success:!1,error:"Confirmed agent trust arguments do not match the pending approval. Please request the trust change again and confirm the new approval."};if(H.level==="trusted"){if(!H.keyFingerprint)return{success:!1,error:"Missing key fingerprint for trusted A2A grant."};let q=await Y.grantA2APeerTrust({domain:Z.domain,keyFingerprint:H.keyFingerprint,grantedLevel:"trusted"});return{success:!0,data:{agent:Z.domain,level:q.grantedLevel,keyFingerprint:q.keyFingerprint}}}return await Y.revokeA2APeerTrust(Z.domain),{success:!0,data:{agent:Z.domain,level:"public"}}}let W=H.level==="trusted"?await FCw(Z.domain,Q):void 0;if(H.level==="trusted"&&!W)return{success:!1,error:`Could not fetch an A2A signing key from ${Z.domain}.`,code:"jwks_unavailable"};let K=$.create((G)=>({agent:Z.domain,level:H.level,confirmed:!0,confirmationToken:G,...W?{keyFingerprint:W}:{}})),U=H.level==="trusted";return{needsConfirmation:!0,toolName:"agent_set_trust_level",summary:U?`Grant inbound trusted A2A access to ${Z.domain}?`:`Revoke inbound trusted A2A access from ${Z.domain}?`,preview:U?`This will grant inbound trusted A2A access to ${Z.domain} and pin key fingerprint ${W}. It will not add or remove the directory contact.`:`This will revoke inbound trusted A2A access from ${Z.domain}. The directory contact remains saved for outbound calls.`,args:K}}}}var bCw=f.object({}).strict();class _AA extends Kw{fetchFn;constructor(A){super("agent",rE,{},bCw);this.fetchFn=A}async getTools(){return[d52(this.getContext(),this.fetchFn),o52(this.getContext(),this.fetchFn)]}}function NAA(){return new _AA}fA();fA();C0();var OM=f.object({name:f.string(),description:f.string(),tags:f.array(f.string()),examples:f.array(f.string())}),s52=OM,Na=l8.extend({entityType:f.literal(rB),metadata:s52});fA();class oE extends d2{constructor(){super({entityType:rB,purpose:"A capability advertised by a remote agent.",schema:Na,frontmatterSchema:OM})}fromMarkdown(A){let Q=this.parseFrontMatter(A,OM);return{content:A,entityType:rB,metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}fA();C0();var LCw=f.object({skills:f.array(OM).max(8)}),a52=e1({name:"skill:skill-derivation",description:"Derive skills from topic titles and brain capabilities",dataSourceId:"shell:ai-content",schema:LCw,useKnowledgeContext:!0,basePrompt:`You are analyzing a brain's content to identify its high-level capabilities.
9873
9873
 
9874
9874
  Given knowledge domains, CONSOLIDATE related topics into broader skills.
9875
9875
  There should be FEWER skills than topics \u2014 combine related domains.
@@ -10019,9 +10019,9 @@ Context:
10019
10019
  ${JSON.stringify($,null,2)}
10020
10020
 
10021
10021
  Draft SWOT:
10022
- ${JSON.stringify(w,null,2)}`}function bW0(A){return A.map((Q)=>Q.detail===null?{title:Q.title}:{title:Q.title,detail:Q.detail})}function dCw(A,Q){let w=["strengths","weaknesses","opportunities","threats"];for(let $ of w){let B=new Set(A[$].map((X)=>X.theme.trim().toLowerCase()));for(let X of Q[$]){let Y=X.sourceTheme.trim().toLowerCase();if(!B.has(Y))throw Error(`SWOT refinement invented theme "${X.sourceTheme}" in ${$}`)}}}class LW0{logger;context;adapter=new $J;constructor(A,Q){this.logger=A,this.context=Q}validateAndParse(A){let Q=MAA.safeParse(A??{});return Q.success?Q.data:null}async process(A,Q,w){await w.report({progress:0.2,message:"Building SWOT context"});let $=await hAA(this.context),B;if($.summary.brainSkillCount+$.summary.approvedAgentCount+$.summary.discoveredAgentCount===0)B={strengths:[],weaknesses:[],opportunities:[],threats:[]};else{await w.report({progress:0.6,message:"Synthesizing SWOT analysis"});let{object:W}=await this.context.ai.generateObject(await lCw(this.context,$),OAA),K=OAA.parse(W);await w.report({progress:0.75,message:"Refining SWOT language"});let U=await this.context.ai.generateObject(await iCw(this.context,$,K),JW0);B=JW0.parse(U.object),dCw(K,B)}let Y=new Date().toISOString(),Z=this.adapter.createSwotContent({strengths:bW0(B.strengths),weaknesses:bW0(B.weaknesses),opportunities:bW0(B.opportunities),threats:bW0(B.threats),derivedAt:Y});await w.report({progress:0.9,message:"Saving SWOT entity"});let H=await this.context.entityService.getEntity({entityType:"swot",id:"swot"});if(H)await this.context.entityService.updateEntity({entity:{...H,content:Z,metadata:{derivedAt:Y}}});else await this.context.entityService.createEntity({entity:{id:"swot",entityType:"swot",content:Z,metadata:{derivedAt:Y}}});return this.logger.info("SWOT derivation complete",{derivedAt:Y,brainSkillCount:$.summary.brainSkillCount,approvedAgentCount:$.summary.approvedAgentCount,discoveredAgentCount:$.summary.discoveredAgentCount}),{entityId:"swot"}}}C0();import{jsxDEV as qX}from"preact/jsx-dev-runtime";var kW0=f.object({title:f.string(),detail:f.string().optional()}),nCw=f.discriminatedUnion("status",[f.object({status:f.literal("generating")}),f.object({status:f.literal("ready"),strengths:f.array(kW0).default([]),weaknesses:f.array(kW0).default([]),opportunities:f.array(kW0).default([]),threats:f.array(kW0).default([]),derivedAt:f.string()})]);function rCw({items:A}){if(A.length===0)return qX("p",{class:"swot-empty",children:"\u2014"},void 0,!1,void 0,this);return qX("ul",{class:"swot-list",children:A.map((Q)=>qX("li",{class:"swot-item",children:[qX("b",{children:Q.title},void 0,!1,void 0,this),Q.detail?qX("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 _W0({title:A,tone:Q,items:w}){return qX("section",{class:`swot-cell is-${Q}`,children:[qX("div",{class:"swot-head",children:A},void 0,!1,void 0,this),qX(rCw,{items:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function yAA({data:A}){let Q=nCw.safeParse(A);if(!Q.success||Q.data.status==="generating")return qX("div",{"data-swot-widget":!0,children:qX("p",{class:"muted",children:"generating assessment\u2026"},void 0,!1,void 0,this)},void 0,!1,void 0,this);let w=Q.data;return qX("div",{"data-swot-widget":!0,children:qX("div",{class:"swot",role:"grid","aria-label":"SWOT analysis of agent network",children:[qX(_W0,{title:"Strengths",tone:"s",items:w.strengths},void 0,!1,void 0,this),qX(_W0,{title:"Weaknesses",tone:"w",items:w.weaknesses},void 0,!1,void 0,this),qX(_W0,{title:"Opportunities",tone:"o",items:w.opportunities},void 0,!1,void 0,this),qX(_W0,{title:"Threats",tone:"t",items:w.threats},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)}var EAA={name:"@brains/assessment",version:"0.2.0-alpha.158",description:"Assessment outputs and capability-profile analysis",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":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{eval:"cd evals && bun run brain-eval",lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var sCw=f.object({status:f.enum(["ready","generating"])}),TAA=new $J;class SAA extends Zw{entityType="swot";schema=sE;adapter=TAA;initialSyncComplete=!1;constructor(){super("swot",EAA,{},i7)}async onRegister(A){let Q=new LW0(this.logger.child("SwotDerivationHandler"),A);A.jobs.registerHandler("derive",Q),A.eval.registerHandler("deriveSwot",async()=>{let X=hX.from(async()=>{});if(!X)throw Error("Expected progress reporter to be created");await Q.process({reason:"eval"},"eval-swot-derive",X);let Y=await A.entityService.getEntity({entityType:"swot",id:"swot"});if(!Y)throw Error("Expected SWOT entity to be created during eval");return TAA.parseSwotContent(Y.content).frontmatter});let w=async(X)=>{try{return await A.jobs.enqueue({type:"derive",data:{reason:X},options:{source:this.id,priority:10,deduplication:"coalesce",deduplicationKey:"swot",metadata:{operationType:"data_processing",operationTarget:`swot:${X}`}}})}catch(Y){return this.logger.error("Failed to queue SWOT derivation",{error:Y,reason:X}),null}},$=async(X)=>{if(!await A.entityService.getEntity({entityType:"swot",id:"swot"}))await w(X)};A.messaging.subscribe("sync:initial:completed",async()=>{return this.initialSyncComplete=!0,await $("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",group:"network",section:"secondary",priority:14,rendererName:"SwotWidget",digestProvider:(X)=>{let{status:Y}=sCw.parse(X);return{digest:[{label:"SWOT",value:Y==="ready"?"Ready":"Generating",tone:Y==="ready"?"good":"warn"}]}},component:yAA,dataProvider:async()=>{let X=await A.entityService.getEntity({entityType:"swot",id:"swot"});if(!X)return{status:"generating"};let{frontmatter:Y}=TAA.parseSwotContent(X.content);return{status:"ready",...Y}}}}),{success:!0}});let B=async(X)=>{let{entityType:Y}=X.payload;if(!this.initialSyncComplete)return{success:!0};if(Y!=="agent"&&Y!=="skill")return{success:!0};return await w("entity-change"),{success:!0}};A.messaging.subscribe("entity:created",B),A.messaging.subscribe("entity:updated",B),A.messaging.subscribe("entity:deleted",B)}}function mAA(){return new SAA}fA();b9();C0();var hS8=new $J,K92=f.object({name:f.string(),description:f.string(),tags:f.array(f.string())}),U92=f.enum(["discovered","approved"]),aCw=f.object({name:f.string(),kind:f.enum(["professional","team","collective"]),organization:f.string().optional(),brainName:f.string(),url:f.string().url(),did:f.string().optional(),status:U92,discoveredAt:f.string().datetime()}),tCw=l8.extend({entityType:f.literal("agent"),metadata:f.object({name:f.string(),url:f.string().url(),status:U92,slug:f.string()})}),uAA=f.object({name:f.string(),description:f.string(),tags:f.array(f.string()),examples:f.array(f.string())}),eCw=l8.extend({entityType:f.literal("skill"),metadata:uAA}),Agw=f.object({about:f.string(),skills:f.array(K92),notes:f.string()});function Qgw(A){if(!Array.isArray(A)||A.length===0)return"";return A.map((w)=>{let $=w.tags.length>0?` [${w.tags.join(", ")}]`:"";return`- ${w.name}: ${w.description}${$}`}).join(`
10022
+ ${JSON.stringify(w,null,2)}`}function bW0(A){return A.map((Q)=>Q.detail===null?{title:Q.title}:{title:Q.title,detail:Q.detail})}function dCw(A,Q){let w=["strengths","weaknesses","opportunities","threats"];for(let $ of w){let B=new Set(A[$].map((X)=>X.theme.trim().toLowerCase()));for(let X of Q[$]){let Y=X.sourceTheme.trim().toLowerCase();if(!B.has(Y))throw Error(`SWOT refinement invented theme "${X.sourceTheme}" in ${$}`)}}}class LW0{logger;context;adapter=new $J;constructor(A,Q){this.logger=A,this.context=Q}validateAndParse(A){let Q=MAA.safeParse(A??{});return Q.success?Q.data:null}async process(A,Q,w){await w.report({progress:0.2,message:"Building SWOT context"});let $=await hAA(this.context),B;if($.summary.brainSkillCount+$.summary.approvedAgentCount+$.summary.discoveredAgentCount===0)B={strengths:[],weaknesses:[],opportunities:[],threats:[]};else{await w.report({progress:0.6,message:"Synthesizing SWOT analysis"});let{object:W}=await this.context.ai.generateObject(await lCw(this.context,$),OAA),K=OAA.parse(W);await w.report({progress:0.75,message:"Refining SWOT language"});let U=await this.context.ai.generateObject(await iCw(this.context,$,K),JW0);B=JW0.parse(U.object),dCw(K,B)}let Y=new Date().toISOString(),Z=this.adapter.createSwotContent({strengths:bW0(B.strengths),weaknesses:bW0(B.weaknesses),opportunities:bW0(B.opportunities),threats:bW0(B.threats),derivedAt:Y});await w.report({progress:0.9,message:"Saving SWOT entity"});let H=await this.context.entityService.getEntity({entityType:"swot",id:"swot"});if(H)await this.context.entityService.updateEntity({entity:{...H,content:Z,metadata:{derivedAt:Y}}});else await this.context.entityService.createEntity({entity:{id:"swot",entityType:"swot",content:Z,metadata:{derivedAt:Y}}});return this.logger.info("SWOT derivation complete",{derivedAt:Y,brainSkillCount:$.summary.brainSkillCount,approvedAgentCount:$.summary.approvedAgentCount,discoveredAgentCount:$.summary.discoveredAgentCount}),{entityId:"swot"}}}C0();import{jsxDEV as qX}from"preact/jsx-dev-runtime";var kW0=f.object({title:f.string(),detail:f.string().optional()}),nCw=f.discriminatedUnion("status",[f.object({status:f.literal("generating")}),f.object({status:f.literal("ready"),strengths:f.array(kW0).default([]),weaknesses:f.array(kW0).default([]),opportunities:f.array(kW0).default([]),threats:f.array(kW0).default([]),derivedAt:f.string()})]);function rCw({items:A}){if(A.length===0)return qX("p",{class:"swot-empty",children:"\u2014"},void 0,!1,void 0,this);return qX("ul",{class:"swot-list",children:A.map((Q)=>qX("li",{class:"swot-item",children:[qX("b",{children:Q.title},void 0,!1,void 0,this),Q.detail?qX("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 _W0({title:A,tone:Q,items:w}){return qX("section",{class:`swot-cell is-${Q}`,children:[qX("div",{class:"swot-head",children:A},void 0,!1,void 0,this),qX(rCw,{items:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function yAA({data:A}){let Q=nCw.safeParse(A);if(!Q.success||Q.data.status==="generating")return qX("div",{"data-swot-widget":!0,children:qX("p",{class:"muted",children:"generating assessment\u2026"},void 0,!1,void 0,this)},void 0,!1,void 0,this);let w=Q.data;return qX("div",{"data-swot-widget":!0,children:qX("div",{class:"swot",role:"grid","aria-label":"SWOT analysis of agent network",children:[qX(_W0,{title:"Strengths",tone:"s",items:w.strengths},void 0,!1,void 0,this),qX(_W0,{title:"Weaknesses",tone:"w",items:w.weaknesses},void 0,!1,void 0,this),qX(_W0,{title:"Opportunities",tone:"o",items:w.opportunities},void 0,!1,void 0,this),qX(_W0,{title:"Threats",tone:"t",items:w.threats},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)}var EAA={name:"@brains/assessment",version:"0.2.0-alpha.159",description:"Assessment outputs and capability-profile analysis",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":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{eval:"cd evals && bun run brain-eval",lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var sCw=f.object({status:f.enum(["ready","generating"])}),TAA=new $J;class SAA extends Zw{entityType="swot";schema=sE;adapter=TAA;initialSyncComplete=!1;constructor(){super("swot",EAA,{},i7)}async onRegister(A){let Q=new LW0(this.logger.child("SwotDerivationHandler"),A);A.jobs.registerHandler("derive",Q),A.eval.registerHandler("deriveSwot",async()=>{let X=hX.from(async()=>{});if(!X)throw Error("Expected progress reporter to be created");await Q.process({reason:"eval"},"eval-swot-derive",X);let Y=await A.entityService.getEntity({entityType:"swot",id:"swot"});if(!Y)throw Error("Expected SWOT entity to be created during eval");return TAA.parseSwotContent(Y.content).frontmatter});let w=async(X)=>{try{return await A.jobs.enqueue({type:"derive",data:{reason:X},options:{source:this.id,priority:10,deduplication:"coalesce",deduplicationKey:"swot",metadata:{operationType:"data_processing",operationTarget:`swot:${X}`}}})}catch(Y){return this.logger.error("Failed to queue SWOT derivation",{error:Y,reason:X}),null}},$=async(X)=>{if(!await A.entityService.getEntity({entityType:"swot",id:"swot"}))await w(X)};A.messaging.subscribe("sync:initial:completed",async()=>{return this.initialSyncComplete=!0,await $("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",group:"network",section:"secondary",priority:14,rendererName:"SwotWidget",digestProvider:(X)=>{let{status:Y}=sCw.parse(X);return{digest:[{label:"SWOT",value:Y==="ready"?"Ready":"Generating",tone:Y==="ready"?"good":"warn"}]}},component:yAA,dataProvider:async()=>{let X=await A.entityService.getEntity({entityType:"swot",id:"swot"});if(!X)return{status:"generating"};let{frontmatter:Y}=TAA.parseSwotContent(X.content);return{status:"ready",...Y}}}}),{success:!0}});let B=async(X)=>{let{entityType:Y}=X.payload;if(!this.initialSyncComplete)return{success:!0};if(Y!=="agent"&&Y!=="skill")return{success:!0};return await w("entity-change"),{success:!0}};A.messaging.subscribe("entity:created",B),A.messaging.subscribe("entity:updated",B),A.messaging.subscribe("entity:deleted",B)}}function mAA(){return new SAA}fA();b9();C0();var hS8=new $J,K92=f.object({name:f.string(),description:f.string(),tags:f.array(f.string())}),U92=f.enum(["discovered","approved"]),aCw=f.object({name:f.string(),kind:f.enum(["professional","team","collective"]),organization:f.string().optional(),brainName:f.string(),url:f.string().url(),did:f.string().optional(),status:U92,discoveredAt:f.string().datetime()}),tCw=l8.extend({entityType:f.literal("agent"),metadata:f.object({name:f.string(),url:f.string().url(),status:U92,slug:f.string()})}),uAA=f.object({name:f.string(),description:f.string(),tags:f.array(f.string()),examples:f.array(f.string())}),eCw=l8.extend({entityType:f.literal("skill"),metadata:uAA}),Agw=f.object({about:f.string(),skills:f.array(K92),notes:f.string()});function Qgw(A){if(!Array.isArray(A)||A.length===0)return"";return A.map((w)=>{let $=w.tags.length>0?` [${w.tags.join(", ")}]`:"";return`- ${w.name}: ${w.description}${$}`}).join(`
10023
10023
  `)}function wgw(A){if(!A.trim())return[];return A.split(`
10024
- `).map((Q)=>Q.match(/^- (.+?): (.+?)(?:\s+\[(.+?)\])?$/)).filter((Q)=>Q!==null).map((Q)=>({name:Q[1]??"",description:Q[2]??"",tags:Q[3]?Q[3].split(",").map((w)=>w.trim()).filter(Boolean):[]}))}var $gw=new R6(Agw,{title:"Agent",mappings:[{key:"about",label:"About",type:"string"},{key:"skills",label:"Skills",type:"custom",formatter:Qgw,parser:wgw},{key:"notes",label:"Notes",type:"string"}]});class G92 extends d2{constructor(){super({entityType:"agent",purpose:"An agent entity used for SWOT evaluation.",schema:tCw,frontmatterSchema:aCw})}fromMarkdown(A){return{content:A,entityType:"agent"}}createAgentContent(A){let Q=$gw.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 D92 extends d2{constructor(){super({entityType:"skill",purpose:"A skill entity used for SWOT evaluation.",schema:eCw,frontmatterSchema:uAA})}fromMarkdown(A){let Q=this.parseFrontMatter(A,uAA);return{content:A,entityType:"skill",metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}var CS8=new G92,gS8=new D92,Bgw=f.object({name:f.string(),description:f.string(),tags:f.array(f.string()),examples:f.array(f.string())}),yS8=f.object({skills:f.array(Bgw),agents:f.array(f.object({id:f.string().optional(),name:f.string(),kind:f.enum(["professional","team","collective"]),organization:f.string().optional(),brainName:f.string(),url:f.url(),did:f.string().optional(),status:f.enum(["discovered","approved"]),discoveredAt:f.string().datetime().optional(),about:f.string(),skills:f.array(K92),notes:f.string().default("")}))});var Xgw=f.object({}).strict();function NW0(A={}){return Xgw.parse(A),[mAA()]}fA();C0();C0();var cAA=f.object({enabled:f.boolean().default(!0),pdsEndpoint:f.url().default("https://bsky.social").describe("AT Protocol PDS service endpoint"),identifier:f.string().optional().describe("PDS login identifier, usually a handle or account DID"),repoDid:f.string().optional().describe("DID of the PDS repo that owns records"),appPassword:f.string().optional().describe("App password for prototype authentication; supply via ${ENV_VAR} interpolation, never a committed literal"),anchorDid:f.string().optional().describe("Optional human/operator DID referenced from records; defaults to did:web:<site-host>:anchor when omitted"),brainDid:f.string().optional().describe("Optional public brain DID referenced from records; defaults to did:web:<site-host> when omitted")});C0();var Ygw=f.looseObject({message:f.string()}),Zgw=f.looseObject({did:f.string(),handle:f.string(),accessJwt:f.string(),refreshJwt:f.string()}),lAA=f.looseObject({uri:f.string(),cid:f.string()}),fgw=lAA.extend({value:f.record(f.string(),f.unknown())}),Hgw=f.looseObject({$type:f.literal("blob").optional(),ref:f.looseObject({$link:f.string()}),mimeType:f.string(),size:f.number().int().nonnegative()}).transform((A)=>({...A.$type!==void 0?{$type:A.$type}:{},ref:{$link:A.ref.$link},mimeType:A.mimeType,size:A.size})),Wgw=f.looseObject({blob:Hgw});function Kgw(A){return A.replace(/\/+$/,"")}var Ugw=(A,Q)=>fetch(A,Q);async function Pa(A,Q){let w=await A.text(),$;try{$=w.length>0?JSON.parse(w):void 0}catch{if(!A.ok)throw Error(`AT Protocol request failed with ${A.status}`);throw Error("Failed to parse JSON")}if(!A.ok){let B=Ygw.safeParse($);throw Error(B.success?B.data.message:`AT Protocol request failed with ${A.status}`)}return Q.parse($)}class Ma{pdsEndpoint;identifier;appPassword;fetchFn;session;constructor(A){this.pdsEndpoint=Kgw(A.pdsEndpoint),this.identifier=A.identifier,this.appPassword=A.appPassword,this.fetchFn=A.fetch??Ugw}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 Pa(A,Zgw);return this.session=Q,Q}async createRecord(A){let Q=await this.getSession(),w=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 Pa(w,lAA)}async putRecord(A){let Q=await this.getSession(),w=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 Pa(w,lAA)}async getRecord(A){let Q=new URLSearchParams({repo:A.repo,collection:A.collection,rkey:A.rkey}),w=await this.fetchFn(`${this.pdsEndpoint}/xrpc/com.atproto.repo.getRecord?${Q.toString()}`,{method:"GET"});return Pa(w,fgw)}async uploadBlob(A){let Q=await this.getSession(),w=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 Pa(w,Wgw)}async getSession(){return this.session??=await this.createSession(),this.session}}function RM(A){return A?.startsWith("did:web:")??!1}function jW0(A){if(!RM(A))return;let Q=A.slice(8);if(!Q)return;let[w]=Q.split(":");if(!w)return;try{return decodeURIComponent(w)}catch{return w}}function z92(A){if(!RM(A))return;let Q=A.slice(8);if(!Q)return;let[,...w]=Q.split(":");if(w.length===0)return"/.well-known/did.json";return`/${w.map((B)=>{try{return decodeURIComponent(B)}catch{return B}}).join("/")}/did.json`}function V92(A){return A.replace(/\/+$/,"")}function Oa(A){return`did:web:${encodeURIComponent(A)}`}function PW0(A){return`${Oa(A)}:anchor`}function pAA(A){return{"@context":["https://www.w3.org/ns/did/v1"],id:A}}function J92(A,Q){let w=A.identifier?.startsWith("did:")?void 0:A.identifier?[`at://${A.identifier}`]:void 0;return{...pAA(Q),...w&&{alsoKnownAs:w},service:[{id:"#atproto_pds",type:"AtprotoPersonalDataServer",serviceEndpoint:V92(A.pdsEndpoint)}]}}function I92(A){if(!RM(A.brainDid))return null;return J92(A,A.brainDid)}function q92(A,Q){if(!A||!Q)return;let w=jW0(A),$=z92(A);if(!w||!$)return;return{path:$,hostname:w,document:Q}}function MW0(A){let Q=[],w=q92(A.brainDid,I92(A));if(w)Q.push(w);if(RM(A.anchorDid)&&A.anchorDid!==A.brainDid){let $=q92(A.anchorDid,pAA(A.anchorDid));if($)Q.push($)}return Q}function iAA(A,Q){let w=[];if(!A.brainDid){let $=Oa(Q);w.push({path:"/.well-known/did.json",hostname:Q,document:J92(A,$)})}if(!A.anchorDid){let $=PW0(Q);w.push({path:"/anchor/did.json",hostname:Q,document:pAA($)})}return w}function Ggw(A,Q){if(!A)return;try{return new URL(A,Q).toString()}catch{return}}function Dgw(A){let Q=A.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,200);return Q.length>0?Q:"skill"}function F92(A,Q){let w=A[Q];return typeof w==="string"&&w.length>0?w:void 0}function b92(A,Q){let w=A[Q];if(!Array.isArray(w))return;let $=w.filter((B)=>typeof B==="string"&&B.length>0);return $.length>0?$:void 0}function qgw(A){let Q=A.metadata,w=F92(Q,"name"),$=F92(Q,"description");if(!w||!$)return;let B=b92(Q,"tags"),X=b92(Q,"examples");return{id:Dgw(w),name:w,description:$,...B&&{tags:B},...X&&{examples:X}}}async function zgw(A){if(!A.entityService.hasEntityType("skill"))return[];return(await A.entityService.listEntities({entityType:"skill",options:{filter:{visibilityScope:"public"}}})).map((w)=>qgw(w)).filter((w)=>w!==void 0).slice(0,100)}async function dAA(A,Q,w=new Date){let $=A.identity.get(),B=A.identity.getProfile(),X=await A.identity.getAppInfo(),Y=Ggw(A.siteUrl??B.website,void 0);if(!Y)throw Error("AT Protocol brain card publishing requires siteUrl");let Z=new URL(Y).hostname,H=Q.brainDid??Oa(Z),W=Q.anchorDid??PW0(Z);if(RM(H)){if(jW0(H)!==Z)throw Error("AT Protocol brain card did:web host must match siteUrl host")}let K=await zgw(A);return{$type:"ai.rizom.brain.card",siteUrl:Y,brain:{did:H,name:$.name,role:$.role,purpose:$.purpose,values:$.values},anchor:{did:W,name:B.name,kind:B.kind},skills:K,model:X.model,version:X.version,createdAt:w.toISOString(),updatedAt:w.toISOString()}}var L92={name:"@brains/atproto",version:"0.2.0-alpha.158",description:"AT Protocol integration for identity, publishing, discovery, and feeds",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":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts","./env-schema":"./src/env-schema.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var k92=S6["ai.rizom.brain.card"],Jgw=f.looseObject({did:f.string()}),Igw=f.looseObject({service:f.array(f.looseObject({id:f.string().optional(),type:f.string().optional(),serviceEndpoint:f.string().optional()})).optional()}),Fgw="ai.rizom.brain.card",bgw="self",_92=50;class nAA extends Kw{deps;projectionRegistry;constructor(A={},Q={}){super("atproto",L92,A,cAA);this.deps=Q,this.projectionRegistry=Q.projectionRegistry??kB.getInstance()}getWebRoutes(){if(!this.config.enabled)return[];let A=MW0(this.config),Q=[...!this.config.brainDid?["/.well-known/did.json"]:[],...!this.config.anchorDid?["/anchor/did.json"]:[]];return[...new Set([...A.map(($)=>$.path),...Q])].map(($)=>({path:$,method:"GET",public:!0,handler:(B)=>{let X=new URL(B.url).hostname,Y=[...MW0(this.config),...iAA(this.config,X)].filter((H)=>H.path===$),Z=Y.find((H)=>H.hostname===X)??Y[0];if(!Z)return new Response("Not found",{status:404});return new Response(JSON.stringify(Z.document),{headers:{"Content-Type":"application/did+json"}})}}))}async publishBrainCard(A,Q={}){let w=await dAA(A,this.config);FV(k92,w);let $=this.config.repoDid;if(Q.dryRun)return{record:w,dryRun:!0,...$&&{repo:$}};let B=this.resolveAppPassword();if(!this.config.identifier||!B)throw Error("AT Protocol publishing requires identifier and app password configuration");let X=this.createPdsClient(B),Y=await X.createSession(),Z=$??Y.did;if(!X.putRecord)throw Error("AT Protocol PDS client does not support record upserts");let H=await X.putRecord({repo:Z,collection:"ai.rizom.brain.card",rkey:"self",validate:!1,record:w});return{record:w,repo:Z,uri:H.uri,cid:H.cid,dryRun:!1}}async publishEntity(A,Q){let w=this.projectionRegistry.get(Q.entityType);if(!w)throw Error(`No AT Protocol projection registered for ${Q.entityType}`);return this.publishProjectedEntity(A,Q,w)}async publishPost(A,Q){let w=this.projectionRegistry.get("post");if(!w)throw Error("No AT Protocol projection registered for post");return this.publishProjectedEntity(A,{entityType:"post",...Q},w)}async discoverBrainCards(A,Q){let w=[...new Set(Q.repos.map((X)=>X.trim()))].filter((X)=>X.length>0);if(w.length===0)throw Error("AT Protocol discovery requires at least one repo DID or handle");if(w.length>_92)throw Error(`AT Protocol discovery accepts at most ${_92} repos per batch`);let $=new Set,B=[];for(let X of w)try{let Y=await this.resolveRepoPdsEndpoint(X),Z=this.createPublicPdsClient(Y.pdsEndpoint);if(!Z.getRecord)throw Error("AT Protocol PDS client does not support record reads");let H=await Z.getRecord({repo:Y.repoDid,collection:Fgw,rkey:bgw});FV(k92,H.value);let W=kgw(H.uri)??Y.repoDid,K=`${W}:${H.uri}:${H.cid}`;if($.has(K)){B.push({repo:X,status:"skipped",repoDid:W,uri:H.uri,cid:H.cid,error:"Duplicate brain card in discovery batch"});continue}$.add(K),await A.messaging.send({type:Hr,payload:{repoDid:W,uri:H.uri,cid:H.cid,record:H.value},broadcast:!0}),B.push({repo:X,status:"discovered",repoDid:W,uri:H.uri,cid:H.cid})}catch(Y){B.push({repo:X,status:"skipped",error:dA(Y)})}return{discovered:B.filter((X)=>X.status==="discovered").length,skipped:B.filter((X)=>X.status==="skipped").length,results:B}}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:dA(Q)}),!1}}async getTools(){return[]}async publishProjectedEntity(A,Q,w){let $=await this.findPublishEntity(A,Q),B=Q.entityId??Q.slug;if(!B)throw Error(`${Q.entityType} publish requires entityId or slug`);if(!$)throw Error(`${Q.entityType} not found: ${B}`);if($.visibility!=="public")throw Error(`Cannot publish non-public ${Q.entityType}: ${B}`);let X=this.config.repoDid;if(Q.dryRun){let G=await w.buildRecord({entity:$,context:A,config:this.config,...Q.topics&&{topics:Q.topics},dryRun:!0});return FV(w.lexicon,G),{record:G,dryRun:!0,...X&&{repo:X}}}let Y=this.resolveAppPassword();if(!this.config.identifier||!Y)throw Error("AT Protocol publishing requires identifier and app password configuration");let Z=this.createPdsClient(Y),H=await Z.createSession(),W=X??H.did,K=await w.buildRecord({entity:$,context:A,config:this.config,client:Z,...Q.topics&&{topics:Q.topics}});if(FV(w.lexicon,K),!Z.putRecord)throw Error("AT Protocol PDS client does not support record upserts");let U=await Z.putRecord({repo:W,collection:w.collection,rkey:Lgw($.id),...w.validate!==void 0&&{validate:w.validate},record:K});return await w.onPublished?.({entity:$,context:A,record:K,uri:U.uri,cid:U.cid}),{record:K,repo:W,uri:U.uri,cid:U.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 Ma({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 w=await this.resolveDidToPdsEndpoint(Q);if(!w)throw Error(`Could not resolve AT Protocol PDS for repo: ${Q}`);return{repoDid:Q,pdsEndpoint:w}}async resolveHandleToDid(A){let Q=new URL("/xrpc/com.atproto.identity.resolveHandle",this.config.pdsEndpoint);Q.searchParams.set("handle",A);let w=await this.fetch(Q.toString());if(!w.ok)return;let $=Jgw.safeParse(await w.json());return $.success?$.data.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(_gw(A)):void 0,w=Igw.safeParse(Q);if(!w.success)return;return w.data.service?.find((B)=>B.id==="#atproto_pds"||B.type==="AtprotoPersonalDataServer")?.serviceEndpoint}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 Ma({pdsEndpoint:this.config.pdsEndpoint,identifier:this.config.identifier??"",appPassword:A})}resolveAppPassword(){return this.config.appPassword}}function Lgw(A){let Q=A.replace(/[^A-Za-z0-9._~:-]/g,"_").slice(0,512);return Q.length>0?Q:"self"}function kgw(A){return/^at:\/\/([^/]+)/.exec(A)?.[1]}function _gw(A){let Q=A.slice(8).split(":").map(decodeURIComponent),[w,...$]=Q;if(!w)throw Error(`Invalid did:web value: ${A}`);if($.length===0)return`https://${w}/.well-known/did.json`;return`https://${w}/${$.join("/")}/did.json`}function OW0(A,Q){return new nAA(A,Q)}fA();C0();var xW0={name:"@brains/rover",version:"0.2.0-alpha.158",dependencies:{"@brains/a2a":"workspace:*","@brains/agent-discovery":"workspace:*","@brains/analytics":"workspace:*","@brains/app":"workspace:*","@brains/assessment":"workspace:*","@brains/atproto":"workspace:*","@brains/atproto-registry":"workspace:*","@brains/auth-service":"workspace:*","@brains/blog":"workspace:*","@brains/chat":"workspace:*","@brains/cms":"workspace:*","@brains/content-pipeline":"workspace:*","@brains/dashboard":"workspace:*","@brains/decks":"workspace:*","@brains/directory-sync":"workspace:*","@brains/discord":"workspace:*","@brains/doc":"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/playbooks":"workspace:*","@brains/portfolio":"workspace:*","@brains/prompt":"workspace:*","@brains/rizom-ecosystem":"workspace:*","@brains/rover-onboarding":"workspace:*","@brains/series":"workspace:*","@brains/site-builder-plugin":"workspace:*","@brains/site-content":"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:"^7.0.2"},files:["src","brain.eval.yaml","env.schema.template"],main:"./src/index.ts",private:!0,scripts:{"build:ui":"turbo run build --filter=@brains/web-chat --filter=@brains/cms",eval:"brain-eval","eval:core":"brain-eval --suite core","eval:core:coverage":"brain-eval --suite core --tool-coverage","eval:default":"brain-eval --suite default","eval:default:coverage":"brain-eval --suite default --tool-coverage","eval:full":"brain-eval --suite full","eval:full:coverage":"brain-eval --suite full --tool-coverage",lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix","start:core":"bun run build:ui && cd test-apps/core && INIT_CWD=$PWD bun run $([ -t 1 ] && echo --elide-lines=0) --filter @rizom/brain dev:start","start:default":"bun run build:ui && cd test-apps/default && INIT_CWD=$PWD bun run $([ -t 1 ] && echo --elide-lines=0) --filter @rizom/brain dev:start","start:full":"bun run build:ui && cd test-apps/full && INIT_CWD=$PWD bun run $([ -t 1 ] && echo --elide-lines=0) --filter @rizom/brain dev:start",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var jgw=f.looseObject({});class N92 extends Kw{constructor(A={}){super("rover-profile",xW0,A,jgw)}async onRegister(A){A.entities.extendFrontmatterSchema("anchor-profile",x_)}}function j92(A={}){return new N92(A)}fA();C0();p$();fA();fA();var xa=Y3.extend(x_.shape);class RW0{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,w){let $=w.entityService,[B,X,Y,Z]=await Promise.all([jR($,xa),cZ0($,{entityType:"post",count:3,parse:Ys}),cZ0($,{entityType:"deck",count:3,parse:Gs}),Bs($)]),H={profile:B,posts:X,decks:Y,postsListUrl:this.postsListUrl,decksListUrl:this.decksListUrl,cta:Ga0(Z.cta),sections:Z.sections??{}};return Q.parse(H)}}fA();class vW0{id="professional:about";name="About Page DataSource";description="Fetches full profile data for the about page";async fetch(A,Q,w){let B={profile:await jR(w.entityService,xa)};return Q.parse(B)}}import{jsxDEV as o$,Fragment as Ogw}from"preact/jsx-dev-runtime";var Pgw="grid md:grid-cols-[14rem_1px_1fr] gap-y-2 gap-x-0 md:gap-16 items-start",Mgw="border-t md:border-t-0 md:border-l border-rule-strong md:self-stretch",rAA=({number:A,title:Q,blurb:w,children:$})=>o$("section",{className:"py-20 border-b border-rule px-6 md:px-12",children:o$("div",{className:"max-w-6xl mx-auto",children:o$("div",{className:Pgw,children:[o$(Fr0,{title:Q,number:A,blurb:w},void 0,!1,void 0,this),o$("div",{className:Mgw,"aria-hidden":"true"},void 0,!1,void 0,this),o$("div",{className:"mt-6 md:mt-0",children:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this),oAA=({profile:A,posts:Q,decks:w,postsListUrl:$,decksListUrl:B,cta:X,sections:Y})=>{let Z=A.tagline?.length?A.tagline:A.description,H=Q.map((q)=>({id:q.id,url:q.url,title:q.metadata.title,date:q.metadata.publishedAt??q.created,description:q.frontmatter.excerpt,series:q.frontmatter.seriesName&&q.frontmatter.seriesIndex?{name:q.frontmatter.seriesName,index:q.frontmatter.seriesIndex}:void 0})),W=w.map((q)=>({id:q.id,url:q.url,title:q.frontmatter.title||q.id,date:q.frontmatter.publishedAt??q.created,description:q.frontmatter.description})),K=A.name||"Home",U=[A.intro,A.description,Z].find((q)=>q)??"Professional site",G=Boolean(A.description)||A.expertise!==void 0&&A.expertise.length>0;return o$(Ogw,{children:[o$($w,{title:K,description:U,ogType:"website"},void 0,!1,void 0,this),o$("div",{className:"homepage-list bg-theme",children:[o$("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:o$("div",{className:"relative z-10 max-w-6xl mx-auto w-full",children:[A.name&&o$("div",{className:"flex items-center gap-[0.6rem] mb-6 font-mono text-[0.7rem] font-medium uppercase tracking-[0.22em] text-accent",children:[o$("span",{className:"w-[18px] h-px bg-accent","aria-hidden":"true"},void 0,!1,void 0,this),o$("span",{children:A.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Z&&o$("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:QY0(Z,"italic font-normal text-accent [font-variation-settings:'opsz'_144,'SOFT'_80]")},void 0,!1,void 0,this),A.intro&&o$("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:QY0(A.intro,"italic text-accent")},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),o$(rAA,{number:"01",title:"Essays",blurb:Y.essays?.blurb,children:o$(AY0,{items:H,viewAllUrl:$,viewAllLabel:"View all essays"},void 0,!1,void 0,this)},void 0,!1,void 0,this),W.length>0&&o$(rAA,{number:"02",title:"Presentations",blurb:Y.presentations?.blurb,children:o$(AY0,{items:W,viewAllUrl:B,viewAllLabel:"View all presentations"},void 0,!1,void 0,this)},void 0,!1,void 0,this),G&&o$(rAA,{number:"03",title:"About",blurb:Y.about?.blurb,children:o$("div",{className:"flex flex-col gap-8",children:[A.description&&o$("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&&o$(br0,{subjects:A.expertise},void 0,!1,void 0,this),o$("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",o$("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),o$(Xr0,{cta:X,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 D$,Fragment as xgw}from"preact/jsx-dev-runtime";var sAA=({profile:A})=>{let Q=`About ${A.name||"Me"}`,w=[A.description,A.intro].find((B)=>B)??"About page",$=A.expertise!==void 0&&A.expertise.length>0||Boolean(A.currentFocus)||Boolean(A.availability)||Boolean(A.email)||Boolean(A.website)||A.socialLinks!==void 0&&A.socialLinks.length>0;return D$(xgw,{children:[D$($w,{title:Q,description:w,ogType:"profile"},void 0,!1,void 0,this),D$("div",{className:"about-page bg-theme",children:[D$("header",{className:"hero-bg-pattern relative w-full py-16 md:py-24 px-6 md:px-12 bg-theme overflow-hidden",children:D$("div",{className:"relative z-10 max-w-4xl mx-auto",children:[D$("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&&D$("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),D$("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-12 md:py-16",children:[A.story&&D$("section",{className:"content-section-reveal mb-20 md:mb-28",children:D$(l9,{markdown:A.story},void 0,!1,void 0,this)},void 0,!1,void 0,this),$&&D$("div",{className:"content-section-reveal grid md:grid-cols-2 gap-x-16 gap-y-12",children:[A.expertise&&A.expertise.length>0&&D$("section",{children:[D$("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Expertise"},void 0,!1,void 0,this),D$("ul",{className:"flex flex-wrap gap-3",children:A.expertise.map((B,X)=>D$("li",{className:Ao({variant:"accent",size:"lg"}),children:B},X,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.currentFocus&&D$("section",{children:[D$("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Current Focus"},void 0,!1,void 0,this),D$("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&&D$("section",{children:[D$("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Availability"},void 0,!1,void 0,this),D$("p",{className:"text-lg text-theme leading-relaxed",children:A.availability},void 0,!1,void 0,this)]},void 0,!0,void 0,this),(Boolean(A.email)||Boolean(A.website)||A.socialLinks!==void 0&&A.socialLinks.length>0)&&D$("section",{children:[D$("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Contact"},void 0,!1,void 0,this),D$("div",{className:"space-y-4",children:[A.email&&D$("p",{className:"text-lg",children:D$("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&&D$("p",{className:"text-lg",children:D$("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&&D$("div",{className:"flex flex-wrap gap-4 mt-4",children:A.socialLinks.map((B,X)=>D$(c9,{href:B.url,external:!0,variant:"secondary",size:"md",children:B.label?.length?B.label:B.platform},X,!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 zX,Fragment as P92}from"preact/jsx-dev-runtime";var aAA=()=>{return zX(P92,{children:[zX($w,{title:"Thanks for subscribing!",description:"You've successfully subscribed to the newsletter."},void 0,!1,void 0,this),zX("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:zX("div",{className:"text-center max-w-md",children:[zX("div",{className:"text-6xl mb-6",children:"\uD83C\uDF89"},void 0,!1,void 0,this),zX("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Thanks for subscribing!"},void 0,!1,void 0,this),zX("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),zX(c9,{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)},tAA=()=>{return zX(P92,{children:[zX($w,{title:"Subscription failed",description:"There was a problem with your subscription."},void 0,!1,void 0,this),zX("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:zX("div",{className:"text-center max-w-md",children:[zX("div",{className:"text-6xl mb-6",children:"\uD83D\uDE22"},void 0,!1,void 0,this),zX("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Something went wrong"},void 0,!1,void 0,this),zX("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),zX(c9,{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)};C0();var M92=f.object({label:f.string().describe("Display label for entity type (e.g., 'Essay')"),pluralName:f.string().optional().describe("URL path segment (defaults to label.toLowerCase() + 's')")}),Rgw={post:{label:"Post"},deck:{label:"Deck"}},O92=f.object({entityDisplay:f.object({post:M92,deck:M92}).default(Rgw).describe("Display metadata for post and deck entity types used by the homepage")});var x92={name:"@brains/site-professional",version:"0.2.0-alpha.158",description:"Professional site composition package",dependencies:{"@brains/blog":"workspace:*","@brains/decks":"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":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},files:["src"],private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",typecheck:"tsc --noEmit"},type:"module"};var hgw=f.object({blurb:f.string().optional().describe("Short italic subtitle under the section title")}),Cgw=f.object({heading:f.string(),buttonText:f.string(),buttonLink:f.string()}),R92=f.looseObject({name:f.string(),kind:f.enum(["professional","team","collective"]),organization:f.string().optional(),description:f.string().optional(),avatar:f.string().optional(),website:f.string().optional(),email:f.string().optional(),socialLinks:f.array(f.object({platform:f.enum(["github","instagram","linkedin","email","website"]),url:f.string(),label:f.string().optional()})).optional(),tagline:f.string().optional(),intro:f.string().optional(),story:f.string().optional(),role:f.string().optional(),audience:f.string().optional(),expertise:f.array(f.string()).optional(),currentFocus:f.string().optional(),availability:f.string().optional(),desiredTone:f.string().optional()}),ggw=f.looseObject({id:f.string(),entityType:f.literal("post"),content:f.string(),created:f.string(),updated:f.string(),contentHash:f.string(),metadata:f.looseObject({title:f.string(),publishedAt:f.string().optional()}),frontmatter:f.looseObject({excerpt:f.string(),seriesName:f.string().optional(),seriesIndex:f.number().optional()}),body:f.string(),url:f.string().optional(),typeLabel:f.string().optional(),listUrl:f.string().optional(),listLabel:f.string().optional(),seriesUrl:f.string().optional(),coverImageUrl:f.string().optional(),ogImageUrl:f.string().optional(),coverImageWidth:f.number().optional(),coverImageHeight:f.number().optional(),coverImageSrcset:f.string().optional(),coverImageSizes:f.string().optional()}),ygw=f.looseObject({id:f.string(),entityType:f.literal("deck"),content:f.string(),created:f.string(),updated:f.string(),contentHash:f.string(),metadata:f.looseObject({title:f.string(),publishedAt:f.string().optional()}),frontmatter:f.looseObject({title:f.string(),description:f.string().optional(),publishedAt:f.string().optional()}),body:f.string(),url:f.string().optional(),typeLabel:f.string().optional(),listUrl:f.string().optional(),listLabel:f.string().optional(),coverImageUrl:f.string().optional(),ogImageUrl:f.string().optional(),coverImageWidth:f.number().optional(),coverImageHeight:f.number().optional()});class eAA extends Kw{dependencies=["blog","decks"];constructor(A){super("professional-site",x92,A,O92)}async onRegister(A){let Q=this.config.entityDisplay.post,w=this.config.entityDisplay.deck,$=`/${Q.pluralName??Q.label.toLowerCase()+"s"}`,B=`/${w.pluralName??w.label.toLowerCase()+"s"}`,X=new RW0($,B);A.entities.registerDataSource(X);let Y=new vW0;A.entities.registerDataSource(Y);let Z=f.object({profile:R92,posts:f.array(ggw),decks:f.array(ygw),postsListUrl:f.string(),decksListUrl:f.string(),cta:Cgw,sections:f.record(f.string(),hgw)}),H=f.object({profile:R92}),W=f.object({});A.templates.register({"homepage-list":e1({name:"homepage-list",description:"Professional homepage with essays and presentations",schema:Z,dataSourceId:"professional:homepage-list",requiredPermission:"public",layout:{component:oAA}}),about:e1({name:"about",description:"About page with full profile information",schema:H,dataSourceId:"professional:about",requiredPermission:"public",layout:{component:sAA}}),"subscribe-thanks":e1({name:"subscribe-thanks",description:"Newsletter subscription success page",schema:W,requiredPermission:"public",layout:{component:aAA}}),"subscribe-error":e1({name:"subscribe-error",description:"Newsletter subscription error page",schema:W,requiredPermission:"public",layout:{component:tAA}})}),this.logger.info("Professional site plugin registered successfully")}async getTools(){return[]}async getResources(){return[]}}function v92(A){return new eAA(A??{})}var h92=[{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 hW0}from"preact/jsx-dev-runtime";function C92({sections:A,siteInfo:Q,slots:w,wordmark:$}){return hW0("div",{className:"flex flex-col min-h-screen bg-theme overflow-x-clip",children:[hW0(Hr0,{title:Q.title,navigation:Q.navigation.primary,showThemeToggle:!0,...Q.logo!==void 0?{logo:Q.logo}:{},...$!==void 0?{wordmark:$}:{}},void 0,!1,void 0,this),hW0("main",{className:"flex-grow flex flex-col bg-theme",children:A},void 0,!1,void 0,this),hW0(fr0,{primaryNavigation:Q.navigation.primary,secondaryNavigation:Q.navigation.secondary,copyright:Q.copyright,socialLinks:Q.socialLinks,title:Q.title,tagline:Q.description,children:w?.getSlot("footer-top").map((B)=>B.render())},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}var Egw={layouts:{default:C92},routes:h92,plugin:v92,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"}}}},Ra=Egw;var g92=`/*
10024
+ `).map((Q)=>Q.match(/^- (.+?): (.+?)(?:\s+\[(.+?)\])?$/)).filter((Q)=>Q!==null).map((Q)=>({name:Q[1]??"",description:Q[2]??"",tags:Q[3]?Q[3].split(",").map((w)=>w.trim()).filter(Boolean):[]}))}var $gw=new R6(Agw,{title:"Agent",mappings:[{key:"about",label:"About",type:"string"},{key:"skills",label:"Skills",type:"custom",formatter:Qgw,parser:wgw},{key:"notes",label:"Notes",type:"string"}]});class G92 extends d2{constructor(){super({entityType:"agent",purpose:"An agent entity used for SWOT evaluation.",schema:tCw,frontmatterSchema:aCw})}fromMarkdown(A){return{content:A,entityType:"agent"}}createAgentContent(A){let Q=$gw.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 D92 extends d2{constructor(){super({entityType:"skill",purpose:"A skill entity used for SWOT evaluation.",schema:eCw,frontmatterSchema:uAA})}fromMarkdown(A){let Q=this.parseFrontMatter(A,uAA);return{content:A,entityType:"skill",metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}var CS8=new G92,gS8=new D92,Bgw=f.object({name:f.string(),description:f.string(),tags:f.array(f.string()),examples:f.array(f.string())}),yS8=f.object({skills:f.array(Bgw),agents:f.array(f.object({id:f.string().optional(),name:f.string(),kind:f.enum(["professional","team","collective"]),organization:f.string().optional(),brainName:f.string(),url:f.url(),did:f.string().optional(),status:f.enum(["discovered","approved"]),discoveredAt:f.string().datetime().optional(),about:f.string(),skills:f.array(K92),notes:f.string().default("")}))});var Xgw=f.object({}).strict();function NW0(A={}){return Xgw.parse(A),[mAA()]}fA();C0();C0();var cAA=f.object({enabled:f.boolean().default(!0),pdsEndpoint:f.url().default("https://bsky.social").describe("AT Protocol PDS service endpoint"),identifier:f.string().optional().describe("PDS login identifier, usually a handle or account DID"),repoDid:f.string().optional().describe("DID of the PDS repo that owns records"),appPassword:f.string().optional().describe("App password for prototype authentication; supply via ${ENV_VAR} interpolation, never a committed literal"),anchorDid:f.string().optional().describe("Optional human/operator DID referenced from records; defaults to did:web:<site-host>:anchor when omitted"),brainDid:f.string().optional().describe("Optional public brain DID referenced from records; defaults to did:web:<site-host> when omitted")});C0();var Ygw=f.looseObject({message:f.string()}),Zgw=f.looseObject({did:f.string(),handle:f.string(),accessJwt:f.string(),refreshJwt:f.string()}),lAA=f.looseObject({uri:f.string(),cid:f.string()}),fgw=lAA.extend({value:f.record(f.string(),f.unknown())}),Hgw=f.looseObject({$type:f.literal("blob").optional(),ref:f.looseObject({$link:f.string()}),mimeType:f.string(),size:f.number().int().nonnegative()}).transform((A)=>({...A.$type!==void 0?{$type:A.$type}:{},ref:{$link:A.ref.$link},mimeType:A.mimeType,size:A.size})),Wgw=f.looseObject({blob:Hgw});function Kgw(A){return A.replace(/\/+$/,"")}var Ugw=(A,Q)=>fetch(A,Q);async function Pa(A,Q){let w=await A.text(),$;try{$=w.length>0?JSON.parse(w):void 0}catch{if(!A.ok)throw Error(`AT Protocol request failed with ${A.status}`);throw Error("Failed to parse JSON")}if(!A.ok){let B=Ygw.safeParse($);throw Error(B.success?B.data.message:`AT Protocol request failed with ${A.status}`)}return Q.parse($)}class Ma{pdsEndpoint;identifier;appPassword;fetchFn;session;constructor(A){this.pdsEndpoint=Kgw(A.pdsEndpoint),this.identifier=A.identifier,this.appPassword=A.appPassword,this.fetchFn=A.fetch??Ugw}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 Pa(A,Zgw);return this.session=Q,Q}async createRecord(A){let Q=await this.getSession(),w=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 Pa(w,lAA)}async putRecord(A){let Q=await this.getSession(),w=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 Pa(w,lAA)}async getRecord(A){let Q=new URLSearchParams({repo:A.repo,collection:A.collection,rkey:A.rkey}),w=await this.fetchFn(`${this.pdsEndpoint}/xrpc/com.atproto.repo.getRecord?${Q.toString()}`,{method:"GET"});return Pa(w,fgw)}async uploadBlob(A){let Q=await this.getSession(),w=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 Pa(w,Wgw)}async getSession(){return this.session??=await this.createSession(),this.session}}function RM(A){return A?.startsWith("did:web:")??!1}function jW0(A){if(!RM(A))return;let Q=A.slice(8);if(!Q)return;let[w]=Q.split(":");if(!w)return;try{return decodeURIComponent(w)}catch{return w}}function z92(A){if(!RM(A))return;let Q=A.slice(8);if(!Q)return;let[,...w]=Q.split(":");if(w.length===0)return"/.well-known/did.json";return`/${w.map((B)=>{try{return decodeURIComponent(B)}catch{return B}}).join("/")}/did.json`}function V92(A){return A.replace(/\/+$/,"")}function Oa(A){return`did:web:${encodeURIComponent(A)}`}function PW0(A){return`${Oa(A)}:anchor`}function pAA(A){return{"@context":["https://www.w3.org/ns/did/v1"],id:A}}function J92(A,Q){let w=A.identifier?.startsWith("did:")?void 0:A.identifier?[`at://${A.identifier}`]:void 0;return{...pAA(Q),...w&&{alsoKnownAs:w},service:[{id:"#atproto_pds",type:"AtprotoPersonalDataServer",serviceEndpoint:V92(A.pdsEndpoint)}]}}function I92(A){if(!RM(A.brainDid))return null;return J92(A,A.brainDid)}function q92(A,Q){if(!A||!Q)return;let w=jW0(A),$=z92(A);if(!w||!$)return;return{path:$,hostname:w,document:Q}}function MW0(A){let Q=[],w=q92(A.brainDid,I92(A));if(w)Q.push(w);if(RM(A.anchorDid)&&A.anchorDid!==A.brainDid){let $=q92(A.anchorDid,pAA(A.anchorDid));if($)Q.push($)}return Q}function iAA(A,Q){let w=[];if(!A.brainDid){let $=Oa(Q);w.push({path:"/.well-known/did.json",hostname:Q,document:J92(A,$)})}if(!A.anchorDid){let $=PW0(Q);w.push({path:"/anchor/did.json",hostname:Q,document:pAA($)})}return w}function Ggw(A,Q){if(!A)return;try{return new URL(A,Q).toString()}catch{return}}function Dgw(A){let Q=A.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,200);return Q.length>0?Q:"skill"}function F92(A,Q){let w=A[Q];return typeof w==="string"&&w.length>0?w:void 0}function b92(A,Q){let w=A[Q];if(!Array.isArray(w))return;let $=w.filter((B)=>typeof B==="string"&&B.length>0);return $.length>0?$:void 0}function qgw(A){let Q=A.metadata,w=F92(Q,"name"),$=F92(Q,"description");if(!w||!$)return;let B=b92(Q,"tags"),X=b92(Q,"examples");return{id:Dgw(w),name:w,description:$,...B&&{tags:B},...X&&{examples:X}}}async function zgw(A){if(!A.entityService.hasEntityType("skill"))return[];return(await A.entityService.listEntities({entityType:"skill",options:{filter:{visibilityScope:"public"}}})).map((w)=>qgw(w)).filter((w)=>w!==void 0).slice(0,100)}async function dAA(A,Q,w=new Date){let $=A.identity.get(),B=A.identity.getProfile(),X=await A.identity.getAppInfo(),Y=Ggw(A.siteUrl??B.website,void 0);if(!Y)throw Error("AT Protocol brain card publishing requires siteUrl");let Z=new URL(Y).hostname,H=Q.brainDid??Oa(Z),W=Q.anchorDid??PW0(Z);if(RM(H)){if(jW0(H)!==Z)throw Error("AT Protocol brain card did:web host must match siteUrl host")}let K=await zgw(A);return{$type:"ai.rizom.brain.card",siteUrl:Y,brain:{did:H,name:$.name,role:$.role,purpose:$.purpose,values:$.values},anchor:{did:W,name:B.name,kind:B.kind},skills:K,model:X.model,version:X.version,createdAt:w.toISOString(),updatedAt:w.toISOString()}}var L92={name:"@brains/atproto",version:"0.2.0-alpha.159",description:"AT Protocol integration for identity, publishing, discovery, and feeds",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":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts","./env-schema":"./src/env-schema.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var k92=S6["ai.rizom.brain.card"],Jgw=f.looseObject({did:f.string()}),Igw=f.looseObject({service:f.array(f.looseObject({id:f.string().optional(),type:f.string().optional(),serviceEndpoint:f.string().optional()})).optional()}),Fgw="ai.rizom.brain.card",bgw="self",_92=50;class nAA extends Kw{deps;projectionRegistry;constructor(A={},Q={}){super("atproto",L92,A,cAA);this.deps=Q,this.projectionRegistry=Q.projectionRegistry??kB.getInstance()}getWebRoutes(){if(!this.config.enabled)return[];let A=MW0(this.config),Q=[...!this.config.brainDid?["/.well-known/did.json"]:[],...!this.config.anchorDid?["/anchor/did.json"]:[]];return[...new Set([...A.map(($)=>$.path),...Q])].map(($)=>({path:$,method:"GET",public:!0,handler:(B)=>{let X=new URL(B.url).hostname,Y=[...MW0(this.config),...iAA(this.config,X)].filter((H)=>H.path===$),Z=Y.find((H)=>H.hostname===X)??Y[0];if(!Z)return new Response("Not found",{status:404});return new Response(JSON.stringify(Z.document),{headers:{"Content-Type":"application/did+json"}})}}))}async publishBrainCard(A,Q={}){let w=await dAA(A,this.config);FV(k92,w);let $=this.config.repoDid;if(Q.dryRun)return{record:w,dryRun:!0,...$&&{repo:$}};let B=this.resolveAppPassword();if(!this.config.identifier||!B)throw Error("AT Protocol publishing requires identifier and app password configuration");let X=this.createPdsClient(B),Y=await X.createSession(),Z=$??Y.did;if(!X.putRecord)throw Error("AT Protocol PDS client does not support record upserts");let H=await X.putRecord({repo:Z,collection:"ai.rizom.brain.card",rkey:"self",validate:!1,record:w});return{record:w,repo:Z,uri:H.uri,cid:H.cid,dryRun:!1}}async publishEntity(A,Q){let w=this.projectionRegistry.get(Q.entityType);if(!w)throw Error(`No AT Protocol projection registered for ${Q.entityType}`);return this.publishProjectedEntity(A,Q,w)}async publishPost(A,Q){let w=this.projectionRegistry.get("post");if(!w)throw Error("No AT Protocol projection registered for post");return this.publishProjectedEntity(A,{entityType:"post",...Q},w)}async discoverBrainCards(A,Q){let w=[...new Set(Q.repos.map((X)=>X.trim()))].filter((X)=>X.length>0);if(w.length===0)throw Error("AT Protocol discovery requires at least one repo DID or handle");if(w.length>_92)throw Error(`AT Protocol discovery accepts at most ${_92} repos per batch`);let $=new Set,B=[];for(let X of w)try{let Y=await this.resolveRepoPdsEndpoint(X),Z=this.createPublicPdsClient(Y.pdsEndpoint);if(!Z.getRecord)throw Error("AT Protocol PDS client does not support record reads");let H=await Z.getRecord({repo:Y.repoDid,collection:Fgw,rkey:bgw});FV(k92,H.value);let W=kgw(H.uri)??Y.repoDid,K=`${W}:${H.uri}:${H.cid}`;if($.has(K)){B.push({repo:X,status:"skipped",repoDid:W,uri:H.uri,cid:H.cid,error:"Duplicate brain card in discovery batch"});continue}$.add(K),await A.messaging.send({type:Hr,payload:{repoDid:W,uri:H.uri,cid:H.cid,record:H.value},broadcast:!0}),B.push({repo:X,status:"discovered",repoDid:W,uri:H.uri,cid:H.cid})}catch(Y){B.push({repo:X,status:"skipped",error:dA(Y)})}return{discovered:B.filter((X)=>X.status==="discovered").length,skipped:B.filter((X)=>X.status==="skipped").length,results:B}}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:dA(Q)}),!1}}async getTools(){return[]}async publishProjectedEntity(A,Q,w){let $=await this.findPublishEntity(A,Q),B=Q.entityId??Q.slug;if(!B)throw Error(`${Q.entityType} publish requires entityId or slug`);if(!$)throw Error(`${Q.entityType} not found: ${B}`);if($.visibility!=="public")throw Error(`Cannot publish non-public ${Q.entityType}: ${B}`);let X=this.config.repoDid;if(Q.dryRun){let G=await w.buildRecord({entity:$,context:A,config:this.config,...Q.topics&&{topics:Q.topics},dryRun:!0});return FV(w.lexicon,G),{record:G,dryRun:!0,...X&&{repo:X}}}let Y=this.resolveAppPassword();if(!this.config.identifier||!Y)throw Error("AT Protocol publishing requires identifier and app password configuration");let Z=this.createPdsClient(Y),H=await Z.createSession(),W=X??H.did,K=await w.buildRecord({entity:$,context:A,config:this.config,client:Z,...Q.topics&&{topics:Q.topics}});if(FV(w.lexicon,K),!Z.putRecord)throw Error("AT Protocol PDS client does not support record upserts");let U=await Z.putRecord({repo:W,collection:w.collection,rkey:Lgw($.id),...w.validate!==void 0&&{validate:w.validate},record:K});return await w.onPublished?.({entity:$,context:A,record:K,uri:U.uri,cid:U.cid}),{record:K,repo:W,uri:U.uri,cid:U.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 Ma({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 w=await this.resolveDidToPdsEndpoint(Q);if(!w)throw Error(`Could not resolve AT Protocol PDS for repo: ${Q}`);return{repoDid:Q,pdsEndpoint:w}}async resolveHandleToDid(A){let Q=new URL("/xrpc/com.atproto.identity.resolveHandle",this.config.pdsEndpoint);Q.searchParams.set("handle",A);let w=await this.fetch(Q.toString());if(!w.ok)return;let $=Jgw.safeParse(await w.json());return $.success?$.data.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(_gw(A)):void 0,w=Igw.safeParse(Q);if(!w.success)return;return w.data.service?.find((B)=>B.id==="#atproto_pds"||B.type==="AtprotoPersonalDataServer")?.serviceEndpoint}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 Ma({pdsEndpoint:this.config.pdsEndpoint,identifier:this.config.identifier??"",appPassword:A})}resolveAppPassword(){return this.config.appPassword}}function Lgw(A){let Q=A.replace(/[^A-Za-z0-9._~:-]/g,"_").slice(0,512);return Q.length>0?Q:"self"}function kgw(A){return/^at:\/\/([^/]+)/.exec(A)?.[1]}function _gw(A){let Q=A.slice(8).split(":").map(decodeURIComponent),[w,...$]=Q;if(!w)throw Error(`Invalid did:web value: ${A}`);if($.length===0)return`https://${w}/.well-known/did.json`;return`https://${w}/${$.join("/")}/did.json`}function OW0(A,Q){return new nAA(A,Q)}fA();C0();var xW0={name:"@brains/rover",version:"0.2.0-alpha.159",dependencies:{"@brains/a2a":"workspace:*","@brains/agent-discovery":"workspace:*","@brains/analytics":"workspace:*","@brains/app":"workspace:*","@brains/assessment":"workspace:*","@brains/atproto":"workspace:*","@brains/atproto-registry":"workspace:*","@brains/auth-service":"workspace:*","@brains/blog":"workspace:*","@brains/chat":"workspace:*","@brains/cms":"workspace:*","@brains/content-pipeline":"workspace:*","@brains/dashboard":"workspace:*","@brains/decks":"workspace:*","@brains/directory-sync":"workspace:*","@brains/discord":"workspace:*","@brains/doc":"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/playbooks":"workspace:*","@brains/portfolio":"workspace:*","@brains/prompt":"workspace:*","@brains/rizom-ecosystem":"workspace:*","@brains/rover-onboarding":"workspace:*","@brains/series":"workspace:*","@brains/site-builder-plugin":"workspace:*","@brains/site-content":"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:"^7.0.2"},files:["src","brain.eval.yaml","env.schema.template"],main:"./src/index.ts",private:!0,scripts:{"build:ui":"turbo run build --filter=@brains/web-chat --filter=@brains/cms",eval:"brain-eval","eval:core":"brain-eval --suite core","eval:core:coverage":"brain-eval --suite core --tool-coverage","eval:default":"brain-eval --suite default","eval:default:coverage":"brain-eval --suite default --tool-coverage","eval:full":"brain-eval --suite full","eval:full:coverage":"brain-eval --suite full --tool-coverage",lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix","start:core":"bun run build:ui && cd test-apps/core && INIT_CWD=$PWD bun run $([ -t 1 ] && echo --elide-lines=0) --filter @rizom/brain dev:start","start:default":"bun run build:ui && cd test-apps/default && INIT_CWD=$PWD bun run $([ -t 1 ] && echo --elide-lines=0) --filter @rizom/brain dev:start","start:full":"bun run build:ui && cd test-apps/full && INIT_CWD=$PWD bun run $([ -t 1 ] && echo --elide-lines=0) --filter @rizom/brain dev:start",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var jgw=f.looseObject({});class N92 extends Kw{constructor(A={}){super("rover-profile",xW0,A,jgw)}async onRegister(A){A.entities.extendFrontmatterSchema("anchor-profile",x_)}}function j92(A={}){return new N92(A)}fA();C0();p$();fA();fA();var xa=Y3.extend(x_.shape);class RW0{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,w){let $=w.entityService,[B,X,Y,Z]=await Promise.all([jR($,xa),cZ0($,{entityType:"post",count:3,parse:Ys}),cZ0($,{entityType:"deck",count:3,parse:Gs}),Bs($)]),H={profile:B,posts:X,decks:Y,postsListUrl:this.postsListUrl,decksListUrl:this.decksListUrl,cta:Ga0(Z.cta),sections:Z.sections??{}};return Q.parse(H)}}fA();class vW0{id="professional:about";name="About Page DataSource";description="Fetches full profile data for the about page";async fetch(A,Q,w){let B={profile:await jR(w.entityService,xa)};return Q.parse(B)}}import{jsxDEV as o$,Fragment as Ogw}from"preact/jsx-dev-runtime";var Pgw="grid md:grid-cols-[14rem_1px_1fr] gap-y-2 gap-x-0 md:gap-16 items-start",Mgw="border-t md:border-t-0 md:border-l border-rule-strong md:self-stretch",rAA=({number:A,title:Q,blurb:w,children:$})=>o$("section",{className:"py-20 border-b border-rule px-6 md:px-12",children:o$("div",{className:"max-w-6xl mx-auto",children:o$("div",{className:Pgw,children:[o$(Fr0,{title:Q,number:A,blurb:w},void 0,!1,void 0,this),o$("div",{className:Mgw,"aria-hidden":"true"},void 0,!1,void 0,this),o$("div",{className:"mt-6 md:mt-0",children:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this),oAA=({profile:A,posts:Q,decks:w,postsListUrl:$,decksListUrl:B,cta:X,sections:Y})=>{let Z=A.tagline?.length?A.tagline:A.description,H=Q.map((q)=>({id:q.id,url:q.url,title:q.metadata.title,date:q.metadata.publishedAt??q.created,description:q.frontmatter.excerpt,series:q.frontmatter.seriesName&&q.frontmatter.seriesIndex?{name:q.frontmatter.seriesName,index:q.frontmatter.seriesIndex}:void 0})),W=w.map((q)=>({id:q.id,url:q.url,title:q.frontmatter.title||q.id,date:q.frontmatter.publishedAt??q.created,description:q.frontmatter.description})),K=A.name||"Home",U=[A.intro,A.description,Z].find((q)=>q)??"Professional site",G=Boolean(A.description)||A.expertise!==void 0&&A.expertise.length>0;return o$(Ogw,{children:[o$($w,{title:K,description:U,ogType:"website"},void 0,!1,void 0,this),o$("div",{className:"homepage-list bg-theme",children:[o$("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:o$("div",{className:"relative z-10 max-w-6xl mx-auto w-full",children:[A.name&&o$("div",{className:"flex items-center gap-[0.6rem] mb-6 font-mono text-[0.7rem] font-medium uppercase tracking-[0.22em] text-accent",children:[o$("span",{className:"w-[18px] h-px bg-accent","aria-hidden":"true"},void 0,!1,void 0,this),o$("span",{children:A.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Z&&o$("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:QY0(Z,"italic font-normal text-accent [font-variation-settings:'opsz'_144,'SOFT'_80]")},void 0,!1,void 0,this),A.intro&&o$("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:QY0(A.intro,"italic text-accent")},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),o$(rAA,{number:"01",title:"Essays",blurb:Y.essays?.blurb,children:o$(AY0,{items:H,viewAllUrl:$,viewAllLabel:"View all essays"},void 0,!1,void 0,this)},void 0,!1,void 0,this),W.length>0&&o$(rAA,{number:"02",title:"Presentations",blurb:Y.presentations?.blurb,children:o$(AY0,{items:W,viewAllUrl:B,viewAllLabel:"View all presentations"},void 0,!1,void 0,this)},void 0,!1,void 0,this),G&&o$(rAA,{number:"03",title:"About",blurb:Y.about?.blurb,children:o$("div",{className:"flex flex-col gap-8",children:[A.description&&o$("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&&o$(br0,{subjects:A.expertise},void 0,!1,void 0,this),o$("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",o$("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),o$(Xr0,{cta:X,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 D$,Fragment as xgw}from"preact/jsx-dev-runtime";var sAA=({profile:A})=>{let Q=`About ${A.name||"Me"}`,w=[A.description,A.intro].find((B)=>B)??"About page",$=A.expertise!==void 0&&A.expertise.length>0||Boolean(A.currentFocus)||Boolean(A.availability)||Boolean(A.email)||Boolean(A.website)||A.socialLinks!==void 0&&A.socialLinks.length>0;return D$(xgw,{children:[D$($w,{title:Q,description:w,ogType:"profile"},void 0,!1,void 0,this),D$("div",{className:"about-page bg-theme",children:[D$("header",{className:"hero-bg-pattern relative w-full py-16 md:py-24 px-6 md:px-12 bg-theme overflow-hidden",children:D$("div",{className:"relative z-10 max-w-4xl mx-auto",children:[D$("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&&D$("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),D$("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-12 md:py-16",children:[A.story&&D$("section",{className:"content-section-reveal mb-20 md:mb-28",children:D$(l9,{markdown:A.story},void 0,!1,void 0,this)},void 0,!1,void 0,this),$&&D$("div",{className:"content-section-reveal grid md:grid-cols-2 gap-x-16 gap-y-12",children:[A.expertise&&A.expertise.length>0&&D$("section",{children:[D$("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Expertise"},void 0,!1,void 0,this),D$("ul",{className:"flex flex-wrap gap-3",children:A.expertise.map((B,X)=>D$("li",{className:Ao({variant:"accent",size:"lg"}),children:B},X,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.currentFocus&&D$("section",{children:[D$("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Current Focus"},void 0,!1,void 0,this),D$("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&&D$("section",{children:[D$("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Availability"},void 0,!1,void 0,this),D$("p",{className:"text-lg text-theme leading-relaxed",children:A.availability},void 0,!1,void 0,this)]},void 0,!0,void 0,this),(Boolean(A.email)||Boolean(A.website)||A.socialLinks!==void 0&&A.socialLinks.length>0)&&D$("section",{children:[D$("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Contact"},void 0,!1,void 0,this),D$("div",{className:"space-y-4",children:[A.email&&D$("p",{className:"text-lg",children:D$("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&&D$("p",{className:"text-lg",children:D$("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&&D$("div",{className:"flex flex-wrap gap-4 mt-4",children:A.socialLinks.map((B,X)=>D$(c9,{href:B.url,external:!0,variant:"secondary",size:"md",children:B.label?.length?B.label:B.platform},X,!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 zX,Fragment as P92}from"preact/jsx-dev-runtime";var aAA=()=>{return zX(P92,{children:[zX($w,{title:"Thanks for subscribing!",description:"You've successfully subscribed to the newsletter."},void 0,!1,void 0,this),zX("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:zX("div",{className:"text-center max-w-md",children:[zX("div",{className:"text-6xl mb-6",children:"\uD83C\uDF89"},void 0,!1,void 0,this),zX("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Thanks for subscribing!"},void 0,!1,void 0,this),zX("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),zX(c9,{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)},tAA=()=>{return zX(P92,{children:[zX($w,{title:"Subscription failed",description:"There was a problem with your subscription."},void 0,!1,void 0,this),zX("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:zX("div",{className:"text-center max-w-md",children:[zX("div",{className:"text-6xl mb-6",children:"\uD83D\uDE22"},void 0,!1,void 0,this),zX("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Something went wrong"},void 0,!1,void 0,this),zX("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),zX(c9,{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)};C0();var M92=f.object({label:f.string().describe("Display label for entity type (e.g., 'Essay')"),pluralName:f.string().optional().describe("URL path segment (defaults to label.toLowerCase() + 's')")}),Rgw={post:{label:"Post"},deck:{label:"Deck"}},O92=f.object({entityDisplay:f.object({post:M92,deck:M92}).default(Rgw).describe("Display metadata for post and deck entity types used by the homepage")});var x92={name:"@brains/site-professional",version:"0.2.0-alpha.159",description:"Professional site composition package",dependencies:{"@brains/blog":"workspace:*","@brains/decks":"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":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},files:["src"],private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",typecheck:"tsc --noEmit"},type:"module"};var hgw=f.object({blurb:f.string().optional().describe("Short italic subtitle under the section title")}),Cgw=f.object({heading:f.string(),buttonText:f.string(),buttonLink:f.string()}),R92=f.looseObject({name:f.string(),kind:f.enum(["professional","team","collective"]),organization:f.string().optional(),description:f.string().optional(),avatar:f.string().optional(),website:f.string().optional(),email:f.string().optional(),socialLinks:f.array(f.object({platform:f.enum(["github","instagram","linkedin","email","website"]),url:f.string(),label:f.string().optional()})).optional(),tagline:f.string().optional(),intro:f.string().optional(),story:f.string().optional(),role:f.string().optional(),audience:f.string().optional(),expertise:f.array(f.string()).optional(),currentFocus:f.string().optional(),availability:f.string().optional(),desiredTone:f.string().optional()}),ggw=f.looseObject({id:f.string(),entityType:f.literal("post"),content:f.string(),created:f.string(),updated:f.string(),contentHash:f.string(),metadata:f.looseObject({title:f.string(),publishedAt:f.string().optional()}),frontmatter:f.looseObject({excerpt:f.string(),seriesName:f.string().optional(),seriesIndex:f.number().optional()}),body:f.string(),url:f.string().optional(),typeLabel:f.string().optional(),listUrl:f.string().optional(),listLabel:f.string().optional(),seriesUrl:f.string().optional(),coverImageUrl:f.string().optional(),ogImageUrl:f.string().optional(),coverImageWidth:f.number().optional(),coverImageHeight:f.number().optional(),coverImageSrcset:f.string().optional(),coverImageSizes:f.string().optional()}),ygw=f.looseObject({id:f.string(),entityType:f.literal("deck"),content:f.string(),created:f.string(),updated:f.string(),contentHash:f.string(),metadata:f.looseObject({title:f.string(),publishedAt:f.string().optional()}),frontmatter:f.looseObject({title:f.string(),description:f.string().optional(),publishedAt:f.string().optional()}),body:f.string(),url:f.string().optional(),typeLabel:f.string().optional(),listUrl:f.string().optional(),listLabel:f.string().optional(),coverImageUrl:f.string().optional(),ogImageUrl:f.string().optional(),coverImageWidth:f.number().optional(),coverImageHeight:f.number().optional()});class eAA extends Kw{dependencies=["blog","decks"];constructor(A){super("professional-site",x92,A,O92)}async onRegister(A){let Q=this.config.entityDisplay.post,w=this.config.entityDisplay.deck,$=`/${Q.pluralName??Q.label.toLowerCase()+"s"}`,B=`/${w.pluralName??w.label.toLowerCase()+"s"}`,X=new RW0($,B);A.entities.registerDataSource(X);let Y=new vW0;A.entities.registerDataSource(Y);let Z=f.object({profile:R92,posts:f.array(ggw),decks:f.array(ygw),postsListUrl:f.string(),decksListUrl:f.string(),cta:Cgw,sections:f.record(f.string(),hgw)}),H=f.object({profile:R92}),W=f.object({});A.templates.register({"homepage-list":e1({name:"homepage-list",description:"Professional homepage with essays and presentations",schema:Z,dataSourceId:"professional:homepage-list",requiredPermission:"public",layout:{component:oAA}}),about:e1({name:"about",description:"About page with full profile information",schema:H,dataSourceId:"professional:about",requiredPermission:"public",layout:{component:sAA}}),"subscribe-thanks":e1({name:"subscribe-thanks",description:"Newsletter subscription success page",schema:W,requiredPermission:"public",layout:{component:aAA}}),"subscribe-error":e1({name:"subscribe-error",description:"Newsletter subscription error page",schema:W,requiredPermission:"public",layout:{component:tAA}})}),this.logger.info("Professional site plugin registered successfully")}async getTools(){return[]}async getResources(){return[]}}function v92(A){return new eAA(A??{})}var h92=[{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 hW0}from"preact/jsx-dev-runtime";function C92({sections:A,siteInfo:Q,slots:w,wordmark:$}){return hW0("div",{className:"flex flex-col min-h-screen bg-theme overflow-x-clip",children:[hW0(Hr0,{title:Q.title,navigation:Q.navigation.primary,showThemeToggle:!0,...Q.logo!==void 0?{logo:Q.logo}:{},...$!==void 0?{wordmark:$}:{}},void 0,!1,void 0,this),hW0("main",{className:"flex-grow flex flex-col bg-theme",children:A},void 0,!1,void 0,this),hW0(fr0,{primaryNavigation:Q.navigation.primary,secondaryNavigation:Q.navigation.secondary,copyright:Q.copyright,socialLinks:Q.socialLinks,title:Q.title,tagline:Q.description,children:w?.getSlot("footer-top").map((B)=>B.render())},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}var Egw={layouts:{default:C92},routes:h92,plugin:v92,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"}}}},Ra=Egw;var g92=`/*
10025
10025
  * Default theme \u2014 simplified editorial base inspired by the Rizom family.
10026
10026
  *
10027
10027
  * This theme is intentionally less branded than @brains/theme-rizom. It
@@ -10604,7 +10604,7 @@ ${JSON.stringify(w,null,2)}`}function bW0(A){return A.map((Q)=>Q.detail===null?{
10604
10604
  font: 10px/1.45 var(--font-mono, "JetBrains Mono", ui-monospace, monospace);
10605
10605
  }
10606
10606
  `}},void 0,!1,void 0,this),FH("section",{className:"product-shell",children:[FH("header",{className:"product-hero",children:[Q.brandLabel&&FH("p",{className:"printable-kicker",children:Q.brandLabel},void 0,!1,void 0,this),FH("h1",{className:"printable-title",children:Q.name},void 0,!1,void 0,this),Q.availability&&FH("div",{className:"printable-meta",children:FH("span",{children:Q.availability},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),FH("div",{className:"product-body-wrap",children:[FH("aside",{className:"product-rail","aria-hidden":"true",children:FH("p",{className:"product-rail-label",children:"Product brief / capabilities"},void 0,!1,void 0,this)},void 0,!1,void 0,this),FH(l9,{markdown:Q.body,className:"printable-body"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.brandLabel&&FH("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 fyw=26214400,Hyw=60000;class X1A{metadata={outputEntityType:"document"};context;renderPdf;constructor(A,Q={}){this.context=A,this.renderPdf=Q.renderPdf??XG}async resolve(A){if(A.sourceEntityType!=="product"||A.attachmentType!==SW0)return;let Q=await this.context.entityService.getEntity({entityType:"product",id:A.sourceEntityId});if(!Q)return;let w=Wyw(Q,{brandLabel:this.resolveBrandLabel()}),$=await Byw(Zyw(Yyw(),"brain-product-printable-"));try{let B=await HH({outputDir:$,mediaPath:`/_media/printable/product/${Q.id}`,template:s92,format:"pdf",content:w,siteConfig:{title:w.name,themeMode:"light"},themeCSS:this.context.themeCSS}),X=await WH({rootDir:$});try{return{type:"document",data:await this.renderPdf(X.urlFor(B.urlPath),{maxBytes:fyw,timeoutMs:Hyw,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${Kyw(Q)}-printable.pdf`}}finally{await X.close()}}finally{await Xyw($,{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 Wyw(A,Q={}){let{frontmatter:w,content:$}=l6(A.content),B=XK.parse(w);return{name:B.name,body:$,availability:B.availability,...Q.brandLabel?{brandLabel:Q.brandLabel}:{}}}function Kyw(A){let Q=A.metadata.slug;return Q.length>0?Q:q1(A.metadata.name)}H7();b2();C0();import{jsxDEV as Dyw}from"preact/jsx-dev-runtime";var mW0="og-image",Uyw="products:og-image",a92=f.object({name:f.string().min(1),tagline:f.string().optional(),availability:f.string().optional(),brandLabel:f.string().optional()}),t92={name:Uyw,pluginId:"products",schema:a92,renderers:{image:Gyw}};function Gyw(A){let Q=a92.parse(A);return Dyw(RV,{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 Y1A{metadata={outputEntityType:"image",targetField:"ogImageId"};context;deps;constructor(A,Q={}){this.context=A,this.deps=Q}async resolve(A){if(A.sourceEntityType!=="product"||A.attachmentType!==mW0)return;let Q=await this.context.entityService.getEntity({entityType:"product",id:A.sourceEntityId});if(!Q)return;let{frontmatter:w,content:$}=l6(Q.content),B=XK.parse(w),X=qyw($,"Tagline"),Y=this.resolveBrandLabel(),Z={name:B.name,availability:B.availability,...X?{tagline:X}:{},...Y?{brandLabel:Y}:{}};return{type:"image",data:await AM({mediaPath:`/_media/og/product/${Q.id}`,template:t92,content:Z,title:Z.name,themeMode:"light",themeCSS:this.context.themeCSS,tmpPrefix:"brain-product-og-image-",...this.deps.screenshotPng&&{screenshotPng:this.deps.screenshotPng}}),mimeType:"image/png",filename:`${zyw(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 qyw(A,Q){let w=A.split(/\r?\n/),$=w.findIndex((Y)=>Y.trim().toLowerCase()===`## ${Q.toLowerCase()}`);if($===-1)return;let B=[];for(let Y of w.slice($+1)){if(Y.trim().startsWith("## "))break;B.push(Y)}let X=B.join(`
10607
- `).trim();return X.length>0?X:void 0}function zyw(A){let Q=A.metadata.slug;return Q.length>0?Q:q1(A.metadata.name)}var e92={name:"@brains/products",version:"0.2.0-alpha.158",description:"Product entity management and overview page for marketing showcase",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":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var Jyw=f.union([f.enum(["public","shared","restricted"]),f.literal("private")]).optional().transform((A)=>{if(A===void 0)return"public";if(A==="private")return"restricted";return A}),A72=f.object({id:f.string(),entityType:f.string(),content:f.string(),created:f.string(),updated:f.string(),visibility:Jyw,metadata:f.record(f.string(),f.unknown()),contentHash:f.string()}),Q72=f.enum(["available","early access","coming soon","planned"]),Iyw=f.object({title:f.string(),description:f.string()}),Fyw=f.object({name:f.string(),availability:Q72,order:f.number(),ogImageId:f.string().optional()}),byw=f.object({tagline:f.string(),promise:f.string(),role:f.string(),purpose:f.string(),audience:f.string(),values:f.array(f.string()).min(1),features:f.array(Iyw).min(1).max(6),story:f.string()}),Lyw=f.object({name:f.string(),availability:Q72,order:f.number(),slug:f.string()}),w72=A72.extend({entityType:f.literal("product"),metadata:Lyw,frontmatter:Fyw,body:byw,labels:f.record(f.string(),f.string()),url:f.string().optional(),typeLabel:f.string().optional(),listUrl:f.string().optional(),listLabel:f.string().optional(),ogImageUrl:f.string().optional()}),uW0=f.object({title:f.string(),description:f.string()}),kyw=f.object({heading:f.string(),buttonText:f.string(),link:f.string()}),_yw=f.object({headline:f.string(),tagline:f.string()}),Nyw=f.object({vision:f.string(),pillars:f.array(uW0).min(1).max(6),approach:f.array(uW0).min(1).max(6),productsIntro:f.string(),technologies:f.array(uW0).min(1).max(6),benefits:f.array(uW0).min(1).max(6),cta:kyw}),jyw=f.object({headline:f.string(),slug:f.string()}),Pyw=A72.extend({entityType:f.literal("products-overview"),metadata:jyw,frontmatter:_yw,body:Nyw,labels:f.record(f.string(),f.string())}),Myw=f.object({overview:Pyw,products:f.array(w72)}),Oyw=f.object({product:w72});class Z1A extends Zw{entityType=yW0.entityType;schema=eE;adapter=yW0;unregisterPrintableAttachmentProvider;unregisterOgImageAttachmentProvider;constructor(A={}){super("products",e92,A,B1A)}getTemplates(){return{"product-list":e1({name:"product-list",description:"Products page \u2014 overview + brain model cards",schema:Myw,dataSourceId:"products:entities",requiredPermission:"public",layout:{component:n92}}),"product-detail":e1({name:"product-detail",description:"Individual product detail page",schema:Oyw,dataSourceId:"products:entities",requiredPermission:"public",layout:{component:r92}})}}getDataSources(){return[new TW0(this.logger.child("ProductsDataSource"))]}async onRegister(A){this.unregisterPrintableAttachmentProvider=A.attachments.register("product",SW0,new X1A(A)),this.unregisterOgImageAttachmentProvider=A.attachments.register("product",mW0,new Y1A(A)),A.entities.register("products-overview",QT,$1A)}async onShutdown(){this.unregisterPrintableAttachmentProvider?.(),this.unregisterPrintableAttachmentProvider=void 0,this.unregisterOgImageAttachmentProvider?.(),this.unregisterOgImageAttachmentProvider=void 0}}function f1A(A={}){return new Z1A(A)}import{join as xiw}from"path";import{jsxDEV as cW0,Fragment as dyw}from"preact/jsx-dev-runtime";import{jsxDEV as Bp8}from"preact/jsx-dev-runtime";import{jsxDEV as fp8}from"preact/jsx-dev-runtime";import{jsxDEV as Wp8}from"preact/jsx-dev-runtime";import{jsxDEV as Up8}from"preact/jsx-dev-runtime";import{jsxDEV as Dp8}from"preact/jsx-dev-runtime";import{jsxDEV as Vp8}from"preact/jsx-dev-runtime";import{jsxDEV as Ip8}from"preact/jsx-dev-runtime";import{jsxDEV as bp8}from"preact/jsx-dev-runtime";import{jsxDEV as kp8,Fragment as _p8}from"preact/jsx-dev-runtime";import{jsxDEV as jp8}from"preact/jsx-dev-runtime";import{Fragment as Mp8}from"preact";import{jsxDEV as xp8}from"preact/jsx-dev-runtime";import{jsxDEV as vp8,Fragment as hp8}from"preact/jsx-dev-runtime";import{jsxDEV as tyw}from"preact/jsx-dev-runtime";import{jsxDEV as Ep8}from"preact/jsx-dev-runtime";import{jsxDEV as Sp8}from"preact/jsx-dev-runtime";import{jsxDEV as QEw}from"preact/jsx-dev-runtime";import{jsxDEV as cp8}from"preact/jsx-dev-runtime";import{jsxDEV as pp8}from"preact/jsx-dev-runtime";import{Fragment as dp8}from"preact";import{jsxDEV as rp8}from"preact/jsx-dev-runtime";import{jsxDEV as $72}from"preact/jsx-dev-runtime";import{default as pq}from"path";import{default as Xiw}from"process";import{fileURLToPath as Yiw}from"url";var{create:xyw,getPrototypeOf:Ryw,defineProperty:u1A,getOwnPropertyNames:vyw}=Object,hyw=Object.prototype.hasOwnProperty;function Cyw(A){return this[A]}var gyw,yyw,_42=(A,Q,w)=>{var $=A!=null&&typeof A==="object";if($){var B=Q?gyw??=new WeakMap:yyw??=new WeakMap,X=B.get(A);if(X)return X}w=A!=null?xyw(Ryw(A)):{};let Y=Q||!A||!A.__esModule?u1A(w,"default",{value:A,enumerable:!0}):w;for(let Z of vyw(A))if(!hyw.call(Y,Z))u1A(Y,Z,{get:Cyw.bind(A,Z),enumerable:!0});if($)B.set(A,Y);return Y},mL=(A,Q)=>()=>(Q||A((Q={exports:{}}).exports,Q),Q.exports),Eyw=(A)=>A;function Tyw(A,Q){this[A]=Eyw.bind(null,Q)}var rq=(A,Q)=>{for(var w in Q)u1A(A,w,{get:Q[w],enumerable:!0,configurable:!0,set:Tyw.bind(Q,w)})},oW0=import.meta.require,Syw=mL((A,Q)=>{var w=1000,$=w*60,B=$*60,X=B*24,Y=X*7,Z=X*365.25;Q.exports=function(G,q){q=q||{};var V=typeof G;if(V==="string"&&G.length>0)return H(G);else if(V==="number"&&isFinite(G))return q.long?K(G):W(G);throw Error("val is not a non-empty string or a valid number. val="+JSON.stringify(G))};function H(G){if(G=String(G),G.length>100)return;var q=/^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(G);if(!q)return;var V=parseFloat(q[1]),I=(q[2]||"ms").toLowerCase();switch(I){case"years":case"year":case"yrs":case"yr":case"y":return V*Z;case"weeks":case"week":case"w":return V*Y;case"days":case"day":case"d":return V*X;case"hours":case"hour":case"hrs":case"hr":case"h":return V*B;case"minutes":case"minute":case"mins":case"min":case"m":return V*$;case"seconds":case"second":case"secs":case"sec":case"s":return V*w;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return V;default:return}}function W(G){var q=Math.abs(G);if(q>=X)return Math.round(G/X)+"d";if(q>=B)return Math.round(G/B)+"h";if(q>=$)return Math.round(G/$)+"m";if(q>=w)return Math.round(G/w)+"s";return G+"ms"}function K(G){var q=Math.abs(G);if(q>=X)return U(G,q,X,"day");if(q>=B)return U(G,q,B,"hour");if(q>=$)return U(G,q,$,"minute");if(q>=w)return U(G,q,w,"second");return G+" ms"}function U(G,q,V,I){var J=q>=V*1.5;return Math.round(G/V)+" "+I+(J?"s":"")}}),N42=mL((A,Q)=>{function w($){X.debug=X,X.default=X,X.coerce=U,X.disable=W,X.enable=Z,X.enabled=K,X.humanize=Syw(),X.destroy=G,Object.keys($).forEach((q)=>{X[q]=$[q]}),X.names=[],X.skips=[],X.formatters={};function B(q){let V=0;for(let I=0;I<q.length;I++)V=(V<<5)-V+q.charCodeAt(I),V|=0;return X.colors[Math.abs(V)%X.colors.length]}X.selectColor=B;function X(q){let V,I=null,J,k;function j(..._){if(!j.enabled)return;let x=j,v=Number(new Date),O=v-(V||v);if(x.diff=O,x.prev=V,x.curr=v,V=v,_[0]=X.coerce(_[0]),typeof _[0]!=="string")_.unshift("%O");let M=0;_[0]=_[0].replace(/%([a-zA-Z%])/g,(u,n)=>{if(u==="%%")return"%";M++;let e=X.formatters[n];if(typeof e==="function"){let X0=_[M];u=e.call(x,X0),_.splice(M,1),M--}return u}),X.formatArgs.call(x,_),(x.log||X.log).apply(x,_)}if(j.namespace=q,j.useColors=X.useColors(),j.color=X.selectColor(q),j.extend=Y,j.destroy=X.destroy,Object.defineProperty(j,"enabled",{enumerable:!0,configurable:!1,get:()=>{if(I!==null)return I;if(J!==X.namespaces)J=X.namespaces,k=X.enabled(q);return k},set:(_)=>{I=_}}),typeof X.init==="function")X.init(j);return j}function Y(q,V){let I=X(this.namespace+(typeof V>"u"?":":V)+q);return I.log=this.log,I}function Z(q){X.save(q),X.namespaces=q,X.names=[],X.skips=[];let V=(typeof q==="string"?q:"").trim().replace(/\s+/g,",").split(",").filter(Boolean);for(let I of V)if(I[0]==="-")X.skips.push(I.slice(1));else X.names.push(I)}function H(q,V){let I=0,J=0,k=-1,j=0;while(I<q.length)if(J<V.length&&(V[J]===q[I]||V[J]==="*"))if(V[J]==="*")k=J,j=I,J++;else I++,J++;else if(k!==-1)J=k+1,j++,I=j;else return!1;while(J<V.length&&V[J]==="*")J++;return J===V.length}function W(){let q=[...X.names,...X.skips.map((V)=>"-"+V)].join(",");return X.enable(""),q}function K(q){for(let V of X.skips)if(H(q,V))return!1;for(let V of X.names)if(H(q,V))return!0;return!1}function U(q){if(q instanceof Error)return q.stack||q.message;return q}function G(){console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.")}return X.enable(X.load()),X}Q.exports=w}),myw=mL((A,Q)=>{A.formatArgs=$,A.save=B,A.load=X,A.useColors=w,A.storage=Y(),A.destroy=(()=>{let H=!1;return()=>{if(!H)H=!0,console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.")}})(),A.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"];function w(){if(typeof window<"u"&&window.process&&(window.process.type==="renderer"||window.process.__nwjs))return!0;if(typeof navigator<"u"&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/))return!1;let H;return typeof document<"u"&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||typeof window<"u"&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||typeof navigator<"u"&&navigator.userAgent&&(H=navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/))&&parseInt(H[1],10)>=31||typeof navigator<"u"&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)}function $(H){if(H[0]=(this.useColors?"%c":"")+this.namespace+(this.useColors?" %c":" ")+H[0]+(this.useColors?"%c ":" ")+"+"+Q.exports.humanize(this.diff),!this.useColors)return;let W="color: "+this.color;H.splice(1,0,W,"color: inherit");let K=0,U=0;H[0].replace(/%[a-zA-Z%]/g,(G)=>{if(G==="%%")return;if(K++,G==="%c")U=K}),H.splice(U,0,W)}A.log=console.debug||console.log||(()=>{});function B(H){try{if(H)A.storage.setItem("debug",H);else A.storage.removeItem("debug")}catch(W){}}function X(){let H;try{H=A.storage.getItem("debug")||A.storage.getItem("DEBUG")}catch(W){}if(!H&&typeof process<"u"&&"env"in process)H=process.env.DEBUG;return H}function Y(){try{return localStorage}catch(H){}}Q.exports=N42()(A);var{formatters:Z}=Q.exports;Z.j=function(H){try{return JSON.stringify(H)}catch(W){return"[UnexpectedJSONParseError]: "+W.message}}}),uyw=mL((A,Q)=>{Q.exports=(w,$=process.argv)=>{let B=w.startsWith("-")?"":w.length===1?"-":"--",X=$.indexOf(B+w),Y=$.indexOf("--");return X!==-1&&(Y===-1||X<Y)}}),cyw=mL((A,Q)=>{var w=oW0("os"),$=oW0("tty"),B=uyw(),{env:X}=process,Y;if(B("no-color")||B("no-colors")||B("color=false")||B("color=never"))Y=0;else if(B("color")||B("colors")||B("color=true")||B("color=always"))Y=1;if("FORCE_COLOR"in X)if(X.FORCE_COLOR==="true")Y=1;else if(X.FORCE_COLOR==="false")Y=0;else Y=X.FORCE_COLOR.length===0?1:Math.min(parseInt(X.FORCE_COLOR,10),3);function Z(K){if(K===0)return!1;return{level:K,hasBasic:!0,has256:K>=2,has16m:K>=3}}function H(K,U){if(Y===0)return 0;if(B("color=16m")||B("color=full")||B("color=truecolor"))return 3;if(B("color=256"))return 2;if(K&&!U&&Y===void 0)return 0;let G=Y||0;if(X.TERM==="dumb")return G;if(process.platform==="win32"){let q=w.release().split(".");if(Number(q[0])>=10&&Number(q[2])>=10586)return Number(q[2])>=14931?3:2;return 1}if("CI"in X){if(["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI","GITHUB_ACTIONS","BUILDKITE"].some((q)=>(q in X))||X.CI_NAME==="codeship")return 1;return G}if("TEAMCITY_VERSION"in X)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(X.TEAMCITY_VERSION)?1:0;if(X.COLORTERM==="truecolor")return 3;if("TERM_PROGRAM"in X){let q=parseInt((X.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(X.TERM_PROGRAM){case"iTerm.app":return q>=3?3:2;case"Apple_Terminal":return 2}}if(/-256(color)?$/i.test(X.TERM))return 2;if(/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(X.TERM))return 1;if("COLORTERM"in X)return 1;return G}function W(K){let U=H(K,K&&K.isTTY);return Z(U)}Q.exports={supportsColor:W,stdout:Z(H(!0,$.isatty(1))),stderr:Z(H(!0,$.isatty(2)))}}),lyw=mL((A,Q)=>{var w=oW0("tty"),$=oW0("util");A.init=K,A.log=Z,A.formatArgs=X,A.save=H,A.load=W,A.useColors=B,A.destroy=$.deprecate(()=>{},"Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."),A.colors=[6,2,3,4,5,1];try{let G=cyw();if(G&&(G.stderr||G).level>=2)A.colors=[20,21,26,27,32,33,38,39,40,41,42,43,44,45,56,57,62,63,68,69,74,75,76,77,78,79,80,81,92,93,98,99,112,113,128,129,134,135,148,149,160,161,162,163,164,165,166,167,168,169,170,171,172,173,178,179,184,185,196,197,198,199,200,201,202,203,204,205,206,207,208,209,214,215,220,221]}catch(G){}A.inspectOpts=Object.keys(process.env).filter((G)=>{return/^debug_/i.test(G)}).reduce((G,q)=>{let V=q.substring(6).toLowerCase().replace(/_([a-z])/g,(J,k)=>{return k.toUpperCase()}),I=process.env[q];if(/^(yes|on|true|enabled)$/i.test(I))I=!0;else if(/^(no|off|false|disabled)$/i.test(I))I=!1;else if(I==="null")I=null;else I=Number(I);return G[V]=I,G},{});function B(){return"colors"in A.inspectOpts?Boolean(A.inspectOpts.colors):w.isatty(process.stderr.fd)}function X(G){let{namespace:q,useColors:V}=this;if(V){let I=this.color,J="\x1B[3"+(I<8?I:"8;5;"+I),k=` ${J};1m${q} \x1B[0m`;G[0]=k+G[0].split(`
10607
+ `).trim();return X.length>0?X:void 0}function zyw(A){let Q=A.metadata.slug;return Q.length>0?Q:q1(A.metadata.name)}var e92={name:"@brains/products",version:"0.2.0-alpha.159",description:"Product entity management and overview page for marketing showcase",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":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var Jyw=f.union([f.enum(["public","shared","restricted"]),f.literal("private")]).optional().transform((A)=>{if(A===void 0)return"public";if(A==="private")return"restricted";return A}),A72=f.object({id:f.string(),entityType:f.string(),content:f.string(),created:f.string(),updated:f.string(),visibility:Jyw,metadata:f.record(f.string(),f.unknown()),contentHash:f.string()}),Q72=f.enum(["available","early access","coming soon","planned"]),Iyw=f.object({title:f.string(),description:f.string()}),Fyw=f.object({name:f.string(),availability:Q72,order:f.number(),ogImageId:f.string().optional()}),byw=f.object({tagline:f.string(),promise:f.string(),role:f.string(),purpose:f.string(),audience:f.string(),values:f.array(f.string()).min(1),features:f.array(Iyw).min(1).max(6),story:f.string()}),Lyw=f.object({name:f.string(),availability:Q72,order:f.number(),slug:f.string()}),w72=A72.extend({entityType:f.literal("product"),metadata:Lyw,frontmatter:Fyw,body:byw,labels:f.record(f.string(),f.string()),url:f.string().optional(),typeLabel:f.string().optional(),listUrl:f.string().optional(),listLabel:f.string().optional(),ogImageUrl:f.string().optional()}),uW0=f.object({title:f.string(),description:f.string()}),kyw=f.object({heading:f.string(),buttonText:f.string(),link:f.string()}),_yw=f.object({headline:f.string(),tagline:f.string()}),Nyw=f.object({vision:f.string(),pillars:f.array(uW0).min(1).max(6),approach:f.array(uW0).min(1).max(6),productsIntro:f.string(),technologies:f.array(uW0).min(1).max(6),benefits:f.array(uW0).min(1).max(6),cta:kyw}),jyw=f.object({headline:f.string(),slug:f.string()}),Pyw=A72.extend({entityType:f.literal("products-overview"),metadata:jyw,frontmatter:_yw,body:Nyw,labels:f.record(f.string(),f.string())}),Myw=f.object({overview:Pyw,products:f.array(w72)}),Oyw=f.object({product:w72});class Z1A extends Zw{entityType=yW0.entityType;schema=eE;adapter=yW0;unregisterPrintableAttachmentProvider;unregisterOgImageAttachmentProvider;constructor(A={}){super("products",e92,A,B1A)}getTemplates(){return{"product-list":e1({name:"product-list",description:"Products page \u2014 overview + brain model cards",schema:Myw,dataSourceId:"products:entities",requiredPermission:"public",layout:{component:n92}}),"product-detail":e1({name:"product-detail",description:"Individual product detail page",schema:Oyw,dataSourceId:"products:entities",requiredPermission:"public",layout:{component:r92}})}}getDataSources(){return[new TW0(this.logger.child("ProductsDataSource"))]}async onRegister(A){this.unregisterPrintableAttachmentProvider=A.attachments.register("product",SW0,new X1A(A)),this.unregisterOgImageAttachmentProvider=A.attachments.register("product",mW0,new Y1A(A)),A.entities.register("products-overview",QT,$1A)}async onShutdown(){this.unregisterPrintableAttachmentProvider?.(),this.unregisterPrintableAttachmentProvider=void 0,this.unregisterOgImageAttachmentProvider?.(),this.unregisterOgImageAttachmentProvider=void 0}}function f1A(A={}){return new Z1A(A)}import{join as xiw}from"path";import{jsxDEV as cW0,Fragment as dyw}from"preact/jsx-dev-runtime";import{jsxDEV as Bp8}from"preact/jsx-dev-runtime";import{jsxDEV as fp8}from"preact/jsx-dev-runtime";import{jsxDEV as Wp8}from"preact/jsx-dev-runtime";import{jsxDEV as Up8}from"preact/jsx-dev-runtime";import{jsxDEV as Dp8}from"preact/jsx-dev-runtime";import{jsxDEV as Vp8}from"preact/jsx-dev-runtime";import{jsxDEV as Ip8}from"preact/jsx-dev-runtime";import{jsxDEV as bp8}from"preact/jsx-dev-runtime";import{jsxDEV as kp8,Fragment as _p8}from"preact/jsx-dev-runtime";import{jsxDEV as jp8}from"preact/jsx-dev-runtime";import{Fragment as Mp8}from"preact";import{jsxDEV as xp8}from"preact/jsx-dev-runtime";import{jsxDEV as vp8,Fragment as hp8}from"preact/jsx-dev-runtime";import{jsxDEV as tyw}from"preact/jsx-dev-runtime";import{jsxDEV as Ep8}from"preact/jsx-dev-runtime";import{jsxDEV as Sp8}from"preact/jsx-dev-runtime";import{jsxDEV as QEw}from"preact/jsx-dev-runtime";import{jsxDEV as cp8}from"preact/jsx-dev-runtime";import{jsxDEV as pp8}from"preact/jsx-dev-runtime";import{Fragment as dp8}from"preact";import{jsxDEV as rp8}from"preact/jsx-dev-runtime";import{jsxDEV as $72}from"preact/jsx-dev-runtime";import{default as pq}from"path";import{default as Xiw}from"process";import{fileURLToPath as Yiw}from"url";var{create:xyw,getPrototypeOf:Ryw,defineProperty:u1A,getOwnPropertyNames:vyw}=Object,hyw=Object.prototype.hasOwnProperty;function Cyw(A){return this[A]}var gyw,yyw,_42=(A,Q,w)=>{var $=A!=null&&typeof A==="object";if($){var B=Q?gyw??=new WeakMap:yyw??=new WeakMap,X=B.get(A);if(X)return X}w=A!=null?xyw(Ryw(A)):{};let Y=Q||!A||!A.__esModule?u1A(w,"default",{value:A,enumerable:!0}):w;for(let Z of vyw(A))if(!hyw.call(Y,Z))u1A(Y,Z,{get:Cyw.bind(A,Z),enumerable:!0});if($)B.set(A,Y);return Y},mL=(A,Q)=>()=>(Q||A((Q={exports:{}}).exports,Q),Q.exports),Eyw=(A)=>A;function Tyw(A,Q){this[A]=Eyw.bind(null,Q)}var rq=(A,Q)=>{for(var w in Q)u1A(A,w,{get:Q[w],enumerable:!0,configurable:!0,set:Tyw.bind(Q,w)})},oW0=import.meta.require,Syw=mL((A,Q)=>{var w=1000,$=w*60,B=$*60,X=B*24,Y=X*7,Z=X*365.25;Q.exports=function(G,q){q=q||{};var V=typeof G;if(V==="string"&&G.length>0)return H(G);else if(V==="number"&&isFinite(G))return q.long?K(G):W(G);throw Error("val is not a non-empty string or a valid number. val="+JSON.stringify(G))};function H(G){if(G=String(G),G.length>100)return;var q=/^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(G);if(!q)return;var V=parseFloat(q[1]),I=(q[2]||"ms").toLowerCase();switch(I){case"years":case"year":case"yrs":case"yr":case"y":return V*Z;case"weeks":case"week":case"w":return V*Y;case"days":case"day":case"d":return V*X;case"hours":case"hour":case"hrs":case"hr":case"h":return V*B;case"minutes":case"minute":case"mins":case"min":case"m":return V*$;case"seconds":case"second":case"secs":case"sec":case"s":return V*w;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return V;default:return}}function W(G){var q=Math.abs(G);if(q>=X)return Math.round(G/X)+"d";if(q>=B)return Math.round(G/B)+"h";if(q>=$)return Math.round(G/$)+"m";if(q>=w)return Math.round(G/w)+"s";return G+"ms"}function K(G){var q=Math.abs(G);if(q>=X)return U(G,q,X,"day");if(q>=B)return U(G,q,B,"hour");if(q>=$)return U(G,q,$,"minute");if(q>=w)return U(G,q,w,"second");return G+" ms"}function U(G,q,V,I){var J=q>=V*1.5;return Math.round(G/V)+" "+I+(J?"s":"")}}),N42=mL((A,Q)=>{function w($){X.debug=X,X.default=X,X.coerce=U,X.disable=W,X.enable=Z,X.enabled=K,X.humanize=Syw(),X.destroy=G,Object.keys($).forEach((q)=>{X[q]=$[q]}),X.names=[],X.skips=[],X.formatters={};function B(q){let V=0;for(let I=0;I<q.length;I++)V=(V<<5)-V+q.charCodeAt(I),V|=0;return X.colors[Math.abs(V)%X.colors.length]}X.selectColor=B;function X(q){let V,I=null,J,k;function j(..._){if(!j.enabled)return;let x=j,v=Number(new Date),O=v-(V||v);if(x.diff=O,x.prev=V,x.curr=v,V=v,_[0]=X.coerce(_[0]),typeof _[0]!=="string")_.unshift("%O");let M=0;_[0]=_[0].replace(/%([a-zA-Z%])/g,(u,n)=>{if(u==="%%")return"%";M++;let e=X.formatters[n];if(typeof e==="function"){let X0=_[M];u=e.call(x,X0),_.splice(M,1),M--}return u}),X.formatArgs.call(x,_),(x.log||X.log).apply(x,_)}if(j.namespace=q,j.useColors=X.useColors(),j.color=X.selectColor(q),j.extend=Y,j.destroy=X.destroy,Object.defineProperty(j,"enabled",{enumerable:!0,configurable:!1,get:()=>{if(I!==null)return I;if(J!==X.namespaces)J=X.namespaces,k=X.enabled(q);return k},set:(_)=>{I=_}}),typeof X.init==="function")X.init(j);return j}function Y(q,V){let I=X(this.namespace+(typeof V>"u"?":":V)+q);return I.log=this.log,I}function Z(q){X.save(q),X.namespaces=q,X.names=[],X.skips=[];let V=(typeof q==="string"?q:"").trim().replace(/\s+/g,",").split(",").filter(Boolean);for(let I of V)if(I[0]==="-")X.skips.push(I.slice(1));else X.names.push(I)}function H(q,V){let I=0,J=0,k=-1,j=0;while(I<q.length)if(J<V.length&&(V[J]===q[I]||V[J]==="*"))if(V[J]==="*")k=J,j=I,J++;else I++,J++;else if(k!==-1)J=k+1,j++,I=j;else return!1;while(J<V.length&&V[J]==="*")J++;return J===V.length}function W(){let q=[...X.names,...X.skips.map((V)=>"-"+V)].join(",");return X.enable(""),q}function K(q){for(let V of X.skips)if(H(q,V))return!1;for(let V of X.names)if(H(q,V))return!0;return!1}function U(q){if(q instanceof Error)return q.stack||q.message;return q}function G(){console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.")}return X.enable(X.load()),X}Q.exports=w}),myw=mL((A,Q)=>{A.formatArgs=$,A.save=B,A.load=X,A.useColors=w,A.storage=Y(),A.destroy=(()=>{let H=!1;return()=>{if(!H)H=!0,console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.")}})(),A.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"];function w(){if(typeof window<"u"&&window.process&&(window.process.type==="renderer"||window.process.__nwjs))return!0;if(typeof navigator<"u"&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/))return!1;let H;return typeof document<"u"&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||typeof window<"u"&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||typeof navigator<"u"&&navigator.userAgent&&(H=navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/))&&parseInt(H[1],10)>=31||typeof navigator<"u"&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)}function $(H){if(H[0]=(this.useColors?"%c":"")+this.namespace+(this.useColors?" %c":" ")+H[0]+(this.useColors?"%c ":" ")+"+"+Q.exports.humanize(this.diff),!this.useColors)return;let W="color: "+this.color;H.splice(1,0,W,"color: inherit");let K=0,U=0;H[0].replace(/%[a-zA-Z%]/g,(G)=>{if(G==="%%")return;if(K++,G==="%c")U=K}),H.splice(U,0,W)}A.log=console.debug||console.log||(()=>{});function B(H){try{if(H)A.storage.setItem("debug",H);else A.storage.removeItem("debug")}catch(W){}}function X(){let H;try{H=A.storage.getItem("debug")||A.storage.getItem("DEBUG")}catch(W){}if(!H&&typeof process<"u"&&"env"in process)H=process.env.DEBUG;return H}function Y(){try{return localStorage}catch(H){}}Q.exports=N42()(A);var{formatters:Z}=Q.exports;Z.j=function(H){try{return JSON.stringify(H)}catch(W){return"[UnexpectedJSONParseError]: "+W.message}}}),uyw=mL((A,Q)=>{Q.exports=(w,$=process.argv)=>{let B=w.startsWith("-")?"":w.length===1?"-":"--",X=$.indexOf(B+w),Y=$.indexOf("--");return X!==-1&&(Y===-1||X<Y)}}),cyw=mL((A,Q)=>{var w=oW0("os"),$=oW0("tty"),B=uyw(),{env:X}=process,Y;if(B("no-color")||B("no-colors")||B("color=false")||B("color=never"))Y=0;else if(B("color")||B("colors")||B("color=true")||B("color=always"))Y=1;if("FORCE_COLOR"in X)if(X.FORCE_COLOR==="true")Y=1;else if(X.FORCE_COLOR==="false")Y=0;else Y=X.FORCE_COLOR.length===0?1:Math.min(parseInt(X.FORCE_COLOR,10),3);function Z(K){if(K===0)return!1;return{level:K,hasBasic:!0,has256:K>=2,has16m:K>=3}}function H(K,U){if(Y===0)return 0;if(B("color=16m")||B("color=full")||B("color=truecolor"))return 3;if(B("color=256"))return 2;if(K&&!U&&Y===void 0)return 0;let G=Y||0;if(X.TERM==="dumb")return G;if(process.platform==="win32"){let q=w.release().split(".");if(Number(q[0])>=10&&Number(q[2])>=10586)return Number(q[2])>=14931?3:2;return 1}if("CI"in X){if(["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI","GITHUB_ACTIONS","BUILDKITE"].some((q)=>(q in X))||X.CI_NAME==="codeship")return 1;return G}if("TEAMCITY_VERSION"in X)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(X.TEAMCITY_VERSION)?1:0;if(X.COLORTERM==="truecolor")return 3;if("TERM_PROGRAM"in X){let q=parseInt((X.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(X.TERM_PROGRAM){case"iTerm.app":return q>=3?3:2;case"Apple_Terminal":return 2}}if(/-256(color)?$/i.test(X.TERM))return 2;if(/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(X.TERM))return 1;if("COLORTERM"in X)return 1;return G}function W(K){let U=H(K,K&&K.isTTY);return Z(U)}Q.exports={supportsColor:W,stdout:Z(H(!0,$.isatty(1))),stderr:Z(H(!0,$.isatty(2)))}}),lyw=mL((A,Q)=>{var w=oW0("tty"),$=oW0("util");A.init=K,A.log=Z,A.formatArgs=X,A.save=H,A.load=W,A.useColors=B,A.destroy=$.deprecate(()=>{},"Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."),A.colors=[6,2,3,4,5,1];try{let G=cyw();if(G&&(G.stderr||G).level>=2)A.colors=[20,21,26,27,32,33,38,39,40,41,42,43,44,45,56,57,62,63,68,69,74,75,76,77,78,79,80,81,92,93,98,99,112,113,128,129,134,135,148,149,160,161,162,163,164,165,166,167,168,169,170,171,172,173,178,179,184,185,196,197,198,199,200,201,202,203,204,205,206,207,208,209,214,215,220,221]}catch(G){}A.inspectOpts=Object.keys(process.env).filter((G)=>{return/^debug_/i.test(G)}).reduce((G,q)=>{let V=q.substring(6).toLowerCase().replace(/_([a-z])/g,(J,k)=>{return k.toUpperCase()}),I=process.env[q];if(/^(yes|on|true|enabled)$/i.test(I))I=!0;else if(/^(no|off|false|disabled)$/i.test(I))I=!1;else if(I==="null")I=null;else I=Number(I);return G[V]=I,G},{});function B(){return"colors"in A.inspectOpts?Boolean(A.inspectOpts.colors):w.isatty(process.stderr.fd)}function X(G){let{namespace:q,useColors:V}=this;if(V){let I=this.color,J="\x1B[3"+(I<8?I:"8;5;"+I),k=` ${J};1m${q} \x1B[0m`;G[0]=k+G[0].split(`
10608
10608
  `).join(`
10609
10609
  `+k),G.push(J+"m+"+Q.exports.humanize(this.diff)+"\x1B[0m")}else G[0]=Y()+q+" "+G[0]}function Y(){if(A.inspectOpts.hideDate)return"";return new Date().toISOString()+" "}function Z(...G){return process.stderr.write($.formatWithOptions(A.inspectOpts,...G)+`
10610
10610
  `)}function H(G){if(G)process.env.DEBUG=G;else delete process.env.DEBUG}function W(){return process.env.DEBUG}function K(G){G.inspectOpts={};let q=Object.keys(A.inspectOpts);for(let V=0;V<q.length;V++)G.inspectOpts[q[V]]=A.inspectOpts[q[V]]}Q.exports=N42()(A);var{formatters:U}=Q.exports;U.o=function(G){return this.inspectOpts.colors=this.useColors,$.inspect(G,this.inspectOpts).split(`
@@ -13231,7 +13231,7 @@ facts, owners, or tasks. Return only the required structured JSON.`});C0();var t
13231
13231
  `);return this.truncateContent($||Q||_T(A))}truncateContent(A){if(A.length<=QU2)return A;let Q=A.slice(0,QU2-1),w=Q.search(/\s\S*$/);return`${(w>0?Q.slice(0,w):Q).trimEnd()}\u2026`}isSummaryEntity(A){return A.entityType===oB}isDecisionEntity(A){return A.entityType===_H}getEntitySpaceId(A){let Q=A.metadata;if("spaceId"in Q&&typeof Q.spaceId==="string")return Q.spaceId;return DG(Q)}}var jdw=5,Pdw=3;function bwA(A){A.messaging.subscribe(nk,async(Q)=>{let w=Nm.parse(Q.payload);return{success:!0,data:await ZU0(A,w)}})}async function ZU0(A,Q){let w=_8(Q.userPermissionLevel);if(!Q.channelId)return wU2(A,Q,{visibilityScope:w,reason:"no-channel-context",items:[]}),{items:[]};let $=new NT(A),B=await $.retrieve({query:Q.message,conversationId:Q.conversationId,interfaceType:Q.interfaceType,channelId:Q.channelId,limit:jdw,visibilityScope:w}),X=B.results.length===0?await $.retrieve({conversationId:Q.conversationId,interfaceType:Q.interfaceType,channelId:Q.channelId,limit:Pdw,visibilityScope:w}):void 0,Y=B.results.length>0,Z=Y?B.results:X?.results??[];return wU2(A,Q,{visibilityScope:w,spaceId:B.spaceId??X?.spaceId,reason:Z.length>0?"memory-injected":"no-same-space-memory",items:Z.map((H)=>Mdw(H,Y))}),{items:Z.map(Odw)}}function wU2(A,Q,w){A.logger.info("Conversation memory agent context audit",{conversationId:Q.conversationId,interfaceType:Q.interfaceType,channelId:Q.channelId,channelName:Q.channelName,userPermissionLevel:Q.userPermissionLevel,visibilityScope:w.visibilityScope,spaceId:w.spaceId,reason:w.reason,itemCount:w.items.length,items:w.items})}function Mdw(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 Odw(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}}}C0();Xf();var XU2=f.union([f.enum(["public","shared","restricted"]),f.literal("private")]).optional().transform((A)=>{if(A===void 0)return"public";if(A==="private")return"restricted";return A}),YU2=f.enum(["user","assistant"]),xdw=f.object({actorId:f.string(),canonicalId:f.string().optional(),interfaceType:f.string(),role:YU2,displayName:f.string().optional(),username:f.string().optional(),isBot:f.boolean().optional()}),Rdw=f.object({messageId:f.string().optional(),channelId:f.string().optional(),channelName:f.string().optional(),threadId:f.string().optional(),metadata:f.record(f.string(),f.unknown()).optional()}),kwA=f.object({role:YU2,content:f.string(),timestamp:f.string().datetime().optional(),actor:xdw.optional(),source:Rdw.optional()}),vdw=f.object({conversationId:f.string().default("eval-conversation"),messages:f.array(kwA)}),hdw=f.object({conversationId:f.string()}),Cdw=f.object({conversationId:f.string().default("eval-conversation"),interfaceType:f.string().default("eval"),channelId:f.string().default("eval-channel"),channelName:f.string().optional(),projectionDecision:f.enum(["update","append"]).default("update"),existingSummary:f.string().optional(),existingMessageCount:f.number().int().min(0).default(0),messages:f.array(kwA)}),fU0=f.object({actorId:f.string(),canonicalId:f.string().optional(),displayName:f.string().optional()}),gdw=fU0.extend({roles:f.array(f.enum(["user","assistant","system"])).default(["user"]),sourceActorIds:f.array(f.string()).optional()}),ydw=f.object({actorId:f.string().optional(),canonicalId:f.string().optional(),displayName:f.string()}),ZU2=f.object({id:f.string(),entityType:f.enum(["summary","decision","action-item"]),content:f.string(),excerpt:f.string().optional(),score:f.number().optional(),conversationId:f.string(),interfaceType:f.string(),channelId:f.string(),channelName:f.string().optional(),updated:f.string().datetime().optional(),visibility:XU2,status:f.string().optional(),participants:f.array(gdw).optional(),decidedBy:f.array(fU0).optional(),mentionedBy:f.array(fU0).optional(),assignedTo:f.array(ydw).optional(),requestedBy:f.array(fU0).optional()}),Edw=f.object({query:f.string().optional(),conversationId:f.string().optional(),interfaceType:f.string().optional(),channelId:f.string().optional(),limit:f.number().int().min(1).optional(),includeOtherSpaces:f.boolean().optional(),actorId:f.string().optional(),canonicalId:f.string().optional(),visibilityScope:XU2.optional(),memory:f.array(ZU2).optional()}),Tdw=f.object({conversationId:f.string().default("eval-conversation"),message:f.string(),interfaceType:f.string().default("eval"),channelId:f.string().optional(),channelName:f.string().optional(),userPermissionLevel:f.enum(["anchor","trusted","public"]).default("trusted"),memory:f.array(ZU2).optional()}),Sdw=f.object({conversationId:f.string().default("eval-conversation"),existingSummary:f.string().optional(),existingMessageCount:f.number().int().min(0).default(0),messages:f.array(kwA)});function fU2(A){let{context:Q,logger:w,config:$}=A;Q.eval.registerHandler("summarizeMessages",async(B)=>{let X=vdw.parse(B),Y=LwA(X.messages,X.conversationId),H=await new bT(Q,w,$).extract(Y);return H.entries.map((W)=>{let K=H.decisions.filter((G)=>G.timeRange.start>=W.timeRange.start).filter((G)=>G.timeRange.end<=W.timeRange.end).map((G)=>G.text),U=H.actionItems.filter((G)=>G.timeRange.start>=W.timeRange.start).filter((G)=>G.timeRange.end<=W.timeRange.end).map((G)=>G.text);return{...W,decisions:K,actionItems:U,keyPointsText:W.keyPoints.join(`
13232
13232
  `),decisionsText:K.join(`
13233
13233
  `),actionItemsText:U.join(`
13234
- `)}})}),Q.eval.registerHandler("decideProjection",async(B)=>{let X=Sdw.parse(B),Y=LwA(X.messages,X.conversationId),Z=X.existingSummary?$U2({conversationId:X.conversationId,content:X.existingSummary,messageCount:X.existingMessageCount,projectionVersion:$.projectionVersion,visibility:$.memoryVisibility}):null;return new lL(Q,w,$).decideProjection(Y,Z)}),Q.eval.registerHandler("retrieveMemory",async(B)=>{let X=Edw.parse(B),Y=X.memory?BU2(Q,X.memory):Q;return new NT(Y).retrieve(X)}),Q.eval.registerHandler("buildAgentContext",async(B)=>{let X=Tdw.parse(B),Y=X.memory?BU2(Q,X.memory):Q;return ZU0(Y,X)}),Q.eval.registerHandler("projectMessages",async(B)=>{let X=Cdw.parse(B),Y=LwA(X.messages,X.conversationId),Z=mdw({conversationId:X.conversationId,interfaceType:X.interfaceType,channelId:X.channelId,channelName:X.channelName,messages:Y}),H=X.existingSummary?$U2({conversationId:X.conversationId,content:X.existingSummary,messageCount:X.existingMessageCount,projectionVersion:$.projectionVersion,visibility:$.memoryVisibility}):null,W=[],K=[],U=udw({context:Q,conversation:Z,messages:Y,existing:H,upserted:W,deleted:K,projectionDecision:X.projectionDecision});return{result:await new lL(U,w,$).projectConversation(X.conversationId),summaries:W.filter((V)=>V.entityType==="summary"),decisions:W.filter((V)=>V.entityType==="decision"),actionItems:W.filter((V)=>V.entityType==="action-item"),deleted:K}}),Q.eval.registerHandler("projectConversation",async(B)=>{let X=hdw.parse(B);return new lL(Q,w,$).projectConversation(X.conversationId)})}function $U2(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 LwA(A,Q){return A.map((w,$)=>{let B=w.timestamp??new Date(Date.UTC(2026,0,1,0,$)).toISOString();return{id:`eval-message-${$+1}`,conversationId:Q,role:w.role,content:w.content,timestamp:B,metadata:{...w.actor?{actor:w.actor}:{},...w.source?{source:w.source}:{}}}})}function mdw(A){let Q=A.messages[0],w=A.messages[A.messages.length-1],$=Q?.timestamp??"2026-01-01T00:00:00.000Z",B=w?.timestamp??$;return{id:A.conversationId,sessionId:A.conversationId,interfaceType:A.interfaceType,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},startedAt:$,lastActiveAt:B,createdAt:$,updatedAt:B,metadata:{}}}function udw(A){let Q=DG(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:w})=>w==="summary"?A.existing:null,listEntities:async()=>[],deleteEntity:async(w)=>{return A.deleted.push(w),!0},upsertEntity:async({entity:w})=>{return A.upserted.push(w),{entityId:w.id,jobId:"eval-upsert",created:!0,skipped:!1}}}}}function BU2(A,Q){let w=Q.map(cdw),$=w.map((B,X)=>({entity:B,score:Q[X]?.score??1,excerpt:Q[X]?.excerpt??_T(B)}));return{...A,entityService:{...A.entityService,search:async()=>$,listEntities:async({entityType:B})=>w.filter((X)=>X.entityType===B)}}}function cdw(A){if(A.entityType==="summary")return ldw(A);if(A.entityType==="decision")return pdw(A);return idw(A)}function _wA(A){let Q=A.updated??"2026-01-01T00:00:00.000Z";return{id:A.id,content:A.content,contentHash:I6(A.content),visibility:A.visibility,created:Q,updated:Q}}function ldw(A){return{..._wA(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 pdw(A){return{..._wA(A),entityType:"decision",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,spaceId:DG(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 idw(A){let Q=A.status==="done"||A.status==="dropped"?A.status:"open";return{..._wA(A),entityType:"action-item",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,spaceId:DG(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 HU2={name:"@brains/conversation-memory",version:"0.2.0-alpha.158",description:"Plugin for deriving durable conversation memory",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.19.43",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},main:"./src/index.ts",private:!0,scripts:{eval:"cd evals && bun run brain-eval",lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var ndw=new UK,rdw=new JT,odw=new IT,sdw=f.object({conversationId:f.string()});class NwA extends Zw{entityType=oB;schema=It;adapter=ndw;constructor(A={}){super(sK0,HU2,A,VwA)}getConfig(){return this.config}getTemplates(){return{"summary-list":hK2,"summary-detail":CK2,"ai-response":gK2}}getDataSources(){return[new FwA(this.logger.child("SummaryDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableProjection)return[];return[{id:"conversation-memory-projection",targetType:oB,job:{type:kK2,handler:new wU0(A,this.logger,this.config)},initialSync:{shouldEnqueue:async()=>A.spaces.length>0&&!await L_(A,oB,{outputVisibility:this.config.memoryVisibility}),jobData:{mode:"rebuild-all",reason:"initial-sync"},jobOptions:{source:GwA,deduplication:"coalesce",deduplicationKey:"conversation-memory:rebuild-all:initial-sync",metadata:{operationType:"data_processing",operationTarget:"conversation-memory:rebuild-all",pluginId:sK0}}},sourceChange:{sourceKind:Xu,sourceTypes:[Xu],shouldEnqueue:(Q)=>this.shouldEnqueueConversationProjection(A,Q),events:[rx],jobData:(Q)=>{let{conversationId:w}=this.parseConversationMessagePayload(Q);return{mode:"conversation",conversationId:w,reason:"message-added"}},jobOptions:(Q)=>{let{conversationId:w}=this.parseConversationMessagePayload(Q);return{priority:5,delayMs:this.config.projectionDelayMs,source:GwA,deduplication:"skip",deduplicationKey:`conversation-memory:${w}`,metadata:{operationType:"data_processing",operationTarget:`conversation-memory:${w}`,pluginId:sK0}}}}}]}parseConversationMessagePayload(A){return sdw.parse(A)}async shouldEnqueueConversationProjection(A,Q){let{conversationId:w}=this.parseConversationMessagePayload(Q),$=await A.conversations.get(w);if(!$)return!1;return mM({conversation:$,spaces:A.spaces}).eligible}async onRegister(A){A.entities.register(_H,Ft,rdw),A.entities.register(KK,bt,odw),TK2({context:A,pluginId:this.id}),mK2({context:A,pluginId:this.id}),sK2({context:A,pluginId:this.id}),eK2({context:A,pluginId:this.id,config:this.config}),bwA(A),fU2({context:A,logger:this.logger,config:this.config})}}function jwA(A={}){return new NwA(A)}fA();C0();C0();b9();var WU2=f.object({label:f.string(),href:f.string()}),KU2=f.object({label:f.string(),title:f.string(),detail:f.string()}),adw=f.object({eyebrow:f.string(),name:f.string(),sub:f.string()}),tdw=f.object({tone:f.enum(["capture","synthesis","share"]),title:f.string(),text:f.string()}),PwA=f.object({captures:f.number(),links:f.number(),topics:f.number(),summaries:f.number(),peers:f.number()}),jT=f.object({eyebrow:f.string(),headline:f.string(),intro:f.string(),primaryCta:WU2,secondaryCta:WU2,inputs:f.array(KU2).min(1),outputs:f.array(KU2).min(1),core:adw,legend:f.array(tdw).min(1)}),MwA=jT.extend({counts:PwA}),UU2={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."}]},GU2=new R6(jT,{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 HU0(A){return GU2.parse(A)}function DU2(A){return GU2.format(A)}C0();var edw=f.looseObject({query:f.object({routeId:f.string().default("home"),sectionId:f.string().default("diagram")}).default({routeId:"home",sectionId:"diagram"})}),Anw={captures:"note",links:"link",topics:"topic",summaries:"summary",peers:"agent"};class OwA{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,w){let $=edw.parse(A??{}),B=await this.fetchContent(w,$.query.routeId,$.query.sectionId),X=await this.fetchCounts(w);return Q.parse({...B,counts:X})}async fetchContent(A,Q,w){let $=await A.entityService.getEntity({entityType:"site-content",id:`${Q}:${w}`});if(!$?.content)return UU2;return jT.parse(HU0($.content))}async fetchCounts(A){let Q=await Promise.all(Object.entries(Anw).map(async([w,$])=>[w,await this.countOrZero(A,$)]));return PwA.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 b1}from"preact/jsx-dev-runtime";var qU2=f.object({label:f.string(),href:f.string()}),Qnw=f.object({label:f.string(),value:f.string(),note:f.string()}),wnw=f.object({eyebrow:f.string(),headline:f.string(),intro:f.string(),primaryCta:qU2,secondaryCta:qU2,signals:f.array(Qnw)}),$nw=f.object({phase:f.string(),title:f.string(),text:f.string()}),Bnw=f.object({eyebrow:f.string(),title:f.string(),intro:f.string(),steps:f.array($nw)}),Xnw=f.object({label:f.string(),title:f.string(),text:f.string()}),Ynw=f.object({title:f.string(),intro:f.string(),cards:f.array(Xnw)}),Znw=f.object({title:f.string(),intro:f.string(),points:f.array(f.string())}),fnw={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."]},Hnw="font-body text-[15px] text-theme-muted transition-colors hover:text-theme";function zU2({href:A,label:Q}){return b1("a",{href:A,className:Hnw,children:Q},void 0,!1,void 0,this)}function Wnw({siteInfo:A,children:Q}){let w=[...A.navigation.primary,...A.navigation.secondary],$=A.cta??{buttonText:"Start here",buttonLink:"/about"};return b1(w2A,{children:[b1("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:[b1("a",{href:"/",className:"font-nav text-[20px]","aria-label":"Relay home",children:[b1("span",{className:"font-bold text-theme",children:"relay"},void 0,!1,void 0,this),b1("span",{className:"font-bold text-accent",children:"."},void 0,!1,void 0,this),b1("span",{className:"text-theme-muted",children:"brain"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),b1("div",{className:"flex items-center gap-5 md:gap-8",children:[b1("div",{className:"hidden items-center gap-6 md:flex",children:w.map((B)=>b1(zU2,{...B},`${B.href}-${B.label}`,!1,void 0,this))},void 0,!1,void 0,this),b1("a",{href:$.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:$.buttonText},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),b1("main",{children:Q},void 0,!1,void 0,this),b1("footer",{className:"relative z-[1] border-t border-theme-light px-6 py-8 md:px-10 xl:px-20",children:b1("div",{className:"flex flex-col gap-4 md:flex-row md:items-center md:justify-between",children:[b1("div",{children:[b1("p",{className:"font-label text-label-sm uppercase tracking-[0.22em] text-theme-light",children:A.copyright},void 0,!1,void 0,this),b1("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),b1("div",{className:"flex flex-wrap items-center gap-5",children:[w.map((B)=>b1(zU2,{...B},`footer-${B.href}-${B.label}`,!1,void 0,this)),b1("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 Knw=({sections:A,siteInfo:Q})=>b1(Wnw,{siteInfo:Q,children:A},void 0,!1,void 0,this);function Unw({eyebrow:A,headline:Q,intro:w,primaryCta:$,secondaryCta:B,signals:X}){return b1(GT,{className:"min-h-[92vh] pt-[152px] pb-20 md:pt-[190px]",children:b1("div",{className:"grid gap-10 lg:grid-cols-[minmax(0,1fr)_420px] lg:items-end",children:[b1("div",{children:[b1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:A},void 0,!1,void 0,this),b1("h1",{className:"mt-7 max-w-[980px] font-display text-display-lg text-theme",children:Q},void 0,!1,void 0,this),b1("p",{className:"mt-7 max-w-[720px] font-body text-body-lg text-theme-muted",children:w},void 0,!1,void 0,this),b1("div",{className:"mt-10 flex flex-col gap-3 sm:flex-row",children:[b1(la,{href:$.href,size:"lg",variant:"primary-strong",children:$.label},void 0,!1,void 0,this),b1(la,{href:B.href,size:"lg",variant:"secondary",children:B.label},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),b1("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:[b1("p",{className:"font-label text-label-xs uppercase tracking-[0.24em] text-theme-light",children:"Live relay signals"},void 0,!1,void 0,this),b1("div",{className:"mt-5 grid gap-3",children:X.map((Y)=>b1("div",{className:"rounded-[22px] border border-card-divider bg-bg-muted p-5",children:[b1("div",{className:"flex items-center justify-between gap-4",children:[b1("p",{className:"font-label text-label-xs uppercase tracking-[0.18em] text-secondary",children:Y.label},void 0,!1,void 0,this),b1("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),b1("p",{className:"mt-4 font-display text-display-sm text-theme",children:Y.value},void 0,!1,void 0,this),b1("p",{className:"mt-2 font-body text-body-xs text-theme-muted",children:Y.note},void 0,!1,void 0,this)]},Y.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 Gnw({eyebrow:A,title:Q,intro:w,steps:$}){return b1(GT,{id:"operating-loop",className:"py-section",children:[b1("div",{className:"max-w-[840px]",children:[b1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-secondary",children:A},void 0,!1,void 0,this),b1("h2",{className:"mt-5 font-display text-display-md text-theme",children:Q},void 0,!1,void 0,this),b1("p",{className:"mt-5 font-body text-body-md text-theme-muted",children:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this),b1("div",{className:"mt-12 grid gap-4 md:grid-cols-3",children:$.map((B)=>b1("article",{className:"min-h-[300px] rounded-[28px] border border-card-panel-border bg-card-panel-bg p-6",children:[b1("p",{className:"font-label text-label-sm text-accent",children:B.phase},void 0,!1,void 0,this),b1("h3",{className:"mt-16 font-display text-display-sm text-theme",children:B.title},void 0,!1,void 0,this),b1("p",{className:"mt-4 font-body text-body-sm text-theme-muted",children:B.text},void 0,!1,void 0,this)]},B.phase,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function Dnw({title:A,intro:Q,cards:w}){return b1(GT,{className:"py-section",children:b1("div",{className:"rounded-[36px] border border-theme-light bg-bg-muted p-6 md:p-10",children:b1("div",{className:"grid gap-8 lg:grid-cols-[360px_1fr]",children:[b1("div",{children:[b1("h2",{className:"font-display text-display-md text-theme",children:A},void 0,!1,void 0,this),b1("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),b1("div",{className:"grid gap-4",children:w.map(($)=>b1("article",{className:"rounded-[24px] border border-card-divider bg-bg-subtle/70 p-5",children:[b1("p",{className:"font-label text-label-xs uppercase tracking-[0.22em] text-accent",children:$.label},void 0,!1,void 0,this),b1("h3",{className:"mt-3 font-nav text-heading-lg text-theme",children:$.title},void 0,!1,void 0,this),b1("p",{className:"mt-2 font-body text-body-sm text-theme-muted",children:$.text},void 0,!1,void 0,this)]},$.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 qnw({title:A,intro:Q,points:w}){return b1(GT,{className:"min-h-[78vh] pt-[150px] pb-section md:pt-[190px]",children:[b1("div",{className:"max-w-[920px]",children:[b1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:"Relay model"},void 0,!1,void 0,this),b1("h1",{className:"mt-6 font-display text-display-lg text-theme",children:A},void 0,!1,void 0,this),b1("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),b1("div",{className:"mt-12 grid gap-4 md:grid-cols-3",children:w.map(($)=>b1("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:$},$,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}var znw=(A)=>{switch(A){case"capture":return"bg-accent";case"synthesis":return"bg-secondary";case"share":return"bg-accent-bright"}},Vnw=(A)=>new Intl.NumberFormat("en",{notation:A>999?"compact":"standard"}).format(A),_t=(A,Q,w=`${Q}s`)=>`${Vnw(A)} ${A===1?Q:w}`;function Jnw({eyebrow:A,headline:Q,intro:w,primaryCta:$,secondaryCta:B,inputs:X,outputs:Y,core:Z,legend:H,counts:W}){let K=[{key:"captures",className:"top-[-10px] left-1/2 -translate-x-1/2",label:_t(W.captures,"capture")},{key:"topics",className:"top-1/2 right-[-28px] -translate-y-1/2",label:_t(W.topics,"topic")},{key:"peers",className:"bottom-[-10px] left-1/2 -translate-x-1/2",label:_t(W.peers,"peer brain")},{key:"summaries",className:"top-1/2 left-[-28px] -translate-y-1/2",label:_t(W.summaries,"summary","summaries")}];return b1(GT,{className:"pt-[150px] pb-section md:pt-[190px]",id:"diagram",children:[b1("div",{className:"mx-auto max-w-[1040px] text-center",children:[b1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:A},void 0,!1,void 0,this),b1("h1",{className:"mx-auto mt-7 max-w-[22ch] font-display text-display-lg text-theme",children:Q},void 0,!1,void 0,this),b1("p",{className:"mx-auto mt-7 max-w-[64ch] font-body text-body-lg text-theme-muted",children:w},void 0,!1,void 0,this),b1("div",{className:"mt-10 flex flex-col justify-center gap-3 sm:flex-row",children:[b1(la,{href:$.href,size:"lg",variant:"primary-strong",children:$.label},void 0,!1,void 0,this),b1(la,{href:B.href,size:"lg",variant:"secondary",children:B.label},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),b1("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:[b1("div",{className:"grid items-center gap-8 lg:grid-cols-[1fr_1.4fr_1fr]",children:[b1("div",{className:"flex flex-col gap-3.5",children:X.map((U)=>b1("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:[b1("p",{className:"font-label text-[10px] uppercase tracking-[0.22em] text-secondary",children:U.label},void 0,!1,void 0,this),b1("h2",{className:"mt-1.5 font-display text-[18px] font-medium text-theme",children:U.title},void 0,!1,void 0,this),b1("p",{className:"mt-1 font-body text-[13px] leading-[1.5] text-theme-muted",children:U.detail},void 0,!1,void 0,this)]},`${U.label}-${U.title}`,!0,void 0,this))},void 0,!1,void 0,this),b1("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:[b1("div",{className:"absolute inset-0 rounded-full border border-dashed border-accent/30"},void 0,!1,void 0,this),b1("div",{className:"absolute inset-6 animate-spin rounded-full border border-dashed border-secondary/40 [animation-duration:28s]"},void 0,!1,void 0,this),K.map((U)=>b1("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 ${U.className}`,children:U.label},U.key,!1,void 0,this)),b1("div",{className:"relative z-[1] px-6 text-center",children:[b1("p",{className:"font-label text-[10px] uppercase tracking-[0.28em] text-accent",children:Z.eyebrow},void 0,!1,void 0,this),b1("p",{className:"mt-2 font-display text-[36px] leading-none text-theme",children:Z.name},void 0,!1,void 0,this),b1("p",{className:"mt-2 font-body text-[13px] text-theme-muted",children:Z.sub},void 0,!1,void 0,this),b1("p",{className:"mt-4 font-label text-[10px] uppercase tracking-[0.18em] text-theme-light",children:[_t(W.links,"link")," indexed"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),b1("div",{className:"flex flex-col gap-3.5",children:Y.map((U)=>b1("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:[b1("p",{className:"font-label text-[10px] uppercase tracking-[0.22em] text-secondary",children:U.label},void 0,!1,void 0,this),b1("h2",{className:"mt-1.5 font-display text-[18px] font-medium text-theme",children:U.title},void 0,!1,void 0,this),b1("p",{className:"mt-1 font-body text-[13px] leading-[1.5] text-theme-muted",children:U.detail},void 0,!1,void 0,this)]},`${U.label}-${U.title}`,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),b1("div",{className:"mt-14 grid gap-4 border-t border-theme-light pt-8 md:grid-cols-3",children:H.map((U)=>b1("div",{className:"text-left",children:[b1("h2",{className:"font-display text-[16px] font-medium text-theme",children:[b1("span",{className:`mr-2.5 inline-block h-3 w-3 rounded-[3px] align-middle ${znw(U.tone)}`},void 0,!1,void 0,this),U.title]},void 0,!0,void 0,this),b1("p",{className:"mt-1.5 font-body text-[13px] leading-[1.6] text-theme-muted",children:U.text},void 0,!1,void 0,this)]},U.title,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}var Inw=e1({name:"home-diagram",description:"Relay homepage system diagram with live entity counts",schema:MwA,formatter:{parse:(A)=>MwA.parse({...HU0(A),counts:{captures:0,links:0,topics:0,summaries:0,peers:0}}),format:(A)=>DU2(jT.parse(A))},dataSourceId:"relay-site:home-counts",requiredPermission:"public",layout:{component:Jnw}}),Fnw=(A)=>Unw(wnw.parse(A)),bnw=(A)=>Gnw(Bnw.parse(A)),Lnw=(A)=>Dnw(Ynw.parse(A)),knw=(A)=>qnw(Znw.parse(A)),VU2={type:"object",label:"CTA",fields:{label:{type:"string",label:"Label"},href:{type:"string",label:"Href"}}},JU2={namespace:"relay-site",sections:{"home-hero":{title:"Home hero",description:"Relay homepage hero section",layout:Fnw,fields:{eyebrow:{type:"string",label:"Eyebrow"},headline:{type:"string",label:"Headline"},intro:{type:"string",label:"Intro"},primaryCta:{...VU2,label:"Primary CTA"},secondaryCta:{...VU2,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:bnw,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:Lnw,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:knw,fields:{title:{type:"string",label:"Title"},intro:{type:"string",label:"Intro"},points:{type:"array",label:"Points",minItems:1,items:{type:"string",label:"Point"}}}}}},_nw=[{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:fnw}]}],IU2=FK2({packageName:"@brains/relay/site",themeProfile:"studio",layout:Knw,routes:_nw,runtime:{contentNamespace:"relay-site",templates:{"home-diagram":Inw},dataSources:[new OwA]}});var FU2={name:"@brains/relay",version:"0.2.0-alpha.158",description:"Relay brain model \u2014 collaborative knowledge management",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/theme-rizom":"workspace:*","@brains/topics":"workspace:*","@brains/utils":"workspace:*","@brains/web-chat":"workspace:*","@brains/webserver":"workspace:*","@rizom/site-rizom":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/ai-evaluation":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*",typescript:"^7.0.2"},exports:{".":"./src/index.ts","./env-schema":"./src/env-schema.ts"},files:["src","brain.eval.yaml","env.schema.template"],private:!0,scripts:{"build:ui":"turbo run build --filter=@brains/web-chat --filter=@brains/cms",eval:"brain-eval",lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix","start:core":"bun run build:ui && cd test-apps/core && INIT_CWD=$PWD bun run $([ -t 1 ] && echo --elide-lines=0) --filter @rizom/brain dev:start","start:default":"bun run build:ui && cd test-apps/default && INIT_CWD=$PWD bun run $([ -t 1 ] && echo --elide-lines=0) --filter @rizom/brain dev:start","start:docs":"bun run build:ui && cd test-apps/docs && INIT_CWD=$PWD bun run $([ -t 1 ] && echo --elide-lines=0) --filter @rizom/brain dev:start","start:full":"bun run build:ui && cd test-apps/full && INIT_CWD=$PWD bun run $([ -t 1 ] && echo --elide-lines=0) --filter @rizom/brain dev:start",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var bU2=["prompt","directory-sync","note","link","topics","conversation-memory","agents","assessment","auth-service","notifications","email-resend","cms","dashboard","mcp","webserver","web-chat","discord","a2a"],LU2=[...bU2,"image","site-info","site-content","site-builder"],Pnw=[...LU2,"docs","decks"],Mnw=["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."],Onw=YF({name:"relay",version:FU2.version,model:"gpt-5.6-luna",reasoningEffort:"low",site:IU2,theme:zT,presets:{core:bU2,default:LU2,full:Pnw},evalDisable:["webserver","web-chat","mcp","discord"],agentInstructions:Mnw,capabilities:[["prompt",jM,void 0],["note",WM,{}],["link",UM,{}],["image",Yp,void 0],["topics",WH0,{includeEntityTypes:["note","link","summary","agent","swot","deck","doc","anchor-profile","brain-character"],extractableStatuses:["published","draft"]}],["conversation-memory",jwA,{memoryVisibility:"shared"}],["docs",Vs,void 0],["decks",Ds,void 0],["agents",qW0,void 0],["assessment",NW0,void 0],["auth-service",si,void 0],["notifications",$B0,void 0],["email-resend",QX0,void 0],["cms",IM,{}],["dashboard",OL,void 0],["directory-sync",UP,{seedContent:!0,seedContentPath:jnw(import.meta.dir,"..","seed-content"),initialSync:!0}],["site-content",sP,{definitions:JU2}],["rizom-ecosystem",PM,void 0],["site-info",aP,void 0],["site-builder",oP,{}]],interfaces:[["mcp",iF,()=>({})],["discord",xb,()=>({captureUrls:!0})],["a2a",ng,()=>({})],["webserver",yb,()=>({})],["web-chat",dg,()=>({})]],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:{note:{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"}}}),kU2=Onw;import{readFileSync as Waw}from"fs";import{join as Kaw}from"path";import{execSync as Uaw}from"child_process";import{parseArgs as vnw}from"util";var hnw={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 qG(A,Q){let w=A[Q];return typeof w==="string"?w:void 0}function pL(A,Q){let w=A[Q];return typeof w==="boolean"?w:void 0}function _U2(A){let{values:Q,positionals:w}=vnw({args:A,options:hnw,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:w[0]??"help",args:w.slice(1),flags:{model:qG(Q,"model"),domain:qG(Q,"domain"),"content-repo":qG(Q,"content-repo"),backend:qG(Q,"backend"),"push-to":qG(Q,"push-to"),"ai-api-key":qG(Q,"ai-api-key"),"no-interactive":pL(Q,"no-interactive"),preview:pL(Q,"preview"),deploy:pL(Q,"deploy"),regen:pL(Q,"regen"),all:pL(Q,"all"),only:qG(Q,"only"),"dry-run":pL(Q,"dry-run"),"startup-check":pL(Q,"startup-check"),"storage-dir":qG(Q,"storage-dir"),yes:pL(Q,"yes"),remote:qG(Q,"remote"),token:qG(Q,"token"),outputDir:qG(Q,"outputDir")}}}Nt();import{mkdirSync as Aaw}from"fs";import{join as Qaw}from"path";import{execSync as waw}from"child_process";var KU0={name:"@rizom/brain",version:"0.2.0-alpha.158",description:"Brain runtime + CLI \u2014 scaffold, run, and manage AI brain instances",keywords:["brain","ai","cli","mcp","agent","personal-ai","knowledge-management"],license:"Apache-2.0",author:"Yeehaa <yeehaa@rizom.ai> (https://rizom.ai)",bin:{brain:"./dist/brain.js"},bugs:"https://github.com/rizom-ai/brains/issues",dependencies:{"@clack/prompts":"^1.5.1","@modelcontextprotocol/sdk":"^1.29.0","@tailwindcss/postcss":"^4.3.1","@tailwindcss/typography":"^0.5.20",postcss:"^8.5.15",preact:"^10.27.2","preact-render-to-string":"^6.7.0",tailwindcss:"^4.3.1",zod:"^4.1.8"},devDependencies:{"@brains/app":"workspace:*","@brains/build-tools":"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":"^1.3.14",rolldown:"^1.0.0","rolldown-plugin-dts":"^0.27.4",typescript:"^7.0.2"},engines:{bun:">=1.3.3"},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"],homepage:"https://github.com/rizom-ai/brains/tree/main/packages/brain-cli#readme",optionalDependencies:{"@bitwarden/sdk-napi":"^1.0.0","@libsql/client":"^0.17.4","@tailwindcss/oxide":"^4.1.4",lightningcss:"^1.29.2","playwright-core":"^1.61.0","react-devtools-core":"^7.0.1",sharp:"^0.35.1"},publishConfig:{access:"public"},repository:{type:"git",url:"https://github.com/rizom-ai/brains.git",directory:"packages/brain-cli"},scripts:{build:"bun scripts/build.ts","dev:start":"bun scripts/build.ts && bun dist/brain.js start",lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",prepublishOnly:"bun scripts/build.ts",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};import{mkdirSync as SU2,writeFileSync as Pt,chmodSync as Mt,existsSync as SwA,readFileSync as mwA}from"fs";import{basename as uwA,dirname as cwA,join as YB,resolve as Grw}from"path";import{fileURLToPath as Drw}from"url";var NU2=`ARG BUN_VERSION=1.3.10
13234
+ `)}})}),Q.eval.registerHandler("decideProjection",async(B)=>{let X=Sdw.parse(B),Y=LwA(X.messages,X.conversationId),Z=X.existingSummary?$U2({conversationId:X.conversationId,content:X.existingSummary,messageCount:X.existingMessageCount,projectionVersion:$.projectionVersion,visibility:$.memoryVisibility}):null;return new lL(Q,w,$).decideProjection(Y,Z)}),Q.eval.registerHandler("retrieveMemory",async(B)=>{let X=Edw.parse(B),Y=X.memory?BU2(Q,X.memory):Q;return new NT(Y).retrieve(X)}),Q.eval.registerHandler("buildAgentContext",async(B)=>{let X=Tdw.parse(B),Y=X.memory?BU2(Q,X.memory):Q;return ZU0(Y,X)}),Q.eval.registerHandler("projectMessages",async(B)=>{let X=Cdw.parse(B),Y=LwA(X.messages,X.conversationId),Z=mdw({conversationId:X.conversationId,interfaceType:X.interfaceType,channelId:X.channelId,channelName:X.channelName,messages:Y}),H=X.existingSummary?$U2({conversationId:X.conversationId,content:X.existingSummary,messageCount:X.existingMessageCount,projectionVersion:$.projectionVersion,visibility:$.memoryVisibility}):null,W=[],K=[],U=udw({context:Q,conversation:Z,messages:Y,existing:H,upserted:W,deleted:K,projectionDecision:X.projectionDecision});return{result:await new lL(U,w,$).projectConversation(X.conversationId),summaries:W.filter((V)=>V.entityType==="summary"),decisions:W.filter((V)=>V.entityType==="decision"),actionItems:W.filter((V)=>V.entityType==="action-item"),deleted:K}}),Q.eval.registerHandler("projectConversation",async(B)=>{let X=hdw.parse(B);return new lL(Q,w,$).projectConversation(X.conversationId)})}function $U2(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 LwA(A,Q){return A.map((w,$)=>{let B=w.timestamp??new Date(Date.UTC(2026,0,1,0,$)).toISOString();return{id:`eval-message-${$+1}`,conversationId:Q,role:w.role,content:w.content,timestamp:B,metadata:{...w.actor?{actor:w.actor}:{},...w.source?{source:w.source}:{}}}})}function mdw(A){let Q=A.messages[0],w=A.messages[A.messages.length-1],$=Q?.timestamp??"2026-01-01T00:00:00.000Z",B=w?.timestamp??$;return{id:A.conversationId,sessionId:A.conversationId,interfaceType:A.interfaceType,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},startedAt:$,lastActiveAt:B,createdAt:$,updatedAt:B,metadata:{}}}function udw(A){let Q=DG(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:w})=>w==="summary"?A.existing:null,listEntities:async()=>[],deleteEntity:async(w)=>{return A.deleted.push(w),!0},upsertEntity:async({entity:w})=>{return A.upserted.push(w),{entityId:w.id,jobId:"eval-upsert",created:!0,skipped:!1}}}}}function BU2(A,Q){let w=Q.map(cdw),$=w.map((B,X)=>({entity:B,score:Q[X]?.score??1,excerpt:Q[X]?.excerpt??_T(B)}));return{...A,entityService:{...A.entityService,search:async()=>$,listEntities:async({entityType:B})=>w.filter((X)=>X.entityType===B)}}}function cdw(A){if(A.entityType==="summary")return ldw(A);if(A.entityType==="decision")return pdw(A);return idw(A)}function _wA(A){let Q=A.updated??"2026-01-01T00:00:00.000Z";return{id:A.id,content:A.content,contentHash:I6(A.content),visibility:A.visibility,created:Q,updated:Q}}function ldw(A){return{..._wA(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 pdw(A){return{..._wA(A),entityType:"decision",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,spaceId:DG(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 idw(A){let Q=A.status==="done"||A.status==="dropped"?A.status:"open";return{..._wA(A),entityType:"action-item",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,spaceId:DG(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 HU2={name:"@brains/conversation-memory",version:"0.2.0-alpha.159",description:"Plugin for deriving durable conversation memory",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.19.43",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},main:"./src/index.ts",private:!0,scripts:{eval:"cd evals && bun run brain-eval",lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var ndw=new UK,rdw=new JT,odw=new IT,sdw=f.object({conversationId:f.string()});class NwA extends Zw{entityType=oB;schema=It;adapter=ndw;constructor(A={}){super(sK0,HU2,A,VwA)}getConfig(){return this.config}getTemplates(){return{"summary-list":hK2,"summary-detail":CK2,"ai-response":gK2}}getDataSources(){return[new FwA(this.logger.child("SummaryDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableProjection)return[];return[{id:"conversation-memory-projection",targetType:oB,job:{type:kK2,handler:new wU0(A,this.logger,this.config)},initialSync:{shouldEnqueue:async()=>A.spaces.length>0&&!await L_(A,oB,{outputVisibility:this.config.memoryVisibility}),jobData:{mode:"rebuild-all",reason:"initial-sync"},jobOptions:{source:GwA,deduplication:"coalesce",deduplicationKey:"conversation-memory:rebuild-all:initial-sync",metadata:{operationType:"data_processing",operationTarget:"conversation-memory:rebuild-all",pluginId:sK0}}},sourceChange:{sourceKind:Xu,sourceTypes:[Xu],shouldEnqueue:(Q)=>this.shouldEnqueueConversationProjection(A,Q),events:[rx],jobData:(Q)=>{let{conversationId:w}=this.parseConversationMessagePayload(Q);return{mode:"conversation",conversationId:w,reason:"message-added"}},jobOptions:(Q)=>{let{conversationId:w}=this.parseConversationMessagePayload(Q);return{priority:5,delayMs:this.config.projectionDelayMs,source:GwA,deduplication:"skip",deduplicationKey:`conversation-memory:${w}`,metadata:{operationType:"data_processing",operationTarget:`conversation-memory:${w}`,pluginId:sK0}}}}}]}parseConversationMessagePayload(A){return sdw.parse(A)}async shouldEnqueueConversationProjection(A,Q){let{conversationId:w}=this.parseConversationMessagePayload(Q),$=await A.conversations.get(w);if(!$)return!1;return mM({conversation:$,spaces:A.spaces}).eligible}async onRegister(A){A.entities.register(_H,Ft,rdw),A.entities.register(KK,bt,odw),TK2({context:A,pluginId:this.id}),mK2({context:A,pluginId:this.id}),sK2({context:A,pluginId:this.id}),eK2({context:A,pluginId:this.id,config:this.config}),bwA(A),fU2({context:A,logger:this.logger,config:this.config})}}function jwA(A={}){return new NwA(A)}fA();C0();C0();b9();var WU2=f.object({label:f.string(),href:f.string()}),KU2=f.object({label:f.string(),title:f.string(),detail:f.string()}),adw=f.object({eyebrow:f.string(),name:f.string(),sub:f.string()}),tdw=f.object({tone:f.enum(["capture","synthesis","share"]),title:f.string(),text:f.string()}),PwA=f.object({captures:f.number(),links:f.number(),topics:f.number(),summaries:f.number(),peers:f.number()}),jT=f.object({eyebrow:f.string(),headline:f.string(),intro:f.string(),primaryCta:WU2,secondaryCta:WU2,inputs:f.array(KU2).min(1),outputs:f.array(KU2).min(1),core:adw,legend:f.array(tdw).min(1)}),MwA=jT.extend({counts:PwA}),UU2={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."}]},GU2=new R6(jT,{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 HU0(A){return GU2.parse(A)}function DU2(A){return GU2.format(A)}C0();var edw=f.looseObject({query:f.object({routeId:f.string().default("home"),sectionId:f.string().default("diagram")}).default({routeId:"home",sectionId:"diagram"})}),Anw={captures:"note",links:"link",topics:"topic",summaries:"summary",peers:"agent"};class OwA{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,w){let $=edw.parse(A??{}),B=await this.fetchContent(w,$.query.routeId,$.query.sectionId),X=await this.fetchCounts(w);return Q.parse({...B,counts:X})}async fetchContent(A,Q,w){let $=await A.entityService.getEntity({entityType:"site-content",id:`${Q}:${w}`});if(!$?.content)return UU2;return jT.parse(HU0($.content))}async fetchCounts(A){let Q=await Promise.all(Object.entries(Anw).map(async([w,$])=>[w,await this.countOrZero(A,$)]));return PwA.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 b1}from"preact/jsx-dev-runtime";var qU2=f.object({label:f.string(),href:f.string()}),Qnw=f.object({label:f.string(),value:f.string(),note:f.string()}),wnw=f.object({eyebrow:f.string(),headline:f.string(),intro:f.string(),primaryCta:qU2,secondaryCta:qU2,signals:f.array(Qnw)}),$nw=f.object({phase:f.string(),title:f.string(),text:f.string()}),Bnw=f.object({eyebrow:f.string(),title:f.string(),intro:f.string(),steps:f.array($nw)}),Xnw=f.object({label:f.string(),title:f.string(),text:f.string()}),Ynw=f.object({title:f.string(),intro:f.string(),cards:f.array(Xnw)}),Znw=f.object({title:f.string(),intro:f.string(),points:f.array(f.string())}),fnw={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."]},Hnw="font-body text-[15px] text-theme-muted transition-colors hover:text-theme";function zU2({href:A,label:Q}){return b1("a",{href:A,className:Hnw,children:Q},void 0,!1,void 0,this)}function Wnw({siteInfo:A,children:Q}){let w=[...A.navigation.primary,...A.navigation.secondary],$=A.cta??{buttonText:"Start here",buttonLink:"/about"};return b1(w2A,{children:[b1("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:[b1("a",{href:"/",className:"font-nav text-[20px]","aria-label":"Relay home",children:[b1("span",{className:"font-bold text-theme",children:"relay"},void 0,!1,void 0,this),b1("span",{className:"font-bold text-accent",children:"."},void 0,!1,void 0,this),b1("span",{className:"text-theme-muted",children:"brain"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),b1("div",{className:"flex items-center gap-5 md:gap-8",children:[b1("div",{className:"hidden items-center gap-6 md:flex",children:w.map((B)=>b1(zU2,{...B},`${B.href}-${B.label}`,!1,void 0,this))},void 0,!1,void 0,this),b1("a",{href:$.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:$.buttonText},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),b1("main",{children:Q},void 0,!1,void 0,this),b1("footer",{className:"relative z-[1] border-t border-theme-light px-6 py-8 md:px-10 xl:px-20",children:b1("div",{className:"flex flex-col gap-4 md:flex-row md:items-center md:justify-between",children:[b1("div",{children:[b1("p",{className:"font-label text-label-sm uppercase tracking-[0.22em] text-theme-light",children:A.copyright},void 0,!1,void 0,this),b1("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),b1("div",{className:"flex flex-wrap items-center gap-5",children:[w.map((B)=>b1(zU2,{...B},`footer-${B.href}-${B.label}`,!1,void 0,this)),b1("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 Knw=({sections:A,siteInfo:Q})=>b1(Wnw,{siteInfo:Q,children:A},void 0,!1,void 0,this);function Unw({eyebrow:A,headline:Q,intro:w,primaryCta:$,secondaryCta:B,signals:X}){return b1(GT,{className:"min-h-[92vh] pt-[152px] pb-20 md:pt-[190px]",children:b1("div",{className:"grid gap-10 lg:grid-cols-[minmax(0,1fr)_420px] lg:items-end",children:[b1("div",{children:[b1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:A},void 0,!1,void 0,this),b1("h1",{className:"mt-7 max-w-[980px] font-display text-display-lg text-theme",children:Q},void 0,!1,void 0,this),b1("p",{className:"mt-7 max-w-[720px] font-body text-body-lg text-theme-muted",children:w},void 0,!1,void 0,this),b1("div",{className:"mt-10 flex flex-col gap-3 sm:flex-row",children:[b1(la,{href:$.href,size:"lg",variant:"primary-strong",children:$.label},void 0,!1,void 0,this),b1(la,{href:B.href,size:"lg",variant:"secondary",children:B.label},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),b1("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:[b1("p",{className:"font-label text-label-xs uppercase tracking-[0.24em] text-theme-light",children:"Live relay signals"},void 0,!1,void 0,this),b1("div",{className:"mt-5 grid gap-3",children:X.map((Y)=>b1("div",{className:"rounded-[22px] border border-card-divider bg-bg-muted p-5",children:[b1("div",{className:"flex items-center justify-between gap-4",children:[b1("p",{className:"font-label text-label-xs uppercase tracking-[0.18em] text-secondary",children:Y.label},void 0,!1,void 0,this),b1("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),b1("p",{className:"mt-4 font-display text-display-sm text-theme",children:Y.value},void 0,!1,void 0,this),b1("p",{className:"mt-2 font-body text-body-xs text-theme-muted",children:Y.note},void 0,!1,void 0,this)]},Y.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 Gnw({eyebrow:A,title:Q,intro:w,steps:$}){return b1(GT,{id:"operating-loop",className:"py-section",children:[b1("div",{className:"max-w-[840px]",children:[b1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-secondary",children:A},void 0,!1,void 0,this),b1("h2",{className:"mt-5 font-display text-display-md text-theme",children:Q},void 0,!1,void 0,this),b1("p",{className:"mt-5 font-body text-body-md text-theme-muted",children:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this),b1("div",{className:"mt-12 grid gap-4 md:grid-cols-3",children:$.map((B)=>b1("article",{className:"min-h-[300px] rounded-[28px] border border-card-panel-border bg-card-panel-bg p-6",children:[b1("p",{className:"font-label text-label-sm text-accent",children:B.phase},void 0,!1,void 0,this),b1("h3",{className:"mt-16 font-display text-display-sm text-theme",children:B.title},void 0,!1,void 0,this),b1("p",{className:"mt-4 font-body text-body-sm text-theme-muted",children:B.text},void 0,!1,void 0,this)]},B.phase,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function Dnw({title:A,intro:Q,cards:w}){return b1(GT,{className:"py-section",children:b1("div",{className:"rounded-[36px] border border-theme-light bg-bg-muted p-6 md:p-10",children:b1("div",{className:"grid gap-8 lg:grid-cols-[360px_1fr]",children:[b1("div",{children:[b1("h2",{className:"font-display text-display-md text-theme",children:A},void 0,!1,void 0,this),b1("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),b1("div",{className:"grid gap-4",children:w.map(($)=>b1("article",{className:"rounded-[24px] border border-card-divider bg-bg-subtle/70 p-5",children:[b1("p",{className:"font-label text-label-xs uppercase tracking-[0.22em] text-accent",children:$.label},void 0,!1,void 0,this),b1("h3",{className:"mt-3 font-nav text-heading-lg text-theme",children:$.title},void 0,!1,void 0,this),b1("p",{className:"mt-2 font-body text-body-sm text-theme-muted",children:$.text},void 0,!1,void 0,this)]},$.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 qnw({title:A,intro:Q,points:w}){return b1(GT,{className:"min-h-[78vh] pt-[150px] pb-section md:pt-[190px]",children:[b1("div",{className:"max-w-[920px]",children:[b1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:"Relay model"},void 0,!1,void 0,this),b1("h1",{className:"mt-6 font-display text-display-lg text-theme",children:A},void 0,!1,void 0,this),b1("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),b1("div",{className:"mt-12 grid gap-4 md:grid-cols-3",children:w.map(($)=>b1("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:$},$,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}var znw=(A)=>{switch(A){case"capture":return"bg-accent";case"synthesis":return"bg-secondary";case"share":return"bg-accent-bright"}},Vnw=(A)=>new Intl.NumberFormat("en",{notation:A>999?"compact":"standard"}).format(A),_t=(A,Q,w=`${Q}s`)=>`${Vnw(A)} ${A===1?Q:w}`;function Jnw({eyebrow:A,headline:Q,intro:w,primaryCta:$,secondaryCta:B,inputs:X,outputs:Y,core:Z,legend:H,counts:W}){let K=[{key:"captures",className:"top-[-10px] left-1/2 -translate-x-1/2",label:_t(W.captures,"capture")},{key:"topics",className:"top-1/2 right-[-28px] -translate-y-1/2",label:_t(W.topics,"topic")},{key:"peers",className:"bottom-[-10px] left-1/2 -translate-x-1/2",label:_t(W.peers,"peer brain")},{key:"summaries",className:"top-1/2 left-[-28px] -translate-y-1/2",label:_t(W.summaries,"summary","summaries")}];return b1(GT,{className:"pt-[150px] pb-section md:pt-[190px]",id:"diagram",children:[b1("div",{className:"mx-auto max-w-[1040px] text-center",children:[b1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:A},void 0,!1,void 0,this),b1("h1",{className:"mx-auto mt-7 max-w-[22ch] font-display text-display-lg text-theme",children:Q},void 0,!1,void 0,this),b1("p",{className:"mx-auto mt-7 max-w-[64ch] font-body text-body-lg text-theme-muted",children:w},void 0,!1,void 0,this),b1("div",{className:"mt-10 flex flex-col justify-center gap-3 sm:flex-row",children:[b1(la,{href:$.href,size:"lg",variant:"primary-strong",children:$.label},void 0,!1,void 0,this),b1(la,{href:B.href,size:"lg",variant:"secondary",children:B.label},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),b1("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:[b1("div",{className:"grid items-center gap-8 lg:grid-cols-[1fr_1.4fr_1fr]",children:[b1("div",{className:"flex flex-col gap-3.5",children:X.map((U)=>b1("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:[b1("p",{className:"font-label text-[10px] uppercase tracking-[0.22em] text-secondary",children:U.label},void 0,!1,void 0,this),b1("h2",{className:"mt-1.5 font-display text-[18px] font-medium text-theme",children:U.title},void 0,!1,void 0,this),b1("p",{className:"mt-1 font-body text-[13px] leading-[1.5] text-theme-muted",children:U.detail},void 0,!1,void 0,this)]},`${U.label}-${U.title}`,!0,void 0,this))},void 0,!1,void 0,this),b1("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:[b1("div",{className:"absolute inset-0 rounded-full border border-dashed border-accent/30"},void 0,!1,void 0,this),b1("div",{className:"absolute inset-6 animate-spin rounded-full border border-dashed border-secondary/40 [animation-duration:28s]"},void 0,!1,void 0,this),K.map((U)=>b1("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 ${U.className}`,children:U.label},U.key,!1,void 0,this)),b1("div",{className:"relative z-[1] px-6 text-center",children:[b1("p",{className:"font-label text-[10px] uppercase tracking-[0.28em] text-accent",children:Z.eyebrow},void 0,!1,void 0,this),b1("p",{className:"mt-2 font-display text-[36px] leading-none text-theme",children:Z.name},void 0,!1,void 0,this),b1("p",{className:"mt-2 font-body text-[13px] text-theme-muted",children:Z.sub},void 0,!1,void 0,this),b1("p",{className:"mt-4 font-label text-[10px] uppercase tracking-[0.18em] text-theme-light",children:[_t(W.links,"link")," indexed"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),b1("div",{className:"flex flex-col gap-3.5",children:Y.map((U)=>b1("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:[b1("p",{className:"font-label text-[10px] uppercase tracking-[0.22em] text-secondary",children:U.label},void 0,!1,void 0,this),b1("h2",{className:"mt-1.5 font-display text-[18px] font-medium text-theme",children:U.title},void 0,!1,void 0,this),b1("p",{className:"mt-1 font-body text-[13px] leading-[1.5] text-theme-muted",children:U.detail},void 0,!1,void 0,this)]},`${U.label}-${U.title}`,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),b1("div",{className:"mt-14 grid gap-4 border-t border-theme-light pt-8 md:grid-cols-3",children:H.map((U)=>b1("div",{className:"text-left",children:[b1("h2",{className:"font-display text-[16px] font-medium text-theme",children:[b1("span",{className:`mr-2.5 inline-block h-3 w-3 rounded-[3px] align-middle ${znw(U.tone)}`},void 0,!1,void 0,this),U.title]},void 0,!0,void 0,this),b1("p",{className:"mt-1.5 font-body text-[13px] leading-[1.6] text-theme-muted",children:U.text},void 0,!1,void 0,this)]},U.title,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}var Inw=e1({name:"home-diagram",description:"Relay homepage system diagram with live entity counts",schema:MwA,formatter:{parse:(A)=>MwA.parse({...HU0(A),counts:{captures:0,links:0,topics:0,summaries:0,peers:0}}),format:(A)=>DU2(jT.parse(A))},dataSourceId:"relay-site:home-counts",requiredPermission:"public",layout:{component:Jnw}}),Fnw=(A)=>Unw(wnw.parse(A)),bnw=(A)=>Gnw(Bnw.parse(A)),Lnw=(A)=>Dnw(Ynw.parse(A)),knw=(A)=>qnw(Znw.parse(A)),VU2={type:"object",label:"CTA",fields:{label:{type:"string",label:"Label"},href:{type:"string",label:"Href"}}},JU2={namespace:"relay-site",sections:{"home-hero":{title:"Home hero",description:"Relay homepage hero section",layout:Fnw,fields:{eyebrow:{type:"string",label:"Eyebrow"},headline:{type:"string",label:"Headline"},intro:{type:"string",label:"Intro"},primaryCta:{...VU2,label:"Primary CTA"},secondaryCta:{...VU2,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:bnw,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:Lnw,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:knw,fields:{title:{type:"string",label:"Title"},intro:{type:"string",label:"Intro"},points:{type:"array",label:"Points",minItems:1,items:{type:"string",label:"Point"}}}}}},_nw=[{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:fnw}]}],IU2=FK2({packageName:"@brains/relay/site",themeProfile:"studio",layout:Knw,routes:_nw,runtime:{contentNamespace:"relay-site",templates:{"home-diagram":Inw},dataSources:[new OwA]}});var FU2={name:"@brains/relay",version:"0.2.0-alpha.159",description:"Relay brain model \u2014 collaborative knowledge management",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/theme-rizom":"workspace:*","@brains/topics":"workspace:*","@brains/utils":"workspace:*","@brains/web-chat":"workspace:*","@brains/webserver":"workspace:*","@rizom/site-rizom":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/ai-evaluation":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*",typescript:"^7.0.2"},exports:{".":"./src/index.ts","./env-schema":"./src/env-schema.ts"},files:["src","brain.eval.yaml","env.schema.template"],private:!0,scripts:{"build:ui":"turbo run build --filter=@brains/web-chat --filter=@brains/cms",eval:"brain-eval",lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix","start:core":"bun run build:ui && cd test-apps/core && INIT_CWD=$PWD bun run $([ -t 1 ] && echo --elide-lines=0) --filter @rizom/brain dev:start","start:default":"bun run build:ui && cd test-apps/default && INIT_CWD=$PWD bun run $([ -t 1 ] && echo --elide-lines=0) --filter @rizom/brain dev:start","start:docs":"bun run build:ui && cd test-apps/docs && INIT_CWD=$PWD bun run $([ -t 1 ] && echo --elide-lines=0) --filter @rizom/brain dev:start","start:full":"bun run build:ui && cd test-apps/full && INIT_CWD=$PWD bun run $([ -t 1 ] && echo --elide-lines=0) --filter @rizom/brain dev:start",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var bU2=["prompt","directory-sync","note","link","topics","conversation-memory","agents","assessment","auth-service","notifications","email-resend","cms","dashboard","mcp","webserver","web-chat","discord","a2a"],LU2=[...bU2,"image","site-info","site-content","site-builder"],Pnw=[...LU2,"docs","decks"],Mnw=["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."],Onw=YF({name:"relay",version:FU2.version,model:"gpt-5.6-luna",reasoningEffort:"low",site:IU2,theme:zT,presets:{core:bU2,default:LU2,full:Pnw},evalDisable:["webserver","web-chat","mcp","discord"],agentInstructions:Mnw,capabilities:[["prompt",jM,void 0],["note",WM,{}],["link",UM,{}],["image",Yp,void 0],["topics",WH0,{includeEntityTypes:["note","link","summary","agent","swot","deck","doc","anchor-profile","brain-character"],extractableStatuses:["published","draft"]}],["conversation-memory",jwA,{memoryVisibility:"shared"}],["docs",Vs,void 0],["decks",Ds,void 0],["agents",qW0,void 0],["assessment",NW0,void 0],["auth-service",si,void 0],["notifications",$B0,void 0],["email-resend",QX0,void 0],["cms",IM,{}],["dashboard",OL,void 0],["directory-sync",UP,{seedContent:!0,seedContentPath:jnw(import.meta.dir,"..","seed-content"),initialSync:!0}],["site-content",sP,{definitions:JU2}],["rizom-ecosystem",PM,void 0],["site-info",aP,void 0],["site-builder",oP,{}]],interfaces:[["mcp",iF,()=>({})],["discord",xb,()=>({captureUrls:!0})],["a2a",ng,()=>({})],["webserver",yb,()=>({})],["web-chat",dg,()=>({})]],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:{note:{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"}}}),kU2=Onw;import{readFileSync as Waw}from"fs";import{join as Kaw}from"path";import{execSync as Uaw}from"child_process";import{parseArgs as vnw}from"util";var hnw={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 qG(A,Q){let w=A[Q];return typeof w==="string"?w:void 0}function pL(A,Q){let w=A[Q];return typeof w==="boolean"?w:void 0}function _U2(A){let{values:Q,positionals:w}=vnw({args:A,options:hnw,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:w[0]??"help",args:w.slice(1),flags:{model:qG(Q,"model"),domain:qG(Q,"domain"),"content-repo":qG(Q,"content-repo"),backend:qG(Q,"backend"),"push-to":qG(Q,"push-to"),"ai-api-key":qG(Q,"ai-api-key"),"no-interactive":pL(Q,"no-interactive"),preview:pL(Q,"preview"),deploy:pL(Q,"deploy"),regen:pL(Q,"regen"),all:pL(Q,"all"),only:qG(Q,"only"),"dry-run":pL(Q,"dry-run"),"startup-check":pL(Q,"startup-check"),"storage-dir":qG(Q,"storage-dir"),yes:pL(Q,"yes"),remote:qG(Q,"remote"),token:qG(Q,"token"),outputDir:qG(Q,"outputDir")}}}Nt();import{mkdirSync as Aaw}from"fs";import{join as Qaw}from"path";import{execSync as waw}from"child_process";var KU0={name:"@rizom/brain",version:"0.2.0-alpha.159",description:"Brain runtime + CLI \u2014 scaffold, run, and manage AI brain instances",keywords:["brain","ai","cli","mcp","agent","personal-ai","knowledge-management"],license:"Apache-2.0",author:"Yeehaa <yeehaa@rizom.ai> (https://rizom.ai)",bin:{brain:"./dist/brain.js"},bugs:"https://github.com/rizom-ai/brains/issues",dependencies:{"@clack/prompts":"^1.5.1","@modelcontextprotocol/sdk":"^1.29.0","@tailwindcss/postcss":"^4.3.1","@tailwindcss/typography":"^0.5.20",postcss:"^8.5.15",preact:"^10.27.2","preact-render-to-string":"^6.7.0",tailwindcss:"^4.3.1",zod:"^4.1.8"},devDependencies:{"@brains/app":"workspace:*","@brains/build-tools":"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":"^1.3.14",rolldown:"^1.0.0","rolldown-plugin-dts":"^0.27.4",typescript:"^7.0.2"},engines:{bun:">=1.3.3"},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"],homepage:"https://github.com/rizom-ai/brains/tree/main/packages/brain-cli#readme",optionalDependencies:{"@bitwarden/sdk-napi":"^1.0.0","@libsql/client":"^0.17.4","@tailwindcss/oxide":"^4.1.4",lightningcss:"^1.29.2","playwright-core":"^1.61.0","react-devtools-core":"^7.0.1",sharp:"^0.35.1"},publishConfig:{access:"public"},repository:{type:"git",url:"https://github.com/rizom-ai/brains.git",directory:"packages/brain-cli"},scripts:{build:"bun scripts/build.ts","dev:start":"bun scripts/build.ts && bun dist/brain.js start",lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",prepublishOnly:"bun scripts/build.ts",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};import{mkdirSync as SU2,writeFileSync as Pt,chmodSync as Mt,existsSync as SwA,readFileSync as mwA}from"fs";import{basename as uwA,dirname as cwA,join as YB,resolve as Grw}from"path";import{fileURLToPath as Drw}from"url";var NU2=`ARG BUN_VERSION=1.3.10
13235
13235
  FROM oven/bun:\${BUN_VERSION}-slim AS runtime
13236
13236
 
13237
13237
  WORKDIR /app