@rizom/brain 0.2.0-alpha.150 → 0.2.0-alpha.151
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 +35 -35
- package/dist/deploy.d.ts +8 -8
- package/dist/entities.d.ts +414 -421
- package/dist/index.d.ts +38 -46
- package/dist/index.js +2 -2
- package/dist/index.js.map +2 -2
- package/dist/interfaces.d.ts +211 -132
- package/dist/plugins.d.ts +967 -954
- package/dist/services.d.ts +399 -397
- package/dist/site.d.ts +63 -66
- package/dist/site.js +4 -4
- package/dist/site.js.map +1 -1
- package/dist/templates.d.ts +117 -115
- package/dist/themes.d.ts +3 -2
- package/package.json +4 -4
package/dist/brain.js
CHANGED
|
@@ -430,7 +430,7 @@ ${f}`:"")}function h_0(A,Q,w,B){return async($,f)=>{if(B){let Y={toolName:A,args
|
|
|
430
430
|
hash text NOT NULL,
|
|
431
431
|
created_at numeric
|
|
432
432
|
)
|
|
433
|
-
`;await A.session.run($);let Y=(await A.values(r0`SELECT id, hash, created_at FROM ${r0.identifier(B)} ORDER BY created_at DESC LIMIT 1`))[0]??void 0,X=[];for(let H of w)if(!Y||Number(Y[2])<H.folderMillis){for(let W of H.sql)X.push(A.run(r0.raw(W)));X.push(A.run(r0`INSERT INTO ${r0.identifier(B)} ("hash", "created_at") VALUES(${H.hash}, ${H.folderMillis})`))}await A.session.migrate(X)}var Cu=i(()=>{nLA();Q9()});async function rLA(A,Q){let w=Q?.child("entity-migrate")??LQ.getInstance().child("entity-migrate"),{db:B,client:$,url:f}=p00(A);w.debug("Running entity database migrations...");try{await i00($,f);let X=import.meta.url.includes("/dist/")?new URL("./migrations/entity-service",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await ab(B,{migrationsFolder:X}),await d00($),w.debug("Entity database migrations completed successfully")}catch(Y){throw w.error("Entity database migration failed:",Y),Y}finally{$.close()}}var oLA=i(()=>{Cu();WJ0();y9()});async function sLA(A,Q){let w=Q?.child("job-queue-migrate")??LQ.getInstance().child("job-queue-migrate"),{db:B,client:$,url:f}=T00(A);w.debug("Running job queue migrations...");try{await S00($,f);let X=import.meta.url.includes("/dist/")?new URL("./migrations/job-queue",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await ab(B,{migrationsFolder:X}),w.debug("Job queue migrations completed successfully")}catch(Y){throw w.error("Job queue migration failed:",Y),Y}finally{$.close()}}var aLA=i(()=>{Cu();rb0();y9()});async function tLA(A,Q){let w=Q?.child("conversation-migrate")??LQ.getInstance().child("conversation-migrate"),{db:B,client:$,url:f}=m00(A);w.debug("Running conversation database migrations...");try{if(f.startsWith("file:"))await $.execute("PRAGMA journal_mode = WAL");let X=import.meta.url.includes("/dist/")?new URL("./migrations/conversation-service",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await ab(B,{migrationsFolder:X}),w.debug("Conversation database migrations completed successfully")}catch(Y){throw w.error("Conversation database migration failed:",Y),Y}finally{$.close()}}var eLA=i(()=>{Cu();AJ0();y9()});async function AkA(A,Q){let w=Q?.child("runtime-state-migrate")??LQ.getInstance().child("runtime-state-migrate"),{db:B,client:$,url:f}=U20(A);w.debug("Running runtime state migrations...");try{await G20($,f);let X=import.meta.url.includes("/dist/")?new URL("./migrations/runtime-state",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await ab(B,{migrationsFolder:X}),w.debug("Runtime state migrations completed successfully")}catch(Y){throw w.error("Runtime state migration failed:",Y),Y}finally{$.close()}}var QkA=i(()=>{Cu();y9();d_0()});import{mkdir as KN0}from"fs/promises";function F20(A=process.env){return{dataDir:A.XDG_DATA_HOME??"./data",cacheDir:A.XDG_CACHE_HOME??"./cache",distDir:"./dist"}}function L20(A=process.env){return Sb(F20(A))}async function k20(A=process.env){let Q=F20(A);try{await KN0(Q.dataDir,{recursive:!0}),await KN0(Q.cacheDir,{recursive:!0}),await KN0(Q.distDir,{recursive:!0})}catch(w){let B=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(B,{cause:w})}return Sb(Q)}var _20=i(()=>{J20()});class gu{logger;migrations;constructor(A,Q){this.logger=A,this.migrations=Q??{getStandardConfigWithDirectories:()=>k20(),migrateEntities:rLA,migrateJobQueue:sLA,migrateConversations:tLA,migrateRuntimeState:AkA}}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 UN0=i(()=>{oLA();aLA();eLA();QkA();_20()});function ug2(){return process.env[mg2]}function wkA(){return ug2()!=="production"}var mg2="NODE_ENV";var N20;var GN0=i(()=>{_0();N20=Z.object({theme:Z.object({primaryColor:Z.string().describe("Primary color for the CLI theme").default("#0066cc"),accentColor:Z.string().describe("Accent color for the CLI theme").default("#ff6600")}).describe("Theme configuration for the CLI interface").default({primaryColor:"#0066cc",accentColor:"#ff6600"})})});var $kA;var BkA=i(()=>{$kA={name:"@brains/chat-repl",version:"0.2.0-alpha.150",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:"^6.0.3"},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 eQ=O((lg2,j20)=>{(function(){function A($0,L0){Object.defineProperty(B.prototype,$0,{get:function(){console.warn("%s(...) is deprecated in plain JavaScript React classes. %s",L0[0],L0[1])}})}function Q($0){if($0===null||typeof $0!=="object")return null;return $0=k0&&$0[k0]||$0["@@iterator"],typeof $0==="function"?$0:null}function w($0,L0){$0=($0=$0.constructor)&&($0.displayName||$0.name)||"ReactClass";var R0=$0+"."+L0;N0[R0]||(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.",L0,$0),N0[R0]=!0)}function B($0,L0,R0){this.props=$0,this.context=L0,this.refs=T0,this.updater=R0||P0}function $(){}function f($0,L0,R0){this.props=$0,this.context=L0,this.refs=T0,this.updater=R0||P0}function Y(){}function X($0){return""+$0}function H($0){try{X($0);var L0=!1}catch(x0){L0=!0}if(L0){L0=console;var R0=L0.error,m0=typeof Symbol==="function"&&Symbol.toStringTag&&$0[Symbol.toStringTag]||$0.constructor.name||"Object";return R0.call(L0,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",m0),X($0)}}function W($0){if($0==null)return null;if(typeof $0==="function")return $0.$$typeof===XA?null:$0.displayName||$0.name||null;if(typeof $0==="string")return $0;switch($0){case K0:return"Fragment";case X0:return"Profiler";case c:return"StrictMode";case S0:return"Suspense";case b0:return"SuspenseList";case C0:return"Activity"}if(typeof $0==="object")switch(typeof $0.tag==="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),$0.$$typeof){case o:return"Portal";case w0:return $0.displayName||"Context";case V0:return($0._context.displayName||"Context")+".Consumer";case h0:var L0=$0.render;return $0=$0.displayName,$0||($0=L0.displayName||L0.name||"",$0=$0!==""?"ForwardRef("+$0+")":"ForwardRef"),$0;case J0:return L0=$0.displayName||null,L0!==null?L0:W($0.type)||"Memo";case j0:L0=$0._payload,$0=$0._init;try{return W($0(L0))}catch(R0){}}return null}function K($0){if($0===K0)return"<>";if(typeof $0==="object"&&$0!==null&&$0.$$typeof===j0)return"<...>";try{var L0=W($0);return L0?"<"+L0+">":"<...>"}catch(R0){return"<...>"}}function U(){var $0=YA.A;return $0===null?null:$0.getOwner()}function G(){return Error("react-stack-top-frame")}function q($0){if(u0.call($0,"key")){var L0=Object.getOwnPropertyDescriptor($0,"key").get;if(L0&&L0.isReactWarning)return!1}return $0.key!==void 0}function V($0,L0){function R0(){UA||(UA=!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)",L0))}R0.isReactWarning=!0,Object.defineProperty($0,"key",{get:R0,configurable:!0})}function J(){var $0=W(this.type);return RA[$0]||(RA[$0]=!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.")),$0=this.props.ref,$0!==void 0?$0:null}function b($0,L0,R0,m0,x0,e0){var d0=R0.ref;return $0={$$typeof:n,type:$0,key:L0,props:R0,_owner:m0},(d0!==void 0?d0:null)!==null?Object.defineProperty($0,"ref",{enumerable:!1,get:J}):Object.defineProperty($0,"ref",{enumerable:!1,value:null}),$0._store={},Object.defineProperty($0._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty($0,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty($0,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:x0}),Object.defineProperty($0,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:e0}),Object.freeze&&(Object.freeze($0.props),Object.freeze($0)),$0}function L($0,L0){return L0=b($0.type,L0,$0.props,$0._owner,$0._debugStack,$0._debugTask),$0._store&&(L0._store.validated=$0._store.validated),L0}function N($0){k($0)?$0._store&&($0._store.validated=1):typeof $0==="object"&&$0!==null&&$0.$$typeof===j0&&($0._payload.status==="fulfilled"?k($0._payload.value)&&$0._payload.value._store&&($0._payload.value._store.validated=1):$0._store&&($0._store.validated=1))}function k($0){return typeof $0==="object"&&$0!==null&&$0.$$typeof===n}function x($0){var L0={"=":"=0",":":"=2"};return"$"+$0.replace(/[=:]/g,function(R0){return L0[R0]})}function v($0,L0){return typeof $0==="object"&&$0!==null&&$0.key!=null?(H($0.key),x(""+$0.key)):L0.toString(36)}function h($0){switch($0.status){case"fulfilled":return $0.value;case"rejected":throw $0.reason;default:switch(typeof $0.status==="string"?$0.then(Y,Y):($0.status="pending",$0.then(function(L0){$0.status==="pending"&&($0.status="fulfilled",$0.value=L0)},function(L0){$0.status==="pending"&&($0.status="rejected",$0.reason=L0)})),$0.status){case"fulfilled":return $0.value;case"rejected":throw $0.reason}}throw $0}function P($0,L0,R0,m0,x0){var e0=typeof $0;if(e0==="undefined"||e0==="boolean")$0=null;var d0=!1;if($0===null)d0=!0;else switch(e0){case"bigint":case"string":case"number":d0=!0;break;case"object":switch($0.$$typeof){case n:case o:d0=!0;break;case j0:return d0=$0._init,P(d0($0._payload),L0,R0,m0,x0)}}if(d0){d0=$0,x0=x0(d0);var LA=m0===""?"."+v(d0,0):m0;return zA(x0)?(R0="",LA!=null&&(R0=LA.replace(o0,"$&/")+"/"),P(x0,L0,R0,"",function(sA){return sA})):x0!=null&&(k(x0)&&(x0.key!=null&&(d0&&d0.key===x0.key||H(x0.key)),R0=L(x0,R0+(x0.key==null||d0&&d0.key===x0.key?"":(""+x0.key).replace(o0,"$&/")+"/")+LA),m0!==""&&d0!=null&&k(d0)&&d0.key==null&&d0._store&&!d0._store.validated&&(R0._store.validated=2),x0=R0),L0.push(x0)),1}if(d0=0,LA=m0===""?".":m0+":",zA($0))for(var kA=0;kA<$0.length;kA++)m0=$0[kA],e0=LA+v(m0,kA),d0+=P(m0,L0,R0,e0,x0);else if(kA=Q($0),typeof kA==="function")for(kA===$0.entries&&(QA||console.warn("Using Maps as children is not supported. Use an array of keyed ReactElements instead."),QA=!0),$0=kA.call($0),kA=0;!(m0=$0.next()).done;)m0=m0.value,e0=LA+v(m0,kA++),d0+=P(m0,L0,R0,e0,x0);else if(e0==="object"){if(typeof $0.then==="function")return P(h($0),L0,R0,m0,x0);throw L0=String($0),Error("Objects are not valid as a React child (found: "+(L0==="[object Object]"?"object with keys {"+Object.keys($0).join(", ")+"}":L0)+"). If you meant to render a collection of children, use an array instead.")}return d0}function E($0,L0,R0){if($0==null)return $0;var m0=[],x0=0;return P($0,m0,"","",function(e0){return L0.call(R0,e0,x0++)}),m0}function S($0){if($0._status===-1){var L0=$0._ioInfo;L0!=null&&(L0.start=L0.end=performance.now()),L0=$0._result;var R0=L0();if(R0.then(function(x0){if($0._status===0||$0._status===-1){$0._status=1,$0._result=x0;var e0=$0._ioInfo;e0!=null&&(e0.end=performance.now()),R0.status===void 0&&(R0.status="fulfilled",R0.value=x0)}},function(x0){if($0._status===0||$0._status===-1){$0._status=2,$0._result=x0;var e0=$0._ioInfo;e0!=null&&(e0.end=performance.now()),R0.status===void 0&&(R0.status="rejected",R0.reason=x0)}}),L0=$0._ioInfo,L0!=null){L0.value=R0;var m0=R0.displayName;typeof m0==="string"&&(L0.name=m0)}$0._status===-1&&($0._status=0,$0._result=R0)}if($0._status===1)return L0=$0._result,L0===void 0&&console.error(`lazy: Expected the result of a dynamic import() call. Instead received: %s
|
|
433
|
+
`;await A.session.run($);let Y=(await A.values(r0`SELECT id, hash, created_at FROM ${r0.identifier(B)} ORDER BY created_at DESC LIMIT 1`))[0]??void 0,X=[];for(let H of w)if(!Y||Number(Y[2])<H.folderMillis){for(let W of H.sql)X.push(A.run(r0.raw(W)));X.push(A.run(r0`INSERT INTO ${r0.identifier(B)} ("hash", "created_at") VALUES(${H.hash}, ${H.folderMillis})`))}await A.session.migrate(X)}var Cu=i(()=>{nLA();Q9()});async function rLA(A,Q){let w=Q?.child("entity-migrate")??LQ.getInstance().child("entity-migrate"),{db:B,client:$,url:f}=p00(A);w.debug("Running entity database migrations...");try{await i00($,f);let X=import.meta.url.includes("/dist/")?new URL("./migrations/entity-service",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await ab(B,{migrationsFolder:X}),await d00($),w.debug("Entity database migrations completed successfully")}catch(Y){throw w.error("Entity database migration failed:",Y),Y}finally{$.close()}}var oLA=i(()=>{Cu();WJ0();y9()});async function sLA(A,Q){let w=Q?.child("job-queue-migrate")??LQ.getInstance().child("job-queue-migrate"),{db:B,client:$,url:f}=T00(A);w.debug("Running job queue migrations...");try{await S00($,f);let X=import.meta.url.includes("/dist/")?new URL("./migrations/job-queue",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await ab(B,{migrationsFolder:X}),w.debug("Job queue migrations completed successfully")}catch(Y){throw w.error("Job queue migration failed:",Y),Y}finally{$.close()}}var aLA=i(()=>{Cu();rb0();y9()});async function tLA(A,Q){let w=Q?.child("conversation-migrate")??LQ.getInstance().child("conversation-migrate"),{db:B,client:$,url:f}=m00(A);w.debug("Running conversation database migrations...");try{if(f.startsWith("file:"))await $.execute("PRAGMA journal_mode = WAL");let X=import.meta.url.includes("/dist/")?new URL("./migrations/conversation-service",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await ab(B,{migrationsFolder:X}),w.debug("Conversation database migrations completed successfully")}catch(Y){throw w.error("Conversation database migration failed:",Y),Y}finally{$.close()}}var eLA=i(()=>{Cu();AJ0();y9()});async function AkA(A,Q){let w=Q?.child("runtime-state-migrate")??LQ.getInstance().child("runtime-state-migrate"),{db:B,client:$,url:f}=U20(A);w.debug("Running runtime state migrations...");try{await G20($,f);let X=import.meta.url.includes("/dist/")?new URL("./migrations/runtime-state",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await ab(B,{migrationsFolder:X}),w.debug("Runtime state migrations completed successfully")}catch(Y){throw w.error("Runtime state migration failed:",Y),Y}finally{$.close()}}var QkA=i(()=>{Cu();y9();d_0()});import{mkdir as KN0}from"fs/promises";function F20(A=process.env){return{dataDir:A.XDG_DATA_HOME??"./data",cacheDir:A.XDG_CACHE_HOME??"./cache",distDir:"./dist"}}function L20(A=process.env){return Sb(F20(A))}async function k20(A=process.env){let Q=F20(A);try{await KN0(Q.dataDir,{recursive:!0}),await KN0(Q.cacheDir,{recursive:!0}),await KN0(Q.distDir,{recursive:!0})}catch(w){let B=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(B,{cause:w})}return Sb(Q)}var _20=i(()=>{J20()});class gu{logger;migrations;constructor(A,Q){this.logger=A,this.migrations=Q??{getStandardConfigWithDirectories:()=>k20(),migrateEntities:rLA,migrateJobQueue:sLA,migrateConversations:tLA,migrateRuntimeState:AkA}}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 UN0=i(()=>{oLA();aLA();eLA();QkA();_20()});function ug2(){return process.env[mg2]}function wkA(){return ug2()!=="production"}var mg2="NODE_ENV";var N20;var GN0=i(()=>{_0();N20=Z.object({theme:Z.object({primaryColor:Z.string().describe("Primary color for the CLI theme").default("#0066cc"),accentColor:Z.string().describe("Accent color for the CLI theme").default("#ff6600")}).describe("Theme configuration for the CLI interface").default({primaryColor:"#0066cc",accentColor:"#ff6600"})})});var $kA;var BkA=i(()=>{$kA={name:"@brains/chat-repl",version:"0.2.0-alpha.151",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 eQ=O((lg2,j20)=>{(function(){function A($0,L0){Object.defineProperty(B.prototype,$0,{get:function(){console.warn("%s(...) is deprecated in plain JavaScript React classes. %s",L0[0],L0[1])}})}function Q($0){if($0===null||typeof $0!=="object")return null;return $0=k0&&$0[k0]||$0["@@iterator"],typeof $0==="function"?$0:null}function w($0,L0){$0=($0=$0.constructor)&&($0.displayName||$0.name)||"ReactClass";var R0=$0+"."+L0;N0[R0]||(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.",L0,$0),N0[R0]=!0)}function B($0,L0,R0){this.props=$0,this.context=L0,this.refs=T0,this.updater=R0||P0}function $(){}function f($0,L0,R0){this.props=$0,this.context=L0,this.refs=T0,this.updater=R0||P0}function Y(){}function X($0){return""+$0}function H($0){try{X($0);var L0=!1}catch(x0){L0=!0}if(L0){L0=console;var R0=L0.error,m0=typeof Symbol==="function"&&Symbol.toStringTag&&$0[Symbol.toStringTag]||$0.constructor.name||"Object";return R0.call(L0,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",m0),X($0)}}function W($0){if($0==null)return null;if(typeof $0==="function")return $0.$$typeof===XA?null:$0.displayName||$0.name||null;if(typeof $0==="string")return $0;switch($0){case K0:return"Fragment";case X0:return"Profiler";case c:return"StrictMode";case S0:return"Suspense";case b0:return"SuspenseList";case C0:return"Activity"}if(typeof $0==="object")switch(typeof $0.tag==="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),$0.$$typeof){case o:return"Portal";case w0:return $0.displayName||"Context";case V0:return($0._context.displayName||"Context")+".Consumer";case h0:var L0=$0.render;return $0=$0.displayName,$0||($0=L0.displayName||L0.name||"",$0=$0!==""?"ForwardRef("+$0+")":"ForwardRef"),$0;case J0:return L0=$0.displayName||null,L0!==null?L0:W($0.type)||"Memo";case j0:L0=$0._payload,$0=$0._init;try{return W($0(L0))}catch(R0){}}return null}function K($0){if($0===K0)return"<>";if(typeof $0==="object"&&$0!==null&&$0.$$typeof===j0)return"<...>";try{var L0=W($0);return L0?"<"+L0+">":"<...>"}catch(R0){return"<...>"}}function U(){var $0=YA.A;return $0===null?null:$0.getOwner()}function G(){return Error("react-stack-top-frame")}function q($0){if(u0.call($0,"key")){var L0=Object.getOwnPropertyDescriptor($0,"key").get;if(L0&&L0.isReactWarning)return!1}return $0.key!==void 0}function V($0,L0){function R0(){UA||(UA=!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)",L0))}R0.isReactWarning=!0,Object.defineProperty($0,"key",{get:R0,configurable:!0})}function J(){var $0=W(this.type);return RA[$0]||(RA[$0]=!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.")),$0=this.props.ref,$0!==void 0?$0:null}function b($0,L0,R0,m0,x0,e0){var d0=R0.ref;return $0={$$typeof:n,type:$0,key:L0,props:R0,_owner:m0},(d0!==void 0?d0:null)!==null?Object.defineProperty($0,"ref",{enumerable:!1,get:J}):Object.defineProperty($0,"ref",{enumerable:!1,value:null}),$0._store={},Object.defineProperty($0._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty($0,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty($0,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:x0}),Object.defineProperty($0,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:e0}),Object.freeze&&(Object.freeze($0.props),Object.freeze($0)),$0}function L($0,L0){return L0=b($0.type,L0,$0.props,$0._owner,$0._debugStack,$0._debugTask),$0._store&&(L0._store.validated=$0._store.validated),L0}function N($0){k($0)?$0._store&&($0._store.validated=1):typeof $0==="object"&&$0!==null&&$0.$$typeof===j0&&($0._payload.status==="fulfilled"?k($0._payload.value)&&$0._payload.value._store&&($0._payload.value._store.validated=1):$0._store&&($0._store.validated=1))}function k($0){return typeof $0==="object"&&$0!==null&&$0.$$typeof===n}function x($0){var L0={"=":"=0",":":"=2"};return"$"+$0.replace(/[=:]/g,function(R0){return L0[R0]})}function v($0,L0){return typeof $0==="object"&&$0!==null&&$0.key!=null?(H($0.key),x(""+$0.key)):L0.toString(36)}function h($0){switch($0.status){case"fulfilled":return $0.value;case"rejected":throw $0.reason;default:switch(typeof $0.status==="string"?$0.then(Y,Y):($0.status="pending",$0.then(function(L0){$0.status==="pending"&&($0.status="fulfilled",$0.value=L0)},function(L0){$0.status==="pending"&&($0.status="rejected",$0.reason=L0)})),$0.status){case"fulfilled":return $0.value;case"rejected":throw $0.reason}}throw $0}function P($0,L0,R0,m0,x0){var e0=typeof $0;if(e0==="undefined"||e0==="boolean")$0=null;var d0=!1;if($0===null)d0=!0;else switch(e0){case"bigint":case"string":case"number":d0=!0;break;case"object":switch($0.$$typeof){case n:case o:d0=!0;break;case j0:return d0=$0._init,P(d0($0._payload),L0,R0,m0,x0)}}if(d0){d0=$0,x0=x0(d0);var LA=m0===""?"."+v(d0,0):m0;return zA(x0)?(R0="",LA!=null&&(R0=LA.replace(o0,"$&/")+"/"),P(x0,L0,R0,"",function(sA){return sA})):x0!=null&&(k(x0)&&(x0.key!=null&&(d0&&d0.key===x0.key||H(x0.key)),R0=L(x0,R0+(x0.key==null||d0&&d0.key===x0.key?"":(""+x0.key).replace(o0,"$&/")+"/")+LA),m0!==""&&d0!=null&&k(d0)&&d0.key==null&&d0._store&&!d0._store.validated&&(R0._store.validated=2),x0=R0),L0.push(x0)),1}if(d0=0,LA=m0===""?".":m0+":",zA($0))for(var kA=0;kA<$0.length;kA++)m0=$0[kA],e0=LA+v(m0,kA),d0+=P(m0,L0,R0,e0,x0);else if(kA=Q($0),typeof kA==="function")for(kA===$0.entries&&(QA||console.warn("Using Maps as children is not supported. Use an array of keyed ReactElements instead."),QA=!0),$0=kA.call($0),kA=0;!(m0=$0.next()).done;)m0=m0.value,e0=LA+v(m0,kA++),d0+=P(m0,L0,R0,e0,x0);else if(e0==="object"){if(typeof $0.then==="function")return P(h($0),L0,R0,m0,x0);throw L0=String($0),Error("Objects are not valid as a React child (found: "+(L0==="[object Object]"?"object with keys {"+Object.keys($0).join(", ")+"}":L0)+"). If you meant to render a collection of children, use an array instead.")}return d0}function E($0,L0,R0){if($0==null)return $0;var m0=[],x0=0;return P($0,m0,"","",function(e0){return L0.call(R0,e0,x0++)}),m0}function S($0){if($0._status===-1){var L0=$0._ioInfo;L0!=null&&(L0.start=L0.end=performance.now()),L0=$0._result;var R0=L0();if(R0.then(function(x0){if($0._status===0||$0._status===-1){$0._status=1,$0._result=x0;var e0=$0._ioInfo;e0!=null&&(e0.end=performance.now()),R0.status===void 0&&(R0.status="fulfilled",R0.value=x0)}},function(x0){if($0._status===0||$0._status===-1){$0._status=2,$0._result=x0;var e0=$0._ioInfo;e0!=null&&(e0.end=performance.now()),R0.status===void 0&&(R0.status="rejected",R0.reason=x0)}}),L0=$0._ioInfo,L0!=null){L0.value=R0;var m0=R0.displayName;typeof m0==="string"&&(L0.name=m0)}$0._status===-1&&($0._status=0,$0._result=R0)}if($0._status===1)return L0=$0._result,L0===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'))
|
|
@@ -1189,7 +1189,7 @@ Examples:
|
|
|
1189
1189
|
|
|
1190
1190
|
`+A}var UOA=i(()=>{HOA()});function KJ(A){if(A===void 0)return[];return Array.isArray(A)?A:[A]}function GOA(A){return iQ0.safeParse(A).success}function DOA(A){let Q={};for(let[w,B]of Object.entries(A??{}))if(!GOA(B))Q[w]=B;return Q}function zOA(A){let Q={};for(let[w,B]of Object.entries(A??{}))if(GOA(B))Q[w]=B;return Q}function Gc2(A){return[A.sitePackageRef,A.themeRef,A.themeOverrideRef,A.siteContentDefinitionsRef].some(Boolean)}function Dc2(A,Q){let w={...A};if(!w.package&&Q.sitePackageRef)w.package=Q.sitePackageRef;if(!w.theme&&Q.themeRef)w.theme=Q.themeRef;if(!w.themeOverride&&Q.themeOverrideRef)w.themeOverride=Q.themeOverrideRef;return w}function zc2(A,Q){let w={...A},B={...w["site-content"]??{}};if(B.definitions===void 0&&Q.siteContentDefinitionsRef)B.definitions=Q.siteContentDefinitionsRef;if(Object.keys(B).length>0)w["site-content"]=B;return w}function mv(A,Q){if(!Gc2(Q))return A;let w=Dc2(A.site??{},Q),B=zc2(A.plugins??{},Q);return{...A,...Object.keys(w).length>0?{site:w}:{},...Object.keys(B).length>0?{plugins:B}:{}}}function qOA(A){let{package:Q,theme:w,themeOverride:B,...$}=A??{};return $}function PP0(A){if(A===null||A===void 0)return;if(Array.isArray(A))return A.map((w)=>PP0(w)).filter((w)=>w!==void 0);let Q=fc2.safeParse(A);if(Q.success){let w={};for(let[B,$]of Object.entries(Q.data)){let f=PP0($);if(f!==void 0)w[B]=f}return w}return A}function qc2(A){return`invalid brain.yaml:
|
|
1191
1191
|
${A.issues.map((w)=>{return` - ${w.path.length>0?w.path.join("."):"(root)"}: ${w.message}`}).join(`
|
|
1192
|
-
`)}`}function VOA(A){let Q=q20(A);if(!Q.ok)throw new xc(`failed to parse brain.yaml: ${Q.error}`);let w=K00(Q.data),B=PP0(w),$=Uc2.safeParse(B);if(!$.success)throw new xc(qc2($.error));return $.data}var $c2,fc2,Yc2,Xc2,Zc2,Hc2,Oc,Wc2,Kc2,iQ0,vc,Uc2,SG="@brains/local-site",UJ="@brains/local-theme",Sv="@brains/local-site-content",xc;var Rc=i(()=>{U2();fv();_0();Zv();$c2=Z.record(Z.string(),Z.unknown()),fc2=Z.record(Z.string(),Z.unknown()),Yc2=Z.enum(["core","default","full"]),Xc2=Z.enum(["eval"]),Zc2=Z.enum(["debug","info","warn","error"]),Hc2=Z.enum(["anchor","trusted","public"]),Oc=Z.enum(["never","anchor","trusted","public"]),Wc2=Z.strictObject({create:Oc.optional(),update:Oc.optional(),delete:Oc.optional(),extract:Oc.optional(),publish:Oc.optional()}),Kc2=Z.record(Z.string(),Wc2),iQ0=Z.strictObject({package:Z.string().min(1),config:Z.record(Z.string(),Z.unknown()).optional()}),vc=$c2.superRefine((A,Q)=>{if(typeof A.package!=="string")return;if(!iQ0.safeParse(A).success)Q.addIssue({code:Z.ZodIssueCode.custom,message:'external plugin declarations may only contain "package" and optional nested "config"'})}),Uc2=Z.object({brain:Z.string().optional(),site:Z.object({package:Z.string().optional(),variant:Z.string().optional(),theme:Z.string().optional(),themeOverride:Z.string().optional()}).optional(),name:Z.string().optional(),logLevel:Zc2.optional(),logFile:Z.string().optional(),port:Z.number().optional(),domain:Z.string().optional(),database:Z.string().optional(),model:Z.string().optional(),reasoningEffort:hu.optional(),preset:Yc2.optional(),mode:Xc2.optional(),add:Z.array(Z.string()).optional(),remove:Z.array(Z.string()).optional(),anchors:Z.array(Z.string()).optional(),trusted:Z.array(Z.string()).optional(),spaces:Z.array(Z.string()).optional(),plugins:Z.record(Z.string(),vc).optional(),permissions:Z.object({anchors:Z.array(Z.string()).optional(),trusted:Z.array(Z.string()).optional(),rules:Z.array(Z.object({pattern:Z.string(),level:Hc2})).optional(),entityActions:Kc2.optional()}).optional()});xc=class xc extends Error{constructor(A){super(A);this.name="InstanceOverridesParseError"}}});var bOA;var MP0=i(()=>{e8();_0();bOA=Z.custom((A)=>dV0.safeParse(A).success)});function JOA(A,Q){let{AI_API_KEY:w,AI_IMAGE_KEY:B}=A,$={};if(w)$.aiApiKey=w;if(B)$.aiImageKey=B;if(Q?.model){let f=Q.model.indexOf(":");$.aiModel=f>0?Q.model.slice(f+1):Q.model}if(Q?.reasoningEffort)$.aiReasoningEffort=Q.reasoningEffort;return $}function uH(A,Q){OP0.set(A,Q)}function W_(A){return OP0.get(A)}function gz(A){return OP0.has(A)}var OP0;var hc=i(()=>{OP0=new Map});function _OA(A,Q){if(!A.presets)return;let w=Q?.preset??A.defaultPreset??"default";if(!A.presets[w])throw Error(`Unknown preset "${w}". Available: ${Object.keys(A.presets).join(", ")}`);return w}function Ic2(A,Q){let w=new Set([...A.capabilities.map(([f])=>f),...A.interfaces.map(([f])=>f)]),B=_OA(A,Q);if(!A.presets||!B)return null;let $=new Set(A.presets[B]);if(Q?.mode==="eval"&&A.evalDisable)for(let f of A.evalDisable)$.delete(f);if(Q?.add){for(let f of Q.add)if(w.has(f))$.add(f)}if(Q?.remove)for(let f of Q.remove)$.delete(f);return $}function IOA(A){return bc2.safeParse(A).success}function K_(A,Q){let w={...A};for(let B of Object.keys(Q)){let $=Q[B];if($===null)delete w[B];else if(IOA(w[B])&&IOA($))w[B]=K_(w[B],$);else w[B]=$}return w}function xP0(A,Q){return!A||A.has(Q)}function Fc2(A,Q,w){return Q?Q.has(w):A.interfaces.some(([B])=>B===w)}function Lc2(A,Q,w){return Q?Q.has(w):A.capabilities.some(([B])=>B===w)}function kc2(A,Q){let{webserverEnabled:w,siteBuilderEnabled:B,site:$,theme:f}=Q;if(w){let Y=A.webserver??{},X={enablePreview:B};A.webserver=K_(X,Y)}if($||f!==void 0){let Y=A["site-builder"]??{},X={...f!==void 0&&{themeCSS:f},...$&&{routes:$.routes,entityDisplay:$.entityDisplay,layouts:$.layouts},...$?.staticAssets&&{staticAssets:$.staticAssets}};A["site-builder"]=K_(X,Y)}if(f!==void 0){let Y={themeCSS:f},X=A.dashboard??{};A.dashboard=K_(Y,X);let H=A["dashboard-root"]??{};A["dashboard-root"]=K_(Y,H)}}function _c2(A){if(!A)return[];return Array.isArray(A)?A:[A]}class NOA{id="site-package";version="0.1.0";type="service";description="Declarative site package adapter";packageName;site;constructor(A,Q){this.packageName=A,this.site=Q}async register(A){for(let Q of _c2(this.site.content))A.registerTemplates(zb(Q),Q.namespace);if(this.site.headScripts?.length){let Q=A.getMessageBus();Q.subscribe("system:plugins:ready",async()=>{for(let[w,B]of this.site.headScripts?.entries()??[])await Q.send({type:"plugin:site-builder:head-script:register",sender:this.id,payload:{pluginId:`${this.id}:${w}`,script:B}});return{success:!0}})}return{tools:[],resources:[]}}}function Nc2(A,Q,w){if(!A||!xP0(w,"site-builder"))return[];let B=[];if(A.plugin)B.push(A.plugin({entityDisplay:A.entityDisplay,...qOA(Q?.site)}));if(A.content||A.headScripts?.length)B.push(new NOA(Q?.site?.package??"@rizom/site-package",A));return B}function jc2(A,Q,w,B,$,f){let Y=[];for(let[X,H,W]of A.capabilities){if(!xP0(w,X))continue;let K=typeof W==="function"?W(Q,{...B?{preset:B}:{}}):W??{},U=$[X],G=U?K_(K,U):K;try{let q=H(G);Y.push(...KJ(q))}catch(q){if(q instanceof o3)f?.warn(`Skipping capability "${X}": missing required config`);else throw q}}return Y}function Pc2(A,Q){let w=[];for(let[B,$]of Object.entries(A)){if(Q?.remove?.includes(B))continue;let Y=ic2(B,$)($.config??{});w.push(...KJ(Y))}return w}function Mc2(A,Q,w,B,$){let f=[];for(let[Y,X,H]of A.interfaces){if(!xP0(w,Y))continue;let W=H(Q);if(!W)continue;let K=B[Y],U=K?K_(W,K):W;try{f.push(new X(U))}catch(G){if(G instanceof o3)$?.warn(`Skipping interface "${Y}": missing required config`);else throw G}}return f}function Oc2(A){return A.identity?{name:A.identity.characterName,role:A.identity.role,purpose:A.identity.purpose,values:A.identity.values}:void 0}function xc2(A,Q){let w={...A.deployment??{}};if(Q?.domain)w.domain=Q.domain;if(Q?.port)w.ports={...w.ports??{},production:Q.port};return w}function vc2(A,Q){return{...Q?.logLevel?{logLevel:Q.logLevel}:Xv.safeParse(A.LOG_LEVEL).success?{logLevel:Xv.parse(A.LOG_LEVEL)}:{},...Q?.logFile?{logFile:Q.logFile}:A.LOG_FILE?{logFile:A.LOG_FILE}:{},...Q?.database?{database:Q.database}:A.DATABASE_URL?{database:A.DATABASE_URL}:{}}}function Rc2(A,Q){if(Q.extra)Object.assign(A,Q.extra)}function hc2(A,Q){if(Q===void 0)return;A.shellConfig={...A.shellConfig,themeCSS:Q}}function Cc2(A,Q){if(!Q)return;let w=A.shellConfig??{},B=w.entityDisplay??{};A.shellConfig={...w,entityDisplay:{...Q.entityDisplay,...B}}}function jOA(A,Q,w,B){let $=_OA(A,w),f=Ic2(A,w),Y=cc2(DOA(w?.plugins)),X=zOA(w?.plugins),H=w?.model??A.model,W=w?.reasoningEffort??A.reasoningEffort,K=Fc2(A,f,"webserver"),U=Lc2(A,f,"site-builder"),G=Al2(A,w),q=Ql2(A,w,G);kc2(Y,{webserverEnabled:K,siteBuilderEnabled:U,site:G,theme:q});let V=[...Nc2(G,w,f),...jc2(A,Q,f,$,Y,B),...Pc2(X,w)],J=Mc2(A,Q,f,Y,B),b=Oc2(A),L=xc2(A,w),N={name:w?.name??A.name,version:A.version,plugins:[...V,...J],...JOA(Q,{...H&&{model:H},...W&&{reasoningEffort:W}}),...b&&{identity:b},...A.agentInstructions&&{agentInstructions:A.agentInstructions},...gc2(A.permissions,w,V),...w?.spaces?{spaces:w.spaces}:{},deployment:L,...vc2(Q,w)};return Rc2(N,A),hc2(N,q),Cc2(N,G),pQ0(N)}function gc2(A,Q,w=[]){let B=Q?.permissions,$=yc2(w),f=POA(Vc2,$,A?.entityActions,B?.entityActions);return Ec2(f),{permissions:{...A??{},...Q?.anchors&&{anchors:Q.anchors},...Q?.trusted&&{trusted:Q.trusted},...B?.anchors&&{anchors:B.anchors},...B?.trusted&&{trusted:B.trusted},...B?.rules&&{rules:B.rules},...f&&{entityActions:f}}}}function yc2(A){let Q=[];for(let w of A){if(!w.entityActionPolicy)continue;let B=bA0.safeParse(w.entityActionPolicy);if(!B.success)throw Error(`Plugin "${w.id}" declared an invalid entityActionPolicy: ${B.error.message}`);Q.push(B.data)}return POA(...Q)}function POA(...A){if(!A.some(Boolean))return;let Q={};for(let w of A){if(!w)continue;for(let[B,$]of Object.entries(w))Q[B]={...Q[B]??{},...$}}return Q}function Ec2(A){if(!A)return;for(let Q of Object.keys(A)){let w={...A["*"]??{},...A[Q]??{}};if(!w.update||!w.publish)continue;if(FOA[w.publish]<FOA[w.update])throw Error(`Invalid entity action policy for "${Q}": publish must be at least as restrictive as update`)}}function GJ(A){return Tc2.test(A)}function Sc2(A){return typeof A==="string"&&GJ(A)&&gz(A)}function mc2(A){return Sc2(A)?W_(A):A}function uc2(A){return Object.fromEntries(Object.entries(A).map(([Q,w])=>[Q,mc2(w)]))}function cc2(A){return Object.fromEntries(Object.entries(A).map(([Q,w])=>[Q,uc2(w)]))}function lc2(A,Q){if(!gz(Q))throw Error(`External plugin package "${Q}" for plugins.${A} is not registered. Install it and ensure it is imported before resolve().`);return W_(Q)}function pc2(A){let Q=kOA.safeParse(A);if(Q.success)return Q.data;let w=Jc2.safeParse(A);return w.success?w.data.plugin:void 0}function ic2(A,Q){let w=Q.package,B=lc2(A,w),$=pc2(B);if($)return $;throw Error(`External plugin package "${w}" for plugins.${A} must export a plugin factory as the package default or as a named "plugin" export.`)}function ac2(A,Q){if(!Q||!A.plugin)return A;let w=A.plugin;return{...A,plugin:(B)=>w({...Q,...B??{}})}}function tc2(A,Q){if(!Q.site)return;let w=sc2.safeParse(A);if(!w.success)return;let{pluginConfig:B,...$}=w.data,f=bb(Q.site,$);return ac2(f,B)}function ec2(A,Q,w){let B=bOA.safeParse(Q);if(B.success)return B.data;if(A===SG)return tc2(Q,w);return}function Al2(A,Q){let w=Q?.site?.package;if(!w)return A.site;if(!gz(w))throw Error(`brain.yaml site.package "${w}" could not be resolved \u2014 the package is not installed or failed to import. Refusing to fall back to the default site.`);let B=ec2(w,W_(w),A);if(B)return B;throw Error(`Package "${w}" is not a valid SitePackage`)}function LOA(A){if(gz(A)){let Q=W_(A),w=D00.safeParse(Q);if(!w.success)throw Error(`Package "${A}" does not export theme CSS`);return w.data}return A}function Ql2(A,Q,w){let B=Q?.site?.theme?LOA(Q.site.theme):A.theme,$=w?.themeOverride,f=Q?.site?.themeOverride?LOA(Q.site.themeOverride):void 0,Y=[B,$,f].filter(Boolean).join(`
|
|
1192
|
+
`)}`}function VOA(A){let Q=q20(A);if(!Q.ok)throw new xc(`failed to parse brain.yaml: ${Q.error}`);let w=K00(Q.data),B=PP0(w),$=Uc2.safeParse(B);if(!$.success)throw new xc(qc2($.error));return $.data}var $c2,fc2,Yc2,Xc2,Zc2,Hc2,Oc,Wc2,Kc2,iQ0,vc,Uc2,SG="@brains/local-site",UJ="@brains/local-theme",Sv="@brains/local-site-content",xc;var Rc=i(()=>{U2();fv();_0();Zv();$c2=Z.record(Z.string(),Z.unknown()),fc2=Z.record(Z.string(),Z.unknown()),Yc2=Z.enum(["core","default","full"]),Xc2=Z.enum(["eval"]),Zc2=Z.enum(["debug","info","warn","error"]),Hc2=Z.enum(["anchor","trusted","public"]),Oc=Z.enum(["never","anchor","trusted","public"]),Wc2=Z.strictObject({create:Oc.optional(),update:Oc.optional(),delete:Oc.optional(),extract:Oc.optional(),publish:Oc.optional()}),Kc2=Z.record(Z.string(),Wc2),iQ0=Z.strictObject({package:Z.string().min(1),config:Z.record(Z.string(),Z.unknown()).optional()}),vc=$c2.superRefine((A,Q)=>{if(typeof A.package!=="string")return;if(!iQ0.safeParse(A).success)Q.addIssue({code:Z.ZodIssueCode.custom,message:'external plugin declarations may only contain "package" and optional nested "config"'})}),Uc2=Z.object({brain:Z.string().optional(),site:Z.object({package:Z.string().optional(),variant:Z.string().optional(),theme:Z.string().optional(),themeOverride:Z.string().optional()}).optional(),name:Z.string().optional(),logLevel:Zc2.optional(),logFile:Z.string().optional(),port:Z.number().optional(),domain:Z.string().optional(),database:Z.string().optional(),model:Z.string().optional(),reasoningEffort:hu.optional(),preset:Yc2.optional(),mode:Xc2.optional(),add:Z.array(Z.string()).optional(),remove:Z.array(Z.string()).optional(),anchors:Z.array(Z.string()).optional(),trusted:Z.array(Z.string()).optional(),spaces:Z.array(Z.string()).optional(),plugins:Z.record(Z.string(),vc).optional(),permissions:Z.object({anchors:Z.array(Z.string()).optional(),trusted:Z.array(Z.string()).optional(),rules:Z.array(Z.object({pattern:Z.string(),level:Hc2})).optional(),entityActions:Kc2.optional()}).optional()});xc=class xc extends Error{constructor(A){super(A);this.name="InstanceOverridesParseError"}}});var bOA;var MP0=i(()=>{e8();_0();bOA=Z.custom((A)=>dV0.safeParse(A).success)});function JOA(A,Q){let{AI_API_KEY:w,AI_IMAGE_KEY:B}=A,$={};if(w)$.aiApiKey=w;if(B)$.aiImageKey=B;if(Q?.model){let f=Q.model.indexOf(":");$.aiModel=f>0?Q.model.slice(f+1):Q.model}if(Q?.reasoningEffort)$.aiReasoningEffort=Q.reasoningEffort;return $}function uH(A,Q){OP0.set(A,Q)}function W_(A){return OP0.get(A)}function gz(A){return OP0.has(A)}var OP0;var hc=i(()=>{OP0=new Map});function _OA(A,Q){if(!A.presets)return;let w=Q?.preset??A.defaultPreset??"default";if(!A.presets[w])throw Error(`Unknown preset "${w}". Available: ${Object.keys(A.presets).join(", ")}`);return w}function Ic2(A,Q){let w=new Set([...A.capabilities.map(([f])=>f),...A.interfaces.map(([f])=>f)]),B=_OA(A,Q);if(!A.presets||!B)return null;let $=new Set(A.presets[B]);if(Q?.mode==="eval"&&A.evalDisable)for(let f of A.evalDisable)$.delete(f);if(Q?.add){for(let f of Q.add)if(w.has(f))$.add(f)}if(Q?.remove)for(let f of Q.remove)$.delete(f);return $}function IOA(A){return bc2.safeParse(A).success}function K_(A,Q){let w={...A};for(let B of Object.keys(Q)){let $=Q[B];if($===null)delete w[B];else if(IOA(w[B])&&IOA($))w[B]=K_(w[B],$);else w[B]=$}return w}function xP0(A,Q){return!A||A.has(Q)}function Fc2(A,Q,w){return Q?Q.has(w):A.interfaces.some(([B])=>B===w)}function Lc2(A,Q,w){return Q?Q.has(w):A.capabilities.some(([B])=>B===w)}function kc2(A,Q){let{webserverEnabled:w,siteBuilderEnabled:B,site:$,theme:f}=Q;if(w){let Y=A.webserver??{},X={enablePreview:B};A.webserver=K_(X,Y)}if($||f!==void 0){let Y=A["site-builder"]??{},X={...f!==void 0&&{themeCSS:f},...$&&{routes:$.routes,entityDisplay:$.entityDisplay,layouts:$.layouts},...$?.staticAssets&&{staticAssets:$.staticAssets}};A["site-builder"]=K_(X,Y)}if(f!==void 0){let Y={themeCSS:f},X=A.dashboard??{};A.dashboard=K_(Y,X);let H=A["dashboard-root"]??{};A["dashboard-root"]=K_(Y,H)}}function _c2(A){if(!A)return[];return Array.isArray(A)?A:[A]}class NOA{id="site-package";version="0.1.0";type="service";description="Declarative site package adapter";packageName;site;constructor(A,Q){this.packageName=A,this.site=Q}async register(A){for(let Q of _c2(this.site.content))A.registerTemplates(zb(Q),Q.namespace);if(this.site.headScripts?.length){let Q=A.getMessageBus();Q.subscribe("system:plugins:ready",async()=>{for(let[w,B]of this.site.headScripts?.entries()??[])await Q.send({type:"plugin:site-builder:head-script:register",sender:this.id,payload:{pluginId:`${this.id}:${w}`,script:B}});return{success:!0}})}return{tools:[],resources:[]}}}function Nc2(A,Q,w){if(!A||!xP0(w,"site-builder"))return[];let B=[];if(A.plugin)B.push(A.plugin({entityDisplay:A.entityDisplay,...qOA(Q?.site)}));if(A.content||A.headScripts?.length)B.push(new NOA(Q?.site?.package??"@rizom/site-package",A));return B}function jc2(A,Q,w,B,$,f){let Y=[];for(let[X,H,W]of A.capabilities){if(!xP0(w,X))continue;let K=typeof W==="function"?W(Q,{...B?{preset:B}:{}}):W??{},U=$[X],G=U?K_(K,U):K;try{let q=H(G);Y.push(...KJ(q))}catch(q){if(q instanceof o3)f?.warn(`Skipping capability "${X}": missing required config`);else throw q}}return Y}function Pc2(A,Q){let w=[];for(let[B,$]of Object.entries(A)){if(Q?.remove?.includes(B))continue;let Y=ic2(B,$)($.config??{});w.push(...KJ(Y))}return w}function Mc2(A,Q,w,B,$){let f=[];for(let[Y,X,H]of A.interfaces){if(!xP0(w,Y))continue;let W=H(Q);if(!W)continue;let K=B[Y],U=K?K_(W,K):W;try{f.push(new X(U))}catch(G){if(G instanceof o3)$?.warn(`Skipping interface "${Y}": missing required config`);else throw G}}return f}function Oc2(A){return A.identity?{name:A.identity.characterName,role:A.identity.role,purpose:A.identity.purpose,values:A.identity.values}:void 0}function xc2(A,Q){let w={...A.deployment??{}};if(Q?.domain)w.domain=Q.domain;if(Q?.port)w.ports={...w.ports??{},production:Q.port};return w}function vc2(A,Q){return{...Q?.logLevel?{logLevel:Q.logLevel}:Xv.safeParse(A.LOG_LEVEL).success?{logLevel:Xv.parse(A.LOG_LEVEL)}:{},...Q?.logFile?{logFile:Q.logFile}:A.LOG_FILE?{logFile:A.LOG_FILE}:{},...Q?.database?{database:Q.database}:A.DATABASE_URL?{database:A.DATABASE_URL}:{}}}function Rc2(A,Q){if(Q.extra)Object.assign(A,Q.extra)}function hc2(A,Q){if(Q===void 0)return;A.shellConfig={...A.shellConfig,themeCSS:Q}}function Cc2(A,Q){if(!Q)return;let w=A.shellConfig??{},B=w.entityDisplay??{};A.shellConfig={...w,entityDisplay:{...Q.entityDisplay,...B}}}function jOA(A,Q,w,B){let $=_OA(A,w),f=Ic2(A,w),Y=cc2(DOA(w?.plugins)),X=zOA(w?.plugins),H=w?.model??A.model,W=w?.reasoningEffort??A.reasoningEffort,K=Fc2(A,f,"webserver"),U=Lc2(A,f,"site-builder"),G=Al2(A,w),q=Ql2(A,w,G);kc2(Y,{webserverEnabled:K,siteBuilderEnabled:U,site:G,theme:q});let V=[...Nc2(G,w,f),...jc2(A,Q,f,$,Y,B),...Pc2(X,w)],J=Mc2(A,Q,f,Y,B),b=Oc2(A),L=xc2(A,w),N={name:w?.name??A.name,version:A.version,plugins:[...V,...J],...JOA(Q,{...H&&{model:H},...W&&{reasoningEffort:W}}),...b&&{identity:b},...A.agentInstructions&&{agentInstructions:A.agentInstructions},...gc2(A.permissions,w,V),...w?.spaces?{spaces:w.spaces}:{},deployment:L,...vc2(Q,w)};return Rc2(N,A),hc2(N,q),Cc2(N,G),pQ0(N)}function gc2(A,Q,w=[]){let B=Q?.permissions,$=yc2(w),f=POA(Vc2,$,A?.entityActions,B?.entityActions);return Ec2(f),{permissions:{...A??{},...Q?.anchors&&{anchors:Q.anchors},...Q?.trusted&&{trusted:Q.trusted},...B?.anchors&&{anchors:B.anchors},...B?.trusted&&{trusted:B.trusted},...B?.rules&&{rules:B.rules},...f&&{entityActions:f}}}}function yc2(A){let Q=[];for(let w of A){if(!w.entityActionPolicy)continue;let B=bA0.safeParse(w.entityActionPolicy);if(!B.success)throw Error(`Plugin "${w.id}" declared an invalid entityActionPolicy: ${B.error.message}`);Q.push(B.data)}return POA(...Q)}function POA(...A){if(!A.some(Boolean))return;let Q={};for(let w of A){if(!w)continue;for(let[B,$]of Object.entries(w))Q[B]={...Q[B]??{},...$}}return Q}function Ec2(A){if(!A)return;for(let Q of Object.keys(A)){let w={...A["*"]??{},...A[Q]??{}};if(!w.update||!w.publish)continue;if(FOA[w.publish]<FOA[w.update])throw Error(`Invalid entity action policy for "${Q}": publish must be at least as restrictive as update`)}}function GJ(A){return Tc2.test(A)}function Sc2(A){return typeof A==="string"&&GJ(A)&&gz(A)}function mc2(A){return Sc2(A)?W_(A):A}function uc2(A){return Object.fromEntries(Object.entries(A).map(([Q,w])=>[Q,mc2(w)]))}function cc2(A){return Object.fromEntries(Object.entries(A).map(([Q,w])=>[Q,uc2(w)]))}function lc2(A,Q){if(!gz(Q))throw Error(`External plugin package "${Q}" for plugins.${A} is not registered. Install it and ensure it is imported before resolve().`);return W_(Q)}function pc2(A){let Q=kOA.safeParse(A);if(Q.success)return Q.data;let w=Jc2.safeParse(A);return w.success?w.data.plugin:void 0}function ic2(A,Q){let w=Q.package,B=lc2(A,w),$=pc2(B);if($)return $;throw Error(`External plugin package "${w}" for plugins.${A} must export a plugin factory as the package default or as a named "plugin" export.`)}function ac2(A,Q){if(!Q||!A.plugin)return A;let w=A.plugin;return{...A,plugin:(B)=>w({...Q,...B??{}})}}function tc2(A,Q){if(!Q.site)return;let w=sc2.safeParse(A);if(!w.success)return;let{pluginConfig:B,...$}=w.data,f=bb(Q.site,$);return ac2(f,B)}function ec2(A,Q,w){if(A===SG){let $=tc2(Q,w);if($)return $}let B=bOA.safeParse(Q);return B.success?B.data:void 0}function Al2(A,Q){let w=Q?.site?.package;if(!w)return A.site;if(!gz(w))throw Error(`brain.yaml site.package "${w}" could not be resolved \u2014 the package is not installed or failed to import. Refusing to fall back to the default site.`);let B=ec2(w,W_(w),A);if(B)return B;throw Error(`Package "${w}" is not a valid SitePackage`)}function LOA(A){if(gz(A)){let Q=W_(A),w=D00.safeParse(Q);if(!w.success)throw Error(`Package "${A}" does not export theme CSS`);return w.data}return A}function Ql2(A,Q,w){let B=Q?.site?.theme?LOA(Q.site.theme):A.theme,$=w?.themeOverride,f=Q?.site?.themeOverride?LOA(Q.site.themeOverride):void 0,Y=[B,$,f].filter(Boolean).join(`
|
|
1193
1193
|
|
|
1194
1194
|
`);if(!Y)return;return KOA(Y)}var Vc2,bc2,kOA,Jc2,FOA,Tc2,dc2,nc2,rc2,oc2,sc2;var vP0=i(()=>{wA();jB();UOA();_0();Rc();MP0();kP0();Zv();hc();Vc2={"*":{create:"anchor",update:"anchor",delete:"anchor",extract:"anchor",publish:"anchor"},"anchor-profile":{create:"never",update:"anchor",delete:"never"},"brain-character":{create:"never",update:"anchor",delete:"never"}},bc2=Z.record(Z.string(),Z.unknown()),kOA=Z.custom((A)=>typeof A==="function"),Jc2=Z.looseObject({plugin:kOA.optional()});FOA={public:0,trusted:1,anchor:2,never:3};Tc2=/^@[\w-]+\/[\w-]+$/;dc2=Z.looseObject({id:Z.string().min(1)}),nc2=Z.looseObject({label:Z.string().min(1)}),rc2=Z.custom((A)=>typeof A==="function"),oc2=Z.looseObject({layouts:Z.record(Z.string(),Z.unknown()).optional(),plugin:rc2.optional(),pluginConfig:Z.record(Z.string(),Z.unknown()).optional(),routes:Z.array(dc2).optional(),entityDisplay:Z.record(Z.string(),nc2).optional(),content:Z.unknown().optional(),themeOverride:Z.string().optional(),headScripts:Z.array(Z.string()).optional(),staticAssets:Z.record(Z.string(),Z.string()).optional()}),sc2=Z.custom((A)=>oc2.safeParse(A).success)});function dQ0(A){let Q=[],w=A.site?.package;if(w&&GJ(w))Q.push(w);let B=A.site?.theme;if(B&&GJ(B))Q.push(B);let $=A.site?.themeOverride;if($&&GJ($))Q.push($);if(A.plugins){for(let f of Object.values(A.plugins))for(let Y of Object.values(f))if(typeof Y==="string"&&GJ(Y))Q.push(Y)}return[...new Set(Q)]}var RP0=i(()=>{vP0()});async function MOA(A,Q=(w)=>import(w)){let w=dQ0(A);await Promise.all(w.map(async(B)=>{if(gz(B))return;try{let $=await Q(B);uH(B,$.default??$)}catch($){let f=$ instanceof Error?$.message:String($);console.error(`\u274C brain.yaml: failed to import package "${B}": ${f}`)}}))}var OOA=i(()=>{RP0();hc()});import{existsSync as hP0,readFileSync as wl2}from"fs";import{join as CP0}from"path";import{pathToFileURL as xOA}from"url";async function nQ0(A,Q){let w=Q,B=CP0(A,"src/site.ts");if(!Q.site?.package&&hP0(B)){let X=await import(xOA(B).href);if(X.default===void 0)throw Error(`Conventional site file ${B} must default-export a SitePackage or site overrides`);uH(SG,X.default),w=mv(w,{sitePackageRef:SG})}let $=CP0(A,"src/theme.css");if(!Q.site?.themeOverride&&hP0($))uH(UJ,wl2($,"utf-8")),w=mv(w,{themeOverrideRef:UJ});let f=CP0(A,"src/site-content.ts");if(w.plugins?.["site-content"]?.definitions===void 0&&hP0(f)){let X=await import(xOA(f).href);if(X.default===void 0)throw Error(`Conventional site-content file ${f} must default-export site content definitions`);uH(Sv,X.default),w=mv(w,{siteContentDefinitionsRef:Sv})}return w}var vOA=i(()=>{Rc();hc();Rc()});var ROA={};D6(ROA,{resolveStandardPaths:()=>F20,resolveStandardConfigWithDirectories:()=>k20,resolveStandardConfig:()=>L20,resolve:()=>jOA,registerPackage:()=>uH,registerOverridePackages:()=>MOA,registerConventionalSiteTheme:()=>nQ0,reasoningEffortSchema:()=>hu,pluginOverrideEntrySchema:()=>vc,parseInstanceOverrides:()=>VOA,logLevelSchema:()=>Xv,isScopedPackageRef:()=>GJ,hasPackage:()=>gz,handleCLI:()=>fOA,getPackage:()=>W_,externalPluginDeclarationSchema:()=>iQ0,extendSite:()=>bb,deploymentConfigSchema:()=>HN0,defineConfig:()=>pQ0,defineBrain:()=>WJ,collectOverridePackageRefs:()=>dQ0,applyConventionalSiteRefs:()=>mv,SeedDataManager:()=>jP0,MigrationManager:()=>gu,InstanceOverridesParseError:()=>xc,CONVENTIONAL_THEME_PACKAGE_REF:()=>UJ,CONVENTIONAL_SITE_PACKAGE_REF:()=>SG,CONVENTIONAL_SITE_CONTENT_PACKAGE_REF:()=>Sv,App:()=>Ev});var DJ=i(()=>{LP0();kP0();YOA();XOA();UN0();_20();Zv();ZOA();vP0();hc();RP0();OOA();Rc();vOA();MP0()});var MM0=O((Ry6,Ow0)=>{var fvA,YvA,XvA,ZvA,HvA,WvA,KvA,UvA,GvA,DvA,zvA,qvA,VvA,Pw0,PM0,bvA,JvA,IvA,HR,FvA,LvA,kvA,_vA,NvA,jvA,PvA,MvA,OvA,Mw0,xvA,vvA,RvA;(function(A){var Q=typeof global==="object"?global:typeof self==="object"?self:typeof this==="object"?this:{};if(typeof define==="function"&&define.amd)define("tslib",["exports"],function(B){A(w(Q,w(B)))});else if(typeof Ow0==="object"&&typeof Ry6==="object")A(w(Q,w(Ry6)));else A(w(Q));function w(B,$){if(B!==Q)if(typeof Object.create==="function")Object.defineProperty(B,"__esModule",{value:!0});else B.__esModule=!0;return function(f,Y){return B[f]=$?$(f,Y):Y}}})(function(A){var Q=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(f,Y){f.__proto__=Y}||function(f,Y){for(var X in Y)if(Object.prototype.hasOwnProperty.call(Y,X))f[X]=Y[X]};fvA=function(f,Y){if(typeof Y!=="function"&&Y!==null)throw TypeError("Class extends value "+String(Y)+" is not a constructor or null");Q(f,Y);function X(){this.constructor=f}f.prototype=Y===null?Object.create(Y):(X.prototype=Y.prototype,new X)},YvA=Object.assign||function(f){for(var Y,X=1,H=arguments.length;X<H;X++){Y=arguments[X];for(var W in Y)if(Object.prototype.hasOwnProperty.call(Y,W))f[W]=Y[W]}return f},XvA=function(f,Y){var X={};for(var H in f)if(Object.prototype.hasOwnProperty.call(f,H)&&Y.indexOf(H)<0)X[H]=f[H];if(f!=null&&typeof Object.getOwnPropertySymbols==="function"){for(var W=0,H=Object.getOwnPropertySymbols(f);W<H.length;W++)if(Y.indexOf(H[W])<0&&Object.prototype.propertyIsEnumerable.call(f,H[W]))X[H[W]]=f[H[W]]}return X},ZvA=function(f,Y,X,H){var W=arguments.length,K=W<3?Y:H===null?H=Object.getOwnPropertyDescriptor(Y,X):H,U;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")K=Reflect.decorate(f,Y,X,H);else for(var G=f.length-1;G>=0;G--)if(U=f[G])K=(W<3?U(K):W>3?U(Y,X,K):U(Y,X))||K;return W>3&&K&&Object.defineProperty(Y,X,K),K},HvA=function(f,Y){return function(X,H){Y(X,H,f)}},WvA=function(f,Y,X,H,W,K){function U(h){if(h!==void 0&&typeof h!=="function")throw TypeError("Function expected");return h}var G=H.kind,q=G==="getter"?"get":G==="setter"?"set":"value",V=!Y&&f?H.static?f:f.prototype:null,J=Y||(V?Object.getOwnPropertyDescriptor(V,H.name):{}),b,L=!1;for(var N=X.length-1;N>=0;N--){var k={};for(var x in H)k[x]=x==="access"?{}:H[x];for(var x in H.access)k.access[x]=H.access[x];k.addInitializer=function(h){if(L)throw TypeError("Cannot add initializers after decoration has completed");K.push(U(h||null))};var v=(0,X[N])(G==="accessor"?{get:J.get,set:J.set}:J[q],k);if(G==="accessor"){if(v===void 0)continue;if(v===null||typeof v!=="object")throw TypeError("Object expected");if(b=U(v.get))J.get=b;if(b=U(v.set))J.set=b;if(b=U(v.init))W.unshift(b)}else if(b=U(v))if(G==="field")W.unshift(b);else J[q]=b}if(V)Object.defineProperty(V,H.name,J);L=!0},KvA=function(f,Y,X){var H=arguments.length>2;for(var W=0;W<Y.length;W++)X=H?Y[W].call(f,X):Y[W].call(f);return H?X:void 0},UvA=function(f){return typeof f==="symbol"?f:"".concat(f)},GvA=function(f,Y,X){if(typeof Y==="symbol")Y=Y.description?"[".concat(Y.description,"]"):"";return Object.defineProperty(f,"name",{configurable:!0,value:X?"".concat(X," ",Y):Y})},DvA=function(f,Y){if(typeof Reflect==="object"&&typeof Reflect.metadata==="function")return Reflect.metadata(f,Y)},zvA=function(f,Y,X,H){function W(K){return K instanceof X?K:new X(function(U){U(K)})}return new(X||(X=Promise))(function(K,U){function G(J){try{V(H.next(J))}catch(b){U(b)}}function q(J){try{V(H.throw(J))}catch(b){U(b)}}function V(J){J.done?K(J.value):W(J.value).then(G,q)}V((H=H.apply(f,Y||[])).next())})},qvA=function(f,Y){var X={label:0,sent:function(){if(K[0]&1)throw K[1];return K[1]},trys:[],ops:[]},H,W,K,U=Object.create((typeof Iterator==="function"?Iterator:Object).prototype);return U.next=G(0),U.throw=G(1),U.return=G(2),typeof Symbol==="function"&&(U[Symbol.iterator]=function(){return this}),U;function G(V){return function(J){return q([V,J])}}function q(V){if(H)throw TypeError("Generator is already executing.");while(U&&(U=0,V[0]&&(X=0)),X)try{if(H=1,W&&(K=V[0]&2?W.return:V[0]?W.throw||((K=W.return)&&K.call(W),0):W.next)&&!(K=K.call(W,V[1])).done)return K;if(W=0,K)V=[V[0]&2,K.value];switch(V[0]){case 0:case 1:K=V;break;case 4:return X.label++,{value:V[1],done:!1};case 5:X.label++,W=V[1],V=[0];continue;case 7:V=X.ops.pop(),X.trys.pop();continue;default:if((K=X.trys,!(K=K.length>0&&K[K.length-1]))&&(V[0]===6||V[0]===2)){X=0;continue}if(V[0]===3&&(!K||V[1]>K[0]&&V[1]<K[3])){X.label=V[1];break}if(V[0]===6&&X.label<K[1]){X.label=K[1],K=V;break}if(K&&X.label<K[2]){X.label=K[2],X.ops.push(V);break}if(K[2])X.ops.pop();X.trys.pop();continue}V=Y.call(f,X)}catch(J){V=[6,J],W=0}finally{H=K=0}if(V[0]&5)throw V[1];return{value:V[0]?V[1]:void 0,done:!0}}},VvA=function(f,Y){for(var X in f)if(X!=="default"&&!Object.prototype.hasOwnProperty.call(Y,X))Mw0(Y,f,X)},Mw0=Object.create?function(f,Y,X,H){if(H===void 0)H=X;var W=Object.getOwnPropertyDescriptor(Y,X);if(!W||("get"in W?!Y.__esModule:W.writable||W.configurable))W={enumerable:!0,get:function(){return Y[X]}};Object.defineProperty(f,H,W)}:function(f,Y,X,H){if(H===void 0)H=X;f[H]=Y[X]},Pw0=function(f){var Y=typeof Symbol==="function"&&Symbol.iterator,X=Y&&f[Y],H=0;if(X)return X.call(f);if(f&&typeof f.length==="number")return{next:function(){if(f&&H>=f.length)f=void 0;return{value:f&&f[H++],done:!f}}};throw TypeError(Y?"Object is not iterable.":"Symbol.iterator is not defined.")},PM0=function(f,Y){var X=typeof Symbol==="function"&&f[Symbol.iterator];if(!X)return f;var H=X.call(f),W,K=[],U;try{while((Y===void 0||Y-- >0)&&!(W=H.next()).done)K.push(W.value)}catch(G){U={error:G}}finally{try{if(W&&!W.done&&(X=H.return))X.call(H)}finally{if(U)throw U.error}}return K},bvA=function(){for(var f=[],Y=0;Y<arguments.length;Y++)f=f.concat(PM0(arguments[Y]));return f},JvA=function(){for(var f=0,Y=0,X=arguments.length;Y<X;Y++)f+=arguments[Y].length;for(var H=Array(f),W=0,Y=0;Y<X;Y++)for(var K=arguments[Y],U=0,G=K.length;U<G;U++,W++)H[W]=K[U];return H},IvA=function(f,Y,X){if(X||arguments.length===2){for(var H=0,W=Y.length,K;H<W;H++)if(K||!(H in Y)){if(!K)K=Array.prototype.slice.call(Y,0,H);K[H]=Y[H]}}return f.concat(K||Array.prototype.slice.call(Y))},HR=function(f){return this instanceof HR?(this.v=f,this):new HR(f)},FvA=function(f,Y,X){if(!Symbol.asyncIterator)throw TypeError("Symbol.asyncIterator is not defined.");var H=X.apply(f,Y||[]),W,K=[];return W=Object.create((typeof AsyncIterator==="function"?AsyncIterator:Object).prototype),G("next"),G("throw"),G("return",U),W[Symbol.asyncIterator]=function(){return this},W;function U(N){return function(k){return Promise.resolve(k).then(N,b)}}function G(N,k){if(H[N]){if(W[N]=function(x){return new Promise(function(v,h){K.push([N,x,v,h])>1||q(N,x)})},k)W[N]=k(W[N])}}function q(N,k){try{V(H[N](k))}catch(x){L(K[0][3],x)}}function V(N){N.value instanceof HR?Promise.resolve(N.value.v).then(J,b):L(K[0][2],N)}function J(N){q("next",N)}function b(N){q("throw",N)}function L(N,k){if(N(k),K.shift(),K.length)q(K[0][0],K[0][1])}},LvA=function(f){var Y,X;return Y={},H("next"),H("throw",function(W){throw W}),H("return"),Y[Symbol.iterator]=function(){return this},Y;function H(W,K){Y[W]=f[W]?function(U){return(X=!X)?{value:HR(f[W](U)),done:!1}:K?K(U):U}:K}},kvA=function(f){if(!Symbol.asyncIterator)throw TypeError("Symbol.asyncIterator is not defined.");var Y=f[Symbol.asyncIterator],X;return Y?Y.call(f):(f=typeof Pw0==="function"?Pw0(f):f[Symbol.iterator](),X={},H("next"),H("throw"),H("return"),X[Symbol.asyncIterator]=function(){return this},X);function H(K){X[K]=f[K]&&function(U){return new Promise(function(G,q){U=f[K](U),W(G,q,U.done,U.value)})}}function W(K,U,G,q){Promise.resolve(q).then(function(V){K({value:V,done:G})},U)}},_vA=function(f,Y){if(Object.defineProperty)Object.defineProperty(f,"raw",{value:Y});else f.raw=Y;return f};var w=Object.create?function(f,Y){Object.defineProperty(f,"default",{enumerable:!0,value:Y})}:function(f,Y){f.default=Y},B=function(f){return B=Object.getOwnPropertyNames||function(Y){var X=[];for(var H in Y)if(Object.prototype.hasOwnProperty.call(Y,H))X[X.length]=H;return X},B(f)};NvA=function(f){if(f&&f.__esModule)return f;var Y={};if(f!=null){for(var X=B(f),H=0;H<X.length;H++)if(X[H]!=="default")Mw0(Y,f,X[H])}return w(Y,f),Y},jvA=function(f){return f&&f.__esModule?f:{default:f}},PvA=function(f,Y,X,H){if(X==="a"&&!H)throw TypeError("Private accessor was defined without a getter");if(typeof Y==="function"?f!==Y||!H:!Y.has(f))throw TypeError("Cannot read private member from an object whose class did not declare it");return X==="m"?H:X==="a"?H.call(f):H?H.value:Y.get(f)},MvA=function(f,Y,X,H,W){if(H==="m")throw TypeError("Private method is not writable");if(H==="a"&&!W)throw TypeError("Private accessor was defined without a setter");if(typeof Y==="function"?f!==Y||!W:!Y.has(f))throw TypeError("Cannot write private member to an object whose class did not declare it");return H==="a"?W.call(f,X):W?W.value=X:Y.set(f,X),X},OvA=function(f,Y){if(Y===null||typeof Y!=="object"&&typeof Y!=="function")throw TypeError("Cannot use 'in' operator on non-object");return typeof f==="function"?Y===f:f.has(Y)},xvA=function(f,Y,X){if(Y!==null&&Y!==void 0){if(typeof Y!=="object"&&typeof Y!=="function")throw TypeError("Object expected.");var H,W;if(X){if(!Symbol.asyncDispose)throw TypeError("Symbol.asyncDispose is not defined.");H=Y[Symbol.asyncDispose]}if(H===void 0){if(!Symbol.dispose)throw TypeError("Symbol.dispose is not defined.");if(H=Y[Symbol.dispose],X)W=H}if(typeof H!=="function")throw TypeError("Object not disposable.");if(W)H=function(){try{W.call(this)}catch(K){return Promise.reject(K)}};f.stack.push({value:Y,dispose:H,async:X})}else if(X)f.stack.push({async:!0});return Y};var $=typeof SuppressedError==="function"?SuppressedError:function(f,Y,X){var H=Error(X);return H.name="SuppressedError",H.error=f,H.suppressed=Y,H};vvA=function(f){function Y(K){f.error=f.hasError?new $(K,f.error,"An error was suppressed during disposal."):K,f.hasError=!0}var X,H=0;function W(){while(X=f.stack.pop())try{if(!X.async&&H===1)return H=0,f.stack.push(X),Promise.resolve().then(W);if(X.dispose){var K=X.dispose.call(X.value);if(X.async)return H|=2,Promise.resolve(K).then(W,function(U){return Y(U),W()})}else H|=1}catch(U){Y(U)}if(H===1)return f.hasError?Promise.reject(f.error):Promise.resolve();if(f.hasError)throw f.error}return W()},RvA=function(f,Y){if(typeof f==="string"&&/^\.\.?\//.test(f))return f.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i,function(X,H,W,K,U){return H?Y?".jsx":".js":W&&(!K||!U)?X:W+K+"."+U.toLowerCase()+"js"});return f},A("__extends",fvA),A("__assign",YvA),A("__rest",XvA),A("__decorate",ZvA),A("__param",HvA),A("__esDecorate",WvA),A("__runInitializers",KvA),A("__propKey",UvA),A("__setFunctionName",GvA),A("__metadata",DvA),A("__awaiter",zvA),A("__generator",qvA),A("__exportStar",VvA),A("__createBinding",Mw0),A("__values",Pw0),A("__read",PM0),A("__spread",bvA),A("__spreadArrays",JvA),A("__spreadArray",IvA),A("__await",HR),A("__asyncGenerator",FvA),A("__asyncDelegator",LvA),A("__asyncValues",kvA),A("__makeTemplateObject",_vA),A("__importStar",NvA),A("__importDefault",jvA),A("__classPrivateFieldGet",PvA),A("__classPrivateFieldSet",MvA),A("__classPrivateFieldIn",OvA),A("__addDisposableResource",xvA),A("__disposeResources",vvA),A("__rewriteRelativeImportExtension",RvA)})});var BRA=O(()=>{/*! *****************************************************************************
|
|
1195
1195
|
Copyright (C) Microsoft. All rights reserved.
|
|
@@ -1717,7 +1717,7 @@ Example bad output: "A dreamlike crystal formation glowing with ethereal light i
|
|
|
1717
1717
|
Title: "${A.entityTitle??X}"
|
|
1718
1718
|
|
|
1719
1719
|
Content:
|
|
1720
|
-
${K}`,$l2);W=`${B.trim()} ${L.imagePrompt}`}catch(L){this.logger.warn("AI prompt distillation failed, using fallback",{error:SA(L)})}}await this.reportProgress(w,{progress:nQ.PROCESS,message:"Generating image"});let U=this.context.identity.get(),G=this.context.identity.getProfile(),V=hOA(U,G)+W,J;try{J=await this.context.ai.generateImage(V,{...$&&{aspectRatio:$}})}catch(L){return this.logger.error("Image generation failed",{jobId:Q,error:SA(L)}),w$.failure(L)}await this.reportProgress(w,{progress:nQ.GENERATE,message:"Creating image entity"});let b=mX.createImageEntity({dataUrl:J.dataUrl,title:X,status:"draft",attachmentType:"generated",...f&&{sourceEntityType:f},...Y&&{sourceEntityId:Y}});if(await Jf({entityService:this.context.entityService,entity:{...b,id:H}}),this.logger.debug("Created image entity",{imageId:H}),f&&Y){await this.reportProgress(w,{progress:nQ.SAVE,message:`Updating ${f} with cover image`});let L=await zk(this.context.entityService,f,Y,this.logger);if(!L)return w$.failure(Error(`Target entity not found: ${f}/${Y}`));let N=dk(L,H);await this.context.entities.update(N),this.logger.debug("Updated target entity with cover image",{targetEntityType:f,targetEntityId:Y,imageId:H})}return await this.reportProgress(w,{progress:nQ.COMPLETE,message:"Image generation complete"}),this.logger.info("Image generation job complete",{jobId:Q,imageId:H,targetEntityType:f,targetEntityId:Y}),{success:!0,imageId:H}}catch(W){let K=SA(W);return this.logger.error("Image generation job failed",{jobId:Q,error:K}),await kG({entityService:this.context.entityService,entityType:"image",id:H,error:K}),w$.failure(W)}}summarizeDataForLog(A){return{title:A.title,promptLength:A.prompt.length,aspectRatio:A.aspectRatio,targetEntityType:A.targetEntityType,targetEntityId:A.targetEntityId}}}wA();_0();y6();F4();var Yl2=Z.object({sourceEntityType:Z.string().min(1),sourceEntityId:Z.string().min(1),attachmentType:Z.string().min(1),imageId:Z.string().min(1),dedupKey:Z.string().min(1).optional(),replace:Z.boolean().optional(),targetEntityType:Z.string().min(1).optional(),targetEntityId:Z.string().min(1).optional(),targetImageField:Z.enum(["coverImageId","ogImageId"]).optional()});class yP0 extends tw{context;constructor(A,Q){super(Q,{schema:Yl2,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:nQ.COMPLETE,message:"Reusing existing generated image"}),{success:!0,imageId:Y.id,reused:!0}}await this.reportProgress(w,{progress:nQ.PROCESS,message:"Rendering source image"});let B=await this.context.attachments.resolve({sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType});if(!B)return w$.failure(Error(`No attachment provider found for ${A.sourceEntityType}/${A.attachmentType}`));if(B.type!=="image")return w$.failure(Error(`Attachment provider returned ${B.type}; expected image`));await this.reportProgress(w,{progress:nQ.GENERATE,message:"Creating image entity"});let $=B.mimeType.split("/")[1]??"png",f=mX.createImageEntity({dataUrl:BN0(B.data.toString("base64"),$),title:A.imageId,status:"draft",sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType,...A.dedupKey&&{dedupKey:A.dedupKey}});return await Jf({entityService:this.context.entityService,entity:{...f,id:A.imageId}}),await this.updateTarget(A,A.imageId),await this.reportProgress(w,{progress:nQ.COMPLETE,message:"Image render complete"}),{success:!0,imageId:A.imageId,reused:!1}}catch(B){let $=SA(B);return this.logger.error("Source image render job failed",{jobId:Q,error:$}),await kG({entityService:this.context.entityService,entityType:"image",id:A.imageId,error:$}),w$.failure(B)}}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 zk(this.context.entityService,A.targetEntityType,A.targetEntityId,this.logger);if(!w)throw Error(`Target entity not found: ${A.targetEntityType}/${A.targetEntityId}`);let $=(A.targetImageField??"coverImageId")==="ogImageId"?Ru(w,Q):dk(w,Q);await this.context.entities.update($)}}wA();_0();y6();F4();U2();var uv={namespace:"upload",refKind:"upload",routePath:"/api/chat/uploads"};function sQ0(A){return["image/png","image/jpeg","image/webp","image/gif"].includes(A.toLowerCase())}function aQ0(A){let Q=Xl2(A.title,A.filename),w=H1(Q);if(!w)throw Error("Could not derive an image id from the uploaded filename. Provide a title.");return{id:w,title:Q}}function COA(A,Q){return`data:${A};base64,${Q.toString("base64")}`}function Xl2(A,Q){let w=A?.trim();if(w)return w;return Q.replace(/\.[^.]+$/,"").trim()||Q}var Zl2=Z.object({uploadId:Z.string().min(1),imageId:Z.string().min(1).optional(),title:Z.string().optional()});class EP0 extends tw{context;constructor(A,Q){super(A,{schema:Zl2,jobTypeName:"upload-promote"});this.context=Q}async process(A,Q,w){try{await this.reportProgress(w,{progress:10,message:"Reading uploaded image"});let B=await this.context.uploads.scoped(uv).read(A.uploadId);if(!sQ0(B.record.mediaType))throw Error("Only image uploads can be promoted to image entities");let $=aQ0({filename:B.record.filename,...A.title!==void 0?{title:A.title}:{}}),f=A.imageId??$.id;await this.reportProgress(w,{progress:60,message:"Saving uploaded image"});let Y=new Date().toISOString(),X=mX.createImageEntity({dataUrl:COA(B.record.mediaType,B.content),title:$.title,status:"draft",sourceUploadId:A.uploadId,sourceFilename:B.record.filename,sourceMediaType:B.record.mediaType,attachmentType:"uploaded"}),H=await Jf({entityService:this.context.entityService,entity:{id:f,...X,created:Y,updated:Y}});return await this.reportProgress(w,{progress:100,message:"Uploaded image promoted"}),{entityId:H.entityId,status:"created"}}catch(B){if(A.imageId)await kG({entityService:this.context.entityService,entityType:"image",id:A.imageId,error:SA(B)});return w$.failure(B)}}summarizeDataForLog(A){return{uploadId:A.uploadId,imageId:A.imageId,hasTitle:A.title!==void 0}}}var gOA={name:"@brains/image-plugin",version:"0.2.0-alpha.150",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:"^6.0.3"},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 Wl2="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==",Kl2=Z.object({defaultAspectRatio:Z.enum(["1:1","16:9","9:16","4:3","3:4"]).default("16:9").describe("Default aspect ratio for generated images")});function vK(A){let Q=A?.trim();if(!Q)return;return Q}function Ul2(A){let Q=vK(A.prompt);if(Q)return Q;let w=vK(A.content);if(w&&!gP0(w))return w;return}function Gl2(A){let Q=A.attachmentType==="og-image"?"og":A.attachmentType;return H1(`${Q}-${A.sourceEntityType}-${A.sourceEntityId}`)}function yOA(A){let Q=vK(A.title)??(A.targetEntityId?`cover-${A.targetEntityId}`:A.prompt.slice(0,60).trim());return H1(Q)}async function Dl2(A,Q){let w=`${Q.attachmentType}:${Q.sourceEntityType}:${Q.sourceEntityId}:resolved-attachment`,B=await A.entityService.getEntity({entityType:Q.sourceEntityType,id:Q.sourceEntityId});return B?`${w}:${B.contentHash}`:w}function TP0(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 zl2(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 SP0 extends rQ{entityType=mX.entityType;schema=xu;adapter=mX;constructor(A={}){super("image",gOA,A,Kl2)}getEntityTypeConfig(){return{embeddable:!1}}async interceptCreate(A,Q,w){if(A.from?.kind===uv.refKind)return this.promoteUpload(A,w);let B=Ul2(A),$=vK(A.targetEntityType),f=vK(A.targetEntityId),Y=$===this.entityType?f:void 0,X=A.from;if(X?.kind==="entity-attachment")return this.enqueueSourceImageRender({...A,from:X},w);if(!$||!f||Y){if(!B)return{kind:"continue",input:A};let G=vK(A.title)??Y,q=yOA({prompt:B,...G&&{title:G}});await this.createPendingImage(w,{id:q,title:G??B.slice(0,60).trim(),alt:G??B.slice(0,60).trim(),attachmentType:"generated"});let V=await w.jobs.enqueue({type:"image-generate",data:{prompt:B,...G&&{title:G}}});return{kind:"handled",result:{success:!0,data:{entityId:q,status:"generating",jobId:V,attachment:TP0(q)}}}}let H=await z4(w.entityService,$,f,this.logger,"Target entity");if(!H.ok)return{kind:"handled",result:{success:!1,error:H.error}};if(!B)return{kind:"continue",input:{...A,targetEntityId:H.entity.id}};let W=rQ0(H.entity.content),K=yOA({prompt:B,...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:$,sourceEntityId:H.entity.id});let U=await w.jobs.enqueue({type:"image-generate",data:{prompt:B,...A.title&&{title:A.title},targetEntityType:$,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:TP0(K)}}}}async promoteUpload(A,Q){let w=A.from;if(w?.kind!==uv.refKind)return{kind:"handled",result:{success:!1,error:"Unsupported upload ref kind"}};let B=w.id,$;try{$=await Q.uploads.scoped(uv).readRecord(B)}catch{return{kind:"handled",result:{success:!1,error:"Upload ref not found"}}}if(!sQ0($.mediaType))return{kind:"handled",result:{success:!1,error:"Only image uploads can be promoted to image entities"}};let f;try{f=aQ0({filename:$.filename,...A.title!==void 0?{title:A.title}:{}})}catch(X){return{kind:"handled",result:{success:!1,error:X instanceof Error?X.message:String(X)}}}await this.createPendingImage(Q,{id:f.id,title:f.title,alt:f.title,sourceUploadId:B,sourceFilename:$.filename,sourceMediaType:$.mediaType,attachmentType:"uploaded"});let Y=await Q.jobs.enqueue({type:"upload-promote",data:{uploadId:B,imageId:f.id,title:f.title}});return{kind:"handled",result:{success:!0,data:{entityId:f.id,status:"generating",jobId:Y,attachment:zl2({mediaType:$.mediaType,entityId:f.id,filename:$.filename})}}}}async enqueueSourceImageRender(A,Q){let w=vK(A.from.sourceEntityType),B=vK(A.from.sourceEntityId),$=vK(A.from.attachmentType);if(!w||!B||!$)return{kind:"handled",result:{success:!1,error:"Image source requires sourceEntityType, sourceEntityId, and attachmentType"}};let f=await z4(Q.entityService,w,B,this.logger,"Source entity");if(!f.ok)return{kind:"handled",result:{success:!1,error:f.error}};let Y=vK(A.targetEntityType),X=vK(A.targetEntityId),H;if(Y&&X){let q=await z4(Q.entityService,Y,X,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:f.entity.id,attachmentType:$},K=await Dl2(Q,W),U=Gl2(W);await this.createPendingImage(Q,{id:U,title:U,alt:U,sourceEntityType:W.sourceEntityType,sourceEntityId:W.sourceEntityId,attachmentType:$,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},...$==="og-image"&&{targetImageField:"ogImageId"}}});return{kind:"handled",result:{success:!0,data:{entityId:U,status:"generating",jobId:G,attachment:TP0(U,$)}}}}async createPendingImage(A,Q){let w=new Date().toISOString(),B=mX.createImageEntity({dataUrl:Wl2,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 Vk({entityService:A.entityService,entity:{id:Q.id,...B,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 oQ0(A,this.logger)}async onRegister(A){A.entities.registerUploadSaveHandler({entityType:this.entityType,mediaTypes:["image/*"],handler:async(w)=>{let B=await this.promoteUpload({entityType:this.entityType,...w.title!==void 0?{title:w.title}:{},from:w.upload},A);return B.kind==="handled"?B.result:{success:!1,error:"Image upload save was not handled"}}});let Q=new oQ0(A,this.logger);A.jobs.registerHandler("image-generate",Q),A.jobs.registerHandler("image-render-source",new yP0(A,this.logger)),A.jobs.registerHandler("upload-promote",new EP0(this.logger.child("UploadPromotionJobHandler"),A))}}function Cc(A={}){return new SP0(A)}wA();import{StdioServerTransport as Vl2}from"@modelcontextprotocol/sdk/server/stdio.js";_0();var ql2=Z.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 EOA(){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 mP0(){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 tQ0(A){let Q=ql2.safeParse(A);if(Q.success)return{info:(w,...B)=>Q.data.info(w,...B),debug:(w,...B)=>Q.data.debug(w,...B),error:(w,...B)=>Q.data.error(w,...B),warn:(w,...B)=>Q.data.warn(w,...B)};return mP0()}class RK{static instance=null;mcpServer=null;transport=null;config;logger;static getInstance(A){return RK.instance??=new RK(A),RK.instance}static resetInstance(){if(RK.instance)RK.instance.stop(),RK.instance=null}static createFresh(A){return new RK(A)}constructor(A={}){this.config=A,this.logger=this.config.logger?tQ0(this.config.logger):EOA()}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 Vl2,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 bl2,timingSafeEqual as Jl2}from"crypto";import{WebStandardStreamableHTTPServerTransport as Il2}from"@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";import{isInitializeRequest as Fl2}from"@modelcontextprotocol/sdk/types.js";_0();var Ll2=1800000,kl2=60000,_l2={"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"},Nl2=Z.looseObject({code:Z.string().optional()});function jl2(A){let Q=new URL(A.url),B=A.headers.get("x-forwarded-proto")?.split(",")[0]?.trim(),$=A.headers.get("x-forwarded-host")??A.headers.get("host");if(!$)return Q.origin;return`${B??Q.protocol.replace(":","")}://${$}`}class yz{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?tQ0(this.config.logger):mP0(),this.authConfig=A.auth??{},this.sessionIdleTtlMs=A.sessionIdleTtlMs??Ll2,this.evictionTimer=setInterval(()=>this.evictIdleSessions(),Math.min(this.sessionIdleTtlMs,kl2)),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 yz.instance??=new yz(A),yz.instance}static resetInstance(){yz.instance=null}static createFresh(A){return new yz(A)}withCors(A){let Q=new Headers(A.headers);for(let[w,B]of Object.entries(_l2))Q.set(w,B);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 B=this.createJsonResponse({jsonrpc:"2.0",error:{code:-32001,message:A},id:null},Q);if(!w)return B;let $=new Headers(B.headers);return $.set("WWW-Authenticate",w),new Response(B.body,{status:B.status,statusText:B.statusText,headers:$})}getBearerChallenge(A,Q={}){let w={...this.authConfig.token?{}:{resource_metadata:`${jl2(A)}/.well-known/oauth-protected-resource`},...Q};return`Bearer ${Object.entries(w).map(([$,f])=>`${$}="${Pl2(f)}"`).join(", ")}`}async authenticate(A){let Q=new URL(A.url).pathname;if(Q==="/health"||Q==="/status"||Q==="/mcp"&&A.method==="OPTIONS")return null;if(this.authConfig.disabled)return null;let 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 B=w.substring(7);if(!Ml2(B,this.authConfig.token))return this.logger.warn("Authentication failed: Invalid token"),this.getAuthErrorResponse("Unauthorized: Invalid token",401,this.getBearerChallenge(A,{error:"invalid_token"}));return this.logger.debug("Authentication successful"),null}try{let B=await this.authConfig.verifyBearerToken?.(A);if(!B)return this.logger.warn("Authentication failed: Invalid token"),this.getAuthErrorResponse("Unauthorized: Invalid token",401,this.getBearerChallenge(A,{error:"invalid_token"}));let $=this.authConfig.requiredScopes??[],f=$.filter((Y)=>!B.scope?.includes(Y));if(f.length>0)return this.logger.warn(`Authentication failed: Missing required scope(s): ${f.join(", ")}`),this.getAuthErrorResponse("Forbidden: Missing required scope",403,this.getBearerChallenge(A,{error:"insufficient_scope",scope:$.join(" ")}));return this.logger.debug("Authentication successful"),null}catch(B){return this.logger.warn("Authentication failed: Invalid token",B),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 B=this.transports[Q];if(B)delete this.transports[Q],B.close().catch(($)=>{this.logger.error(`Error closing idle transport for session ${Q}:`,$)})}}async handleMcpRequest(A){let Q=A.headers.get("mcp-session-id")??void 0;if(A.method==="GET"){if(!Q||!this.transports[Q])return this.createTextResponse("Invalid or missing session ID",400);return this.touchSession(Q),this.logger.debug(`GET /mcp - SSE stream for session ${Q}`),this.withCors(await this.transports[Q].handleRequest(A))}if(A.method==="DELETE"){if(!Q||!this.transports[Q])return this.createTextResponse("Invalid or missing session ID",400);return this.logger.info(`DELETE /mcp - Terminating session ${Q}`),this.withCors(await this.transports[Q].handleRequest(A))}if(A.method==="OPTIONS")return this.withCors(new Response(null,{status:204}));if(A.method!=="POST")return this.createTextResponse("Method Not Allowed",405);if(!this.mcpServer)return this.createJsonResponse({jsonrpc:"2.0",error:{code:-32603,message:"Service Unavailable: MCP server not connected"},id:null},503);let w;try{w=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: ${Q??"new"}`);try{let B;if(Q&&this.transports[Q])B=this.transports[Q],this.touchSession(Q);else if(!Q&&Fl2(w))B=new Il2({sessionIdGenerator:()=>bl2(),onsessioninitialized:(f)=>{this.logger.info(`Session initialized: ${f}`),this.transports[f]=B,this.touchSession(f)},onsessionclosed:(f)=>{this.logger.info(`Session closed: ${f}`),delete this.transports[f],this.sessionLastActivity.delete(f)}}),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:w}))}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)return w;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 B=Nl2.safeParse(w);if(B.success&&B.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 Pl2(A){return A.replace(/["\\]/g,(Q)=>`\\${Q}`)}function Ml2(A,Q){let w=Buffer.from(A),B=Buffer.from(Q);if(w.length!==B.length)return!1;return Jl2(w,B)}import{randomUUID as gl2}from"crypto";import{chmod as Ol2,mkdir as xl2,readFile as vl2,rename as TOA,writeFile as Rl2}from"fs/promises";import{dirname as hl2}from"path";class Pf{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 vl2(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 xl2(hl2(this.filePath),{recursive:!0,mode:448});let Q=`${this.filePath}.tmp`;await Rl2(Q,`${JSON.stringify(A,null,2)}
|
|
1720
|
+
${K}`,$l2);W=`${B.trim()} ${L.imagePrompt}`}catch(L){this.logger.warn("AI prompt distillation failed, using fallback",{error:SA(L)})}}await this.reportProgress(w,{progress:nQ.PROCESS,message:"Generating image"});let U=this.context.identity.get(),G=this.context.identity.getProfile(),V=hOA(U,G)+W,J;try{J=await this.context.ai.generateImage(V,{...$&&{aspectRatio:$}})}catch(L){return this.logger.error("Image generation failed",{jobId:Q,error:SA(L)}),w$.failure(L)}await this.reportProgress(w,{progress:nQ.GENERATE,message:"Creating image entity"});let b=mX.createImageEntity({dataUrl:J.dataUrl,title:X,status:"draft",attachmentType:"generated",...f&&{sourceEntityType:f},...Y&&{sourceEntityId:Y}});if(await Jf({entityService:this.context.entityService,entity:{...b,id:H}}),this.logger.debug("Created image entity",{imageId:H}),f&&Y){await this.reportProgress(w,{progress:nQ.SAVE,message:`Updating ${f} with cover image`});let L=await zk(this.context.entityService,f,Y,this.logger);if(!L)return w$.failure(Error(`Target entity not found: ${f}/${Y}`));let N=dk(L,H);await this.context.entities.update(N),this.logger.debug("Updated target entity with cover image",{targetEntityType:f,targetEntityId:Y,imageId:H})}return await this.reportProgress(w,{progress:nQ.COMPLETE,message:"Image generation complete"}),this.logger.info("Image generation job complete",{jobId:Q,imageId:H,targetEntityType:f,targetEntityId:Y}),{success:!0,imageId:H}}catch(W){let K=SA(W);return this.logger.error("Image generation job failed",{jobId:Q,error:K}),await kG({entityService:this.context.entityService,entityType:"image",id:H,error:K}),w$.failure(W)}}summarizeDataForLog(A){return{title:A.title,promptLength:A.prompt.length,aspectRatio:A.aspectRatio,targetEntityType:A.targetEntityType,targetEntityId:A.targetEntityId}}}wA();_0();y6();F4();var Yl2=Z.object({sourceEntityType:Z.string().min(1),sourceEntityId:Z.string().min(1),attachmentType:Z.string().min(1),imageId:Z.string().min(1),dedupKey:Z.string().min(1).optional(),replace:Z.boolean().optional(),targetEntityType:Z.string().min(1).optional(),targetEntityId:Z.string().min(1).optional(),targetImageField:Z.enum(["coverImageId","ogImageId"]).optional()});class yP0 extends tw{context;constructor(A,Q){super(Q,{schema:Yl2,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:nQ.COMPLETE,message:"Reusing existing generated image"}),{success:!0,imageId:Y.id,reused:!0}}await this.reportProgress(w,{progress:nQ.PROCESS,message:"Rendering source image"});let B=await this.context.attachments.resolve({sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType});if(!B)return w$.failure(Error(`No attachment provider found for ${A.sourceEntityType}/${A.attachmentType}`));if(B.type!=="image")return w$.failure(Error(`Attachment provider returned ${B.type}; expected image`));await this.reportProgress(w,{progress:nQ.GENERATE,message:"Creating image entity"});let $=B.mimeType.split("/")[1]??"png",f=mX.createImageEntity({dataUrl:BN0(B.data.toString("base64"),$),title:A.imageId,status:"draft",sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType,...A.dedupKey&&{dedupKey:A.dedupKey}});return await Jf({entityService:this.context.entityService,entity:{...f,id:A.imageId}}),await this.updateTarget(A,A.imageId),await this.reportProgress(w,{progress:nQ.COMPLETE,message:"Image render complete"}),{success:!0,imageId:A.imageId,reused:!1}}catch(B){let $=SA(B);return this.logger.error("Source image render job failed",{jobId:Q,error:$}),await kG({entityService:this.context.entityService,entityType:"image",id:A.imageId,error:$}),w$.failure(B)}}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 zk(this.context.entityService,A.targetEntityType,A.targetEntityId,this.logger);if(!w)throw Error(`Target entity not found: ${A.targetEntityType}/${A.targetEntityId}`);let $=(A.targetImageField??"coverImageId")==="ogImageId"?Ru(w,Q):dk(w,Q);await this.context.entities.update($)}}wA();_0();y6();F4();U2();var uv={namespace:"upload",refKind:"upload",routePath:"/api/chat/uploads"};function sQ0(A){return["image/png","image/jpeg","image/webp","image/gif"].includes(A.toLowerCase())}function aQ0(A){let Q=Xl2(A.title,A.filename),w=H1(Q);if(!w)throw Error("Could not derive an image id from the uploaded filename. Provide a title.");return{id:w,title:Q}}function COA(A,Q){return`data:${A};base64,${Q.toString("base64")}`}function Xl2(A,Q){let w=A?.trim();if(w)return w;return Q.replace(/\.[^.]+$/,"").trim()||Q}var Zl2=Z.object({uploadId:Z.string().min(1),imageId:Z.string().min(1).optional(),title:Z.string().optional()});class EP0 extends tw{context;constructor(A,Q){super(A,{schema:Zl2,jobTypeName:"upload-promote"});this.context=Q}async process(A,Q,w){try{await this.reportProgress(w,{progress:10,message:"Reading uploaded image"});let B=await this.context.uploads.scoped(uv).read(A.uploadId);if(!sQ0(B.record.mediaType))throw Error("Only image uploads can be promoted to image entities");let $=aQ0({filename:B.record.filename,...A.title!==void 0?{title:A.title}:{}}),f=A.imageId??$.id;await this.reportProgress(w,{progress:60,message:"Saving uploaded image"});let Y=new Date().toISOString(),X=mX.createImageEntity({dataUrl:COA(B.record.mediaType,B.content),title:$.title,status:"draft",sourceUploadId:A.uploadId,sourceFilename:B.record.filename,sourceMediaType:B.record.mediaType,attachmentType:"uploaded"}),H=await Jf({entityService:this.context.entityService,entity:{id:f,...X,created:Y,updated:Y}});return await this.reportProgress(w,{progress:100,message:"Uploaded image promoted"}),{entityId:H.entityId,status:"created"}}catch(B){if(A.imageId)await kG({entityService:this.context.entityService,entityType:"image",id:A.imageId,error:SA(B)});return w$.failure(B)}}summarizeDataForLog(A){return{uploadId:A.uploadId,imageId:A.imageId,hasTitle:A.title!==void 0}}}var gOA={name:"@brains/image-plugin",version:"0.2.0-alpha.151",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 Wl2="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==",Kl2=Z.object({defaultAspectRatio:Z.enum(["1:1","16:9","9:16","4:3","3:4"]).default("16:9").describe("Default aspect ratio for generated images")});function vK(A){let Q=A?.trim();if(!Q)return;return Q}function Ul2(A){let Q=vK(A.prompt);if(Q)return Q;let w=vK(A.content);if(w&&!gP0(w))return w;return}function Gl2(A){let Q=A.attachmentType==="og-image"?"og":A.attachmentType;return H1(`${Q}-${A.sourceEntityType}-${A.sourceEntityId}`)}function yOA(A){let Q=vK(A.title)??(A.targetEntityId?`cover-${A.targetEntityId}`:A.prompt.slice(0,60).trim());return H1(Q)}async function Dl2(A,Q){let w=`${Q.attachmentType}:${Q.sourceEntityType}:${Q.sourceEntityId}:resolved-attachment`,B=await A.entityService.getEntity({entityType:Q.sourceEntityType,id:Q.sourceEntityId});return B?`${w}:${B.contentHash}`:w}function TP0(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 zl2(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 SP0 extends rQ{entityType=mX.entityType;schema=xu;adapter=mX;constructor(A={}){super("image",gOA,A,Kl2)}getEntityTypeConfig(){return{embeddable:!1}}async interceptCreate(A,Q,w){if(A.from?.kind===uv.refKind)return this.promoteUpload(A,w);let B=Ul2(A),$=vK(A.targetEntityType),f=vK(A.targetEntityId),Y=$===this.entityType?f:void 0,X=A.from;if(X?.kind==="entity-attachment")return this.enqueueSourceImageRender({...A,from:X},w);if(!$||!f||Y){if(!B)return{kind:"continue",input:A};let G=vK(A.title)??Y,q=yOA({prompt:B,...G&&{title:G}});await this.createPendingImage(w,{id:q,title:G??B.slice(0,60).trim(),alt:G??B.slice(0,60).trim(),attachmentType:"generated"});let V=await w.jobs.enqueue({type:"image-generate",data:{prompt:B,...G&&{title:G}}});return{kind:"handled",result:{success:!0,data:{entityId:q,status:"generating",jobId:V,attachment:TP0(q)}}}}let H=await z4(w.entityService,$,f,this.logger,"Target entity");if(!H.ok)return{kind:"handled",result:{success:!1,error:H.error}};if(!B)return{kind:"continue",input:{...A,targetEntityId:H.entity.id}};let W=rQ0(H.entity.content),K=yOA({prompt:B,...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:$,sourceEntityId:H.entity.id});let U=await w.jobs.enqueue({type:"image-generate",data:{prompt:B,...A.title&&{title:A.title},targetEntityType:$,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:TP0(K)}}}}async promoteUpload(A,Q){let w=A.from;if(w?.kind!==uv.refKind)return{kind:"handled",result:{success:!1,error:"Unsupported upload ref kind"}};let B=w.id,$;try{$=await Q.uploads.scoped(uv).readRecord(B)}catch{return{kind:"handled",result:{success:!1,error:"Upload ref not found"}}}if(!sQ0($.mediaType))return{kind:"handled",result:{success:!1,error:"Only image uploads can be promoted to image entities"}};let f;try{f=aQ0({filename:$.filename,...A.title!==void 0?{title:A.title}:{}})}catch(X){return{kind:"handled",result:{success:!1,error:X instanceof Error?X.message:String(X)}}}await this.createPendingImage(Q,{id:f.id,title:f.title,alt:f.title,sourceUploadId:B,sourceFilename:$.filename,sourceMediaType:$.mediaType,attachmentType:"uploaded"});let Y=await Q.jobs.enqueue({type:"upload-promote",data:{uploadId:B,imageId:f.id,title:f.title}});return{kind:"handled",result:{success:!0,data:{entityId:f.id,status:"generating",jobId:Y,attachment:zl2({mediaType:$.mediaType,entityId:f.id,filename:$.filename})}}}}async enqueueSourceImageRender(A,Q){let w=vK(A.from.sourceEntityType),B=vK(A.from.sourceEntityId),$=vK(A.from.attachmentType);if(!w||!B||!$)return{kind:"handled",result:{success:!1,error:"Image source requires sourceEntityType, sourceEntityId, and attachmentType"}};let f=await z4(Q.entityService,w,B,this.logger,"Source entity");if(!f.ok)return{kind:"handled",result:{success:!1,error:f.error}};let Y=vK(A.targetEntityType),X=vK(A.targetEntityId),H;if(Y&&X){let q=await z4(Q.entityService,Y,X,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:f.entity.id,attachmentType:$},K=await Dl2(Q,W),U=Gl2(W);await this.createPendingImage(Q,{id:U,title:U,alt:U,sourceEntityType:W.sourceEntityType,sourceEntityId:W.sourceEntityId,attachmentType:$,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},...$==="og-image"&&{targetImageField:"ogImageId"}}});return{kind:"handled",result:{success:!0,data:{entityId:U,status:"generating",jobId:G,attachment:TP0(U,$)}}}}async createPendingImage(A,Q){let w=new Date().toISOString(),B=mX.createImageEntity({dataUrl:Wl2,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 Vk({entityService:A.entityService,entity:{id:Q.id,...B,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 oQ0(A,this.logger)}async onRegister(A){A.entities.registerUploadSaveHandler({entityType:this.entityType,mediaTypes:["image/*"],handler:async(w)=>{let B=await this.promoteUpload({entityType:this.entityType,...w.title!==void 0?{title:w.title}:{},from:w.upload},A);return B.kind==="handled"?B.result:{success:!1,error:"Image upload save was not handled"}}});let Q=new oQ0(A,this.logger);A.jobs.registerHandler("image-generate",Q),A.jobs.registerHandler("image-render-source",new yP0(A,this.logger)),A.jobs.registerHandler("upload-promote",new EP0(this.logger.child("UploadPromotionJobHandler"),A))}}function Cc(A={}){return new SP0(A)}wA();import{StdioServerTransport as Vl2}from"@modelcontextprotocol/sdk/server/stdio.js";_0();var ql2=Z.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 EOA(){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 mP0(){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 tQ0(A){let Q=ql2.safeParse(A);if(Q.success)return{info:(w,...B)=>Q.data.info(w,...B),debug:(w,...B)=>Q.data.debug(w,...B),error:(w,...B)=>Q.data.error(w,...B),warn:(w,...B)=>Q.data.warn(w,...B)};return mP0()}class RK{static instance=null;mcpServer=null;transport=null;config;logger;static getInstance(A){return RK.instance??=new RK(A),RK.instance}static resetInstance(){if(RK.instance)RK.instance.stop(),RK.instance=null}static createFresh(A){return new RK(A)}constructor(A={}){this.config=A,this.logger=this.config.logger?tQ0(this.config.logger):EOA()}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 Vl2,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 bl2,timingSafeEqual as Jl2}from"crypto";import{WebStandardStreamableHTTPServerTransport as Il2}from"@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";import{isInitializeRequest as Fl2}from"@modelcontextprotocol/sdk/types.js";_0();var Ll2=1800000,kl2=60000,_l2={"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"},Nl2=Z.looseObject({code:Z.string().optional()});function jl2(A){let Q=new URL(A.url),B=A.headers.get("x-forwarded-proto")?.split(",")[0]?.trim(),$=A.headers.get("x-forwarded-host")??A.headers.get("host");if(!$)return Q.origin;return`${B??Q.protocol.replace(":","")}://${$}`}class yz{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?tQ0(this.config.logger):mP0(),this.authConfig=A.auth??{},this.sessionIdleTtlMs=A.sessionIdleTtlMs??Ll2,this.evictionTimer=setInterval(()=>this.evictIdleSessions(),Math.min(this.sessionIdleTtlMs,kl2)),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 yz.instance??=new yz(A),yz.instance}static resetInstance(){yz.instance=null}static createFresh(A){return new yz(A)}withCors(A){let Q=new Headers(A.headers);for(let[w,B]of Object.entries(_l2))Q.set(w,B);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 B=this.createJsonResponse({jsonrpc:"2.0",error:{code:-32001,message:A},id:null},Q);if(!w)return B;let $=new Headers(B.headers);return $.set("WWW-Authenticate",w),new Response(B.body,{status:B.status,statusText:B.statusText,headers:$})}getBearerChallenge(A,Q={}){let w={...this.authConfig.token?{}:{resource_metadata:`${jl2(A)}/.well-known/oauth-protected-resource`},...Q};return`Bearer ${Object.entries(w).map(([$,f])=>`${$}="${Pl2(f)}"`).join(", ")}`}async authenticate(A){let Q=new URL(A.url).pathname;if(Q==="/health"||Q==="/status"||Q==="/mcp"&&A.method==="OPTIONS")return null;if(this.authConfig.disabled)return null;let 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 B=w.substring(7);if(!Ml2(B,this.authConfig.token))return this.logger.warn("Authentication failed: Invalid token"),this.getAuthErrorResponse("Unauthorized: Invalid token",401,this.getBearerChallenge(A,{error:"invalid_token"}));return this.logger.debug("Authentication successful"),null}try{let B=await this.authConfig.verifyBearerToken?.(A);if(!B)return this.logger.warn("Authentication failed: Invalid token"),this.getAuthErrorResponse("Unauthorized: Invalid token",401,this.getBearerChallenge(A,{error:"invalid_token"}));let $=this.authConfig.requiredScopes??[],f=$.filter((Y)=>!B.scope?.includes(Y));if(f.length>0)return this.logger.warn(`Authentication failed: Missing required scope(s): ${f.join(", ")}`),this.getAuthErrorResponse("Forbidden: Missing required scope",403,this.getBearerChallenge(A,{error:"insufficient_scope",scope:$.join(" ")}));return this.logger.debug("Authentication successful"),null}catch(B){return this.logger.warn("Authentication failed: Invalid token",B),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 B=this.transports[Q];if(B)delete this.transports[Q],B.close().catch(($)=>{this.logger.error(`Error closing idle transport for session ${Q}:`,$)})}}async handleMcpRequest(A){let Q=A.headers.get("mcp-session-id")??void 0;if(A.method==="GET"){if(!Q||!this.transports[Q])return this.createTextResponse("Invalid or missing session ID",400);return this.touchSession(Q),this.logger.debug(`GET /mcp - SSE stream for session ${Q}`),this.withCors(await this.transports[Q].handleRequest(A))}if(A.method==="DELETE"){if(!Q||!this.transports[Q])return this.createTextResponse("Invalid or missing session ID",400);return this.logger.info(`DELETE /mcp - Terminating session ${Q}`),this.withCors(await this.transports[Q].handleRequest(A))}if(A.method==="OPTIONS")return this.withCors(new Response(null,{status:204}));if(A.method!=="POST")return this.createTextResponse("Method Not Allowed",405);if(!this.mcpServer)return this.createJsonResponse({jsonrpc:"2.0",error:{code:-32603,message:"Service Unavailable: MCP server not connected"},id:null},503);let w;try{w=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: ${Q??"new"}`);try{let B;if(Q&&this.transports[Q])B=this.transports[Q],this.touchSession(Q);else if(!Q&&Fl2(w))B=new Il2({sessionIdGenerator:()=>bl2(),onsessioninitialized:(f)=>{this.logger.info(`Session initialized: ${f}`),this.transports[f]=B,this.touchSession(f)},onsessionclosed:(f)=>{this.logger.info(`Session closed: ${f}`),delete this.transports[f],this.sessionLastActivity.delete(f)}}),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:w}))}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)return w;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 B=Nl2.safeParse(w);if(B.success&&B.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 Pl2(A){return A.replace(/["\\]/g,(Q)=>`\\${Q}`)}function Ml2(A,Q){let w=Buffer.from(A),B=Buffer.from(Q);if(w.length!==B.length)return!1;return Jl2(w,B)}import{randomUUID as gl2}from"crypto";import{chmod as Ol2,mkdir as xl2,readFile as vl2,rename as TOA,writeFile as Rl2}from"fs/promises";import{dirname as hl2}from"path";class Pf{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 vl2(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 xl2(hl2(this.filePath),{recursive:!0,mode:448});let Q=`${this.filePath}.tmp`;await Rl2(Q,`${JSON.stringify(A,null,2)}
|
|
1721
1721
|
`,{mode:384}),await Ol2(Q,384),await TOA(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 TOA(this.filePath,Q)}catch(w){this.logError(`Failed to quarantine corrupt JSON store at ${this.filePath}`,w)}}}function cv(A){let Q=A.toISOString();return Q.substring(0,Q.indexOf("T"))}function eQ0(){let A=new Date;return A.setDate(A.getDate()-1),A}function SOA(A){let Q=new Date;return Q.setDate(Q.getDate()-A),Q}function Z9(){return Math.floor(Date.now()/1000)}_0();import{join as yl2}from"path";function mOA(A){let Q=A.toLowerCase();return Q==="localhost"||Q==="[::1]"||Q==="::1"||Q.startsWith("127.")}function uOA(A){try{return new URL(A)}catch{return}}function uP0(A,Q){if(A===Q)return!0;let w=uOA(A),B=uOA(Q);if(!w||!B)return!1;if(!mOA(w.hostname)||!mOA(B.hostname))return!1;return w.protocol===B.protocol&&w.port===B.port&&Cl2(w.pathname,B.pathname)&&w.search===B.search&&w.hash===B.hash}function Cl2(A,Q){return A===Q||A===`${Q}/debug`||Q===`${A}/debug`}function cP0(A,Q){return A.some((w)=>uP0(w,Q))}var El2="oauth-auth-codes.json",Tl2=600,Sl2=Z.looseObject({code:Z.string(),client_id:Z.string(),redirect_uri:Z.string(),code_challenge:Z.string(),code_challenge_method:Z.literal("S256"),scope:Z.string().optional(),subject:Z.string(),created_at:Z.number(),expires_at:Z.number(),consumed_at:Z.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}:{}})),ml2=Z.looseObject({codes:Z.array(Z.unknown()).optional()});function ul2(A){let Q=ml2.safeParse(A);if(!Q.success)return{codes:[]};return{codes:Q.data.codes?.flatMap(cl2)??[]}}function cl2(A){let Q=Sl2.safeParse(A);return Q.success?[Q.data]:[]}async function ll2(A){let Q=await crypto.subtle.digest("SHA-256",new TextEncoder().encode(A));return Buffer.from(Q).toString("base64url")}class Aw0{store;constructor(A){this.store=new Pf({filePath:yl2(A.storageDir,A.storeFile??El2),parse:ul2,empty:()=>({codes:[]})})}async createCode(A){let Q=Z9(),w={code:`ocd_${gl2()}`,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+Tl2};return await this.store.enqueueWrite(async()=>{let B=await this.store.read();B.codes=B.codes.filter(($)=>$.expires_at>Q),B.codes.push(w),await this.store.write(B)}),w}async consumeCode(A){let Q=Z9(),w;if(await this.store.enqueueWrite(async()=>{let B=await this.store.read(),$=B.codes.findIndex((X)=>X.code===A.code),f=$>=0?B.codes[$]:void 0;if(!f)throw new hK("Authorization code not found");if(f.consumed_at!==void 0)throw new hK("Authorization code already consumed");if(f.expires_at<=Q)throw new hK("Authorization code expired");if(f.client_id!==A.clientId)throw new hK("Authorization code client mismatch");if(!uP0(f.redirect_uri,A.redirectUri))throw new hK("Authorization code redirect URI mismatch");let Y=await ll2(A.codeVerifier);if(f.code_challenge!==Y)throw new hK("PKCE verification failed");w={...f,consumed_at:Q},B.codes[$]=w,await this.store.write(B)}),!w)throw new hK("Authorization code not consumed");return w}}class hK extends Error{constructor(A){super(A);this.name="InvalidGrantError"}}import{randomUUID as cOA}from"crypto";_0();import{join as pl2}from"path";var il2="oauth-clients.json",dl2=Z.enum(["none","client_secret_basic","client_secret_post"]),nl2=Z.object({redirect_uris:Z.array(Z.url()).min(1),token_endpoint_auth_method:dl2.default("none"),grant_types:Z.array(Z.enum(["authorization_code","refresh_token"])).default(["authorization_code","refresh_token"]),response_types:Z.array(Z.literal("code")).default(["code"]),scope:Z.string().optional(),client_name:Z.string().optional(),client_uri:Z.url().optional(),logo_uri:Z.url().optional(),contacts:Z.array(Z.string()).optional()}),rl2=Z.looseObject({client_id:Z.string(),client_id_issued_at:Z.number(),redirect_uris:Z.array(Z.string()),token_endpoint_auth_method:Z.string().optional(),grant_types:Z.array(Z.string()).optional(),response_types:Z.array(Z.string()).optional(),scope:Z.string().optional(),client_name:Z.string().optional(),client_uri:Z.string().optional(),logo_uri:Z.string().optional(),contacts:Z.array(Z.string()).optional(),client_secret:Z.string().optional(),client_secret_expires_at:Z.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}:{}})),ol2=Z.looseObject({clients:Z.array(Z.unknown()).optional()});function sl2(){return`ocs_${cOA().replaceAll("-","")}`}function al2(A){let Q=ol2.safeParse(A);if(!Q.success)return{clients:[]};return{clients:Q.data.clients?.flatMap(tl2)??[]}}function tl2(A){let Q=rl2.safeParse(A);return Q.success?[Q.data]:[]}class Qw0{store;constructor(A){this.store=new Pf({filePath:pl2(A.storageDir,A.storeFile??il2),parse:al2,empty:()=>({clients:[]})})}async registerClient(A){let Q=nl2.safeParse(A);if(!Q.success)throw new gc(Q.error.message);let w=Q.data,B=Z9(),$=`oc_${cOA()}`,f=w.token_endpoint_auth_method==="none",Y={client_id:$,client_id_issued_at:B,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}:{},...!f?{client_secret:sl2(),client_secret_expires_at:0}:{}};return await this.store.enqueueWrite(async()=>{let X=await this.store.read();X.clients.push(Y),await this.store.write(X)}),Y}async getClient(A){return(await this.store.read()).clients.find((w)=>w.client_id===A)}}class gc extends Error{constructor(A){super(A);this.name="InvalidClientMetadataError"}}_0();import{createHash as lOA,generateKeyPairSync as el2}from"crypto";import{mkdir as Ap2,readFile as pOA,writeFile as Qp2,chmod as wp2}from"fs/promises";import{dirname as Bp2,join as iOA}from"path";var $p2="oauth-signing-key.jwk",fp2="a2a-signing-key.jwk",dOA=Z.object({kty:Z.literal("EC"),crv:Z.literal("P-256"),x:Z.string(),y:Z.string(),d:Z.string(),kid:Z.string().optional()}),nOA=Z.object({kty:Z.literal("OKP"),crv:Z.literal("Ed25519"),x:Z.string(),d:Z.string(),kid:Z.string().optional()});function Yp2(A){let Q=JSON.stringify({crv:A.crv,kty:A.kty,x:A.x,y:A.y});return lOA("sha256").update(Q).digest("base64url")}function Xp2(A){let Q=JSON.stringify({crv:A.crv,kty:A.kty,x:A.x});return lOA("sha256").update(Q).digest("base64url")}function Zp2(A){return{kty:"EC",crv:"P-256",x:A.x,y:A.y,kid:A.kid,use:"sig",alg:"ES256"}}function Hp2(A){return{kty:"OKP",crv:"Ed25519",x:A.x,kid:A.kid,use:"sig",alg:"EdDSA"}}async function Wp2(){let A=await crypto.subtle.generateKey({name:"ECDSA",namedCurve:"P-256"},!0,["sign","verify"]),Q=dOA.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 rOA(Q.data)}function Kp2(){let{privateKey:A}=el2("ed25519"),Q=nOA.safeParse(A.export({format:"jwk"}));if(!Q.success)throw Error("Generated A2A signing key is not an Ed25519 private JWK");return oOA(Q.data)}function rOA(A){return{kty:"EC",crv:"P-256",x:A.x,y:A.y,d:A.d,kid:A.kid??Yp2(A),use:"sig",alg:"ES256"}}function oOA(A){return{kty:"OKP",crv:"Ed25519",x:A.x,d:A.d,kid:A.kid??Xp2(A),use:"sig",alg:"EdDSA"}}class ww0{keyFile;cachedKey;loadPromise;constructor(A){this.keyFile=iOA(A.storageDir,A.keyFile??$p2)}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 Wp2();return await sOA(this.keyFile,Q),Q}async getPublicJwk(){return Zp2(await this.getPrivateJwk())}async readExistingKey(){try{let A=dOA.safeParse(JSON.parse(await pOA(this.keyFile,"utf8")));if(!A.success)throw Error(`OAuth signing key at ${this.keyFile} is not a private P-256 JWK`);return rOA(A.data)}catch(A){if(aOA(A))return;throw A}}}class lP0{keyFile;cachedKey;loadPromise;constructor(A){this.keyFile=iOA(A.storageDir,A.keyFile??fp2)}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=Kp2();return await sOA(this.keyFile,Q),Q}async getPublicJwk(){return Hp2(await this.getPrivateJwk())}async readExistingKey(){try{let A=nOA.safeParse(JSON.parse(await pOA(this.keyFile,"utf8")));if(!A.success)throw Error(`A2A signing key at ${this.keyFile} is not a private Ed25519 JWK`);return oOA(A.data)}catch(A){if(aOA(A))return;throw A}}}async function sOA(A,Q){await Ap2(Bp2(A),{recursive:!0,mode:448}),await Qp2(A,`${JSON.stringify(Q,null,2)}
|
|
1722
1722
|
`,{mode:384}),await wp2(A,384)}function aOA(A){return A instanceof Error&&"code"in A&&A.code==="ENOENT"}var PQ={};D6(PQ,{trimPadding:()=>eOA,toUTF8String:()=>Ip2,toBuffer:()=>qp2,toBase64:()=>bp2,isBase64URL:()=>Lp2,isBase64:()=>Fp2,fromUTF8String:()=>Jp2,fromBuffer:()=>Vp2});var tOA=(A)=>{let Q=typeof Uint8Array>"u"?[]:new Uint8Array(256),w=64;for(let B=0;B<64;B++)Q[A.charCodeAt(B)]=B;return Q},Up2=tOA("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"),Gp2=tOA("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"),Dp2=/^[-A-Za-z0-9\-_]*$/,zp2=/^[-A-Za-z0-9+/]*={0,3}$/,mG={};mG.toArrayBuffer=(A,Q)=>{let w=A.length,B=A.length*0.75,$,f=0,Y,X,H,W;if(A[A.length-1]==="="){if(B--,A[A.length-2]==="=")B--}let K=new ArrayBuffer(B),U=new Uint8Array(K),G=Q?Gp2:Up2;for($=0;$<w;$+=4)Y=G[A.charCodeAt($)],X=G[A.charCodeAt($+1)],H=G[A.charCodeAt($+2)],W=G[A.charCodeAt($+3)],U[f++]=Y<<2|X>>4,U[f++]=(X&15)<<4|H>>2,U[f++]=(H&3)<<6|W&63;return K};mG.fromArrayBuffer=(A,Q)=>{let w=new Uint8Array(A),B,$="",f=w.length,Y=Q?"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_":"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";for(B=0;B<f;B+=3)$+=Y[w[B]>>2],$+=Y[(w[B]&3)<<4|w[B+1]>>4],$+=Y[(w[B+1]&15)<<2|w[B+2]>>6],$+=Y[w[B+2]&63];let X=f%3;if(X===2)$=$.substring(0,$.length-1)+(Q?"":"=");else if(X===1)$=$.substring(0,$.length-2)+(Q?"":"==");return $};mG.toString=(A,Q)=>{return new TextDecoder().decode(mG.toArrayBuffer(A,Q))};mG.fromString=(A,Q)=>{return mG.fromArrayBuffer(new TextEncoder().encode(A),Q)};mG.validate=(A,Q)=>{if(!(typeof A==="string"||A instanceof String))return!1;try{return Q?Dp2.test(A):zp2.test(A)}catch(w){return!1}};mG.base64=mG;var Ez=mG;function qp2(A,Q="base64url"){let w=Ez.toArrayBuffer(A,Q==="base64url");return new Uint8Array(w)}function Vp2(A,Q="base64url"){let w=new Uint8Array(A);return Ez.fromArrayBuffer(w.buffer,Q==="base64url")}function bp2(A){let Q=Ez.toArrayBuffer(A,!0);return Ez.fromArrayBuffer(Q)}function Jp2(A){return Ez.fromString(A,!0)}function Ip2(A){return Ez.toString(A,!0)}function Fp2(A){return Ez.validate(A,!1)}function Lp2(A){return A=eOA(A),Ez.validate(A,!0)}function eOA(A){return A.replace(/=/g,"")}var Mf={};D6(Mf,{encode:()=>lp2,decodeFirst:()=>cp2});function lv(A,Q,w){if(Q<24)return[Q,1];let B=A.byteLength-w-1,$=new DataView(A.buffer,w+1),f,Y=0;switch(Q){case 24:{if(B>0)f=$.getUint8(0),Y=2;break}case 25:{if(B>1)f=$.getUint16(0,!1),Y=3;break}case 26:{if(B>3)f=$.getUint32(0,!1),Y=5;break}case 27:{if(B>7){let X=$.getBigUint64(0,!1);if(X>=24n&&X<=Number.MAX_SAFE_INTEGER)return[Number(X),9]}break}}if(f&&f>=24)return[f,Y];throw Error("Length not supported or not well formed")}var Bw0=0,yc=1,pP0=2,iP0=3,dP0=4,nP0=5,rP0=6,AxA=7;function uG(A,Q){let w=A<<5;if(Q<0)throw Error("CBOR Data Item argument must not be negative");let B;if(typeof Q=="number"){if(!Number.isInteger(Q))throw Error("CBOR Data Item argument must be an integer");B=BigInt(Q)}else B=Q;if(A==yc){if(B==0n)throw Error("CBOR Data Item argument cannot be zero when negative");B=B-1n}if(B>18446744073709551615n)throw Error("CBOR number out of range");let $=new Uint8Array(8);if(new DataView($.buffer).setBigUint64(0,B,!1),B<=23)return[w|$[7]];else if(B<=255)return[w|24,$[7]];else if(B<=65535)return[w|25,...$.slice(6)];else if(B<=4294967295)return[w|26,...$.slice(4)];else return[w|27,...$]}class fw0{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 QxA(A,Q,w){return lv(A,Q,w)}function kp2(A,Q,w){let[B,$]=QxA(A,Q,w);return[-B-1,$]}function wxA(A,Q,w){let[B,$]=lv(A,Q,w),f=w+$;return[new Uint8Array(A.buffer.slice(f,f+B)),$+B]}var _p2=new TextDecoder;function Np2(A,Q,w){let[B,$]=wxA(A,Q,w);return[_p2.decode(B),$]}function jp2(A,Q,w){if(Q===0)return[[],1];let[B,$]=lv(A,Q,w),f=$,Y=[];for(let X=0;X<B;X++){if(A.byteLength-w-f<=0)throw Error("array is not supported or well formed");let[W,K]=U_(A,w+f);Y.push(W),f+=K}return[Y,f]}var $w0="Map is not supported or well formed";function Pp2(A,Q,w){if(Q===0)return[new Map,1];let[B,$]=lv(A,Q,w),f=$,Y=new Map;for(let X=0;X<B;X++){let H=A.byteLength-w-f;if(H<=0)throw Error($w0);let[W,K]=U_(A,w+f);if(f+=K,H-=K,H<=0)throw Error($w0);if(typeof W!=="string"&&typeof W!=="number")throw Error($w0);if(Y.has(W))throw Error($w0);let[U,G]=U_(A,w+f);f+=G,Y.set(W,U)}return[Y,f]}function Mp2(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 Op2(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 xp2(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 vp2(A,Q,w){let[B,$]=lv(A,Q,w),[f,Y]=U_(A,w+$);return[new fw0(B,f),$+Y]}function U_(A,Q){if(Q>=A.byteLength)throw Error("CBOR stream ended before tag value");let w=A.getUint8(Q),B=w>>5,$=w&31;switch(B){case Bw0:return QxA(A,$,Q);case yc:return kp2(A,$,Q);case pP0:return wxA(A,$,Q);case iP0:return Np2(A,$,Q);case dP0:return jp2(A,$,Q);case nP0:return Pp2(A,$,Q);case rP0:return vp2(A,$,Q);case AxA:switch($){case 20:return[!1,1];case 21:return[!0,1];case 22:return[null,1];case 23:return[void 0,1];case 25:return Mp2(A,Q);case 26:return Op2(A,Q);case 27:return xp2(A,Q)}}throw Error(`Unsupported or not well formed at ${Q}`)}function Rp2(A){if(A===!0)return 245;else if(A===!1)return 244;else if(A===null)return 246;return 247}function hp2(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 Cp2(A){if(typeof A=="number"){if(Number.isSafeInteger(A))if(A<0)return uG(yc,Math.abs(A));else return uG(Bw0,A);return[hp2(A)]}else if(A<0n)return uG(yc,A*-1n);else return uG(Bw0,A)}var gp2=new TextEncoder;function yp2(A,Q){Q.push(...uG(iP0,A.length)),Q.push(gp2.encode(A))}function Ep2(A,Q){Q.push(...uG(pP0,A.length)),Q.push(A)}function Tp2(A,Q){Q.push(...uG(dP0,A.length));for(let w of A)Ec(w,Q)}function Sp2(A,Q){Q.push(new Uint8Array(uG(nP0,A.size)));for(let[w,B]of A.entries())Ec(w,Q),Ec(B,Q)}function mp2(A,Q){Q.push(...uG(rP0,A.tag)),Ec(A.value,Q)}function Ec(A,Q){if(typeof A=="boolean"||A===null||A==null){Q.push(Rp2(A));return}if(typeof A=="number"||typeof A=="bigint"){Q.push(...Cp2(A));return}if(typeof A=="string"){yp2(A,Q);return}if(A instanceof Uint8Array){Ep2(A,Q);return}if(Array.isArray(A)){Tp2(A,Q);return}if(A instanceof Map){Sp2(A,Q);return}if(A instanceof fw0){mp2(A,Q);return}throw Error("Not implemented")}function oP0(A,Q){if(A.byteLength===0||A.byteLength<=Q||Q<0)throw Error("No data");if(A instanceof Uint8Array)return U_(new DataView(A.buffer),Q);else if(A instanceof ArrayBuffer)return U_(new DataView(A),Q);return U_(A,Q)}function sP0(A){let Q=[];Ec(A,Q);let w=0;for(let f of Q)if(typeof f=="number")w+=1;else w+=f.length;let B=new Uint8Array(w),$=0;for(let f of Q)if(typeof f=="number")B[$]=f,$+=1;else B.set(f,$),$+=f.length;return B}function cp2(A){let Q=new Uint8Array(A),w=oP0(Q,0),[B]=w;return B}function lp2(A){return sP0(A)}var lG={};D6(lG,{verify:()=>TCA,getRandomValues:()=>XxA,digest:()=>YxA});function BxA(A){let Q=A.get(IQ.kty);return aP0(Q)&&Q===uX.OKP}function zJ(A){let Q=A.get(IQ.kty);return aP0(Q)&&Q===uX.EC2}function pv(A){let Q=A.get(IQ.kty);return aP0(Q)&&Q===uX.RSA}var IQ;(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"})(IQ||(IQ={}));var uX;(function(A){A[A.OKP=1]="OKP",A[A.EC2=2]="EC2",A[A.RSA=3]="RSA"})(uX||(uX={}));function aP0(A){return Object.values(uX).indexOf(A)>=0}var _4;(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"})(_4||(_4={}));function $xA(A){return Object.values(_4).indexOf(A)>=0}var Aw;(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"})(Aw||(Aw={}));function cG(A){return Object.values(Aw).indexOf(A)>=0}function qJ(A){if([Aw.RS1].indexOf(A)>=0)return"SHA-1";else if([Aw.ES256,Aw.PS256,Aw.RS256].indexOf(A)>=0)return"SHA-256";else if([Aw.ES384,Aw.PS384,Aw.RS384].indexOf(A)>=0)return"SHA-384";else if([Aw.ES512,Aw.PS512,Aw.RS512,Aw.EdDSA].indexOf(A)>=0)return"SHA-512";throw Error(`Could not map COSE alg value of ${A} to a WebCrypto alg`)}var Tc=void 0;function cH(){return new Promise((Q,w)=>{if(Tc)return Q(Tc);let B=ip2.stubThisGlobalThisCrypto();if(B)return Tc=B,Q(Tc);return w(new fxA)})}class fxA extends Error{constructor(){super("An instance of the Crypto API could not be located");this.name="MissingWebCrypto"}}var ip2={stubThisGlobalThisCrypto:()=>globalThis.crypto,setCachedCrypto:(A)=>{Tc=A}};async function YxA(A,Q){let w=await cH(),B=qJ(Q),$=await w.subtle.digest(B,A);return new Uint8Array($)}async function XxA(A){return(await cH()).getRandomValues(A),A}async function iv(A){let Q=await cH(),{keyData:w,algorithm:B}=A;return Q.subtle.importKey("jwk",w,B,!1,["verify"])}async function Yw0(A){let{cosePublicKey:Q,signature:w,data:B,shaHashOverride:$}=A,f=await cH(),Y=Q.get(IQ.alg),X=Q.get(IQ.crv),H=Q.get(IQ.x),W=Q.get(IQ.y);if(!Y)throw Error("Public key was missing alg (EC2)");if(!X)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(X===_4.P256)K="P-256";else if(X===_4.P384)K="P-384";else if(X===_4.P521)K="P-521";else throw Error(`Unexpected COSE crv value of ${X} (EC2)`);let U={kty:"EC",crv:K,x:PQ.fromBuffer(H),y:PQ.fromBuffer(W),ext:!1},q=await iv({keyData:U,algorithm:{name:"ECDSA",namedCurve:K}}),V=qJ(Y);if($)V=qJ($);let J={name:"ECDSA",hash:{name:V}};return f.subtle.verify(J,q,w,B)}function tP0(A){if([Aw.EdDSA].indexOf(A)>=0)return"Ed25519";else if([Aw.ES256,Aw.ES384,Aw.ES512,Aw.ES256K].indexOf(A)>=0)return"ECDSA";else if([Aw.RS256,Aw.RS384,Aw.RS512,Aw.RS1].indexOf(A)>=0)return"RSASSA-PKCS1-v1_5";else if([Aw.PS256,Aw.PS384,Aw.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 Xw0(A){let{cosePublicKey:Q,signature:w,data:B,shaHashOverride:$}=A,f=await cH(),Y=Q.get(IQ.alg),X=Q.get(IQ.n),H=Q.get(IQ.e);if(!Y)throw Error("Public key was missing alg (RSA)");if(!cG(Y))throw Error(`Public key had invalid alg ${Y} (RSA)`);if(!X)throw Error("Public key was missing n (RSA)");if(!H)throw Error("Public key was missing e (RSA)");let W={kty:"RSA",alg:"",n:PQ.fromBuffer(X),e:PQ.fromBuffer(H),ext:!1},K={name:tP0(Y),hash:{name:qJ(Y)}},U={name:tP0(Y)};if($)K.hash.name=qJ($);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 iv({keyData:W,algorithm:K});return f.subtle.verify(U,G,w,B)}function Zw0(A){let Q=R2.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 k8(A){let Q;if(typeof A==="string")if(PQ.isBase64URL(A))Q=PQ.toBase64(A);else if(PQ.isBase64(A))Q=A;else throw Error("Certificate is not a valid base64 or base64url string");else Q=PQ.fromBuffer(A,"base64");let w="";for(let B=0;B<Math.ceil(Q.length/64);B+=1){let $=64*B;w+=`${Q.substr($,64)}
|
|
1723
1723
|
`}return w=`-----BEGIN CERTIFICATE-----
|
|
@@ -2292,14 +2292,14 @@ ${L}`)}if(B!==void 0&&f?.algorithms!==void 0){let b=f.algorithms.map((L)=>L.alg)
|
|
|
2292
2292
|
</form>
|
|
2293
2293
|
</main>
|
|
2294
2294
|
</body>
|
|
2295
|
-
</html>`}function Lp(A){let Q=`${new URL(A.url).pathname}${new URL(A.url).search}`;return new Response(Gv0(Q,"Operator login required"),{status:401,headers:{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store"}})}function $D(A){return A.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""")}import{randomUUID as br2}from"crypto";function agA(A){return Buffer.from(JSON.stringify(A)).toString("base64url")}function Vr2(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 B=Q[w+1];if(B===void 0)throw Error("Invalid DER ECDSA signature");let $=w+2,f=Q.slice($,$+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 X=w+2,H=Q.slice(X,X+Y);return new Uint8Array([...tgA(f),...tgA(H)])}function tgA(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 zv0(A,Q){let w={typ:"JWT",alg:"ES256",kid:A.kid},B=`${agA(w)}.${agA(Q)}`,$=await crypto.subtle.importKey("jwk",A,{name:"ECDSA",namedCurve:"P-256"},!1,["sign"]),f=await crypto.subtle.sign({name:"ECDSA",hash:"SHA-256"},$,new TextEncoder().encode(B));return`${B}.${Buffer.from(Vr2(f)).toString("base64url")}`}var Jr2=600;class qv0{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 Lp(A);let w=await this.validateAuthorizationRequest(new URL(A.url).searchParams);if(!w.success)return new Response(w.error,{status:400});let B=this.createAuthorizationApprovalToken(Q,w.params);return Wh(sgA(w.params,B))}async handleAuthorizeApproval(A){let Q=await this.sessionStore.getSessionFromRequest(A);if(!Q)return Lp(A);let w=await A.formData(),B=await this.validateAuthorizationRequest(new URLSearchParams(Hv0(w)));if(!B.success)return new Response(B.error,{status:400});let $=w.get("approval_token"),f=typeof $==="string"?$:void 0;if(!f||!this.consumeAuthorizationApprovalToken(f,Q,B.params))return new Response("Invalid authorization approval token",{status:400});let Y=await this.authCodeStore.createCode({clientId:B.params.clientId,redirectUri:B.params.redirectUri,codeChallenge:B.params.codeChallenge,...B.params.scope?{scope:B.params.scope}:{},subject:Q.subject}),X=new URL(B.params.redirectUri);if(X.searchParams.set("code",Y.code),B.params.state)X.searchParams.set("state",B.params.state);return Response.redirect(X.toString(),302)}createAuthorizationApprovalToken(A,Q){this.pruneExpiredAuthorizationApprovalTokens();let w=`oat_${br2()}`;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)+Jr2}),w}consumeAuthorizationApprovalToken(A,Q,w){this.pruneExpiredAuthorizationApprovalTokens();let B=this.authorizationApprovalTokens.get(A);if(!B)return!1;return this.authorizationApprovalTokens.delete(A),B.sessionId===Q.id&&B.clientId===w.clientId&&B.redirectUri===w.redirectUri&&B.codeChallenge===w.codeChallenge&&B.scope===w.scope&&B.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"),B=A.get("redirect_uri"),$=A.get("code_challenge"),f=A.get("code_challenge_method"),Y=A.get("scope")??void 0,X=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(!B)return{success:!1,error:"Missing redirect_uri"};if(!$)return{success:!1,error:"Missing code_challenge"};if(f!=="S256")return{success:!1,error:"Unsupported code_challenge_method"};let H=await this.clientStore.getClient(w);if(!H)return{success:!1,error:"Unknown client_id"};if(!cP0(H.redirect_uris,B))return{success:!1,error:"Unregistered redirect_uri"};let W=Y??H.scope;return{success:!0,params:{clientId:w,redirectUri:B,codeChallenge:$,...W?{scope:W}:{},...X?{state:X}:{},clientName:H.client_name??H.client_id}}}async handleClientRegistration(A){let Q;try{Q=await A.json()}catch{return o$("invalid_client_metadata","Request body must be JSON")}try{let w=await this.clientStore.registerClient(Q);return sX(w,201)}catch(w){if(w instanceof gc)return o$("invalid_client_metadata",w.message);throw w}}async handleTokenRequest(A,Q){let w=await Zv0(A),B=w.get("grant_type"),$=Kv0(A,w),f=$.clientId??w.get("client_id");if($.error)return o$("invalid_client",$.error);if(!f)return o$("invalid_request","client_id is required");let Y=await this.clientStore.getClient(f),X=Wv0(Y,$);if(X)return o$("invalid_client",X);if(B==="authorization_code")return this.handleAuthorizationCodeGrant(w,f,Q);if(B==="refresh_token")return this.handleRefreshTokenGrant(w,f,Q);return o$("unsupported_grant_type","Only authorization_code and refresh_token are supported")}async handleAuthorizationCodeGrant(A,Q,w){let B=A.get("code"),$=A.get("redirect_uri"),f=A.get("code_verifier");if(!B||!$||!f)return o$("invalid_request","code, redirect_uri, and code_verifier are required");let Y=await this.clientStore.getClient(Q);if(!Y||!cP0(Y.redirect_uris,$))return o$("invalid_grant","Unregistered redirect_uri");try{let X=await this.authCodeStore.consumeCode({code:B,clientId:Q,redirectUri:$,codeVerifier:f});return await this.createTokenResponse({issuer:w,clientId:Q,subject:X.subject,...X.scope?{scope:X.scope}:{}})}catch(X){if(X instanceof hK)return o$("invalid_grant",X.message);throw X}}async handleRefreshTokenGrant(A,Q,w){let B=A.get("refresh_token");if(!B)return o$("invalid_request","refresh_token is required");try{let $=await this.refreshTokenStore.rotateToken(B,Q);return await this.createTokenResponse({issuer:w,clientId:Q,subject:$.consumed.subject,...$.consumed.scope?{scope:$.consumed.scope}:{},refreshToken:$.replacement.token})}catch($){if($ instanceof Yq)return o$("invalid_grant",$.message);throw $}}async createTokenResponse(A){let Q=Math.floor(Date.now()/1000),w=900,B=await zv0(await this.keyStore.getPrivateJwk(),{iss:A.issuer,sub:A.subject,aud:A.clientId,iat:Q,exp:Q+900,...A.scope?{scope:A.scope}:{}}),$=A.refreshToken??(await this.refreshTokenStore.issueToken({clientId:A.clientId,subject:A.subject,...A.scope?{scope:A.scope}:{}})).token;return sX({access_token:B,token_type:"Bearer",expires_in:900,...A.scope?{scope:A.scope}:{},refresh_token:$})}async handleRevokeRequest(A){let Q=await Zv0(A),w=Kv0(A,Q),B=w.clientId??Q.get("client_id")??void 0,$=Q.get("token");if(w.error)return o$("invalid_client",w.error);if(!$)return o$("invalid_request","token is required");if(B){let f=await this.clientStore.getClient(B),Y=Wv0(f,w);if(Y)return o$("invalid_client",Y)}return await this.refreshTokenStore.revokeToken($,B),new Response(null,{status:200})}}class Vv0{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 o$("access_denied","Passkey setup already completed");if(!this.setupFlow.hasValidSetupToken(A))return o$("access_denied","Invalid setup token");let Q=await this.passkeyService.generateRegistrationOptions(u60(A));return sX(Q)}async handleRegistrationVerify(A){if(await this.passkeyService.hasCredentials())return o$("access_denied","Passkey setup already completed");if(!this.setupFlow.hasValidSetupToken(A))return o$("access_denied","Invalid setup token");let Q=await this.passkeyService.verifyRegistrationResponse(await A.json(),u60(A));if(!Q.verified)return o$("access_denied","Passkey registration failed");await this.setupFlow.clearSetupState();let w=await this.sessionStore.createSession(Q.subject??"single-operator",{secure:bp(A)});return sX({verified:!0},200,{"Set-Cookie":w.cookie})}async handleAuthenticationOptions(A){if(!await this.passkeyService.hasCredentials())return o$("access_denied","No passkey registered");let Q=await this.passkeyService.generateAuthenticationOptions(u60(A));return sX(Q)}async handleAuthenticationVerify(A){let Q=await this.passkeyService.verifyAuthenticationResponse(await A.json(),u60(A));if(!Q.verified)return o$("access_denied","Passkey authentication failed");let w=await this.sessionStore.createSession(Q.subject??"single-operator",{secure:bp(A)});return sX({verified:!0},200,{"Set-Cookie":w.cookie})}}function u60(A){let Q=Bh(A),w=new URL(Q);return{origin:w.origin,rpID:w.hostname}}import{randomUUID as Ir2}from"crypto";var kp=86400;class bv0{setupStateStore;passkeyService;setupTokenTtlSeconds;setupToken;constructor(A){this.setupStateStore=A.setupStateStore,this.passkeyService=A.passkeyService,this.setupTokenTtlSeconds=A.setupTokenTtlSeconds??kp}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_${Ir2()}`,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 pK(A,`/setup?token=${encodeURIComponent(Q.token)}`)}async getOperatorSetupRequired(A){if(await this.passkeyService.hasCredentials())return;let Q=this.getValidSetupToken();if(!Q)return;return{setupUrl:pK(A,`/setup?token=${encodeURIComponent(Q.token)}`),expiresAt:Q.expiresAt,setupTokenId:cx0(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 Wh(rgA(Q))}async hasSetupEmailDelivery(A,Q){return this.setupStateStore.hasDelivery(A,Q)}async recordSetupEmailDelivery(A,Q,w={}){await this.setupStateStore.recordDelivery(A,Q,w)}}class c60{issuer;trustedIssuers;allowLocalhostIssuers;keyStore;a2aKeyStore;clientStore;authCodeStore;sessionStore;peerTrustStore;passkeyService;setupFlow;oauthEndpoints;webauthnEndpoints;logger;constructor(A){this.issuer=lK(A.issuer),this.trustedIssuers=new Set([this.issuer,...(A.trustedIssuers??[]).map((Q)=>lK(Q))]),this.allowLocalhostIssuers=A.allowLocalhostIssuers??wh(this.issuer),this.keyStore=new ww0({storageDir:A.storageDir}),this.a2aKeyStore=new lP0({storageDir:A.storageDir}),this.clientStore=new Qw0({storageDir:A.storageDir}),this.authCodeStore=new Aw0({storageDir:A.storageDir}),this.sessionStore=new y60({storageDir:A.storageDir}),this.peerTrustStore=new R60({storageDir:A.storageDir}),this.passkeyService=new v60({storageDir:A.storageDir,...A.logger?{logger:A.logger}:{}}),this.setupFlow=new bv0({setupStateStore:new lx0({storageDir:A.storageDir}),passkeyService:this.passkeyService,setupTokenTtlSeconds:A.setupTokenTtlSeconds??kp}),this.oauthEndpoints=new qv0({clientStore:this.clientStore,authCodeStore:this.authCodeStore,refreshTokenStore:new h60({storageDir:A.storageDir}),sessionStore:this.sessionStore,keyStore:this.keyStore}),this.webauthnEndpoints=new Vv0({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(wh(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:pK(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=lK(A);return{issuer:Q,authorization_endpoint:pK(Q,"/authorize"),token_endpoint:pK(Q,"/token"),registration_endpoint:pK(Q,"/register"),revocation_endpoint:pK(Q,"/revoke"),jwks_uri:pK(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:[lK(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 Lp(A)}async verifyBearerToken(A,Q={}){let w=Xv0(A);if(!w)return;let B=Q.issuer?lK(Q.issuer):this.resolveRequestIssuer(A);return Yv0(w,await this.getJwks(),{issuer:B,...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(B){return this.logger?.warn("Rejected OAuth request from untrusted issuer",{error:B instanceof Error?B.message:String(B)}),new Response("Untrusted OAuth issuer",{status:400})}let w=new URL(A.url).pathname;if(A.method==="OPTIONS"&&igA(w))return dgA();if(A.method==="GET"){if(w==="/.well-known/oauth-authorization-server")return dJ(sX(this.getAuthorizationServerMetadata(Q)));if(w==="/.well-known/jwks.json")return dJ(sX(await this.getJwks()));if(w==="/.well-known/oauth-protected-resource")return dJ(sX(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 dJ(await this.oauthEndpoints.handleClientRegistration(A));if(A.method==="POST"&&w==="/token")return dJ(await this.oauthEndpoints.handleTokenRequest(A,Q));if(A.method==="POST"&&w==="/revoke")return dJ(await this.oauthEndpoints.handleRevokeRequest(A));return new Response("Not Found",{status:404})}async handleWellKnownRequest(A){return this.handleRequest(A)}resolveRequestIssuer(A){let Q=Bh(A,this.issuer);if(this.trustedIssuers.has(Q)||this.allowLocalhostIssuers&&wh(Q))return Q;throw Error(`Request issuer ${Q} is not in trusted issuers`)}handleLoginPage(A){let Q=Uv0(new URL(A.url).searchParams.get("return_to"));return Wh(Gv0(Q))}async handleLogout(A){await this.sessionStore.revokeSessionFromRequest(A);let Q=Uv0(new URL(A.url).searchParams.get("return_to"));return new Response(null,{status:302,headers:{Location:Q,"Set-Cookie":ix0(bp(A)),"Cache-Control":"no-store"}})}}_0();var l60="email:send",egA=Z.strictObject({to:Z.string().email(),subject:Z.string().min(1),text:Z.string().min(1),html:Z.string().min(1).optional(),sensitivity:Z.enum(["normal","secret"]).default("normal")});wA();_0();var AyA={name:"@brains/notifications",version:"0.2.0-alpha.150",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:"^6.0.3"},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 Jv0="notifications:send",Lr2=Z.looseObject({}),kr2=Z.discriminatedUnion("type",[Z.strictObject({type:Z.literal("email"),address:Z.email()})]),_r2=Z.strictObject({recipient:kr2,title:Z.string().min(1),body:Z.string().min(1),html:Z.string().min(1).optional(),sensitivity:Z.enum(["normal","secret"]).default("normal")}),QyA=Z.discriminatedUnion("status",[Z.strictObject({status:Z.literal("sent"),deliveryId:Z.string().optional()}),Z.strictObject({status:Z.literal("failed")})]);class wyA extends tQ{constructor(A={}){super("notifications",AyA,A,Lr2)}async onRegister(A){A.messaging.subscribe(Jv0,async(Q)=>{let w=_r2.parse(Q.payload),B={to:w.recipient.address,subject:w.title,text:w.body,...w.html?{html:w.html}:{},sensitivity:w.sensitivity},$=await A.messaging.send({type:l60,payload:B});if(!("success"in $)||!$.success||!$.data)return{success:!1,error:"Notification delivery failed"};let f=$.data;if(f.status!=="sent")return{success:!1,error:"Notification delivery failed"};return{success:!0,data:f.id?{status:"sent",deliveryId:f.id}:{status:"sent"}}})}}function p60(A={}){return new wyA(A)}wA();_0();var ByA={name:"@brains/auth-service",version:"0.2.0-alpha.150",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:"^6.0.3"},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 jr2=Z.union([Z.string().email(),Z.object({to:Z.string().email(),subject:Z.string().min(1),body:Z.string().min(1)}).strict()]),Pr2=Z.object({issuer:Z.string().optional(),trustedIssuers:Z.array(Z.string()).default([]),allowLocalhostIssuers:Z.boolean().optional(),storageDir:Z.string().default("./data/auth"),setupTokenTtlSeconds:Z.number().int().positive().default(kp),setupEmail:jr2.optional()}),i60;function M7(){return i60}class Iv0 extends tQ{service;constructor(A={}){super("auth-service",ByA,A,Pr2)}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 c60({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(),i60=this.service}async onReady(A){await this.requestSetupEmailIfNeeded(A)}async onShutdown(){if(i60===this.service)i60=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 B=Mr2(this.config.setupEmail,w);if(await Q.hasSetupEmailDelivery(w.setupTokenId,B.to))return;let $=await A.messaging.send({type:Jv0,payload:{recipient:{type:"email",address:B.to},title:B.subject,body:B.body,sensitivity:"secret"}});if(!("success"in $)||!$.success||!$.data){A.logger.warn("Passkey setup email delivery was not confirmed");return}let f=QyA.safeParse($.data);if(!f.success||f.data.status!=="sent"){A.logger.warn("Passkey setup email delivery was not confirmed");return}await Q.recordSetupEmailDelivery(w.setupTokenId,B.to,f.data.deliveryId?{deliveryId:f.data.deliveryId}:{})}}function Mr2(A,Q){if(typeof A==="string"){let w=new Date(Q.expiresAt*1000).toISOString(),B=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: ${B}/`,`MCP endpoint: ${B}/mcp`,"The first successful passkey registration completes setup and closes this link."].join(`
|
|
2296
|
-
`)}}return{to:A.to,subject:$yA(A.subject,Q),body:$yA(A.body,Q)}}function $yA(A,Q){let w=new Date(Q.expiresAt*1000).toISOString(),B=new URL(Q.setupUrl).origin;return A.replaceAll("{{setupUrl}}",Q.setupUrl).replaceAll("{{expiresAt}}",w).replaceAll("{{origin}}",B)}function _p(A={}){return new Iv0(A)}_0();var Fv0=Z.object({transport:Z.enum(["stdio","http"]).default("http"),mode:Z.enum(["basic","debug"]).default("basic"),httpPort:Z.number().describe("Port for HTTP transport (only used when transport is 'http')").default(3333),authToken:Z.string().describe("Bearer token for HTTP transport authentication").optional(),sessionIdleTtlMs:Z.number().describe("Idle time in ms after which an HTTP session is closed and evicted").default(1800000)});_0();function Or2(A){return typeof A==="object"&&A!==null&&!Array.isArray(A)}function Np(A,Q){let w=A?.[Q];return typeof w==="string"&&w.length>0?w:void 0}function xr2(A){let Q=Or2(A.data)?A.data:void 0,w=A.args,B=Np(Q,"entityId")??Np(Q,"id"),$=A.jobId??Np(Q,"jobId"),f=Np(w,"entityType")??Np(w,"type");if(!B&&!$)return;return{toolName:A.toolName,...f?{entityType:f}:{},...B?{entityId:B}:{},...$?{jobId:$}:{}}}function vr2(A){return A?.map(xr2).filter((Q)=>Q!==void 0)??[]}function Lv0(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 B=vr2(A.toolResults);return{success:!0,data:{text:A.text,...A.toolResults?{toolResults:A.toolResults}:{},...B.length>0?{readYourWrites:B}:{}}}}var fyA=Z.object({message:Z.string().min(1),conversationId:Z.string().min(1).optional()}),YyA=Z.object({approvalId:Z.string().min(1),confirmed:Z.boolean(),conversationId:Z.string().min(1).optional()});function XyA(A,Q,w,B){return A.conversationId??w??B??`mcp:${Q}`}function ZyA(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 HyA(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:fyA.shape,visibility:"public",sideEffects:"writes",handler:async(w,B)=>{let $=fyA.parse(w),f=Q();if(!f)return{success:!1,error:"MCP chat tool is not initialized."};let Y=XyA($,B.userId,B.conversationId,B.channelId),X=await f.agent.chat($.message,Y,{...ZyA(B)});return Lv0(X,{conversationId:Y})}},{name:"confirm",description:"Resolve a pending confirmation returned by chat. Use this only after chat returns needsConfirmation with an approvalId.",inputSchema:YyA.shape,visibility:"public",sideEffects:"writes",handler:async(w,B)=>{let $=YyA.parse(w),f=Q();if(!f)return{success:!1,error:"MCP confirm tool is not initialized."};let Y=XyA($,B.userId,B.conversationId,B.channelId),X=await f.agent.confirmPendingAction(Y,$.confirmed,$.approvalId,ZyA(B));return Lv0(X,{conversationId:Y})}}]}wA();function kv0(A,Q){A.messaging.subscribe("job-progress",async(w)=>{let B=IO.safeParse(w.payload);if(!B.success)return Q.warn("Received invalid job-progress message",{error:B.error.message}),{success:!1};let $=B.data,f=$.type,Y=$.status,X=$.id;if(Q.debug(`${f} ${X} - ${Y}:`,{id:$.id,message:$.message,progress:$.progress,metadata:$.metadata}),$.batchDetails)Q.debug(`Batch details for ${X}:`,{totalOperations:$.batchDetails.totalOperations,completedOperations:$.batchDetails.completedOperations,failedOperations:$.batchDetails.failedOperations,currentOperation:$.batchDetails.currentOperation,errors:$.batchDetails.errors});if($.jobDetails)Q.debug(`Job details for ${X}:`,{jobType:$.jobDetails.jobType,priority:$.jobDetails.priority,retryCount:$.jobDetails.retryCount});return{success:!0}}),Q.debug("Subscribed to job progress events")}var WyA={name:"@brains/mcp",version:"0.2.0-alpha.
|
|
2295
|
+
</html>`}function Lp(A){let Q=`${new URL(A.url).pathname}${new URL(A.url).search}`;return new Response(Gv0(Q,"Operator login required"),{status:401,headers:{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store"}})}function $D(A){return A.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""")}import{randomUUID as br2}from"crypto";function agA(A){return Buffer.from(JSON.stringify(A)).toString("base64url")}function Vr2(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 B=Q[w+1];if(B===void 0)throw Error("Invalid DER ECDSA signature");let $=w+2,f=Q.slice($,$+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 X=w+2,H=Q.slice(X,X+Y);return new Uint8Array([...tgA(f),...tgA(H)])}function tgA(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 zv0(A,Q){let w={typ:"JWT",alg:"ES256",kid:A.kid},B=`${agA(w)}.${agA(Q)}`,$=await crypto.subtle.importKey("jwk",A,{name:"ECDSA",namedCurve:"P-256"},!1,["sign"]),f=await crypto.subtle.sign({name:"ECDSA",hash:"SHA-256"},$,new TextEncoder().encode(B));return`${B}.${Buffer.from(Vr2(f)).toString("base64url")}`}var Jr2=600;class qv0{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 Lp(A);let w=await this.validateAuthorizationRequest(new URL(A.url).searchParams);if(!w.success)return new Response(w.error,{status:400});let B=this.createAuthorizationApprovalToken(Q,w.params);return Wh(sgA(w.params,B))}async handleAuthorizeApproval(A){let Q=await this.sessionStore.getSessionFromRequest(A);if(!Q)return Lp(A);let w=await A.formData(),B=await this.validateAuthorizationRequest(new URLSearchParams(Hv0(w)));if(!B.success)return new Response(B.error,{status:400});let $=w.get("approval_token"),f=typeof $==="string"?$:void 0;if(!f||!this.consumeAuthorizationApprovalToken(f,Q,B.params))return new Response("Invalid authorization approval token",{status:400});let Y=await this.authCodeStore.createCode({clientId:B.params.clientId,redirectUri:B.params.redirectUri,codeChallenge:B.params.codeChallenge,...B.params.scope?{scope:B.params.scope}:{},subject:Q.subject}),X=new URL(B.params.redirectUri);if(X.searchParams.set("code",Y.code),B.params.state)X.searchParams.set("state",B.params.state);return Response.redirect(X.toString(),302)}createAuthorizationApprovalToken(A,Q){this.pruneExpiredAuthorizationApprovalTokens();let w=`oat_${br2()}`;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)+Jr2}),w}consumeAuthorizationApprovalToken(A,Q,w){this.pruneExpiredAuthorizationApprovalTokens();let B=this.authorizationApprovalTokens.get(A);if(!B)return!1;return this.authorizationApprovalTokens.delete(A),B.sessionId===Q.id&&B.clientId===w.clientId&&B.redirectUri===w.redirectUri&&B.codeChallenge===w.codeChallenge&&B.scope===w.scope&&B.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"),B=A.get("redirect_uri"),$=A.get("code_challenge"),f=A.get("code_challenge_method"),Y=A.get("scope")??void 0,X=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(!B)return{success:!1,error:"Missing redirect_uri"};if(!$)return{success:!1,error:"Missing code_challenge"};if(f!=="S256")return{success:!1,error:"Unsupported code_challenge_method"};let H=await this.clientStore.getClient(w);if(!H)return{success:!1,error:"Unknown client_id"};if(!cP0(H.redirect_uris,B))return{success:!1,error:"Unregistered redirect_uri"};let W=Y??H.scope;return{success:!0,params:{clientId:w,redirectUri:B,codeChallenge:$,...W?{scope:W}:{},...X?{state:X}:{},clientName:H.client_name??H.client_id}}}async handleClientRegistration(A){let Q;try{Q=await A.json()}catch{return o$("invalid_client_metadata","Request body must be JSON")}try{let w=await this.clientStore.registerClient(Q);return sX(w,201)}catch(w){if(w instanceof gc)return o$("invalid_client_metadata",w.message);throw w}}async handleTokenRequest(A,Q){let w=await Zv0(A),B=w.get("grant_type"),$=Kv0(A,w),f=$.clientId??w.get("client_id");if($.error)return o$("invalid_client",$.error);if(!f)return o$("invalid_request","client_id is required");let Y=await this.clientStore.getClient(f),X=Wv0(Y,$);if(X)return o$("invalid_client",X);if(B==="authorization_code")return this.handleAuthorizationCodeGrant(w,f,Q);if(B==="refresh_token")return this.handleRefreshTokenGrant(w,f,Q);return o$("unsupported_grant_type","Only authorization_code and refresh_token are supported")}async handleAuthorizationCodeGrant(A,Q,w){let B=A.get("code"),$=A.get("redirect_uri"),f=A.get("code_verifier");if(!B||!$||!f)return o$("invalid_request","code, redirect_uri, and code_verifier are required");let Y=await this.clientStore.getClient(Q);if(!Y||!cP0(Y.redirect_uris,$))return o$("invalid_grant","Unregistered redirect_uri");try{let X=await this.authCodeStore.consumeCode({code:B,clientId:Q,redirectUri:$,codeVerifier:f});return await this.createTokenResponse({issuer:w,clientId:Q,subject:X.subject,...X.scope?{scope:X.scope}:{}})}catch(X){if(X instanceof hK)return o$("invalid_grant",X.message);throw X}}async handleRefreshTokenGrant(A,Q,w){let B=A.get("refresh_token");if(!B)return o$("invalid_request","refresh_token is required");try{let $=await this.refreshTokenStore.rotateToken(B,Q);return await this.createTokenResponse({issuer:w,clientId:Q,subject:$.consumed.subject,...$.consumed.scope?{scope:$.consumed.scope}:{},refreshToken:$.replacement.token})}catch($){if($ instanceof Yq)return o$("invalid_grant",$.message);throw $}}async createTokenResponse(A){let Q=Math.floor(Date.now()/1000),w=900,B=await zv0(await this.keyStore.getPrivateJwk(),{iss:A.issuer,sub:A.subject,aud:A.clientId,iat:Q,exp:Q+900,...A.scope?{scope:A.scope}:{}}),$=A.refreshToken??(await this.refreshTokenStore.issueToken({clientId:A.clientId,subject:A.subject,...A.scope?{scope:A.scope}:{}})).token;return sX({access_token:B,token_type:"Bearer",expires_in:900,...A.scope?{scope:A.scope}:{},refresh_token:$})}async handleRevokeRequest(A){let Q=await Zv0(A),w=Kv0(A,Q),B=w.clientId??Q.get("client_id")??void 0,$=Q.get("token");if(w.error)return o$("invalid_client",w.error);if(!$)return o$("invalid_request","token is required");if(B){let f=await this.clientStore.getClient(B),Y=Wv0(f,w);if(Y)return o$("invalid_client",Y)}return await this.refreshTokenStore.revokeToken($,B),new Response(null,{status:200})}}class Vv0{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 o$("access_denied","Passkey setup already completed");if(!this.setupFlow.hasValidSetupToken(A))return o$("access_denied","Invalid setup token");let Q=await this.passkeyService.generateRegistrationOptions(u60(A));return sX(Q)}async handleRegistrationVerify(A){if(await this.passkeyService.hasCredentials())return o$("access_denied","Passkey setup already completed");if(!this.setupFlow.hasValidSetupToken(A))return o$("access_denied","Invalid setup token");let Q=await this.passkeyService.verifyRegistrationResponse(await A.json(),u60(A));if(!Q.verified)return o$("access_denied","Passkey registration failed");await this.setupFlow.clearSetupState();let w=await this.sessionStore.createSession(Q.subject??"single-operator",{secure:bp(A)});return sX({verified:!0},200,{"Set-Cookie":w.cookie})}async handleAuthenticationOptions(A){if(!await this.passkeyService.hasCredentials())return o$("access_denied","No passkey registered");let Q=await this.passkeyService.generateAuthenticationOptions(u60(A));return sX(Q)}async handleAuthenticationVerify(A){let Q=await this.passkeyService.verifyAuthenticationResponse(await A.json(),u60(A));if(!Q.verified)return o$("access_denied","Passkey authentication failed");let w=await this.sessionStore.createSession(Q.subject??"single-operator",{secure:bp(A)});return sX({verified:!0},200,{"Set-Cookie":w.cookie})}}function u60(A){let Q=Bh(A),w=new URL(Q);return{origin:w.origin,rpID:w.hostname}}import{randomUUID as Ir2}from"crypto";var kp=86400;class bv0{setupStateStore;passkeyService;setupTokenTtlSeconds;setupToken;constructor(A){this.setupStateStore=A.setupStateStore,this.passkeyService=A.passkeyService,this.setupTokenTtlSeconds=A.setupTokenTtlSeconds??kp}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_${Ir2()}`,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 pK(A,`/setup?token=${encodeURIComponent(Q.token)}`)}async getOperatorSetupRequired(A){if(await this.passkeyService.hasCredentials())return;let Q=this.getValidSetupToken();if(!Q)return;return{setupUrl:pK(A,`/setup?token=${encodeURIComponent(Q.token)}`),expiresAt:Q.expiresAt,setupTokenId:cx0(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 Wh(rgA(Q))}async hasSetupEmailDelivery(A,Q){return this.setupStateStore.hasDelivery(A,Q)}async recordSetupEmailDelivery(A,Q,w={}){await this.setupStateStore.recordDelivery(A,Q,w)}}class c60{issuer;trustedIssuers;allowLocalhostIssuers;keyStore;a2aKeyStore;clientStore;authCodeStore;sessionStore;peerTrustStore;passkeyService;setupFlow;oauthEndpoints;webauthnEndpoints;logger;constructor(A){this.issuer=lK(A.issuer),this.trustedIssuers=new Set([this.issuer,...(A.trustedIssuers??[]).map((Q)=>lK(Q))]),this.allowLocalhostIssuers=A.allowLocalhostIssuers??wh(this.issuer),this.keyStore=new ww0({storageDir:A.storageDir}),this.a2aKeyStore=new lP0({storageDir:A.storageDir}),this.clientStore=new Qw0({storageDir:A.storageDir}),this.authCodeStore=new Aw0({storageDir:A.storageDir}),this.sessionStore=new y60({storageDir:A.storageDir}),this.peerTrustStore=new R60({storageDir:A.storageDir}),this.passkeyService=new v60({storageDir:A.storageDir,...A.logger?{logger:A.logger}:{}}),this.setupFlow=new bv0({setupStateStore:new lx0({storageDir:A.storageDir}),passkeyService:this.passkeyService,setupTokenTtlSeconds:A.setupTokenTtlSeconds??kp}),this.oauthEndpoints=new qv0({clientStore:this.clientStore,authCodeStore:this.authCodeStore,refreshTokenStore:new h60({storageDir:A.storageDir}),sessionStore:this.sessionStore,keyStore:this.keyStore}),this.webauthnEndpoints=new Vv0({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(wh(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:pK(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=lK(A);return{issuer:Q,authorization_endpoint:pK(Q,"/authorize"),token_endpoint:pK(Q,"/token"),registration_endpoint:pK(Q,"/register"),revocation_endpoint:pK(Q,"/revoke"),jwks_uri:pK(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:[lK(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 Lp(A)}async verifyBearerToken(A,Q={}){let w=Xv0(A);if(!w)return;let B=Q.issuer?lK(Q.issuer):this.resolveRequestIssuer(A);return Yv0(w,await this.getJwks(),{issuer:B,...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(B){return this.logger?.warn("Rejected OAuth request from untrusted issuer",{error:B instanceof Error?B.message:String(B)}),new Response("Untrusted OAuth issuer",{status:400})}let w=new URL(A.url).pathname;if(A.method==="OPTIONS"&&igA(w))return dgA();if(A.method==="GET"){if(w==="/.well-known/oauth-authorization-server")return dJ(sX(this.getAuthorizationServerMetadata(Q)));if(w==="/.well-known/jwks.json")return dJ(sX(await this.getJwks()));if(w==="/.well-known/oauth-protected-resource")return dJ(sX(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 dJ(await this.oauthEndpoints.handleClientRegistration(A));if(A.method==="POST"&&w==="/token")return dJ(await this.oauthEndpoints.handleTokenRequest(A,Q));if(A.method==="POST"&&w==="/revoke")return dJ(await this.oauthEndpoints.handleRevokeRequest(A));return new Response("Not Found",{status:404})}async handleWellKnownRequest(A){return this.handleRequest(A)}resolveRequestIssuer(A){let Q=Bh(A,this.issuer);if(this.trustedIssuers.has(Q)||this.allowLocalhostIssuers&&wh(Q))return Q;throw Error(`Request issuer ${Q} is not in trusted issuers`)}handleLoginPage(A){let Q=Uv0(new URL(A.url).searchParams.get("return_to"));return Wh(Gv0(Q))}async handleLogout(A){await this.sessionStore.revokeSessionFromRequest(A);let Q=Uv0(new URL(A.url).searchParams.get("return_to"));return new Response(null,{status:302,headers:{Location:Q,"Set-Cookie":ix0(bp(A)),"Cache-Control":"no-store"}})}}_0();var l60="email:send",egA=Z.strictObject({to:Z.string().email(),subject:Z.string().min(1),text:Z.string().min(1),html:Z.string().min(1).optional(),sensitivity:Z.enum(["normal","secret"]).default("normal")});wA();_0();var AyA={name:"@brains/notifications",version:"0.2.0-alpha.151",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 Jv0="notifications:send",Lr2=Z.looseObject({}),kr2=Z.discriminatedUnion("type",[Z.strictObject({type:Z.literal("email"),address:Z.email()})]),_r2=Z.strictObject({recipient:kr2,title:Z.string().min(1),body:Z.string().min(1),html:Z.string().min(1).optional(),sensitivity:Z.enum(["normal","secret"]).default("normal")}),QyA=Z.discriminatedUnion("status",[Z.strictObject({status:Z.literal("sent"),deliveryId:Z.string().optional()}),Z.strictObject({status:Z.literal("failed")})]);class wyA extends tQ{constructor(A={}){super("notifications",AyA,A,Lr2)}async onRegister(A){A.messaging.subscribe(Jv0,async(Q)=>{let w=_r2.parse(Q.payload),B={to:w.recipient.address,subject:w.title,text:w.body,...w.html?{html:w.html}:{},sensitivity:w.sensitivity},$=await A.messaging.send({type:l60,payload:B});if(!("success"in $)||!$.success||!$.data)return{success:!1,error:"Notification delivery failed"};let f=$.data;if(f.status!=="sent")return{success:!1,error:"Notification delivery failed"};return{success:!0,data:f.id?{status:"sent",deliveryId:f.id}:{status:"sent"}}})}}function p60(A={}){return new wyA(A)}wA();_0();var ByA={name:"@brains/auth-service",version:"0.2.0-alpha.151",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 jr2=Z.union([Z.string().email(),Z.object({to:Z.string().email(),subject:Z.string().min(1),body:Z.string().min(1)}).strict()]),Pr2=Z.object({issuer:Z.string().optional(),trustedIssuers:Z.array(Z.string()).default([]),allowLocalhostIssuers:Z.boolean().optional(),storageDir:Z.string().default("./data/auth"),setupTokenTtlSeconds:Z.number().int().positive().default(kp),setupEmail:jr2.optional()}),i60;function M7(){return i60}class Iv0 extends tQ{service;constructor(A={}){super("auth-service",ByA,A,Pr2)}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 c60({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(),i60=this.service}async onReady(A){await this.requestSetupEmailIfNeeded(A)}async onShutdown(){if(i60===this.service)i60=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 B=Mr2(this.config.setupEmail,w);if(await Q.hasSetupEmailDelivery(w.setupTokenId,B.to))return;let $=await A.messaging.send({type:Jv0,payload:{recipient:{type:"email",address:B.to},title:B.subject,body:B.body,sensitivity:"secret"}});if(!("success"in $)||!$.success||!$.data){A.logger.warn("Passkey setup email delivery was not confirmed");return}let f=QyA.safeParse($.data);if(!f.success||f.data.status!=="sent"){A.logger.warn("Passkey setup email delivery was not confirmed");return}await Q.recordSetupEmailDelivery(w.setupTokenId,B.to,f.data.deliveryId?{deliveryId:f.data.deliveryId}:{})}}function Mr2(A,Q){if(typeof A==="string"){let w=new Date(Q.expiresAt*1000).toISOString(),B=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: ${B}/`,`MCP endpoint: ${B}/mcp`,"The first successful passkey registration completes setup and closes this link."].join(`
|
|
2296
|
+
`)}}return{to:A.to,subject:$yA(A.subject,Q),body:$yA(A.body,Q)}}function $yA(A,Q){let w=new Date(Q.expiresAt*1000).toISOString(),B=new URL(Q.setupUrl).origin;return A.replaceAll("{{setupUrl}}",Q.setupUrl).replaceAll("{{expiresAt}}",w).replaceAll("{{origin}}",B)}function _p(A={}){return new Iv0(A)}_0();var Fv0=Z.object({transport:Z.enum(["stdio","http"]).default("http"),mode:Z.enum(["basic","debug"]).default("basic"),httpPort:Z.number().describe("Port for HTTP transport (only used when transport is 'http')").default(3333),authToken:Z.string().describe("Bearer token for HTTP transport authentication").optional(),sessionIdleTtlMs:Z.number().describe("Idle time in ms after which an HTTP session is closed and evicted").default(1800000)});_0();function Or2(A){return typeof A==="object"&&A!==null&&!Array.isArray(A)}function Np(A,Q){let w=A?.[Q];return typeof w==="string"&&w.length>0?w:void 0}function xr2(A){let Q=Or2(A.data)?A.data:void 0,w=A.args,B=Np(Q,"entityId")??Np(Q,"id"),$=A.jobId??Np(Q,"jobId"),f=Np(w,"entityType")??Np(w,"type");if(!B&&!$)return;return{toolName:A.toolName,...f?{entityType:f}:{},...B?{entityId:B}:{},...$?{jobId:$}:{}}}function vr2(A){return A?.map(xr2).filter((Q)=>Q!==void 0)??[]}function Lv0(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 B=vr2(A.toolResults);return{success:!0,data:{text:A.text,...A.toolResults?{toolResults:A.toolResults}:{},...B.length>0?{readYourWrites:B}:{}}}}var fyA=Z.object({message:Z.string().min(1),conversationId:Z.string().min(1).optional()}),YyA=Z.object({approvalId:Z.string().min(1),confirmed:Z.boolean(),conversationId:Z.string().min(1).optional()});function XyA(A,Q,w,B){return A.conversationId??w??B??`mcp:${Q}`}function ZyA(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 HyA(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:fyA.shape,visibility:"public",sideEffects:"writes",handler:async(w,B)=>{let $=fyA.parse(w),f=Q();if(!f)return{success:!1,error:"MCP chat tool is not initialized."};let Y=XyA($,B.userId,B.conversationId,B.channelId),X=await f.agent.chat($.message,Y,{...ZyA(B)});return Lv0(X,{conversationId:Y})}},{name:"confirm",description:"Resolve a pending confirmation returned by chat. Use this only after chat returns needsConfirmation with an approvalId.",inputSchema:YyA.shape,visibility:"public",sideEffects:"writes",handler:async(w,B)=>{let $=YyA.parse(w),f=Q();if(!f)return{success:!1,error:"MCP confirm tool is not initialized."};let Y=XyA($,B.userId,B.conversationId,B.channelId),X=await f.agent.confirmPendingAction(Y,$.confirmed,$.approvalId,ZyA(B));return Lv0(X,{conversationId:Y})}}]}wA();function kv0(A,Q){A.messaging.subscribe("job-progress",async(w)=>{let B=IO.safeParse(w.payload);if(!B.success)return Q.warn("Received invalid job-progress message",{error:B.error.message}),{success:!1};let $=B.data,f=$.type,Y=$.status,X=$.id;if(Q.debug(`${f} ${X} - ${Y}:`,{id:$.id,message:$.message,progress:$.progress,metadata:$.metadata}),$.batchDetails)Q.debug(`Batch details for ${X}:`,{totalOperations:$.batchDetails.totalOperations,completedOperations:$.batchDetails.completedOperations,failedOperations:$.batchDetails.failedOperations,currentOperation:$.batchDetails.currentOperation,errors:$.batchDetails.errors});if($.jobDetails)Q.debug(`Job details for ${X}:`,{jobType:$.jobDetails.jobType,priority:$.jobDetails.priority,retryCount:$.jobDetails.retryCount});return{success:!0}}),Q.debug("Subscribed to job progress events")}var WyA={name:"@brains/mcp",version:"0.2.0-alpha.151",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 nJ extends _G{mcpTransport;stdioServer;httpServer;domain;constructor(A={}){let Q={...A,authToken:A.authToken??process.env.MCP_AUTH_TOKEN};super("mcp",WyA,Q,Fv0)}async getTools(){return HyA(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"});kv0(A,this.logger)}getOrCreateHttpServer(){if(this.httpServer)return this.httpServer;let A=M7();return this.httpServer=yz.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),B=M7(),$=this.config.transport==="http"&&(this.config.authToken?!0:B!==void 0);if($)w="anchor",this.logger.debug("HTTP authentication configured - authenticated users will have anchor permissions");if(this.config.mode==="debug"){if(this.config.transport==="http"&&!$)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=RK.createFresh();let f=this.mcpTransport.getMcpServer();this.stdioServer.connectMCPServer(f),await this.stdioServer.start(),this.logger.debug("MCP STDIO transport started")}else{this.httpServer=this.getOrCreateHttpServer();let f=this.mcpTransport.getMcpServer();this.httpServer.connectMCPServer(f,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(){RK.resetInstance(),yz.resetInstance()}}wA();function jp(A,Q=2000){if(A.length<=Q)return[A];let w=gr2(A),B=[],$="";for(let f of w){let Y=$?`
|
|
2297
2297
|
|
|
2298
2298
|
`:"";if($.length+Y.length+f.length<=Q){$+=Y+f;continue}if($)B.push($),$="";if(f.length<=Q){$=f;continue}hr2(f,Q,B,(X)=>{$=X})}if($)B.push($);return B}function hr2(A,Q,w,B){let $="",f=A.split(`
|
|
2299
2299
|
`);for(let Y of f){let X=$?`
|
|
2300
2300
|
`:"";if($.length+X.length+Y.length<=Q){$+=X+Y;continue}if($)w.push($),$="";if(Y.length<=Q){$=Y;continue}Cr2(Y,Q,w,(H)=>{$=H})}B($)}function Cr2(A,Q,w,B){let $="",f=A.split(" ");for(let Y of f){let X=$?" ":"";if($.length+X.length+Y.length<=Q){$+=X+Y;continue}if($)w.push($);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)$=W;else w.push(W)}else $=Y}B($)}function gr2(A){let Q=[],w=A.split(`
|
|
2301
2301
|
`),B="",$=!1;for(let f of w){if(f.startsWith("```"))$=!$;if(!$&&f===""&&B){Q.push(B),B="";continue}B+=(B?`
|
|
2302
|
-
`:"")+f}if(B)Q.push(B);return Q}U2();var fZ=Z1(ST0(),1);wA();_0();var mT0=Z.object({botToken:Z.string().min(1).describe("Discord bot token"),allowedChannels:Z.array(Z.string()).default([]),requireMention:Z.boolean().default(!0),allowDMs:Z.boolean().default(!0),showTypingIndicator:Z.boolean().default(!0),statusMessage:Z.string().default("Mention me to chat"),useThreads:Z.boolean().default(!0),threadAutoArchive:Z.union([Z.literal(60),Z.literal(1440),Z.literal(4320),Z.literal(10080)]).default(1440),...Ym.shape,captureUrlEmoji:Z.string().default("\uD83D\uDD16")});var Lz1={name:"@brains/discord",version:"0.2.0-alpha.
|
|
2302
|
+
`:"")+f}if(B)Q.push(B);return Q}U2();var fZ=Z1(ST0(),1);wA();_0();var mT0=Z.object({botToken:Z.string().min(1).describe("Discord bot token"),allowedChannels:Z.array(Z.string()).default([]),requireMention:Z.boolean().default(!0),allowDMs:Z.boolean().default(!0),showTypingIndicator:Z.boolean().default(!0),statusMessage:Z.string().default("Mention me to chat"),useThreads:Z.boolean().default(!0),threadAutoArchive:Z.union([Z.literal(60),Z.literal(1440),Z.literal(4320),Z.literal(10080)]).default(1440),...Ym.shape,captureUrlEmoji:Z.string().default("\uD83D\uDD16")});var Lz1={name:"@brains/discord",version:"0.2.0-alpha.151",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 Kd=2000,WMQ={completed:"Action completed",declined:"Action declined",failed:"Action failed"},KMQ={completed:2278750,declined:9741240,failed:15680580},UMQ=8388608,GMQ=8000,DMQ=100;function K80(A){return!!A&&typeof A==="object"&&"send"in A&&"sendTyping"in A}class RI extends WK{client=null;fetchText;pendingConfirmations=new Map;typingIntervals=new Map;constructor(A,Q={}){super("discord",Lz1,A,mT0);this.fetchText=Q.fetchText??KLA}async onRegister(A){await super.onRegister(A),this.client=new fZ.Client({intents:[fZ.GatewayIntentBits.Guilds,fZ.GatewayIntentBits.GuildMessages,fZ.GatewayIntentBits.MessageContent,fZ.GatewayIntentBits.DirectMessages],partials:[fZ.Partials.Channel]}),this.client.on(fZ.Events.MessageCreate,(Q)=>{this.handleMessage(Q)}),this.client.on(fZ.Events.InteractionCreate,(Q)=>{this.handleInteraction(Q)}),this.client.once(fZ.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(!K80(w))return;let B=jp(Q,Kd);for(let $ of B)w.send($).catch((f)=>this.logger.error("Failed to send message",{error:f}))}async sendMessageWithId({channelId:A,message:Q,approvalCard:w,approvalCards:B}){let $=B??(w?[w]:[]),f=$.length>0?this.buildApprovalMessagePayload(Q,$):Q;return this.sendPayloadWithId(A,f)}async sendPayloadWithId(A,Q){if(!A||!this.client)return;let w=this.client.channels.cache.get(A);if(!K80(w))return;if(typeof Q!=="string")return(await w.send(Q)).id;let B=jp(Q,Kd),$;for(let f of B)$=(await w.send(f)).id;return $}async editMessage({channelId:A,messageId:Q,newMessage:w}){if(!A||!this.client)return!1;let B=this.client.channels.cache.get(A);if(!K80(B))return!1;try{return await(await B.messages.fetch(Q)).edit(w.slice(0,Kd)),!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 B=!!this.client?.user&&A.mentions.has(this.client.user,{ignoreEveryone:!0});if(A.author.bot&&!B)return;let $=w&&"ownerId"in A.channel&&A.channel.ownerId===this.client?.user?.id,f=this.getSpaceChannelId(A),Y=!Q&&this.isConfiguredSpace(f),X={channelId:f,isBot:A.author.bot};if(this.config.allowedChannels.length>0&&!Q&&!this.isAllowedChannel(A.channel.id,f))return;let H=Q||$||!this.config.requireMention||B;if(Y&&(!H||this.willRouteUseNonSpaceConversation(A)))await this.capturePassiveSpaceMessage(A,f).catch((U)=>this.logger.error("Passive Discord space capture failed",{error:U,channelId:f}));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",X).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,X);if(U==="anchor"||U==="trusted")for(let q of A.attachments.values()){let V=q.name,J=q.contentType??void 0,b=q.size;if(!this.isUploadableTextFile(V,J))continue;if(!this.isFileSizeAllowed(b))continue;try{let L=await this.fetchText(q.url);W+=`
|
|
2303
2303
|
|
|
2304
2304
|
`+this.formatFileUploadMessage(V,L)}catch(L){this.logger.error("Failed to download attachment",{error:L,filename:V})}}}if(W=W.trim(),!W)return;let K=A.channel.id;await this.routeToAgent(W,K,A,X)}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 $=this.buildInteractionConfirmationContext(A),f=await this.context.agent.confirmPendingAction(w,Q.confirmed,Q.approvalId,$);await this.handleAgentResponseToolStatuses(f,w),this.syncPendingApprovalsAfterResolution(w,Q.approvalId,f),await this.sendApprovalResultMessage({channelId:A.channelId,response:f,userPermissionLevel:$.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 B=`discord-${Q}`,$=this.getChannelName(A);await this.context.conversations.start({sessionId:B,interfaceType:"discord",channelId:Q,metadata:{channelName:$,interfaceType:"discord",channelId:Q}}),await this.context.conversations.addMessage({conversationId:B,role:"user",content:w,metadata:this.buildUserMessageMetadata(A,Q,$,{threadId:A.channel.isThread()?A.channel.id:void 0})})}async routeToAgent(A,Q,w,B){if(!this.context)return;let $=this.context.agent,f=Q;if(this.config.useThreads&&w.guild&&!w.channel.isThread())try{f=(await w.startThread({name:zf(A,DMQ),autoArchiveDuration:this.config.threadAutoArchive})).id}catch(W){this.logger.error("Failed to create thread",{error:W})}let Y=`discord-${f}`,X=this.context.permissions.getUserLevel("discord",w.author.id,B),H=this.getChannelName(w);this.startProcessingInput(f);try{let W=this.client?.channels.cache.get(f);if(K80(W))this.startTypingIndicator(W);if(this.pendingConfirmations.has(Y)){if(await this.handleConfirmationResponse(A,Y,f,w,B))return}let K=await $.chat(A,Y,{userPermissionLevel:X,interfaceType:"discord",channelId:f,channelName:H,...this.buildUserMessageMetadata(w,Q,H,{threadId:f!==Q||w.channel.isThread()?f:void 0})});await this.handleAgentResponseToolStatuses(K,Y);let U=Fk(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:f,message:Bx(K.text,U),approvalCards:U});if(G&&K.toolResults){for(let q of K.toolResults)if(q.jobId)this.trackAgentResponseForJob(q.jobId,G,f)}}catch(W){this.logger.error("Error handling message",{error:W,channelId:f}),this.sendMessageToChannel({channelId:f,message:`**Error:** ${W instanceof Error?W.message:"Unknown error"}`})}finally{this.endProcessingInput(),this.stopTypingIndicator(f)}}buildApprovalMessagePayload(A,Q){let w=Q.length>1;return{content:zf(A.trim().length>0?`${A}
|
|
2305
2305
|
|
|
@@ -2369,7 +2369,7 @@ ${A.value}
|
|
|
2369
2369
|
`);if(z80(A))return this.renderList(A,0,(Q)=>this.nodeToDiscordMarkdown(Q));if(A.type==="break")return`
|
|
2370
2370
|
`;if(A.type==="thematicBreak")return"---";if(aS0(A))return`\`\`\`
|
|
2371
2371
|
${tS0(A)}
|
|
2372
|
-
\`\`\``;return this.defaultNodeToText(A,(Q)=>this.nodeToDiscordMarkdown(Q))}};var cj1={DeferredChannelMessageWithSource:5,DeferredUpdateMessage:6},j80="https://discord.com/api/v10",lj1=2000,rgQ=/^[0-9a-f]{64}$/,ogQ=/^[0-9a-f]+$/,sgQ=class A{name="discord";userName;botUserId;apiBaseUrl;botToken;publicKey;applicationId;mentionRoleIds;interactionFlags;chat=null;logger;formatConverter=new ngQ;requestContext=new EgQ;threadParentCache=new Map;static THREAD_PARENT_CACHE_TTL=300000;constructor(Q={}){let w=Q.botToken??process.env.DISCORD_BOT_TOKEN;if(!w)throw new WW("discord","botToken is required. Set DISCORD_BOT_TOKEN or provide it in config.");let B=Q.publicKey??process.env.DISCORD_PUBLIC_KEY;if(!B)throw new WW("discord","publicKey is required. Set DISCORD_PUBLIC_KEY or provide it in config.");let $=Q.applicationId??process.env.DISCORD_APPLICATION_ID;if(!$)throw new WW("discord","applicationId is required. Set DISCORD_APPLICATION_ID or provide it in config.");if(this.apiBaseUrl=Q.apiUrl??process.env.DISCORD_API_URL??j80,this.botToken=w,this.publicKey=B.trim().toLowerCase(),this.applicationId=$,this.mentionRoleIds=Q.mentionRoleIds??(process.env.DISCORD_MENTION_ROLE_IDS?process.env.DISCORD_MENTION_ROLE_IDS.split(",").map((f)=>f.trim()):[]),this.botUserId=$,this.interactionFlags=Q.interactionFlags,this.logger=Q.logger??new L80("info").child("discord"),this.userName=Q.userName??"bot",!rgQ.test(this.publicKey))this.logger.error("Invalid Discord public key format",{length:this.publicKey.length,isHex:ogQ.test(this.publicKey)})}async initialize(Q){this.chat=Q,this.logger.info("Discord adapter initialized")}async getUser(Q){try{let B=await(await this.discordFetch(`/users/${Q}`,"GET")).json();return{avatarUrl:B.avatar?`https://cdn.discordapp.com/avatars/${B.id}/${B.avatar}.png`:void 0,email:void 0,fullName:B.global_name||B.username,isBot:B.bot??!1,userId:B.id,userName:B.username}}catch{return null}}async handleWebhook(Q,w){let B=await Q.arrayBuffer(),$=new Uint8Array(B),f=new TextDecoder().decode($),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(f);return this.handleForwardedGatewayEvent(U,w)}catch{return new Response("Invalid JSON",{status:400})}}this.logger.info("Discord webhook received",{bodyLength:f.length,bodyBytesLength:$.length,hasSignature:!!Q.headers.get("x-signature-ed25519"),hasTimestamp:!!Q.headers.get("x-signature-timestamp")});let X=Q.headers.get("x-signature-ed25519"),H=Q.headers.get("x-signature-timestamp");if(!await this.verifySignature($,X,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(f)}catch{return new Response("Invalid JSON",{status:400})}if(this.logger.info("Discord interaction parsed",{type:K.type,typeIsPing:K.type===NC.Ping,expectedPingType:NC.Ping,id:K.id}),K.type===NC.Ping){let U=JSON.stringify({type:kd.InteractionResponseType.PONG});return this.logger.info("Discord PING received, responding with PONG",{responseBody:U,responseType:kd.InteractionResponseType.PONG}),new Response(U,{status:200,headers:{"Content-Type":"application/json"}})}if(K.type===NC.MessageComponent)return this.handleComponentInteraction(K,w),this.respondToInteraction({type:cj1.DeferredUpdateMessage});if(K.type===NC.ApplicationCommand){let U=this.getApplicationCommandContext(K),G=this.getInteractionFlags(U);return this.handleApplicationCommandInteraction(U,w),this.respondToInteraction({...G===void 0?{}:{data:{flags:G}},type:cj1.DeferredChannelMessageWithSource})}return new Response("Unknown interaction type",{status:400})}async verifySignature(Q,w,B){if(!(w&&B))return this.logger.warn("Discord signature verification failed: missing headers",{hasSignature:!!w,hasTimestamp:!!B}),!1;try{this.logger.info("Discord signature verification attempt",{bodyBytesLength:Q.length,signatureLength:w.length,timestampLength:B.length,publicKeyLength:this.publicKey.length,timestamp:B,signaturePrefix:w.slice(0,16),publicKey:this.publicKey});let $=await kd.verifyKey(Q,w,B,this.publicKey);if(!$){let f=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:B,bodyLength:Q.length,bodyPrefix:f.slice(0,50)})}return $}catch($){return this.logger.warn("Discord signature verification failed: exception",{error:$}),!1}}respondToInteraction(Q){return Response.json(Q)}handleComponentInteraction(Q,w){if(!this.chat){this.logger.warn("Chat instance not initialized, ignoring interaction");return}let B=Q.data?.custom_id;if(!B){this.logger.warn("No custom_id in component interaction");return}let $=Q.member?.user||Q.user;if(!$){this.logger.warn("No user in component interaction");return}let f=Q.channel_id,Y=Q.guild_id||"@me",X=Q.message?.id;if(!(f&&X)){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:f,U=W?this.encodeThreadId({guildId:Y,channelId:K,threadId:f}):this.encodeThreadId({guildId:Y,channelId:f}),G=SgQ(B),q={actionId:G.actionId,value:G.value??G.actionId,user:{userId:$.id,userName:$.username,fullName:$.global_name||$.username,isBot:$.bot??!1,isMe:!1},messageId:X,threadId:U,adapter:this,raw:Q};this.logger.debug("Processing Discord button action",{actionId:B,messageId:X,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 B=Q.member?.user||Q.user;if(!B)return this.logger.warn("No user in application command interaction"),null;let $=Q.channel_id;if(!$)return this.logger.warn("Missing channel_id in application command interaction"),null;let f=Q.guild_id||"@me",Y=Q.channel,X=Y?.type===11||Y?.type===12,H=X&&Y?.parent_id?Y.parent_id:$,W=X?this.encodeThreadId({guildId:f,channelId:H,threadId:$}):this.encodeThreadId({guildId:f,channelId:$}),{command:K,text:U}=this.parseSlashCommand(w,Q.data?.options);return{channelId:W,command:K,interaction:Q,text:U,user:B}}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:B,command:$,interaction:f,text:Y,user:X}=Q;this.logger.debug("Processing Discord slash command",{command:$,text:Y,userId:X.id,channelId:B}),this.requestContext.run({slashCommand:{channelId:B,interactionToken:f.token,initialResponseSent:!1}},()=>{this.chat?.processSlashCommand({command:$,text:Y,user:{userId:X.id,userName:X.username,fullName:X.global_name||X.username,isBot:X.bot??!1,isMe:X.id===this.applicationId},adapter:this,raw:f,channelId:B},w)})}parseSlashCommand(Q,w){let B=[Q.startsWith("/")?Q:`/${Q}`],$=[],f=(Y)=>{for(let X of Y){if(X.value!==void 0){$.push(String(X.value));continue}if(X.options&&X.options.length>0)B.push(X.name),f(X.options)}};if(w&&w.length>0)f(w);return{command:B.join(" "),text:$.join(" ").trim()}}async handleGatewayInteraction(Q){if(Q.isChatInputCommand()){let w=this.getApplicationCommandContext(this.normalizeGatewaySlashCommandInteraction(Q)),B=this.getInteractionFlags(w);await Q.deferReply(B===void 0?void 0:{flags:B}),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 B=Q.guild_id||"@me",$=Q.channel_id,f,Y=$;if(Q.thread)f=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/${$}`,"GET")).json();if(q.parent_id)f=$,Y=q.parent_id,this.logger.debug("Fetched thread parent for forwarded message",{threadId:$,parentId:q.parent_id})}catch(G){this.logger.error("Failed to fetch thread parent",{error:String(G),channelId:$})}let X=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=X||H;if(!f&&W)try{let G=await this.createDiscordThread($,Q.id);f=G.id,this.logger.debug("Created Discord thread for forwarded mention",{channelId:$,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:B,channelId:Y,threadId:f}),U=new p5({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,B){if(!this.chat)return;let $=Q.guild_id||"@me",f=Q.channel_id,Y,X=f;if(Q.channel_type===rN.GuildPublicThread||Q.channel_type===rN.GuildPrivateThread){let q=this.threadParentCache.get(f);if(q&&q.expiresAt>Date.now())Y=f,X=q.parentId;else try{let J=await(await this.discordFetch(`/channels/${f}`,"GET")).json();if(J.parent_id)Y=f,X=J.parent_id,this.threadParentCache.set(f,{parentId:J.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:f})}}let H=this.encodeThreadId({guildId:$,channelId:X,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:B,threadId:$}=this.decodeThreadId(Q),f=Q;if($)B=$;let Y={},X=[],H=[],W=N80(w);if(W){let V=Em0(W);X.push(...V.embeds),H.push(...V.components)}else Y.content=this.truncateContent(pN(this.formatConverter.renderPostable(w),"discord"));if(X.length>0)Y.embeds=X;if(H.length>0)Y.components=H;let K=zm0(w),U=this.tryPostSlashResponse(f,Y,K);if(U)return U;if(K.length>0)return this.postMessageWithFiles(B,f,Y,K);this.logger.debug("Discord API: POST message",{channelId:B,contentLength:Y.content?.length||0,embedCount:X.length,componentCount:H.length});let q=await(await this.discordFetch(`/channels/${B}/messages`,"POST",Y)).json();return this.logger.debug("Discord API: POST message response",{messageId:q.id}),{id:q.id,threadId:f,raw:q}}tryPostSlashResponse(Q,w,B){let $=this.requestContext.getStore()?.slashCommand;if(!$||$.channelId!==Q)return;return this.postSlashCommandResponse($,Q,w,B)}async postSlashCommandResponse(Q,w,B,$){let f=!Q.initialResponseSent;Q.initialResponseSent=!0;let Y=f?`/webhooks/${this.applicationId}/${Q.interactionToken}/messages/@original`:`/webhooks/${this.applicationId}/${Q.interactionToken}?wait=true`,X=f?"PATCH":"POST";this.logger.debug("Discord interaction webhook: responding to slash command",{threadId:w,isInitialResponse:f,hasFiles:$.length>0});let W=await($.length>0?await this.discordInteractionFetchWithFiles(Y,X,B,$):await this.discordInteractionFetch(Y,X,B)).json();return{id:W.id,threadId:w,raw:W}}async createDiscordThread(Q,w){let B=`Thread ${new Date().toLocaleString()}`;this.logger.debug("Discord API: POST thread",{channelId:Q,messageId:w,threadName:B});try{let f=await(await this.discordFetch(`/channels/${Q}/messages/${w}/threads`,"POST",{name:B,auto_archive_duration:1440})).json();return this.logger.debug("Discord API: POST thread response",{threadId:f.id,threadName:f.name}),f}catch($){if($ instanceof yI&&typeof $.message==="string"&&$.message.includes('"code"')&&$.message.includes("160004"))return this.logger.debug("Thread already exists for message, reusing existing thread",{channelId:Q,messageId:w}),{id:w,name:B};throw $}}truncateContent(Q){if(Q.length<=lj1)return Q;return`${Q.slice(0,lj1-3)}...`}async postMessageWithFiles(Q,w,B,$){let f=new FormData;f.append("payload_json",JSON.stringify(B));for(let H=0;H<$.length;H++){let W=$[H];if(!W)continue;let K=await qm0(W.data,{platform:"discord"});if(!K)continue;let U=new Blob([new Uint8Array(K)],{type:W.mimeType||"application/octet-stream"});f.append(`files[${H}]`,U,W.filename)}let Y=await fetch(`${j80}/channels/${Q}/messages`,{method:"POST",headers:{Authorization:`Bot ${this.botToken}`},body:f});if(!Y.ok){let H=await Y.text();throw new yI("discord",`Failed to post message: ${Y.status} ${H}`)}let X=await Y.json();return{id:X.id,threadId:w,raw:X}}async discordInteractionFetch(Q,w,B){let $=await fetch(`${j80}${Q}`,{method:w,headers:B?{"Content-Type":"application/json"}:void 0,body:B?JSON.stringify(B):void 0});if(!$.ok){let f=await $.text();throw this.logger.error("Discord interaction API error",{path:Q,method:w,status:$.status,error:f}),new yI("discord",`Discord interaction API error: ${$.status} ${f}`)}return $}async discordInteractionFetchWithFiles(Q,w,B,$){let f=new FormData;f.append("payload_json",JSON.stringify(B));for(let X=0;X<$.length;X++){let H=$[X];if(!H)continue;let W=await qm0(H.data,{platform:"discord"});if(!W)continue;let K=new Blob([new Uint8Array(W)],{type:H.mimeType||"application/octet-stream"});f.append(`files[${X}]`,K,H.filename)}let Y=await fetch(`${j80}${Q}`,{method:w,body:f});if(!Y.ok){let X=await Y.text();throw this.logger.error("Discord interaction API error",{path:Q,method:w,status:Y.status,error:X}),new yI("discord",`Discord interaction API error: ${Y.status} ${X}`)}return Y}async editMessage(Q,w,B){let{channelId:$,threadId:f}=this.decodeThreadId(Q),Y=f||$,X={},H=[],W=[],K=N80(B);if(K){let q=Em0(K);H.push(...q.embeds),W.push(...q.components),X.content=""}else X.content=this.truncateContent(pN(this.formatConverter.renderPostable(B),"discord"));if(H.length>0)X.embeds=H;if(W.length>0)X.components=W;this.logger.debug("Discord API: PATCH message",{channelId:Y,messageId:w,contentLength:X.content?.length||0});let G=await(await this.discordFetch(`/channels/${Y}/messages/${w}`,"PATCH",X)).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:B,threadId:$}=this.decodeThreadId(Q),f=$||B;this.logger.debug("Discord API: DELETE message",{channelId:f,messageId:w}),await this.discordFetch(`/channels/${f}/messages/${w}`,"DELETE"),this.logger.debug("Discord API: DELETE message response",{ok:!0})}async addReaction(Q,w,B){let{channelId:$,threadId:f}=this.decodeThreadId(Q),Y=f||$,X=this.encodeEmoji(B);this.logger.debug("Discord API: PUT reaction",{channelId:Y,messageId:w,emoji:X}),await this.discordFetch(`/channels/${Y}/messages/${w}/reactions/${X}/@me`,"PUT"),this.logger.debug("Discord API: PUT reaction response",{ok:!0})}async removeReaction(Q,w,B){let{channelId:$,threadId:f}=this.decodeThreadId(Q),Y=f||$,X=this.encodeEmoji(B);this.logger.debug("Discord API: DELETE reaction",{channelId:Y,messageId:w,emoji:X}),await this.discordFetch(`/channels/${Y}/messages/${w}/reactions/${X}/@me`,"DELETE"),this.logger.debug("Discord API: DELETE reaction response",{ok:!0})}encodeEmoji(Q){let w=bd.toDiscord?bd.toDiscord(Q):String(Q);return encodeURIComponent(w)}async startTyping(Q,w){let{channelId:B,threadId:$}=this.decodeThreadId(Q),f=$||B;this.logger.debug("Discord API: POST typing",{channelId:f}),await this.discordFetch(`/channels/${f}/typing`,"POST")}async fetchMessages(Q,w={}){let{channelId:B,threadId:$}=this.decodeThreadId(Q),f=$||B,Y=w.limit||50,X=w.direction??"backward",H=new URLSearchParams;if(H.set("limit",String(Y)),w.cursor)if(X==="backward")H.set("before",w.cursor);else H.set("after",w.cursor);this.logger.debug("Discord API: GET messages",{channelId:f,limit:Y,direction:X,cursor:w.cursor});let K=await(await this.discordFetch(`/channels/${f}/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(X==="backward")q=K.at(-1)?.id;else q=K[0]?.id;return{messages:G,nextCursor:q}}async fetchThread(Q){let{channelId:w,guildId:B}=this.decodeThreadId(Q);this.logger.debug("Discord API: GET channel",{channelId:w});let f=await(await this.discordFetch(`/channels/${w}`,"GET")).json();return{id:Q,channelId:w,channelName:f.name,isDM:f.type===rN.DM||f.type===rN.GroupDM,metadata:{guildId:B,channelType:f.type,raw:f}}}async openDM(Q){this.logger.debug("Discord API: POST DM channel",{userId:Q});let B=await(await this.discordFetch("/users/@me/channels","POST",{recipient_id:Q})).json();return this.logger.debug("Discord API: POST DM channel response",{channelId:B.id}),this.encodeThreadId({guildId:"@me",channelId:B.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 WW("discord",`Invalid Discord thread ID: ${Q}`);return{guildId:w[1],channelId:w[2],threadId:w[3]}}parseMessage(Q){let w=Q,B=w.guild_id||"@me",$=this.encodeThreadId({guildId:B,channelId:w.channel_id});return this.parseDiscordMessage(w,$)}parseDiscordMessage(Q,w){let B=Q.type===mF1.ThreadStarterMessage&&Q.referenced_message?Q.referenced_message:Q,$=B.author,f=$.bot??!1,Y=$.id===this.botUserId;return new p5({id:B.id,threadId:w,text:this.formatConverter.extractPlainText(B.content),formatted:this.formatConverter.toAst(B.content),raw:Q,author:{userId:$.id,userName:$.username,fullName:$.global_name||$.username,isBot:f,isMe:Y},metadata:{dateSent:new Date(B.timestamp),edited:B.edited_timestamp!==null,editedAt:B.edited_timestamp?new Date(B.edited_timestamp):void 0},attachments:(B.attachments||[]).map((X)=>({type:this.getAttachmentType(X.content_type),url:X.url,name:X.filename,mimeType:X.content_type,size:X.size,width:X.width??void 0,height:X.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(B){throw new yI("discord","Failed to download Discord attachment",B instanceof Error?B:void 0)}if(!w.ok)throw new yI("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,B){let $=`${this.apiBaseUrl}${Q}`,f={Authorization:`Bot ${this.botToken}`};if(B)f["Content-Type"]="application/json";let Y=await fetch($,{method:w,headers:f,body:B?JSON.stringify(B):void 0});if(!Y.ok){let X=await Y.text();throw this.logger.error("Discord API error",{path:Q,method:w,status:Y.status,error:X}),new yI("discord",`Discord API error: ${Y.status} ${X}`)}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:$?"configured":"not configured"});let f=this.runGatewayListener(w,B,$);return Q.waitUntil(f),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,B){let $=new w7.Client({intents:[w7.GatewayIntentBits.Guilds,w7.GatewayIntentBits.GuildMessages,w7.GatewayIntentBits.MessageContent,w7.GatewayIntentBits.DirectMessages,w7.GatewayIntentBits.GuildMessageReactions,w7.GatewayIntentBits.DirectMessageReactions],partials:[w7.Partials.Channel]}),f=!1;if(B)$.on("raw",async(Y)=>{if(f)return;if(!Y.t)return;this.logger.info("Discord Gateway forwarding event",{type:Y.t}),await this.forwardGatewayEvent(B,{type:`GATEWAY_${Y.t}`,timestamp:Date.now(),data:Y.d})});else this.setupLegacyGatewayHandlers($,()=>f);$.on(w7.Events.ClientReady,()=>{this.logger.info("Discord Gateway connected",{username:$.user?.username,id:$.user?.id})}),$.on(w7.Events.Error,(Y)=>{this.logger.error("Discord Gateway error",{error:String(Y)})});try{await $.login(this.botToken),await new Promise((Y)=>{let X=setTimeout(Y,Q);if(w){if(w.aborted){clearTimeout(X),Y();return}w.addEventListener("abort",()=>{this.logger.info("Discord Gateway listener received abort signal (new listener started)"),clearTimeout(X),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{f=!0,$.destroy(),this.logger.info("Discord Gateway listener stopped")}}setupLegacyGatewayHandlers(Q,w){Q.on(w7.Events.MessageCreate,async(B)=>{if(w()){this.logger.debug("Ignoring message - Gateway is shutting down");return}if(B.author.bot){this.logger.debug("Ignoring message from bot",{authorId:B.author.id,authorName:B.author.username,isMe:B.author.id===Q.user?.id});return}let $=B.mentions.has(Q.user?.id??""),f=this.mentionRoleIds.length>0&&B.mentions.roles.some((X)=>this.mentionRoleIds.includes(X.id)),Y=$||f;this.logger.info("Discord Gateway message received",{channelId:B.channelId,guildId:B.guildId,authorId:B.author.id,isMentioned:Y,isUserMentioned:$,isRoleMentioned:f,content:B.content.slice(0,100)}),await this.handleGatewayMessage(B,Y)}),Q.on(w7.Events.InteractionCreate,async(B)=>{if(w()){this.logger.debug("Ignoring interaction - Gateway is shutting down");return}this.logger.info("Discord Gateway interaction received",{id:B.id,type:B.type});try{await this.handleGatewayInteraction(B)}catch($){this.logger.error("Error handling Gateway interaction",{error:String($),interactionId:B.id})}}),Q.on(w7.Events.MessageReactionAdd,async(B,$)=>{if(w()){this.logger.debug("Ignoring reaction - Gateway is shutting down");return}if($.bot){this.logger.debug("Ignoring reaction from bot",{userId:$.id,isMe:$.id===Q.user?.id});return}if(this.logger.info("Discord Gateway reaction added",{emoji:B.emoji.name,messageId:B.message.id,channelId:B.message.channelId,userId:$.id}),$.username)await this.handleGatewayReaction(B,$,!0)}),Q.on(w7.Events.MessageReactionRemove,async(B,$)=>{if(w()){this.logger.debug("Ignoring reaction removal - Gateway is shutting down");return}if($.bot){this.logger.debug("Ignoring reaction removal from bot",{userId:$.id,isMe:$.id===Q.user?.id});return}if(this.logger.info("Discord Gateway reaction removed",{emoji:B.emoji.name,messageId:B.message.id,channelId:B.message.channelId,userId:$.id}),$.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 B=await fetch(Q,{method:"POST",headers:{"Content-Type":"application/json","x-discord-gateway-token":this.botToken},body:JSON.stringify(w)});if(B.ok)this.logger.debug("Gateway event forwarded successfully",{type:w.type});else{let $=await B.text();this.logger.error("Failed to forward Gateway event",{type:w.type,status:B.status,error:$})}}catch(B){this.logger.error("Error forwarding Gateway event",{type:w.type,error:String(B)})}}async handleGatewayMessage(Q,w){if(!this.chat)return;let B=Q.guildId||"@me",$=Q.channelId,f=Q.channel.isThread(),Y,X=$;if(f&&"parentId"in Q.channel&&Q.channel.parentId)Y=$,X=Q.channel.parentId;if(!Y&&w)try{let K=await this.createDiscordThread($,Q.id);Y=K.id,this.logger.debug("Created Discord thread for incoming mention",{channelId:$,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:B,channelId:X,threadId:Y}),W=new p5({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:$,guild_id:B,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,B){if(!this.chat)return;let $=Q.message.guildId||"@me",f=Q.message.channelId,Y=Q.message.channel?.isThread?.(),X=f,H;if(Y&&Q.message.channel?.parentId)H=f,X=Q.message.channel.parentId;let W=this.encodeThreadId({guildId:$,channelId:X,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:B,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 $=Q.split(":")[2];if(!$)throw new WW("discord",`Invalid Discord channel ID: ${Q}`);let f=w.limit||50,Y=w.direction??"backward",X=new URLSearchParams;if(X.set("limit",String(f)),w.cursor)if(Y==="backward")X.set("before",w.cursor);else X.set("after",w.cursor);this.logger.debug("Discord API: GET channel messages",{channelId:$,limit:f,direction:Y,cursor:w.cursor});let W=await(await this.discordFetch(`/channels/${$}/messages?${X.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===f)if(Y==="backward")G=W.at(-1)?.id;else G=W[0]?.id;return{messages:U,nextCursor:G}}async listThreads(Q,w={}){let B=Q.split(":"),$=B[1],f=B[2];if(!($&&f))throw new WW("discord",`Invalid Discord channel ID: ${Q}`);this.logger.debug("Discord API: GET threads",{guildId:$,channelId:f});let H=((await(await this.discordFetch(`/guilds/${$}/threads/active`,"GET")).json()).threads||[]).filter((b)=>b.parent_id===f),W=[];try{W=(await(await this.discordFetch(`/channels/${f}/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((b)=>{if(U.has(b.id))return!1;return U.add(b.id),!0}),q=w.limit||50,V=G.slice(0,q),J=[];for(let b of V){let L=this.encodeThreadId({guildId:$,channelId:f,threadId:b.id});try{let x=(await(await this.discordFetch(`/channels/${b.id}/messages?limit=1&after=0`,"GET")).json())[0];if(x)J.push({id:L,rootMessage:this.parseDiscordMessage(x,L),replyCount:b.total_message_sent??b.message_count,lastReplyAt:b.thread_metadata?.archive_timestamp?new Date(b.thread_metadata.archive_timestamp):void 0})}catch{J.push({id:L,rootMessage:new p5({id:b.id,threadId:L,text:b.name,formatted:this.formatConverter.toAst(b.name),raw:b,author:{userId:"unknown",userName:"unknown",fullName:"unknown",isBot:!1,isMe:!1},metadata:{dateSent:new Date,edited:!1},attachments:[]}),replyCount:b.total_message_sent??b.message_count})}}return this.logger.debug("Discord API: listThreads result",{threadCount:J.length}),{threads:J,nextCursor:G.length>q?String(q):void 0}}async fetchChannelInfo(Q){let B=Q.split(":")[2];if(!B)throw new WW("discord",`Invalid Discord channel ID: ${Q}`);this.logger.debug("Discord API: GET channel info",{channelId:B});let f=await(await this.discordFetch(`/channels/${B}`,"GET")).json();return{id:Q,name:f.name,isDM:f.type===rN.DM||f.type===rN.GroupDM,memberCount:f.member_count,metadata:{channelType:f.type,raw:f}}}async postChannelMessage(Q,w){let $=Q.split(":")[2];if(!$)throw new WW("discord",`Invalid Discord channel ID: ${Q}`);let f={},Y=[],X=[],H=N80(w);if(H){let q=Em0(H);Y.push(...q.embeds),X.push(...q.components)}else f.content=this.truncateContent(pN(this.formatConverter.renderPostable(w),"discord"));if(Y.length>0)f.embeds=Y;if(X.length>0)f.components=X;let W=zm0(w),K=this.tryPostSlashResponse(Q,f,W);if(K)return K;if(W.length>0)return this.postMessageWithFiles($,Q,f,W);this.logger.debug("Discord API: POST channel message",{channelId:$,contentLength:f.content?.length||0});let G=await(await this.discordFetch(`/channels/${$}/messages`,"POST",f)).json();return{id:G.id,threadId:Q,raw:G}}normalizeDiscordEmoji(Q){let B={"\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 gI(B)}};function dj1(A){return new sgQ(A??{})}var agQ=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 B={threadId:A,token:tgQ(),expiresAt:Date.now()+Q};return this.locks.set(A,B),B}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 B=this.cache.get(A);if(B)if(B.expiresAt!==null&&B.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 B=this.cache.get(A),$;if(B&&B.expiresAt!==null&&B.expiresAt<=Date.now())$=[];else if(B&&Array.isArray(B.value))$=B.value;else $=[];if($.push(Q),w?.maxLength&&$.length>w.maxLength)$=$.slice($.length-w.maxLength);this.cache.set(A,{value:$,expiresAt:w?.ttlMs?Date.now()+w.ttlMs:null})}async enqueue(A,Q,w){this.ensureConnected();let B=this.queues.get(A);if(!B)B=[],this.queues.set(A,B);if(B.push(Q),B.length>w)B.splice(0,B.length-w);return B.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 tgQ(){return`mem_${Date.now()}_${Math.random().toString(36).substring(2,15)}`}function P80(A){return new agQ}_0();var egQ=Z.object({subscribedAt:Z.string().datetime(),routingMode:Z.enum(["auto","mention-required"]).optional(),mentionRequiredNoticeSent:Z.boolean().optional()}),AyQ="chat.discord.subscriptions";function Tm0(A){return A.scoped({namespace:AyQ,schema:egQ})}function nj1(A,Q=P80()){let w=Tm0(A);return new rj1(Q,w)}class rj1{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 oj1(A){let{discord:Q}=A;if(!Q)return new Um0({userName:A.userName,adapters:{},state:P80()});let w=dj1({botToken:Q.botToken,publicKey:Q.publicKey,applicationId:Q.applicationId,mentionRoleIds:Q.mentionRoleIds});return A.gatewayLoop.setAdapter(w),new Um0({userName:A.userName,adapters:{discord:w},concurrency:{strategy:"queue",maxQueueSize:5,onQueueFull:"drop-oldest"},state:nj1(A.runtimeState)})}class Sm0{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 $={...w,routingMode:"mention-required"};if(!Q.isMention&&!w.mentionRequiredNoticeSent)await this.postMentionRequiredNotice(A,$);else await this.deps.getSubscriptions()?.set(A.id,$);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((B)=>!B.isBot&&!B.isMe).length>1}catch(Q){return this.deps.logger.debug("Failed to inspect Discord thread participants",{error:Q,threadId:A.id}),!1}}}wA();class mm0{deps;constructor(A){this.deps=A}async build(A,Q,w,B){let $={message:w.text.trim(),attachments:[],notices:[]};if(w.attachments.length===0)return $;if(!(B==="anchor"||B==="trusted"))return $;let Y=this.deps.getUploadStore();if(!Y)return $;for(let X of w.attachments){let H=X.name;if(!H)continue;let W=Dz(H,"upload"),K=yb(W,X.mimeType),U=X.size??0,G=yA0(W,K);if(!G){$.notices.push(`Unsupported file upload type: ${W}`);continue}if(!EA0(G,U)){$.notices.push(`File upload too large: ${W}`);continue}try{let q=await this.readAttachmentData(X);if(!q)continue;let V=zz({filename:W,mediaType:K,content:q,fallbackFilename:"upload"});if(!V.ok){$.notices.push(V.message);continue}let J=await Y.save({filename:V.filename,mediaType:V.mediaType,content:q,metadata:this.buildMetadata(A,Q,w)});$.attachments.push(aj1(J.filename,J.mediaType,q,J.ref,V.kind==="text"))}catch(q){this.deps.logger.error("Failed to read chat attachment",{error:q,filename:W}),$.notices.push(`Could not read file upload: ${W}`)}}return $}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 B=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,...B.guildId?{guildId:B.guildId}:{},...B.threadId?{threadId:B.threadId}:{}}}}function sj1(A,Q,w,B){return aj1(A,Q,w,B,Eb(A,Q))}function aj1(A,Q,w,B,$){if($)return{kind:"text",filename:A,mediaType:Q,content:w.toString("utf8").replace(/^\uFEFF/,""),sizeBytes:w.byteLength,source:B};return{kind:"file",filename:A,mediaType:Q,data:w,sizeBytes:w.byteLength,source:B}}function _d(){return{namespace:"discord-chat",refKind:"discord-chat-upload",routePath:"/api/webhooks/chat/discord/uploads"}}function FD(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 QyQ(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 tj1(A,Q){if(A.isDM)return!1;let w=FD(A.id);if(!w.threadId)return!1;let B=QyQ(Q);return B!==void 0&&B!==w.threadId}function M80(A,Q){if(Q.allowedChannels.length===0||A.isDM)return!0;let w=FD(A.id);return[A.id,A.channelId,w.channelId,w.threadId].some((B)=>typeof B==="string"&&Q.allowedChannels.includes(B))}function um0(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 M80(A,w)}function cm0(A,Q,w){if(Q!=="discord")return!0;if(!w)return!1;if(A.isDM&&!w.allowDMs)return!1;return M80(A,w)}function lm0(A,Q){return{channelId:FD(A.id).channelId??A.channelId,isBot:Boolean(Q.author.isBot)}}function PC(A){return A.isDM?"DM":A.channelId}var wyQ="https://discord.com/api/v10";async function ej1(A){let Q=FD(A.threadId),w=Q.threadId??Q.channelId;if(!w)return;let B=A.fetchFn??fetch;try{let $=await B(`${wyQ}/channels/${w}/messages/${A.messageId}`,{method:"PATCH",headers:{Authorization:`Bot ${A.botToken}`,"Content-Type":"application/json"},body:JSON.stringify({components:[]})});if(!$.ok)A.logger.debug("Failed to clear Discord message components",{messageId:A.messageId,channelId:w,status:$.status})}catch($){A.logger.debug("Failed to clear Discord message components",{error:$,messageId:A.messageId,channelId:w})}}var AP1={name:"@brains/chat",version:"0.2.0-alpha.150",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 $yQ=/https?:\/\/\S+/i,fyQ=/[\s\S]+/,YyQ=1000,XyQ=Z.looseObject({type:Z.literal("card"),children:Z.array(Z.looseObject({type:Z.string()})),imageUrl:Z.string().optional(),subtitle:Z.string().optional(),title:Z.string().optional()}),ZyQ=Z.object({card:Z.custom((A)=>XyQ.safeParse(A).success),fallbackText:Z.string().optional()});class O80 extends WK{threadRegistry=new U80;pendingApprovals;uploadContinuity;promptActions=new cT0(YyQ);toolStatusMessenger=new lT0(this.threadRegistry);cardBuilder=new nT0({getDisplayBaseUrl:()=>this.getPreferredDisplayBaseUrl(),registerPromptAction:(A,Q)=>this.registerPromptAction(A,Q)});artifactDelivery=new oT0({getContext:()=>this.context,getDisplayBaseUrl:()=>this.getPreferredDisplayBaseUrl(),logger:this.logger});approvalCards=new sT0({cardBuilder:this.cardBuilder,clearMessageComponents:async(A,Q)=>{let w=this.config.adapters.discord?.botToken;if(!w)return;await ej1({threadId:A,messageId:Q,botToken:w,logger:this.logger})}});subscriptionRouter=new Sm0({getSubscriptions:()=>this.discordSubscriptions,getPlatform:(A)=>this.getPlatform(A),isBotCreatedThread:tj1,logger:this.logger});chatInputBuilder=new mm0({getUploadStore:()=>this.context?.uploads.scoped(_d()),getThreadIdParts:FD,logger:this.logger});gatewayLoop;discordApp;discordSubscriptions;constructor(A={}){super("chat",AP1,A,uT0);this.gatewayLoop=new aT0({getApp:()=>this.discordApp.instance,gatewayRunMs:this.config.gatewayRunMs,gatewayRestartDelayMs:this.config.gatewayRestartDelayMs,logger:this.logger}),this.discordApp=new tT0({discord:this.config.adapters.discord,getUploadStore:()=>this.context?.uploads.scoped(_d()),buildApp:(Q)=>oj1({userName:this.config.userName,discord:this.config.adapters.discord,gatewayLoop:this.gatewayLoop,runtimeState:Q})}),this.pendingApprovals=new Km({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 Vm({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(_d());if(!w)throw Error("Chat upload store unavailable");let B=await w.read(Q);return sj1(B.record.filename,B.record.mediaType,B.content,B.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=Tm0(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 B=this.toDiscordCardOutput(Q);if(B){w.post(B).catch(($)=>this.logger.error("Failed to send chat message",{error:$,channelId:A}));return}if(typeof Q!=="string")return;for(let $ of Ud(A,Q))w.post($).catch((f)=>this.logger.error("Failed to send chat message",{error:f,channelId:A}))}async sendMessageWithId({channelId:A,message:Q}){let w=this.threadRegistry.get(A);if(!w)return;let B=this.toDiscordCardOutput(Q);if(B){let f=await w.post(B);return this.threadRegistry.trackMessage(w.id,f),f.id}if(typeof Q!=="string")return;let $;for(let f of Ud(A,Q))$=await w.post(f),this.threadRegistry.trackMessage(w.id,$);return $?.id}async editMessage({channelId:A,messageId:Q,newMessage:w}){let B=this.threadRegistry.getMessage(A,Q);if(!B)return!1;try{let $=await B.edit(this.toDiscordCardOutput(w)??(typeof w==="string"?w:""));if(A)this.threadRegistry.trackMessage(A,$);return!0}catch{return!1}}supportsMessageEditing(){return!0}toDiscordCardOutput(A){let Q=ZyQ.safeParse(A);if(!Q.success)return;let{card:w,fallbackText:B}=Q.data;if(B===void 0)return{card:w};return{card:w,fallbackText:B}}formatProgressOutput(A){return dT0(A)}formatCompletionOutput(A){return dT0(A)}async handleProgressEvent(A,Q){let w=A.metadata.interfaceType;if(w&&w!==this.id){if(!this.isEnabledPlatform(w))return;let B={...A,metadata:{...A.metadata,interfaceType:this.id}};await super.handleProgressEvent(B,B.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 jz1(A,Boolean(this.config.adapters.discord))}registerChatHandlers(A){if(A.onDirectMessage(async(Q,w,B,$)=>{await this.handleRoutedMessage(Q,w,$)}),A.onNewMention(async(Q,w,B)=>{let $=this.getPlatformConfig(Q);if($&&um0(Q,w,$)&&!Q.isDM&&$.useThreads)await this.subscriptionRouter.subscribeOwnedThread(Q,w);await this.handleRoutedMessage(Q,w,B)}),A.onSubscribedMessage(async(Q,w,B)=>{if(!await this.subscriptionRouter.shouldRouteSubscribedMessage(Q,w))return;await this.handleRoutedMessage(Q,w,B)}),this.config.adapters.discord&&!this.config.adapters.discord.requireMention)A.onNewMessage(fyQ,async(Q,w,B)=>{await this.handleRoutedMessage(Q,w,B)});A.onNewMessage($yQ,async(Q,w)=>{await this.handlePassiveUrlCapture(Q,w)}),A.onAction([G80,pT0],async(Q)=>{await this.handleApprovalAction(Q)}),A.onAction(iT0,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(!cm0(w,Q,this.config.adapters.discord))return;let B=this.promptActions.get(A.value);if(B?.threadId!==w.id){await w.post(this.formatNoticePayload("That suggested action is no longer available.","Action unavailable"));return}this.promptActions.consume(A.value);let $=FD(w.id),f=this.context.permissions.getUserLevel(Q,A.user.userId,{channelId:$.channelId??w.channelId,isBot:Boolean(A.user.isBot)}),Y=this.getConversationId(Q,w.id),X=w.id;await this.runAgentTurn({thread:w,channelId:X,logLabel:"Error handling chat prompt action",body:async()=>{if(!this.context)return;let H=await this.context.agent.chat(B.prompt,Y,{userPermissionLevel:f,interfaceType:Q,channelId:X,channelName:PC(w),...this.buildActionEventMetadata(Q,w,A)});await this.renderAgentResponse({thread:w,channelId:X,conversationId:Y,response:H,userPermissionLevel:f})}})}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 $=A.thread;if(!cm0($,Q,this.config.adapters.discord))return;let f=FD($.id),Y=this.context.permissions.getUserLevel(Q,A.user.userId,{channelId:f.channelId??$.channelId,isBot:Boolean(A.user.isBot)});await this.confirmApproval({thread:$,conversationId:w,approvalId:A.value,confirmed:A.actionId===G80,userPermissionLevel:Y,metadata:this.buildActionEventMetadata(Q,$,A)})}async handleRoutedMessage(A,Q,w){if(!this.context)return;let B=this.getPlatform(A);if(B!=="discord")return;let $=this.getPlatformConfig(A);if(!$)return;if(!um0(A,Q,$))return;await this.routeToAgent(B,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 B=this.formatErrorPayload(w),$=this.toDiscordCardOutput(B);if($){await A.post($);return}let f=typeof B==="string"?B:"Message failed.";for(let Y of Ud(Q,f))await A.post(Y)}async routeToAgent(A,Q,w,B){if(!this.context)return;this.threadRegistry.set(Q);let $=this.getConversationId(A,Q.id),f=Q.id,Y=lm0(Q,w),X=this.context.permissions.getUserLevel(A,w.author.userId,Y),H=await this.chatInputBuilder.build(A,Q,w,X),W=[...H.attachments];if(await this.attachPriorUploads($,H,X),await this.postUploadNotices(Q,H.notices),!H.message&&H.attachments.length===0)return;this.rememberUploadAttachments($,W),await this.runAgentTurn({thread:Q,channelId:f,logLabel:"Error handling chat message",body:async()=>{if(!this.context)return;let K=await this.getPendingApprovalIds($);if(K.size>0){if(await this.handleConfirmationResponse(H.message,$,Q,K,X,this.buildUserMessageMetadata(A,Q,w)))return}let U=this.buildCoalescedAgentInput(H.message,B),G=await this.context.agent.chat(U.message,$,{userPermissionLevel:X,interfaceType:A,channelId:f,channelName:PC(Q),...this.buildUserMessageMetadata(A,Q,w,U.metadata),...H.attachments.length>0?{attachments:H.attachments}:{}});await this.renderAgentResponse({thread:Q,channelId:f,conversationId:$,response:G,userPermissionLevel:X})}})}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=Lk(A.response,{deniedCardIds:Q.deniedCardIds});if(A.confirmation)await this.approvalCards.resolve(A.conversationId,A.confirmation.approvalId,A.confirmation.confirmed);let B=A.confirmation?this.formatConfirmationResponsePayload(A.response,A.confirmation.confirmed,this.getRemainingApprovalHelp(A.conversationId,A.response),Q.deniedCardIds):this.formatAgentResponseText(w,Q.deniedCardIds),$=await this.sendAgentResponseWithFiles({thread:A.thread,channelId:A.channelId,message:B,files:Q.files}),f=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 X=f??$;if(X)for(let H of w.jobIds)this.trackAgentResponseForJob(H,X,A.channelId)}rememberPendingConfirmationsFromResponse(A,Q){this.pendingApprovals.rememberFromResponse(A,Q)}async getPendingApprovalIds(A){return this.pendingApprovals.getApprovalIds(A)}async handleConfirmationResponse(A,Q,w,B,$,f){if(!Xm(A,B))return!1;let Y=kA0({message:A,approvalIds:B});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:$,...f?{metadata:f}:{}}),!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:PC(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(`
|
|
2372
|
+
\`\`\``;return this.defaultNodeToText(A,(Q)=>this.nodeToDiscordMarkdown(Q))}};var cj1={DeferredChannelMessageWithSource:5,DeferredUpdateMessage:6},j80="https://discord.com/api/v10",lj1=2000,rgQ=/^[0-9a-f]{64}$/,ogQ=/^[0-9a-f]+$/,sgQ=class A{name="discord";userName;botUserId;apiBaseUrl;botToken;publicKey;applicationId;mentionRoleIds;interactionFlags;chat=null;logger;formatConverter=new ngQ;requestContext=new EgQ;threadParentCache=new Map;static THREAD_PARENT_CACHE_TTL=300000;constructor(Q={}){let w=Q.botToken??process.env.DISCORD_BOT_TOKEN;if(!w)throw new WW("discord","botToken is required. Set DISCORD_BOT_TOKEN or provide it in config.");let B=Q.publicKey??process.env.DISCORD_PUBLIC_KEY;if(!B)throw new WW("discord","publicKey is required. Set DISCORD_PUBLIC_KEY or provide it in config.");let $=Q.applicationId??process.env.DISCORD_APPLICATION_ID;if(!$)throw new WW("discord","applicationId is required. Set DISCORD_APPLICATION_ID or provide it in config.");if(this.apiBaseUrl=Q.apiUrl??process.env.DISCORD_API_URL??j80,this.botToken=w,this.publicKey=B.trim().toLowerCase(),this.applicationId=$,this.mentionRoleIds=Q.mentionRoleIds??(process.env.DISCORD_MENTION_ROLE_IDS?process.env.DISCORD_MENTION_ROLE_IDS.split(",").map((f)=>f.trim()):[]),this.botUserId=$,this.interactionFlags=Q.interactionFlags,this.logger=Q.logger??new L80("info").child("discord"),this.userName=Q.userName??"bot",!rgQ.test(this.publicKey))this.logger.error("Invalid Discord public key format",{length:this.publicKey.length,isHex:ogQ.test(this.publicKey)})}async initialize(Q){this.chat=Q,this.logger.info("Discord adapter initialized")}async getUser(Q){try{let B=await(await this.discordFetch(`/users/${Q}`,"GET")).json();return{avatarUrl:B.avatar?`https://cdn.discordapp.com/avatars/${B.id}/${B.avatar}.png`:void 0,email:void 0,fullName:B.global_name||B.username,isBot:B.bot??!1,userId:B.id,userName:B.username}}catch{return null}}async handleWebhook(Q,w){let B=await Q.arrayBuffer(),$=new Uint8Array(B),f=new TextDecoder().decode($),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(f);return this.handleForwardedGatewayEvent(U,w)}catch{return new Response("Invalid JSON",{status:400})}}this.logger.info("Discord webhook received",{bodyLength:f.length,bodyBytesLength:$.length,hasSignature:!!Q.headers.get("x-signature-ed25519"),hasTimestamp:!!Q.headers.get("x-signature-timestamp")});let X=Q.headers.get("x-signature-ed25519"),H=Q.headers.get("x-signature-timestamp");if(!await this.verifySignature($,X,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(f)}catch{return new Response("Invalid JSON",{status:400})}if(this.logger.info("Discord interaction parsed",{type:K.type,typeIsPing:K.type===NC.Ping,expectedPingType:NC.Ping,id:K.id}),K.type===NC.Ping){let U=JSON.stringify({type:kd.InteractionResponseType.PONG});return this.logger.info("Discord PING received, responding with PONG",{responseBody:U,responseType:kd.InteractionResponseType.PONG}),new Response(U,{status:200,headers:{"Content-Type":"application/json"}})}if(K.type===NC.MessageComponent)return this.handleComponentInteraction(K,w),this.respondToInteraction({type:cj1.DeferredUpdateMessage});if(K.type===NC.ApplicationCommand){let U=this.getApplicationCommandContext(K),G=this.getInteractionFlags(U);return this.handleApplicationCommandInteraction(U,w),this.respondToInteraction({...G===void 0?{}:{data:{flags:G}},type:cj1.DeferredChannelMessageWithSource})}return new Response("Unknown interaction type",{status:400})}async verifySignature(Q,w,B){if(!(w&&B))return this.logger.warn("Discord signature verification failed: missing headers",{hasSignature:!!w,hasTimestamp:!!B}),!1;try{this.logger.info("Discord signature verification attempt",{bodyBytesLength:Q.length,signatureLength:w.length,timestampLength:B.length,publicKeyLength:this.publicKey.length,timestamp:B,signaturePrefix:w.slice(0,16),publicKey:this.publicKey});let $=await kd.verifyKey(Q,w,B,this.publicKey);if(!$){let f=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:B,bodyLength:Q.length,bodyPrefix:f.slice(0,50)})}return $}catch($){return this.logger.warn("Discord signature verification failed: exception",{error:$}),!1}}respondToInteraction(Q){return Response.json(Q)}handleComponentInteraction(Q,w){if(!this.chat){this.logger.warn("Chat instance not initialized, ignoring interaction");return}let B=Q.data?.custom_id;if(!B){this.logger.warn("No custom_id in component interaction");return}let $=Q.member?.user||Q.user;if(!$){this.logger.warn("No user in component interaction");return}let f=Q.channel_id,Y=Q.guild_id||"@me",X=Q.message?.id;if(!(f&&X)){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:f,U=W?this.encodeThreadId({guildId:Y,channelId:K,threadId:f}):this.encodeThreadId({guildId:Y,channelId:f}),G=SgQ(B),q={actionId:G.actionId,value:G.value??G.actionId,user:{userId:$.id,userName:$.username,fullName:$.global_name||$.username,isBot:$.bot??!1,isMe:!1},messageId:X,threadId:U,adapter:this,raw:Q};this.logger.debug("Processing Discord button action",{actionId:B,messageId:X,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 B=Q.member?.user||Q.user;if(!B)return this.logger.warn("No user in application command interaction"),null;let $=Q.channel_id;if(!$)return this.logger.warn("Missing channel_id in application command interaction"),null;let f=Q.guild_id||"@me",Y=Q.channel,X=Y?.type===11||Y?.type===12,H=X&&Y?.parent_id?Y.parent_id:$,W=X?this.encodeThreadId({guildId:f,channelId:H,threadId:$}):this.encodeThreadId({guildId:f,channelId:$}),{command:K,text:U}=this.parseSlashCommand(w,Q.data?.options);return{channelId:W,command:K,interaction:Q,text:U,user:B}}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:B,command:$,interaction:f,text:Y,user:X}=Q;this.logger.debug("Processing Discord slash command",{command:$,text:Y,userId:X.id,channelId:B}),this.requestContext.run({slashCommand:{channelId:B,interactionToken:f.token,initialResponseSent:!1}},()=>{this.chat?.processSlashCommand({command:$,text:Y,user:{userId:X.id,userName:X.username,fullName:X.global_name||X.username,isBot:X.bot??!1,isMe:X.id===this.applicationId},adapter:this,raw:f,channelId:B},w)})}parseSlashCommand(Q,w){let B=[Q.startsWith("/")?Q:`/${Q}`],$=[],f=(Y)=>{for(let X of Y){if(X.value!==void 0){$.push(String(X.value));continue}if(X.options&&X.options.length>0)B.push(X.name),f(X.options)}};if(w&&w.length>0)f(w);return{command:B.join(" "),text:$.join(" ").trim()}}async handleGatewayInteraction(Q){if(Q.isChatInputCommand()){let w=this.getApplicationCommandContext(this.normalizeGatewaySlashCommandInteraction(Q)),B=this.getInteractionFlags(w);await Q.deferReply(B===void 0?void 0:{flags:B}),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 B=Q.guild_id||"@me",$=Q.channel_id,f,Y=$;if(Q.thread)f=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/${$}`,"GET")).json();if(q.parent_id)f=$,Y=q.parent_id,this.logger.debug("Fetched thread parent for forwarded message",{threadId:$,parentId:q.parent_id})}catch(G){this.logger.error("Failed to fetch thread parent",{error:String(G),channelId:$})}let X=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=X||H;if(!f&&W)try{let G=await this.createDiscordThread($,Q.id);f=G.id,this.logger.debug("Created Discord thread for forwarded mention",{channelId:$,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:B,channelId:Y,threadId:f}),U=new p5({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,B){if(!this.chat)return;let $=Q.guild_id||"@me",f=Q.channel_id,Y,X=f;if(Q.channel_type===rN.GuildPublicThread||Q.channel_type===rN.GuildPrivateThread){let q=this.threadParentCache.get(f);if(q&&q.expiresAt>Date.now())Y=f,X=q.parentId;else try{let J=await(await this.discordFetch(`/channels/${f}`,"GET")).json();if(J.parent_id)Y=f,X=J.parent_id,this.threadParentCache.set(f,{parentId:J.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:f})}}let H=this.encodeThreadId({guildId:$,channelId:X,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:B,threadId:$}=this.decodeThreadId(Q),f=Q;if($)B=$;let Y={},X=[],H=[],W=N80(w);if(W){let V=Em0(W);X.push(...V.embeds),H.push(...V.components)}else Y.content=this.truncateContent(pN(this.formatConverter.renderPostable(w),"discord"));if(X.length>0)Y.embeds=X;if(H.length>0)Y.components=H;let K=zm0(w),U=this.tryPostSlashResponse(f,Y,K);if(U)return U;if(K.length>0)return this.postMessageWithFiles(B,f,Y,K);this.logger.debug("Discord API: POST message",{channelId:B,contentLength:Y.content?.length||0,embedCount:X.length,componentCount:H.length});let q=await(await this.discordFetch(`/channels/${B}/messages`,"POST",Y)).json();return this.logger.debug("Discord API: POST message response",{messageId:q.id}),{id:q.id,threadId:f,raw:q}}tryPostSlashResponse(Q,w,B){let $=this.requestContext.getStore()?.slashCommand;if(!$||$.channelId!==Q)return;return this.postSlashCommandResponse($,Q,w,B)}async postSlashCommandResponse(Q,w,B,$){let f=!Q.initialResponseSent;Q.initialResponseSent=!0;let Y=f?`/webhooks/${this.applicationId}/${Q.interactionToken}/messages/@original`:`/webhooks/${this.applicationId}/${Q.interactionToken}?wait=true`,X=f?"PATCH":"POST";this.logger.debug("Discord interaction webhook: responding to slash command",{threadId:w,isInitialResponse:f,hasFiles:$.length>0});let W=await($.length>0?await this.discordInteractionFetchWithFiles(Y,X,B,$):await this.discordInteractionFetch(Y,X,B)).json();return{id:W.id,threadId:w,raw:W}}async createDiscordThread(Q,w){let B=`Thread ${new Date().toLocaleString()}`;this.logger.debug("Discord API: POST thread",{channelId:Q,messageId:w,threadName:B});try{let f=await(await this.discordFetch(`/channels/${Q}/messages/${w}/threads`,"POST",{name:B,auto_archive_duration:1440})).json();return this.logger.debug("Discord API: POST thread response",{threadId:f.id,threadName:f.name}),f}catch($){if($ instanceof yI&&typeof $.message==="string"&&$.message.includes('"code"')&&$.message.includes("160004"))return this.logger.debug("Thread already exists for message, reusing existing thread",{channelId:Q,messageId:w}),{id:w,name:B};throw $}}truncateContent(Q){if(Q.length<=lj1)return Q;return`${Q.slice(0,lj1-3)}...`}async postMessageWithFiles(Q,w,B,$){let f=new FormData;f.append("payload_json",JSON.stringify(B));for(let H=0;H<$.length;H++){let W=$[H];if(!W)continue;let K=await qm0(W.data,{platform:"discord"});if(!K)continue;let U=new Blob([new Uint8Array(K)],{type:W.mimeType||"application/octet-stream"});f.append(`files[${H}]`,U,W.filename)}let Y=await fetch(`${j80}/channels/${Q}/messages`,{method:"POST",headers:{Authorization:`Bot ${this.botToken}`},body:f});if(!Y.ok){let H=await Y.text();throw new yI("discord",`Failed to post message: ${Y.status} ${H}`)}let X=await Y.json();return{id:X.id,threadId:w,raw:X}}async discordInteractionFetch(Q,w,B){let $=await fetch(`${j80}${Q}`,{method:w,headers:B?{"Content-Type":"application/json"}:void 0,body:B?JSON.stringify(B):void 0});if(!$.ok){let f=await $.text();throw this.logger.error("Discord interaction API error",{path:Q,method:w,status:$.status,error:f}),new yI("discord",`Discord interaction API error: ${$.status} ${f}`)}return $}async discordInteractionFetchWithFiles(Q,w,B,$){let f=new FormData;f.append("payload_json",JSON.stringify(B));for(let X=0;X<$.length;X++){let H=$[X];if(!H)continue;let W=await qm0(H.data,{platform:"discord"});if(!W)continue;let K=new Blob([new Uint8Array(W)],{type:H.mimeType||"application/octet-stream"});f.append(`files[${X}]`,K,H.filename)}let Y=await fetch(`${j80}${Q}`,{method:w,body:f});if(!Y.ok){let X=await Y.text();throw this.logger.error("Discord interaction API error",{path:Q,method:w,status:Y.status,error:X}),new yI("discord",`Discord interaction API error: ${Y.status} ${X}`)}return Y}async editMessage(Q,w,B){let{channelId:$,threadId:f}=this.decodeThreadId(Q),Y=f||$,X={},H=[],W=[],K=N80(B);if(K){let q=Em0(K);H.push(...q.embeds),W.push(...q.components),X.content=""}else X.content=this.truncateContent(pN(this.formatConverter.renderPostable(B),"discord"));if(H.length>0)X.embeds=H;if(W.length>0)X.components=W;this.logger.debug("Discord API: PATCH message",{channelId:Y,messageId:w,contentLength:X.content?.length||0});let G=await(await this.discordFetch(`/channels/${Y}/messages/${w}`,"PATCH",X)).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:B,threadId:$}=this.decodeThreadId(Q),f=$||B;this.logger.debug("Discord API: DELETE message",{channelId:f,messageId:w}),await this.discordFetch(`/channels/${f}/messages/${w}`,"DELETE"),this.logger.debug("Discord API: DELETE message response",{ok:!0})}async addReaction(Q,w,B){let{channelId:$,threadId:f}=this.decodeThreadId(Q),Y=f||$,X=this.encodeEmoji(B);this.logger.debug("Discord API: PUT reaction",{channelId:Y,messageId:w,emoji:X}),await this.discordFetch(`/channels/${Y}/messages/${w}/reactions/${X}/@me`,"PUT"),this.logger.debug("Discord API: PUT reaction response",{ok:!0})}async removeReaction(Q,w,B){let{channelId:$,threadId:f}=this.decodeThreadId(Q),Y=f||$,X=this.encodeEmoji(B);this.logger.debug("Discord API: DELETE reaction",{channelId:Y,messageId:w,emoji:X}),await this.discordFetch(`/channels/${Y}/messages/${w}/reactions/${X}/@me`,"DELETE"),this.logger.debug("Discord API: DELETE reaction response",{ok:!0})}encodeEmoji(Q){let w=bd.toDiscord?bd.toDiscord(Q):String(Q);return encodeURIComponent(w)}async startTyping(Q,w){let{channelId:B,threadId:$}=this.decodeThreadId(Q),f=$||B;this.logger.debug("Discord API: POST typing",{channelId:f}),await this.discordFetch(`/channels/${f}/typing`,"POST")}async fetchMessages(Q,w={}){let{channelId:B,threadId:$}=this.decodeThreadId(Q),f=$||B,Y=w.limit||50,X=w.direction??"backward",H=new URLSearchParams;if(H.set("limit",String(Y)),w.cursor)if(X==="backward")H.set("before",w.cursor);else H.set("after",w.cursor);this.logger.debug("Discord API: GET messages",{channelId:f,limit:Y,direction:X,cursor:w.cursor});let K=await(await this.discordFetch(`/channels/${f}/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(X==="backward")q=K.at(-1)?.id;else q=K[0]?.id;return{messages:G,nextCursor:q}}async fetchThread(Q){let{channelId:w,guildId:B}=this.decodeThreadId(Q);this.logger.debug("Discord API: GET channel",{channelId:w});let f=await(await this.discordFetch(`/channels/${w}`,"GET")).json();return{id:Q,channelId:w,channelName:f.name,isDM:f.type===rN.DM||f.type===rN.GroupDM,metadata:{guildId:B,channelType:f.type,raw:f}}}async openDM(Q){this.logger.debug("Discord API: POST DM channel",{userId:Q});let B=await(await this.discordFetch("/users/@me/channels","POST",{recipient_id:Q})).json();return this.logger.debug("Discord API: POST DM channel response",{channelId:B.id}),this.encodeThreadId({guildId:"@me",channelId:B.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 WW("discord",`Invalid Discord thread ID: ${Q}`);return{guildId:w[1],channelId:w[2],threadId:w[3]}}parseMessage(Q){let w=Q,B=w.guild_id||"@me",$=this.encodeThreadId({guildId:B,channelId:w.channel_id});return this.parseDiscordMessage(w,$)}parseDiscordMessage(Q,w){let B=Q.type===mF1.ThreadStarterMessage&&Q.referenced_message?Q.referenced_message:Q,$=B.author,f=$.bot??!1,Y=$.id===this.botUserId;return new p5({id:B.id,threadId:w,text:this.formatConverter.extractPlainText(B.content),formatted:this.formatConverter.toAst(B.content),raw:Q,author:{userId:$.id,userName:$.username,fullName:$.global_name||$.username,isBot:f,isMe:Y},metadata:{dateSent:new Date(B.timestamp),edited:B.edited_timestamp!==null,editedAt:B.edited_timestamp?new Date(B.edited_timestamp):void 0},attachments:(B.attachments||[]).map((X)=>({type:this.getAttachmentType(X.content_type),url:X.url,name:X.filename,mimeType:X.content_type,size:X.size,width:X.width??void 0,height:X.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(B){throw new yI("discord","Failed to download Discord attachment",B instanceof Error?B:void 0)}if(!w.ok)throw new yI("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,B){let $=`${this.apiBaseUrl}${Q}`,f={Authorization:`Bot ${this.botToken}`};if(B)f["Content-Type"]="application/json";let Y=await fetch($,{method:w,headers:f,body:B?JSON.stringify(B):void 0});if(!Y.ok){let X=await Y.text();throw this.logger.error("Discord API error",{path:Q,method:w,status:Y.status,error:X}),new yI("discord",`Discord API error: ${Y.status} ${X}`)}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:$?"configured":"not configured"});let f=this.runGatewayListener(w,B,$);return Q.waitUntil(f),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,B){let $=new w7.Client({intents:[w7.GatewayIntentBits.Guilds,w7.GatewayIntentBits.GuildMessages,w7.GatewayIntentBits.MessageContent,w7.GatewayIntentBits.DirectMessages,w7.GatewayIntentBits.GuildMessageReactions,w7.GatewayIntentBits.DirectMessageReactions],partials:[w7.Partials.Channel]}),f=!1;if(B)$.on("raw",async(Y)=>{if(f)return;if(!Y.t)return;this.logger.info("Discord Gateway forwarding event",{type:Y.t}),await this.forwardGatewayEvent(B,{type:`GATEWAY_${Y.t}`,timestamp:Date.now(),data:Y.d})});else this.setupLegacyGatewayHandlers($,()=>f);$.on(w7.Events.ClientReady,()=>{this.logger.info("Discord Gateway connected",{username:$.user?.username,id:$.user?.id})}),$.on(w7.Events.Error,(Y)=>{this.logger.error("Discord Gateway error",{error:String(Y)})});try{await $.login(this.botToken),await new Promise((Y)=>{let X=setTimeout(Y,Q);if(w){if(w.aborted){clearTimeout(X),Y();return}w.addEventListener("abort",()=>{this.logger.info("Discord Gateway listener received abort signal (new listener started)"),clearTimeout(X),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{f=!0,$.destroy(),this.logger.info("Discord Gateway listener stopped")}}setupLegacyGatewayHandlers(Q,w){Q.on(w7.Events.MessageCreate,async(B)=>{if(w()){this.logger.debug("Ignoring message - Gateway is shutting down");return}if(B.author.bot){this.logger.debug("Ignoring message from bot",{authorId:B.author.id,authorName:B.author.username,isMe:B.author.id===Q.user?.id});return}let $=B.mentions.has(Q.user?.id??""),f=this.mentionRoleIds.length>0&&B.mentions.roles.some((X)=>this.mentionRoleIds.includes(X.id)),Y=$||f;this.logger.info("Discord Gateway message received",{channelId:B.channelId,guildId:B.guildId,authorId:B.author.id,isMentioned:Y,isUserMentioned:$,isRoleMentioned:f,content:B.content.slice(0,100)}),await this.handleGatewayMessage(B,Y)}),Q.on(w7.Events.InteractionCreate,async(B)=>{if(w()){this.logger.debug("Ignoring interaction - Gateway is shutting down");return}this.logger.info("Discord Gateway interaction received",{id:B.id,type:B.type});try{await this.handleGatewayInteraction(B)}catch($){this.logger.error("Error handling Gateway interaction",{error:String($),interactionId:B.id})}}),Q.on(w7.Events.MessageReactionAdd,async(B,$)=>{if(w()){this.logger.debug("Ignoring reaction - Gateway is shutting down");return}if($.bot){this.logger.debug("Ignoring reaction from bot",{userId:$.id,isMe:$.id===Q.user?.id});return}if(this.logger.info("Discord Gateway reaction added",{emoji:B.emoji.name,messageId:B.message.id,channelId:B.message.channelId,userId:$.id}),$.username)await this.handleGatewayReaction(B,$,!0)}),Q.on(w7.Events.MessageReactionRemove,async(B,$)=>{if(w()){this.logger.debug("Ignoring reaction removal - Gateway is shutting down");return}if($.bot){this.logger.debug("Ignoring reaction removal from bot",{userId:$.id,isMe:$.id===Q.user?.id});return}if(this.logger.info("Discord Gateway reaction removed",{emoji:B.emoji.name,messageId:B.message.id,channelId:B.message.channelId,userId:$.id}),$.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 B=await fetch(Q,{method:"POST",headers:{"Content-Type":"application/json","x-discord-gateway-token":this.botToken},body:JSON.stringify(w)});if(B.ok)this.logger.debug("Gateway event forwarded successfully",{type:w.type});else{let $=await B.text();this.logger.error("Failed to forward Gateway event",{type:w.type,status:B.status,error:$})}}catch(B){this.logger.error("Error forwarding Gateway event",{type:w.type,error:String(B)})}}async handleGatewayMessage(Q,w){if(!this.chat)return;let B=Q.guildId||"@me",$=Q.channelId,f=Q.channel.isThread(),Y,X=$;if(f&&"parentId"in Q.channel&&Q.channel.parentId)Y=$,X=Q.channel.parentId;if(!Y&&w)try{let K=await this.createDiscordThread($,Q.id);Y=K.id,this.logger.debug("Created Discord thread for incoming mention",{channelId:$,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:B,channelId:X,threadId:Y}),W=new p5({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:$,guild_id:B,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,B){if(!this.chat)return;let $=Q.message.guildId||"@me",f=Q.message.channelId,Y=Q.message.channel?.isThread?.(),X=f,H;if(Y&&Q.message.channel?.parentId)H=f,X=Q.message.channel.parentId;let W=this.encodeThreadId({guildId:$,channelId:X,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:B,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 $=Q.split(":")[2];if(!$)throw new WW("discord",`Invalid Discord channel ID: ${Q}`);let f=w.limit||50,Y=w.direction??"backward",X=new URLSearchParams;if(X.set("limit",String(f)),w.cursor)if(Y==="backward")X.set("before",w.cursor);else X.set("after",w.cursor);this.logger.debug("Discord API: GET channel messages",{channelId:$,limit:f,direction:Y,cursor:w.cursor});let W=await(await this.discordFetch(`/channels/${$}/messages?${X.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===f)if(Y==="backward")G=W.at(-1)?.id;else G=W[0]?.id;return{messages:U,nextCursor:G}}async listThreads(Q,w={}){let B=Q.split(":"),$=B[1],f=B[2];if(!($&&f))throw new WW("discord",`Invalid Discord channel ID: ${Q}`);this.logger.debug("Discord API: GET threads",{guildId:$,channelId:f});let H=((await(await this.discordFetch(`/guilds/${$}/threads/active`,"GET")).json()).threads||[]).filter((b)=>b.parent_id===f),W=[];try{W=(await(await this.discordFetch(`/channels/${f}/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((b)=>{if(U.has(b.id))return!1;return U.add(b.id),!0}),q=w.limit||50,V=G.slice(0,q),J=[];for(let b of V){let L=this.encodeThreadId({guildId:$,channelId:f,threadId:b.id});try{let x=(await(await this.discordFetch(`/channels/${b.id}/messages?limit=1&after=0`,"GET")).json())[0];if(x)J.push({id:L,rootMessage:this.parseDiscordMessage(x,L),replyCount:b.total_message_sent??b.message_count,lastReplyAt:b.thread_metadata?.archive_timestamp?new Date(b.thread_metadata.archive_timestamp):void 0})}catch{J.push({id:L,rootMessage:new p5({id:b.id,threadId:L,text:b.name,formatted:this.formatConverter.toAst(b.name),raw:b,author:{userId:"unknown",userName:"unknown",fullName:"unknown",isBot:!1,isMe:!1},metadata:{dateSent:new Date,edited:!1},attachments:[]}),replyCount:b.total_message_sent??b.message_count})}}return this.logger.debug("Discord API: listThreads result",{threadCount:J.length}),{threads:J,nextCursor:G.length>q?String(q):void 0}}async fetchChannelInfo(Q){let B=Q.split(":")[2];if(!B)throw new WW("discord",`Invalid Discord channel ID: ${Q}`);this.logger.debug("Discord API: GET channel info",{channelId:B});let f=await(await this.discordFetch(`/channels/${B}`,"GET")).json();return{id:Q,name:f.name,isDM:f.type===rN.DM||f.type===rN.GroupDM,memberCount:f.member_count,metadata:{channelType:f.type,raw:f}}}async postChannelMessage(Q,w){let $=Q.split(":")[2];if(!$)throw new WW("discord",`Invalid Discord channel ID: ${Q}`);let f={},Y=[],X=[],H=N80(w);if(H){let q=Em0(H);Y.push(...q.embeds),X.push(...q.components)}else f.content=this.truncateContent(pN(this.formatConverter.renderPostable(w),"discord"));if(Y.length>0)f.embeds=Y;if(X.length>0)f.components=X;let W=zm0(w),K=this.tryPostSlashResponse(Q,f,W);if(K)return K;if(W.length>0)return this.postMessageWithFiles($,Q,f,W);this.logger.debug("Discord API: POST channel message",{channelId:$,contentLength:f.content?.length||0});let G=await(await this.discordFetch(`/channels/${$}/messages`,"POST",f)).json();return{id:G.id,threadId:Q,raw:G}}normalizeDiscordEmoji(Q){let B={"\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 gI(B)}};function dj1(A){return new sgQ(A??{})}var agQ=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 B={threadId:A,token:tgQ(),expiresAt:Date.now()+Q};return this.locks.set(A,B),B}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 B=this.cache.get(A);if(B)if(B.expiresAt!==null&&B.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 B=this.cache.get(A),$;if(B&&B.expiresAt!==null&&B.expiresAt<=Date.now())$=[];else if(B&&Array.isArray(B.value))$=B.value;else $=[];if($.push(Q),w?.maxLength&&$.length>w.maxLength)$=$.slice($.length-w.maxLength);this.cache.set(A,{value:$,expiresAt:w?.ttlMs?Date.now()+w.ttlMs:null})}async enqueue(A,Q,w){this.ensureConnected();let B=this.queues.get(A);if(!B)B=[],this.queues.set(A,B);if(B.push(Q),B.length>w)B.splice(0,B.length-w);return B.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 tgQ(){return`mem_${Date.now()}_${Math.random().toString(36).substring(2,15)}`}function P80(A){return new agQ}_0();var egQ=Z.object({subscribedAt:Z.string().datetime(),routingMode:Z.enum(["auto","mention-required"]).optional(),mentionRequiredNoticeSent:Z.boolean().optional()}),AyQ="chat.discord.subscriptions";function Tm0(A){return A.scoped({namespace:AyQ,schema:egQ})}function nj1(A,Q=P80()){let w=Tm0(A);return new rj1(Q,w)}class rj1{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 oj1(A){let{discord:Q}=A;if(!Q)return new Um0({userName:A.userName,adapters:{},state:P80()});let w=dj1({botToken:Q.botToken,publicKey:Q.publicKey,applicationId:Q.applicationId,mentionRoleIds:Q.mentionRoleIds});return A.gatewayLoop.setAdapter(w),new Um0({userName:A.userName,adapters:{discord:w},concurrency:{strategy:"queue",maxQueueSize:5,onQueueFull:"drop-oldest"},state:nj1(A.runtimeState)})}class Sm0{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 $={...w,routingMode:"mention-required"};if(!Q.isMention&&!w.mentionRequiredNoticeSent)await this.postMentionRequiredNotice(A,$);else await this.deps.getSubscriptions()?.set(A.id,$);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((B)=>!B.isBot&&!B.isMe).length>1}catch(Q){return this.deps.logger.debug("Failed to inspect Discord thread participants",{error:Q,threadId:A.id}),!1}}}wA();class mm0{deps;constructor(A){this.deps=A}async build(A,Q,w,B){let $={message:w.text.trim(),attachments:[],notices:[]};if(w.attachments.length===0)return $;if(!(B==="anchor"||B==="trusted"))return $;let Y=this.deps.getUploadStore();if(!Y)return $;for(let X of w.attachments){let H=X.name;if(!H)continue;let W=Dz(H,"upload"),K=yb(W,X.mimeType),U=X.size??0,G=yA0(W,K);if(!G){$.notices.push(`Unsupported file upload type: ${W}`);continue}if(!EA0(G,U)){$.notices.push(`File upload too large: ${W}`);continue}try{let q=await this.readAttachmentData(X);if(!q)continue;let V=zz({filename:W,mediaType:K,content:q,fallbackFilename:"upload"});if(!V.ok){$.notices.push(V.message);continue}let J=await Y.save({filename:V.filename,mediaType:V.mediaType,content:q,metadata:this.buildMetadata(A,Q,w)});$.attachments.push(aj1(J.filename,J.mediaType,q,J.ref,V.kind==="text"))}catch(q){this.deps.logger.error("Failed to read chat attachment",{error:q,filename:W}),$.notices.push(`Could not read file upload: ${W}`)}}return $}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 B=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,...B.guildId?{guildId:B.guildId}:{},...B.threadId?{threadId:B.threadId}:{}}}}function sj1(A,Q,w,B){return aj1(A,Q,w,B,Eb(A,Q))}function aj1(A,Q,w,B,$){if($)return{kind:"text",filename:A,mediaType:Q,content:w.toString("utf8").replace(/^\uFEFF/,""),sizeBytes:w.byteLength,source:B};return{kind:"file",filename:A,mediaType:Q,data:w,sizeBytes:w.byteLength,source:B}}function _d(){return{namespace:"discord-chat",refKind:"discord-chat-upload",routePath:"/api/webhooks/chat/discord/uploads"}}function FD(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 QyQ(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 tj1(A,Q){if(A.isDM)return!1;let w=FD(A.id);if(!w.threadId)return!1;let B=QyQ(Q);return B!==void 0&&B!==w.threadId}function M80(A,Q){if(Q.allowedChannels.length===0||A.isDM)return!0;let w=FD(A.id);return[A.id,A.channelId,w.channelId,w.threadId].some((B)=>typeof B==="string"&&Q.allowedChannels.includes(B))}function um0(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 M80(A,w)}function cm0(A,Q,w){if(Q!=="discord")return!0;if(!w)return!1;if(A.isDM&&!w.allowDMs)return!1;return M80(A,w)}function lm0(A,Q){return{channelId:FD(A.id).channelId??A.channelId,isBot:Boolean(Q.author.isBot)}}function PC(A){return A.isDM?"DM":A.channelId}var wyQ="https://discord.com/api/v10";async function ej1(A){let Q=FD(A.threadId),w=Q.threadId??Q.channelId;if(!w)return;let B=A.fetchFn??fetch;try{let $=await B(`${wyQ}/channels/${w}/messages/${A.messageId}`,{method:"PATCH",headers:{Authorization:`Bot ${A.botToken}`,"Content-Type":"application/json"},body:JSON.stringify({components:[]})});if(!$.ok)A.logger.debug("Failed to clear Discord message components",{messageId:A.messageId,channelId:w,status:$.status})}catch($){A.logger.debug("Failed to clear Discord message components",{error:$,messageId:A.messageId,channelId:w})}}var AP1={name:"@brains/chat",version:"0.2.0-alpha.151",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 $yQ=/https?:\/\/\S+/i,fyQ=/[\s\S]+/,YyQ=1000,XyQ=Z.looseObject({type:Z.literal("card"),children:Z.array(Z.looseObject({type:Z.string()})),imageUrl:Z.string().optional(),subtitle:Z.string().optional(),title:Z.string().optional()}),ZyQ=Z.object({card:Z.custom((A)=>XyQ.safeParse(A).success),fallbackText:Z.string().optional()});class O80 extends WK{threadRegistry=new U80;pendingApprovals;uploadContinuity;promptActions=new cT0(YyQ);toolStatusMessenger=new lT0(this.threadRegistry);cardBuilder=new nT0({getDisplayBaseUrl:()=>this.getPreferredDisplayBaseUrl(),registerPromptAction:(A,Q)=>this.registerPromptAction(A,Q)});artifactDelivery=new oT0({getContext:()=>this.context,getDisplayBaseUrl:()=>this.getPreferredDisplayBaseUrl(),logger:this.logger});approvalCards=new sT0({cardBuilder:this.cardBuilder,clearMessageComponents:async(A,Q)=>{let w=this.config.adapters.discord?.botToken;if(!w)return;await ej1({threadId:A,messageId:Q,botToken:w,logger:this.logger})}});subscriptionRouter=new Sm0({getSubscriptions:()=>this.discordSubscriptions,getPlatform:(A)=>this.getPlatform(A),isBotCreatedThread:tj1,logger:this.logger});chatInputBuilder=new mm0({getUploadStore:()=>this.context?.uploads.scoped(_d()),getThreadIdParts:FD,logger:this.logger});gatewayLoop;discordApp;discordSubscriptions;constructor(A={}){super("chat",AP1,A,uT0);this.gatewayLoop=new aT0({getApp:()=>this.discordApp.instance,gatewayRunMs:this.config.gatewayRunMs,gatewayRestartDelayMs:this.config.gatewayRestartDelayMs,logger:this.logger}),this.discordApp=new tT0({discord:this.config.adapters.discord,getUploadStore:()=>this.context?.uploads.scoped(_d()),buildApp:(Q)=>oj1({userName:this.config.userName,discord:this.config.adapters.discord,gatewayLoop:this.gatewayLoop,runtimeState:Q})}),this.pendingApprovals=new Km({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 Vm({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(_d());if(!w)throw Error("Chat upload store unavailable");let B=await w.read(Q);return sj1(B.record.filename,B.record.mediaType,B.content,B.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=Tm0(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 B=this.toDiscordCardOutput(Q);if(B){w.post(B).catch(($)=>this.logger.error("Failed to send chat message",{error:$,channelId:A}));return}if(typeof Q!=="string")return;for(let $ of Ud(A,Q))w.post($).catch((f)=>this.logger.error("Failed to send chat message",{error:f,channelId:A}))}async sendMessageWithId({channelId:A,message:Q}){let w=this.threadRegistry.get(A);if(!w)return;let B=this.toDiscordCardOutput(Q);if(B){let f=await w.post(B);return this.threadRegistry.trackMessage(w.id,f),f.id}if(typeof Q!=="string")return;let $;for(let f of Ud(A,Q))$=await w.post(f),this.threadRegistry.trackMessage(w.id,$);return $?.id}async editMessage({channelId:A,messageId:Q,newMessage:w}){let B=this.threadRegistry.getMessage(A,Q);if(!B)return!1;try{let $=await B.edit(this.toDiscordCardOutput(w)??(typeof w==="string"?w:""));if(A)this.threadRegistry.trackMessage(A,$);return!0}catch{return!1}}supportsMessageEditing(){return!0}toDiscordCardOutput(A){let Q=ZyQ.safeParse(A);if(!Q.success)return;let{card:w,fallbackText:B}=Q.data;if(B===void 0)return{card:w};return{card:w,fallbackText:B}}formatProgressOutput(A){return dT0(A)}formatCompletionOutput(A){return dT0(A)}async handleProgressEvent(A,Q){let w=A.metadata.interfaceType;if(w&&w!==this.id){if(!this.isEnabledPlatform(w))return;let B={...A,metadata:{...A.metadata,interfaceType:this.id}};await super.handleProgressEvent(B,B.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 jz1(A,Boolean(this.config.adapters.discord))}registerChatHandlers(A){if(A.onDirectMessage(async(Q,w,B,$)=>{await this.handleRoutedMessage(Q,w,$)}),A.onNewMention(async(Q,w,B)=>{let $=this.getPlatformConfig(Q);if($&&um0(Q,w,$)&&!Q.isDM&&$.useThreads)await this.subscriptionRouter.subscribeOwnedThread(Q,w);await this.handleRoutedMessage(Q,w,B)}),A.onSubscribedMessage(async(Q,w,B)=>{if(!await this.subscriptionRouter.shouldRouteSubscribedMessage(Q,w))return;await this.handleRoutedMessage(Q,w,B)}),this.config.adapters.discord&&!this.config.adapters.discord.requireMention)A.onNewMessage(fyQ,async(Q,w,B)=>{await this.handleRoutedMessage(Q,w,B)});A.onNewMessage($yQ,async(Q,w)=>{await this.handlePassiveUrlCapture(Q,w)}),A.onAction([G80,pT0],async(Q)=>{await this.handleApprovalAction(Q)}),A.onAction(iT0,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(!cm0(w,Q,this.config.adapters.discord))return;let B=this.promptActions.get(A.value);if(B?.threadId!==w.id){await w.post(this.formatNoticePayload("That suggested action is no longer available.","Action unavailable"));return}this.promptActions.consume(A.value);let $=FD(w.id),f=this.context.permissions.getUserLevel(Q,A.user.userId,{channelId:$.channelId??w.channelId,isBot:Boolean(A.user.isBot)}),Y=this.getConversationId(Q,w.id),X=w.id;await this.runAgentTurn({thread:w,channelId:X,logLabel:"Error handling chat prompt action",body:async()=>{if(!this.context)return;let H=await this.context.agent.chat(B.prompt,Y,{userPermissionLevel:f,interfaceType:Q,channelId:X,channelName:PC(w),...this.buildActionEventMetadata(Q,w,A)});await this.renderAgentResponse({thread:w,channelId:X,conversationId:Y,response:H,userPermissionLevel:f})}})}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 $=A.thread;if(!cm0($,Q,this.config.adapters.discord))return;let f=FD($.id),Y=this.context.permissions.getUserLevel(Q,A.user.userId,{channelId:f.channelId??$.channelId,isBot:Boolean(A.user.isBot)});await this.confirmApproval({thread:$,conversationId:w,approvalId:A.value,confirmed:A.actionId===G80,userPermissionLevel:Y,metadata:this.buildActionEventMetadata(Q,$,A)})}async handleRoutedMessage(A,Q,w){if(!this.context)return;let B=this.getPlatform(A);if(B!=="discord")return;let $=this.getPlatformConfig(A);if(!$)return;if(!um0(A,Q,$))return;await this.routeToAgent(B,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 B=this.formatErrorPayload(w),$=this.toDiscordCardOutput(B);if($){await A.post($);return}let f=typeof B==="string"?B:"Message failed.";for(let Y of Ud(Q,f))await A.post(Y)}async routeToAgent(A,Q,w,B){if(!this.context)return;this.threadRegistry.set(Q);let $=this.getConversationId(A,Q.id),f=Q.id,Y=lm0(Q,w),X=this.context.permissions.getUserLevel(A,w.author.userId,Y),H=await this.chatInputBuilder.build(A,Q,w,X),W=[...H.attachments];if(await this.attachPriorUploads($,H,X),await this.postUploadNotices(Q,H.notices),!H.message&&H.attachments.length===0)return;this.rememberUploadAttachments($,W),await this.runAgentTurn({thread:Q,channelId:f,logLabel:"Error handling chat message",body:async()=>{if(!this.context)return;let K=await this.getPendingApprovalIds($);if(K.size>0){if(await this.handleConfirmationResponse(H.message,$,Q,K,X,this.buildUserMessageMetadata(A,Q,w)))return}let U=this.buildCoalescedAgentInput(H.message,B),G=await this.context.agent.chat(U.message,$,{userPermissionLevel:X,interfaceType:A,channelId:f,channelName:PC(Q),...this.buildUserMessageMetadata(A,Q,w,U.metadata),...H.attachments.length>0?{attachments:H.attachments}:{}});await this.renderAgentResponse({thread:Q,channelId:f,conversationId:$,response:G,userPermissionLevel:X})}})}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=Lk(A.response,{deniedCardIds:Q.deniedCardIds});if(A.confirmation)await this.approvalCards.resolve(A.conversationId,A.confirmation.approvalId,A.confirmation.confirmed);let B=A.confirmation?this.formatConfirmationResponsePayload(A.response,A.confirmation.confirmed,this.getRemainingApprovalHelp(A.conversationId,A.response),Q.deniedCardIds):this.formatAgentResponseText(w,Q.deniedCardIds),$=await this.sendAgentResponseWithFiles({thread:A.thread,channelId:A.channelId,message:B,files:Q.files}),f=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 X=f??$;if(X)for(let H of w.jobIds)this.trackAgentResponseForJob(H,X,A.channelId)}rememberPendingConfirmationsFromResponse(A,Q){this.pendingApprovals.rememberFromResponse(A,Q)}async getPendingApprovalIds(A){return this.pendingApprovals.getApprovalIds(A)}async handleConfirmationResponse(A,Q,w,B,$,f){if(!Xm(A,B))return!1;let Y=kA0({message:A,approvalIds:B});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:$,...f?{metadata:f}:{}}),!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:PC(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(`
|
|
2373
2373
|
|
|
2374
2374
|
`)}formatConfirmationResponsePayload(A,Q,w,B){let $=RA0({response:A,confirmed:Q,remainingApprovalHelp:w,deniedCardIds:B,formatCard:(f)=>this.cardBuilder.formatStructuredCard(f,B),formatPendingConfirmationHelp:Yx});return{card:{type:"card",title:xA0($.variant),children:$.parts.map((f)=>({type:"text",content:f}))},fallbackText:$.parts.join(`
|
|
2375
2375
|
|
|
@@ -2441,7 +2441,7 @@ ${tS0(A)}
|
|
|
2441
2441
|
<p>Once built, this page will be replaced with your actual website.</p>
|
|
2442
2442
|
</div>
|
|
2443
2443
|
</body>
|
|
2444
|
-
</html>`;var EP1={name:"@brains/webserver",version:"0.2.0-alpha.150",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:"^6.0.3"},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 TI extends _G{serverManager;siteUrl;previewUrl;constructor(A={}){super("webserver",EP1,A,Xu0)}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 u80({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}`,B=this.previewUrl??A?.previewUrl??`http://localhost:${this.config.previewPort}`,$=[];if(Q){if($.push(`Production: ${w}`),A?.previewUrl)$.push(`Preview: ${B}`)}return{status:Q?"healthy":"error",message:Q?$.join(", "):"Webserver not running",lastCheck:new Date,details:{preview:!!A?.previewUrl,production:Q,previewUrl:A?.previewUrl?B: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&&!TP1(this.config.previewDistDir))await A(this.config.previewDistDir,{recursive:!0}),await Q(SP1(this.config.previewDistDir,"index.html"),Zu0),this.logger.debug(`Created preview directory at ${this.config.previewDistDir}`);if(!TP1(this.config.productionDistDir))await A(this.config.productionDistDir,{recursive:!0}),await Q(SP1(this.config.productionDistDir,"index.html"),Zu0),this.logger.debug(`Created production directory at ${this.config.productionDistDir}`)}}y6();wA();_0();Tk();var mP1={name:"@brains/web-chat",version:"0.2.0-alpha.150",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:"^6.0.3",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"};wA();async function uP1(A,Q){let w=await Q.resolvePermissionLevel(A);if(w==="public")return Q.createOperatorLoginRequiredResponse(A);let B=new URL(A.url),$=B.searchParams.get("id")?.trim();if(!$)return new Response("Missing document id",{status:400});let f=await lP1({entityType:"document",id:$,permissionLevel:w,entityService:Q.entityService});if(!f)return new Response("Document not found",{status:404});if(typeof f.content!=="string")return new Response("Document content is not a PDF",{status:415});let Y=Wz("document",f.content);if(!Y)return new Response("Document content is not a PDF",{status:415});let X=Kz(f.metadata,$,"document",Y.mimeType);return pP1({requestUrl:B,data:Y.data,mediaType:Y.mimeType,filename:X})}async function cP1(A,Q){let w=await Q.resolvePermissionLevel(A);if(w==="public")return Q.createOperatorLoginRequiredResponse(A);let B=new URL(A.url),$=B.searchParams.get("id")?.trim();if(!$)return new Response("Missing image id",{status:400});let f=await lP1({entityType:"image",id:$,permissionLevel:w,entityService:Q.entityService});if(!f)return new Response("Image not found",{status:404});if(typeof f.content!=="string")return new Response("Image content is not an image",{status:415});let Y=Wz("image",f.content);if(!Y)return new Response("Image content is not an image",{status:415});let X=Kz(f.metadata,$,"image",Y.mimeType);return pP1({requestUrl:B,data:Y.data,mediaType:Y.mimeType,filename:X})}async function lP1(A){let Q={entityType:A.entityType,id:A.id},w=await Uz({entityRef:Q,userLevel:A.permissionLevel,getEntity:(B)=>A.entityService.getEntity(B),getVisibleEntity:(B,$)=>A.entityService.getEntity({...B,visibilityScope:$})});return w.status==="visible"?w.entity:void 0}function pP1(A){let Q=new Headers({"Content-Type":A.mediaType,"Content-Length":String(A.data.byteLength),"Content-Disposition":Cb({disposition:A.requestUrl.searchParams.has("download")?"attachment":"inline",filename:A.filename})});return new Response(A.data,{headers:Q})}_0();wA();var vd="upload",iP1=sO;var BEQ={namespace:"upload",refKind:vd,routePath:"/api/chat/uploads"};function c80(){return BEQ}wA();AF0();var dP1=CA0;var nP1=gA0;var $EQ="file",fEQ=16384;async function rP1(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>nP1+fEQ)return new Response("File upload too large",{status:400});let B;try{B=await A.formData()}catch{return new Response("Invalid multipart upload",{status:400})}let $=B.get($EQ);if(!($ instanceof File))return new Response("Missing upload file",{status:400});let f=Buffer.from(await $.arrayBuffer()),Y=zz({filename:$.name,mediaType:$.type,content:f});if(!Y.ok)return new Response(Y.message,{status:400});let X=Q.getUploadStore(),H=await X.save({filename:Y.filename,mediaType:Y.mediaType,content:f});return Response.json(X.toResponseBody(H),{status:201})}async function oP1(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 B=await tP1(w,Q.getUploadStore());if(B instanceof Response)return B;let{record:$,content:f}=B,Y=eP1($,f);if(Y instanceof Response)return Y;let X=new URL(A.url).searchParams.has("download")?"attachment":"inline",H=new Uint8Array(f).buffer;return new Response(H,{headers:{"Content-Type":$.mediaType,"Content-Length":String(f.byteLength),"Content-Disposition":Cb({disposition:X,filename:$.filename})}})}function sP1(A){let Q=Dz(A.filename??dP1),w=XEQ(A.url);if(!w)return new Response(`Unsupported file upload URL: ${Q}`,{status:400});let B=zz({filename:Q,mediaType:A.mediaType,content:w.buffer});if(!B.ok)return new Response(B.message,{status:400});return AM1(B,w.buffer)}async function aP1(A,Q){let w=await tP1(A,Q);if(w instanceof Response)return w;let{record:B,content:$}=w,f=eP1(B,$);if(f instanceof Response)return f;return AM1(f,$,{kind:vd,id:A})}async function tP1(A,Q){try{return await Q.read(A)}catch(w){if(w instanceof NG)return YEQ(w);throw w}}function eP1(A,Q){let w=zz({filename:A.filename,mediaType:A.mediaType,content:Q});if(!w.ok)return new Response(w.message,{status:400});return w}function AM1(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 YEQ(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 XEQ(A){let Q=/^data:[^,]*,(.*)$/s.exec(A);if(!Q)return null;let B=A.slice(5,A.indexOf(",")).split(";").some(($)=>$.toLowerCase()==="base64");try{let $=B?Buffer.from(Q[1]??"","base64"):Buffer.from(decodeURIComponent(Q[1]??""),"utf8");return{buffer:$,byteLength:$.byteLength}}catch{return null}}var ZEQ=Z.object({type:Z.literal("text"),text:Z.string()}),HEQ=Z.object({type:Z.literal("file"),mediaType:Z.string().optional(),filename:Z.string().optional(),url:Z.string()}),WEQ=Z.looseObject({state:Z.literal("approval-responded"),approval:Z.object({id:Z.string(),approved:Z.boolean()})}),KEQ=Z.object({id:Z.string().optional(),role:Z.string(),parts:Z.array(Z.unknown()).optional(),content:Z.string().optional()}),QM1=Z.object({id:Z.string().optional(),messages:Z.array(KEQ).min(1),trigger:Z.string().optional()}),UEQ=Z.object({kind:Z.literal(vd),id:Z.string().regex(iP1)}),GEQ=Z.object({type:Z.literal("data-upload"),data:Z.object({ref:UEQ})});async function wM1(A,Q){let w=DEQ(A);if(!w)return{message:"",attachments:[]};let B=[],$=[];for(let Y of w.parts??[]){let X=ZEQ.safeParse(Y);if(X.success){if(X.data.text.length>0)B.push(X.data.text);continue}let H=HEQ.safeParse(Y);if(H.success){let K=sP1(H.data);if(K instanceof Response)return K;$.push(K);continue}let W=GEQ.safeParse(Y);if(W.success){let K=await aP1(W.data.data.ref.id,Q.uploadStore);if(K instanceof Response)return K;$.push(K);continue}if(zEQ(Y)==="data-upload")return new Response("Invalid upload ref",{status:400})}return{message:B.length>0?B.join(`
|
|
2444
|
+
</html>`;var EP1={name:"@brains/webserver",version:"0.2.0-alpha.151",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 TI extends _G{serverManager;siteUrl;previewUrl;constructor(A={}){super("webserver",EP1,A,Xu0)}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 u80({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}`,B=this.previewUrl??A?.previewUrl??`http://localhost:${this.config.previewPort}`,$=[];if(Q){if($.push(`Production: ${w}`),A?.previewUrl)$.push(`Preview: ${B}`)}return{status:Q?"healthy":"error",message:Q?$.join(", "):"Webserver not running",lastCheck:new Date,details:{preview:!!A?.previewUrl,production:Q,previewUrl:A?.previewUrl?B: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&&!TP1(this.config.previewDistDir))await A(this.config.previewDistDir,{recursive:!0}),await Q(SP1(this.config.previewDistDir,"index.html"),Zu0),this.logger.debug(`Created preview directory at ${this.config.previewDistDir}`);if(!TP1(this.config.productionDistDir))await A(this.config.productionDistDir,{recursive:!0}),await Q(SP1(this.config.productionDistDir,"index.html"),Zu0),this.logger.debug(`Created production directory at ${this.config.productionDistDir}`)}}y6();wA();_0();Tk();var mP1={name:"@brains/web-chat",version:"0.2.0-alpha.151",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"};wA();async function uP1(A,Q){let w=await Q.resolvePermissionLevel(A);if(w==="public")return Q.createOperatorLoginRequiredResponse(A);let B=new URL(A.url),$=B.searchParams.get("id")?.trim();if(!$)return new Response("Missing document id",{status:400});let f=await lP1({entityType:"document",id:$,permissionLevel:w,entityService:Q.entityService});if(!f)return new Response("Document not found",{status:404});if(typeof f.content!=="string")return new Response("Document content is not a PDF",{status:415});let Y=Wz("document",f.content);if(!Y)return new Response("Document content is not a PDF",{status:415});let X=Kz(f.metadata,$,"document",Y.mimeType);return pP1({requestUrl:B,data:Y.data,mediaType:Y.mimeType,filename:X})}async function cP1(A,Q){let w=await Q.resolvePermissionLevel(A);if(w==="public")return Q.createOperatorLoginRequiredResponse(A);let B=new URL(A.url),$=B.searchParams.get("id")?.trim();if(!$)return new Response("Missing image id",{status:400});let f=await lP1({entityType:"image",id:$,permissionLevel:w,entityService:Q.entityService});if(!f)return new Response("Image not found",{status:404});if(typeof f.content!=="string")return new Response("Image content is not an image",{status:415});let Y=Wz("image",f.content);if(!Y)return new Response("Image content is not an image",{status:415});let X=Kz(f.metadata,$,"image",Y.mimeType);return pP1({requestUrl:B,data:Y.data,mediaType:Y.mimeType,filename:X})}async function lP1(A){let Q={entityType:A.entityType,id:A.id},w=await Uz({entityRef:Q,userLevel:A.permissionLevel,getEntity:(B)=>A.entityService.getEntity(B),getVisibleEntity:(B,$)=>A.entityService.getEntity({...B,visibilityScope:$})});return w.status==="visible"?w.entity:void 0}function pP1(A){let Q=new Headers({"Content-Type":A.mediaType,"Content-Length":String(A.data.byteLength),"Content-Disposition":Cb({disposition:A.requestUrl.searchParams.has("download")?"attachment":"inline",filename:A.filename})});return new Response(A.data,{headers:Q})}_0();wA();var vd="upload",iP1=sO;var BEQ={namespace:"upload",refKind:vd,routePath:"/api/chat/uploads"};function c80(){return BEQ}wA();AF0();var dP1=CA0;var nP1=gA0;var $EQ="file",fEQ=16384;async function rP1(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>nP1+fEQ)return new Response("File upload too large",{status:400});let B;try{B=await A.formData()}catch{return new Response("Invalid multipart upload",{status:400})}let $=B.get($EQ);if(!($ instanceof File))return new Response("Missing upload file",{status:400});let f=Buffer.from(await $.arrayBuffer()),Y=zz({filename:$.name,mediaType:$.type,content:f});if(!Y.ok)return new Response(Y.message,{status:400});let X=Q.getUploadStore(),H=await X.save({filename:Y.filename,mediaType:Y.mediaType,content:f});return Response.json(X.toResponseBody(H),{status:201})}async function oP1(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 B=await tP1(w,Q.getUploadStore());if(B instanceof Response)return B;let{record:$,content:f}=B,Y=eP1($,f);if(Y instanceof Response)return Y;let X=new URL(A.url).searchParams.has("download")?"attachment":"inline",H=new Uint8Array(f).buffer;return new Response(H,{headers:{"Content-Type":$.mediaType,"Content-Length":String(f.byteLength),"Content-Disposition":Cb({disposition:X,filename:$.filename})}})}function sP1(A){let Q=Dz(A.filename??dP1),w=XEQ(A.url);if(!w)return new Response(`Unsupported file upload URL: ${Q}`,{status:400});let B=zz({filename:Q,mediaType:A.mediaType,content:w.buffer});if(!B.ok)return new Response(B.message,{status:400});return AM1(B,w.buffer)}async function aP1(A,Q){let w=await tP1(A,Q);if(w instanceof Response)return w;let{record:B,content:$}=w,f=eP1(B,$);if(f instanceof Response)return f;return AM1(f,$,{kind:vd,id:A})}async function tP1(A,Q){try{return await Q.read(A)}catch(w){if(w instanceof NG)return YEQ(w);throw w}}function eP1(A,Q){let w=zz({filename:A.filename,mediaType:A.mediaType,content:Q});if(!w.ok)return new Response(w.message,{status:400});return w}function AM1(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 YEQ(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 XEQ(A){let Q=/^data:[^,]*,(.*)$/s.exec(A);if(!Q)return null;let B=A.slice(5,A.indexOf(",")).split(";").some(($)=>$.toLowerCase()==="base64");try{let $=B?Buffer.from(Q[1]??"","base64"):Buffer.from(decodeURIComponent(Q[1]??""),"utf8");return{buffer:$,byteLength:$.byteLength}}catch{return null}}var ZEQ=Z.object({type:Z.literal("text"),text:Z.string()}),HEQ=Z.object({type:Z.literal("file"),mediaType:Z.string().optional(),filename:Z.string().optional(),url:Z.string()}),WEQ=Z.looseObject({state:Z.literal("approval-responded"),approval:Z.object({id:Z.string(),approved:Z.boolean()})}),KEQ=Z.object({id:Z.string().optional(),role:Z.string(),parts:Z.array(Z.unknown()).optional(),content:Z.string().optional()}),QM1=Z.object({id:Z.string().optional(),messages:Z.array(KEQ).min(1),trigger:Z.string().optional()}),UEQ=Z.object({kind:Z.literal(vd),id:Z.string().regex(iP1)}),GEQ=Z.object({type:Z.literal("data-upload"),data:Z.object({ref:UEQ})});async function wM1(A,Q){let w=DEQ(A);if(!w)return{message:"",attachments:[]};let B=[],$=[];for(let Y of w.parts??[]){let X=ZEQ.safeParse(Y);if(X.success){if(X.data.text.length>0)B.push(X.data.text);continue}let H=HEQ.safeParse(Y);if(H.success){let K=sP1(H.data);if(K instanceof Response)return K;$.push(K);continue}let W=GEQ.safeParse(Y);if(W.success){let K=await aP1(W.data.data.ref.id,Q.uploadStore);if(K instanceof Response)return K;$.push(K);continue}if(zEQ(Y)==="data-upload")return new Response("Invalid upload ref",{status:400})}return{message:B.length>0?B.join(`
|
|
2445
2445
|
|
|
2446
2446
|
`):w.content??"",attachments:$,...w.id?{messageId:w.id}:{}}}function BM1(A){let Q=A.messages.at(-1);if(!Q||Q.role==="user")return[];return(Q.parts??[]).map((w)=>WEQ.safeParse(w)).filter((w)=>w.success).map((w)=>w.data.approval)}function DEQ(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 zEQ(A){if(typeof A!=="object"||A===null||!("type"in A))return;let Q=A.type;return typeof Q==="string"?Q:void 0}wA();var qEQ=/\n{0,2}\[Entities affected this turn: [\s\S]*? Reference these IDs directly in follow-ups instead of searching for them\.\]\s*$/;function l80(A){return A.replace(qEQ,"").trimEnd()}wA();function $M1(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 Hu0(A,Q){let w=Q.directives.flatMap((B)=>{switch(B.kind){case"artifact":case"supplemental":return[B.card];case"approvals":return B.cards;default:return[]}});for(let B of w){let $=uA0(B);if($.kind==="attachment"){A.write({type:"data-attachment",id:$.id,data:$});continue}if($.kind==="sources"){A.write({type:"data-sources",id:$.id,data:$});continue}if($.kind==="actions"){A.write({type:"data-actions",id:$.id,data:$});continue}let f=$.toolCallId??$.id,Y=$.input??{};switch(A.write({type:"tool-input-available",toolCallId:f,toolName:$.toolName,input:Y,dynamic:!0,title:$.preview?`${$.summary}
|
|
2447
2447
|
|
|
@@ -5434,7 +5434,7 @@ ${DM1}</style></head><body>${hd(A)}<main id="root" data-web-chat-root>Brain Chat
|
|
|
5434
5434
|
|
|
5435
5435
|
`);$=Y.pop()??"";for(let X of Y){let H=X.split(`
|
|
5436
5436
|
`).find((J)=>J.startsWith("data: "));if(!H)continue;let W;try{let J=XTQ.safeParse(JSON.parse(H.slice(6)));if(!J.success)continue;W=J.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((J)=>J.kind==="text"&&typeof J.text==="string").map((J)=>J.text).join(`
|
|
5437
|
-
`)||"No response text";return{success:!0,data:{state:G,response:V}}}f=await lM1(w,Q)}return{success:!1,error:"Stream ended without a terminal event"}}class Cd extends Error{timeoutMs;constructor(A){super(`request timed out after ${A}ms`);this.timeoutMs=A,this.name="A2ARequestTimeoutError"}}class gd extends Error{timeoutMs;constructor(A){super(`A2A stream stalled waiting for final event after ${A}ms`);this.timeoutMs=A,this.name="A2AStreamIdleTimeoutError"}}async function qTQ(A,Q,w,B){let $=new AbortController,f;try{return await Promise.race([A(Q,{...w,signal:$.signal}),new Promise((Y,X)=>{f=setTimeout(()=>{$.abort(),X(new Cd(B))},B)})])}catch(Y){if(Y instanceof Cd)throw Y;if($.signal.aborted)throw new Cd(B);throw Y}finally{if(f)clearTimeout(f)}}async function lM1(A,Q){let w;try{return await Promise.race([A.read(),new Promise((B,$)=>{w=setTimeout(()=>$(new gd(Q)),Q)})])}catch(B){if(B instanceof gd)A.cancel().catch(()=>{});throw B}finally{if(w)clearTimeout(w)}}function VTQ(A){if(A instanceof Cd||A instanceof gd)return!1;return A instanceof Error}function Iu0(A,Q){let w=Q>1?` after ${Q} attempts`:"";if(A instanceof gd)return`${A.message}${w}`;let B=A instanceof Error?A.message:"Unknown network error";return`Failed to reach remote agent${w}: ${B}`}function iM1(A={}){let Q=A.fetch??globalThis.fetch,w={requestTimeoutMs:A.requestTimeoutMs??ZTQ,streamIdleTimeoutMs:A.streamIdleTimeoutMs??HTQ,maxNetworkAttempts:A.maxNetworkAttempts??WTQ};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:KTQ,visibility:"trusted",sideEffects:"external",handler:async(B)=>{let $=UTQ.safeParse(B);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};let{agent:f,message:Y}=$.data,X=GTQ(f);if(!X.ok)return{success:!1,error:X.error};let{agentId:H}=X;if(!A.entityService)return{success:!1,error:"Agent directory is unavailable. Add the agent first, then try again."};let W=await A.entityService.getEntity({entityType:"agent",id:H,visibilityScope:m9("agent_call tool is anchor-only and resolves saved remote agents at any visibility")});if(!W){if(!DTQ(H))return{success:!1,error:`Agent ${f} is not an exact domain-like id and is not saved. Connect or clarify the agent first.`,code:"agent_not_saved"};let V=`https://${H}`,J=await uM1(V,Q);if(!J)return{success:!1,error:`Could not verify an A2A Agent Card for ${H}. Connect/save it first if you want to add it to the directory.`,code:"agent_card_unavailable"};let b=mM1(J.url,H);if(!b.ok)return{success:!1,error:b.error};let L=await cM1(J.url,Y,Q,A.requestSigner,w);if("success"in L&&L.success===!0){let N=typeof L.data==="object"&&L.data!==null?L.data:{};return{...L,data:{...N,agentCall:{mode:"one-shot",agent:H},agentContactCandidate:{source:{kind:"url",url:X.sourceUrl??H}}}}}return L}if(W.metadata.status==="archived")return{success:!1,error:`Agent ${H} is archived and cannot be contacted until it is restored and approved.`,code:"agent_archived"};if(W.metadata.status!=="approved")return{success:!1,error:`Agent ${H} is discovered but not approved yet. Approve it first.`,code:"agent_not_approved"};let K=`https://${H}`,U=await uM1(K,Q);if(!U)return{success:!1,error:`Could not fetch Agent Card from ${K}`};let G=mM1(U.url,H);if(!G.ok)return{success:!1,error:G.error};let q=U.url;return cM1(q,Y,Q,A.requestSigner,w)}}}var Fu0={name:"@brains/a2a",version:"0.2.0-alpha.150",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:"^6.0.3"},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 JTQ={"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 CC extends _G{agentCard;taskManager=new Ju0;agentService;jwksResolver=new Vu0;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",Fu0,A,vM1)}async onRegister(A){if(await super.onRegister(A),this.hasWebserver=A.plugins.has("webserver"),this.agentService=A.agent,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(),B=A.tools.listForPermissionLevel("public"),$;if(A.entityService.hasEntityType("skill"))try{let f=await A.entityService.listEntities({entityType:"skill",options:{filter:{visibilityScope:"public"}}});if(f.length>0)$=f.map((Y)=>Jm.safeParse(Y.metadata)).filter((Y)=>Y.success).map((Y)=>Y.data)}catch{}this.agentCard=RM1({character:Q,profile:w,version:Fu0.version,domain:A.domain,organization:this.config.organization,tools:B,skills:$,authEnabled:!1}),this.logger.debug("Agent Card rebuilt",{skills:this.agentCard.skills.length})}getAgentCard(){return this.agentCard}async resolveCaller(A,Q){let w=await MM1({method:A.method,url:A.url,headers:A.headers,body:Q},this.jwksResolver);if(w){let B=await M7()?.getA2APeerTrust(w.domain);return{permissionLevel:B?.keyFingerprint===w.keyFingerprint?B.grantedLevel:"public",callerDomain:w.domain}}return{permissionLevel:"public",callerDomain:null}}withCors(A){let Q=new Headers(A.headers);for(let[w,B]of Object.entries(JTQ))Q.set(w,B);return new Response(A.body,{status:A.status,statusText:A.statusText,headers:Q})}getOrCreateApp(){if(this.app)return this.app;let A=new OC;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(),B;try{B=await this.resolveCaller(Q.req.raw,w)}catch{return this.withCors(Q.json({error:"Invalid HTTP signature"},401))}let $;try{$=JSON.parse(w)}catch{return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32700,message:"Parse error"},id:null}))}let f=gM1.safeParse($);if(!f.success)return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32600,message:"Invalid request"},id:null}));if(f.data.method==="message/stream"){let X=EM1.safeParse(f.data.params??{});if(!X.success)return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32602,message:`Invalid params: ${X.error.message}`},id:f.data.id}));let H=TM1(f.data.id,X.data.message,{taskManager:this.taskManager,agentService:this.agentService,callerPermissionLevel:B.permissionLevel,callerDomain:B.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 yM1(f.data,{taskManager:this.taskManager,agentService:this.agentService,callerPermissionLevel:B.permissionLevel,callerDomain:B.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=M7();if(!A)return;return async(Q)=>{let w=await A.getA2ASigningKey();await PM1(Q,w.privateJwk,w.keyId)}}async getTools(){return[iM1({requestSigner:this.createRequestSigner(),requestTimeoutMs:this.config.requestTimeoutMs,streamIdleTimeoutMs:this.config.streamIdleTimeoutMs,maxNetworkAttempts:this.config.maxNetworkAttempts,entityService:this.getContext().entityService})]}async getInstructions(){return"## Agent-to-agent calls\n- Use `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")}}}}wA();_0();var dM1={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 nM1={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 rM1={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 oM1={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 sM1={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 aM1={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 tM1={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 eM1={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 AO1={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 OTQ=Z.object({type:Z.string()}).catchall(Z.unknown()),xTQ=Z.object({lexicon:Z.literal(1),id:Z.string(),defs:Z.object({main:Z.object({type:Z.literal("record"),key:Z.string().min(1),record:Z.object({type:Z.literal("object"),required:Z.array(Z.string()).optional(),properties:Z.record(Z.string(),OTQ)})})})});function BU(A){return xTQ.parse(A)}var k6={"ai.rizom.brain.card":BU(dM1),"ai.rizom.brain.deck":BU(nM1),"ai.rizom.brain.link":BU(rM1),"ai.rizom.brain.note":BU(oM1),"ai.rizom.brain.post":BU(sM1),"ai.rizom.brain.project":BU(aM1),"ai.rizom.brain.series":BU(tM1),"ai.rizom.brain.socialPost":BU(eM1),"ai.rizom.brain.topic":BU(AO1)},vTQ="Additive optional fields are compatible; required-field, type, or constraint changes require a migration plan or new NSID.";function Oq(A){return{status:"approved",version:"1.0.0",revision:1,owner:"Rizom",steward:"Rizom protocol registry",projectionPackage:A,compatibility:vTQ}}var QO1={"ai.rizom.brain.card":Oq("@brains/atproto"),"ai.rizom.brain.deck":Oq("@brains/decks"),"ai.rizom.brain.link":Oq("@brains/link"),"ai.rizom.brain.note":Oq("@brains/note"),"ai.rizom.brain.post":Oq("@brains/blog"),"ai.rizom.brain.project":Oq("@brains/portfolio"),"ai.rizom.brain.series":Oq("@brains/series"),"ai.rizom.brain.socialPost":Oq("@brains/social-media"),"ai.rizom.brain.topic":Oq("@brains/topics")};function mI(){return Object.values(k6)}function o80(A){if(!(A in k6))return;return k6[A]}function s80(){return Object.entries(QO1).map(([A,Q])=>({id:A,...Q}))}_0();function a80(A){return typeof A==="object"&&A!==null&&!Array.isArray(A)}var RTQ=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})$/;function hTQ(A){let Q=Z.string(),w=A.maxLength!==void 0?Q.max(A.maxLength):Q;if(A.knownValues)w=w.refine((B)=>A.knownValues?.includes(B),{message:`expected one of ${A.knownValues.join(", ")}`});if(A.format==="datetime")w=w.refine((B)=>RTQ.test(B)&&!Number.isNaN(Date.parse(B)),{message:"expected datetime"});if(A.format==="uri")w=w.refine((B)=>{try{return new URL(B),!0}catch{return!1}},{message:"expected uri"});return w}function wO1(A){switch(A.type){case"string":return hTQ(A);case"integer":return Z.number().int();case"boolean":return Z.boolean();case"array":{let Q=A.items?wO1(A.items):Z.unknown(),w=Z.array(Q);if(A.maxLength!==void 0)w=w.max(A.maxLength);return w}case"object":return CTQ(A);case"blob":return Z.custom(a80,{message:"expected blob"});default:return Z.unknown()}}function BO1(A){let Q=new Set(A.required??[]),w={};for(let[B,$]of Object.entries(A.properties??{})){let f=wO1($);w[B]=Q.has(B)?f:f.optional()}return w}function CTQ(A){return Z.object(BO1(A)).passthrough()}function Lu0(A,Q,w,B=[]){let $=Object.keys(A).filter((f)=>!Q.has(f));if($.length===0)return;w.addIssue({code:Z.ZodIssueCode.custom,path:B,message:`unrecognized field(s): ${$.join(", ")}`})}function gTQ(A,Q){if(Lu0(A,new Set(["$type","siteUrl","brain","anchor","skills","model","version","createdAt","updatedAt"]),Q),a80(A.brain))Lu0(A.brain,new Set(["did","name","role","purpose","values"]),Q,["brain"]);if(a80(A.anchor))Lu0(A.anchor,new Set(["did","name","kind"]),Q,["anchor"])}function $U(A){let Q=Z.object({...BO1(A.defs.main.record),$type:Z.literal(A.id).optional()}).passthrough();return A.id==="ai.rizom.brain.card"?Q.superRefine(gTQ):Q}var ku0={"ai.rizom.brain.card":$U(k6["ai.rizom.brain.card"]),"ai.rizom.brain.deck":$U(k6["ai.rizom.brain.deck"]),"ai.rizom.brain.link":$U(k6["ai.rizom.brain.link"]),"ai.rizom.brain.note":$U(k6["ai.rizom.brain.note"]),"ai.rizom.brain.post":$U(k6["ai.rizom.brain.post"]),"ai.rizom.brain.project":$U(k6["ai.rizom.brain.project"]),"ai.rizom.brain.series":$U(k6["ai.rizom.brain.series"]),"ai.rizom.brain.socialPost":$U(k6["ai.rizom.brain.socialPost"]),"ai.rizom.brain.topic":$U(k6["ai.rizom.brain.topic"])};function yTQ(A,Q){let w=A;for(let B of Q){if(typeof B==="symbol")return;if(Array.isArray(w)){w=w[Number(B)];continue}if(!a80(w))return;w=w[String(B)]}return w}function ETQ(A,Q,w){let B=w.path.join(".");if(B==="$type")return`AT Protocol record $type must match lexicon id: ${String(Q.$type)} !== ${A.id}`;if(w.code==="invalid_type"&&yTQ(Q,w.path)===void 0)return`Missing required AT Protocol record field: ${B}`;if(w.code==="invalid_type")return`Invalid AT Protocol record field ${B}: expected ${w.expected}`;if(w.code==="too_big")return`Invalid AT Protocol record field ${B}: exceeds maxLength ${w.maximum}`;if(w.code==="custom")return`Invalid AT Protocol record field ${B}: ${w.message}`;if(w.code==="unrecognized_keys")return`Unrecognized AT Protocol record field(s): ${w.keys.join(", ")}`;return`Invalid AT Protocol record field ${B}: ${w.message}`}function xq(A,Q){let w=$U(A).safeParse(Q);if(w.success)return;let B=w.error.issues[0];if(!B)throw w.error;throw Error(ETQ(A,Q,B))}_0();var yd="atproto:brain-card-discovered",_u0="atproto:brain-discovered",Nu0="atproto:brain-card-refreshed",TTQ=Z.custom((A)=>ku0["ai.rizom.brain.card"].safeParse(A).success),ju0=Z.object({repoDid:Z.string().min(1),uri:Z.string().min(1),cid:Z.string().min(1),record:TTQ}).strict(),STQ=Z.object({agentId:Z.string().min(1),name:Z.string().min(1),url:Z.string().url(),status:Z.enum(["discovered","approved"]),repoDid:Z.string().min(1).optional(),brainDid:Z.string().min(1).optional(),anchorDid:Z.string().min(1).optional(),cardUri:Z.string().min(1).optional(),cardCid:Z.string().min(1).optional()}).strict();class Q5{static instance;projections=new Map;static getInstance(){return this.instance??=new Q5,this.instance}static createFresh(){return new Q5}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 B=this.projections.get(A);if(!B)return;let $=B.lastIndexOf(Q);if($!==-1)B.splice($,1);if(B.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}`)}}_0();var $O1={name:"@brains/atproto-registry",version:"0.2.0-alpha.150",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:"^6.0.3"},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 YO1=Z.object({enabled:Z.boolean().default(!0)}),Pu0="/atproto/lexicons",uTQ=Z.strictObject({nsid:Z.string(),record:Z.record(Z.string(),Z.unknown())});function fO1(A){return new Response(`${JSON.stringify(A,null,2)}
|
|
5437
|
+
`)||"No response text";return{success:!0,data:{state:G,response:V}}}f=await lM1(w,Q)}return{success:!1,error:"Stream ended without a terminal event"}}class Cd extends Error{timeoutMs;constructor(A){super(`request timed out after ${A}ms`);this.timeoutMs=A,this.name="A2ARequestTimeoutError"}}class gd extends Error{timeoutMs;constructor(A){super(`A2A stream stalled waiting for final event after ${A}ms`);this.timeoutMs=A,this.name="A2AStreamIdleTimeoutError"}}async function qTQ(A,Q,w,B){let $=new AbortController,f;try{return await Promise.race([A(Q,{...w,signal:$.signal}),new Promise((Y,X)=>{f=setTimeout(()=>{$.abort(),X(new Cd(B))},B)})])}catch(Y){if(Y instanceof Cd)throw Y;if($.signal.aborted)throw new Cd(B);throw Y}finally{if(f)clearTimeout(f)}}async function lM1(A,Q){let w;try{return await Promise.race([A.read(),new Promise((B,$)=>{w=setTimeout(()=>$(new gd(Q)),Q)})])}catch(B){if(B instanceof gd)A.cancel().catch(()=>{});throw B}finally{if(w)clearTimeout(w)}}function VTQ(A){if(A instanceof Cd||A instanceof gd)return!1;return A instanceof Error}function Iu0(A,Q){let w=Q>1?` after ${Q} attempts`:"";if(A instanceof gd)return`${A.message}${w}`;let B=A instanceof Error?A.message:"Unknown network error";return`Failed to reach remote agent${w}: ${B}`}function iM1(A={}){let Q=A.fetch??globalThis.fetch,w={requestTimeoutMs:A.requestTimeoutMs??ZTQ,streamIdleTimeoutMs:A.streamIdleTimeoutMs??HTQ,maxNetworkAttempts:A.maxNetworkAttempts??WTQ};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:KTQ,visibility:"trusted",sideEffects:"external",handler:async(B)=>{let $=UTQ.safeParse(B);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};let{agent:f,message:Y}=$.data,X=GTQ(f);if(!X.ok)return{success:!1,error:X.error};let{agentId:H}=X;if(!A.entityService)return{success:!1,error:"Agent directory is unavailable. Add the agent first, then try again."};let W=await A.entityService.getEntity({entityType:"agent",id:H,visibilityScope:m9("agent_call tool is anchor-only and resolves saved remote agents at any visibility")});if(!W){if(!DTQ(H))return{success:!1,error:`Agent ${f} is not an exact domain-like id and is not saved. Connect or clarify the agent first.`,code:"agent_not_saved"};let V=`https://${H}`,J=await uM1(V,Q);if(!J)return{success:!1,error:`Could not verify an A2A Agent Card for ${H}. Connect/save it first if you want to add it to the directory.`,code:"agent_card_unavailable"};let b=mM1(J.url,H);if(!b.ok)return{success:!1,error:b.error};let L=await cM1(J.url,Y,Q,A.requestSigner,w);if("success"in L&&L.success===!0){let N=typeof L.data==="object"&&L.data!==null?L.data:{};return{...L,data:{...N,agentCall:{mode:"one-shot",agent:H},agentContactCandidate:{source:{kind:"url",url:X.sourceUrl??H}}}}}return L}if(W.metadata.status==="archived")return{success:!1,error:`Agent ${H} is archived and cannot be contacted until it is restored and approved.`,code:"agent_archived"};if(W.metadata.status!=="approved")return{success:!1,error:`Agent ${H} is discovered but not approved yet. Approve it first.`,code:"agent_not_approved"};let K=`https://${H}`,U=await uM1(K,Q);if(!U)return{success:!1,error:`Could not fetch Agent Card from ${K}`};let G=mM1(U.url,H);if(!G.ok)return{success:!1,error:G.error};let q=U.url;return cM1(q,Y,Q,A.requestSigner,w)}}}var Fu0={name:"@brains/a2a",version:"0.2.0-alpha.151",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 JTQ={"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 CC extends _G{agentCard;taskManager=new Ju0;agentService;jwksResolver=new Vu0;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",Fu0,A,vM1)}async onRegister(A){if(await super.onRegister(A),this.hasWebserver=A.plugins.has("webserver"),this.agentService=A.agent,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(),B=A.tools.listForPermissionLevel("public"),$;if(A.entityService.hasEntityType("skill"))try{let f=await A.entityService.listEntities({entityType:"skill",options:{filter:{visibilityScope:"public"}}});if(f.length>0)$=f.map((Y)=>Jm.safeParse(Y.metadata)).filter((Y)=>Y.success).map((Y)=>Y.data)}catch{}this.agentCard=RM1({character:Q,profile:w,version:Fu0.version,domain:A.domain,organization:this.config.organization,tools:B,skills:$,authEnabled:!1}),this.logger.debug("Agent Card rebuilt",{skills:this.agentCard.skills.length})}getAgentCard(){return this.agentCard}async resolveCaller(A,Q){let w=await MM1({method:A.method,url:A.url,headers:A.headers,body:Q},this.jwksResolver);if(w){let B=await M7()?.getA2APeerTrust(w.domain);return{permissionLevel:B?.keyFingerprint===w.keyFingerprint?B.grantedLevel:"public",callerDomain:w.domain}}return{permissionLevel:"public",callerDomain:null}}withCors(A){let Q=new Headers(A.headers);for(let[w,B]of Object.entries(JTQ))Q.set(w,B);return new Response(A.body,{status:A.status,statusText:A.statusText,headers:Q})}getOrCreateApp(){if(this.app)return this.app;let A=new OC;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(),B;try{B=await this.resolveCaller(Q.req.raw,w)}catch{return this.withCors(Q.json({error:"Invalid HTTP signature"},401))}let $;try{$=JSON.parse(w)}catch{return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32700,message:"Parse error"},id:null}))}let f=gM1.safeParse($);if(!f.success)return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32600,message:"Invalid request"},id:null}));if(f.data.method==="message/stream"){let X=EM1.safeParse(f.data.params??{});if(!X.success)return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32602,message:`Invalid params: ${X.error.message}`},id:f.data.id}));let H=TM1(f.data.id,X.data.message,{taskManager:this.taskManager,agentService:this.agentService,callerPermissionLevel:B.permissionLevel,callerDomain:B.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 yM1(f.data,{taskManager:this.taskManager,agentService:this.agentService,callerPermissionLevel:B.permissionLevel,callerDomain:B.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=M7();if(!A)return;return async(Q)=>{let w=await A.getA2ASigningKey();await PM1(Q,w.privateJwk,w.keyId)}}async getTools(){return[iM1({requestSigner:this.createRequestSigner(),requestTimeoutMs:this.config.requestTimeoutMs,streamIdleTimeoutMs:this.config.streamIdleTimeoutMs,maxNetworkAttempts:this.config.maxNetworkAttempts,entityService:this.getContext().entityService})]}async getInstructions(){return"## Agent-to-agent calls\n- Use `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")}}}}wA();_0();var dM1={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 nM1={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 rM1={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 oM1={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 sM1={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 aM1={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 tM1={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 eM1={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 AO1={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 OTQ=Z.object({type:Z.string()}).catchall(Z.unknown()),xTQ=Z.object({lexicon:Z.literal(1),id:Z.string(),defs:Z.object({main:Z.object({type:Z.literal("record"),key:Z.string().min(1),record:Z.object({type:Z.literal("object"),required:Z.array(Z.string()).optional(),properties:Z.record(Z.string(),OTQ)})})})});function BU(A){return xTQ.parse(A)}var k6={"ai.rizom.brain.card":BU(dM1),"ai.rizom.brain.deck":BU(nM1),"ai.rizom.brain.link":BU(rM1),"ai.rizom.brain.note":BU(oM1),"ai.rizom.brain.post":BU(sM1),"ai.rizom.brain.project":BU(aM1),"ai.rizom.brain.series":BU(tM1),"ai.rizom.brain.socialPost":BU(eM1),"ai.rizom.brain.topic":BU(AO1)},vTQ="Additive optional fields are compatible; required-field, type, or constraint changes require a migration plan or new NSID.";function Oq(A){return{status:"approved",version:"1.0.0",revision:1,owner:"Rizom",steward:"Rizom protocol registry",projectionPackage:A,compatibility:vTQ}}var QO1={"ai.rizom.brain.card":Oq("@brains/atproto"),"ai.rizom.brain.deck":Oq("@brains/decks"),"ai.rizom.brain.link":Oq("@brains/link"),"ai.rizom.brain.note":Oq("@brains/note"),"ai.rizom.brain.post":Oq("@brains/blog"),"ai.rizom.brain.project":Oq("@brains/portfolio"),"ai.rizom.brain.series":Oq("@brains/series"),"ai.rizom.brain.socialPost":Oq("@brains/social-media"),"ai.rizom.brain.topic":Oq("@brains/topics")};function mI(){return Object.values(k6)}function o80(A){if(!(A in k6))return;return k6[A]}function s80(){return Object.entries(QO1).map(([A,Q])=>({id:A,...Q}))}_0();function a80(A){return typeof A==="object"&&A!==null&&!Array.isArray(A)}var RTQ=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})$/;function hTQ(A){let Q=Z.string(),w=A.maxLength!==void 0?Q.max(A.maxLength):Q;if(A.knownValues)w=w.refine((B)=>A.knownValues?.includes(B),{message:`expected one of ${A.knownValues.join(", ")}`});if(A.format==="datetime")w=w.refine((B)=>RTQ.test(B)&&!Number.isNaN(Date.parse(B)),{message:"expected datetime"});if(A.format==="uri")w=w.refine((B)=>{try{return new URL(B),!0}catch{return!1}},{message:"expected uri"});return w}function wO1(A){switch(A.type){case"string":return hTQ(A);case"integer":return Z.number().int();case"boolean":return Z.boolean();case"array":{let Q=A.items?wO1(A.items):Z.unknown(),w=Z.array(Q);if(A.maxLength!==void 0)w=w.max(A.maxLength);return w}case"object":return CTQ(A);case"blob":return Z.custom(a80,{message:"expected blob"});default:return Z.unknown()}}function BO1(A){let Q=new Set(A.required??[]),w={};for(let[B,$]of Object.entries(A.properties??{})){let f=wO1($);w[B]=Q.has(B)?f:f.optional()}return w}function CTQ(A){return Z.object(BO1(A)).passthrough()}function Lu0(A,Q,w,B=[]){let $=Object.keys(A).filter((f)=>!Q.has(f));if($.length===0)return;w.addIssue({code:Z.ZodIssueCode.custom,path:B,message:`unrecognized field(s): ${$.join(", ")}`})}function gTQ(A,Q){if(Lu0(A,new Set(["$type","siteUrl","brain","anchor","skills","model","version","createdAt","updatedAt"]),Q),a80(A.brain))Lu0(A.brain,new Set(["did","name","role","purpose","values"]),Q,["brain"]);if(a80(A.anchor))Lu0(A.anchor,new Set(["did","name","kind"]),Q,["anchor"])}function $U(A){let Q=Z.object({...BO1(A.defs.main.record),$type:Z.literal(A.id).optional()}).passthrough();return A.id==="ai.rizom.brain.card"?Q.superRefine(gTQ):Q}var ku0={"ai.rizom.brain.card":$U(k6["ai.rizom.brain.card"]),"ai.rizom.brain.deck":$U(k6["ai.rizom.brain.deck"]),"ai.rizom.brain.link":$U(k6["ai.rizom.brain.link"]),"ai.rizom.brain.note":$U(k6["ai.rizom.brain.note"]),"ai.rizom.brain.post":$U(k6["ai.rizom.brain.post"]),"ai.rizom.brain.project":$U(k6["ai.rizom.brain.project"]),"ai.rizom.brain.series":$U(k6["ai.rizom.brain.series"]),"ai.rizom.brain.socialPost":$U(k6["ai.rizom.brain.socialPost"]),"ai.rizom.brain.topic":$U(k6["ai.rizom.brain.topic"])};function yTQ(A,Q){let w=A;for(let B of Q){if(typeof B==="symbol")return;if(Array.isArray(w)){w=w[Number(B)];continue}if(!a80(w))return;w=w[String(B)]}return w}function ETQ(A,Q,w){let B=w.path.join(".");if(B==="$type")return`AT Protocol record $type must match lexicon id: ${String(Q.$type)} !== ${A.id}`;if(w.code==="invalid_type"&&yTQ(Q,w.path)===void 0)return`Missing required AT Protocol record field: ${B}`;if(w.code==="invalid_type")return`Invalid AT Protocol record field ${B}: expected ${w.expected}`;if(w.code==="too_big")return`Invalid AT Protocol record field ${B}: exceeds maxLength ${w.maximum}`;if(w.code==="custom")return`Invalid AT Protocol record field ${B}: ${w.message}`;if(w.code==="unrecognized_keys")return`Unrecognized AT Protocol record field(s): ${w.keys.join(", ")}`;return`Invalid AT Protocol record field ${B}: ${w.message}`}function xq(A,Q){let w=$U(A).safeParse(Q);if(w.success)return;let B=w.error.issues[0];if(!B)throw w.error;throw Error(ETQ(A,Q,B))}_0();var yd="atproto:brain-card-discovered",_u0="atproto:brain-discovered",Nu0="atproto:brain-card-refreshed",TTQ=Z.custom((A)=>ku0["ai.rizom.brain.card"].safeParse(A).success),ju0=Z.object({repoDid:Z.string().min(1),uri:Z.string().min(1),cid:Z.string().min(1),record:TTQ}).strict(),STQ=Z.object({agentId:Z.string().min(1),name:Z.string().min(1),url:Z.string().url(),status:Z.enum(["discovered","approved"]),repoDid:Z.string().min(1).optional(),brainDid:Z.string().min(1).optional(),anchorDid:Z.string().min(1).optional(),cardUri:Z.string().min(1).optional(),cardCid:Z.string().min(1).optional()}).strict();class Q5{static instance;projections=new Map;static getInstance(){return this.instance??=new Q5,this.instance}static createFresh(){return new Q5}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 B=this.projections.get(A);if(!B)return;let $=B.lastIndexOf(Q);if($!==-1)B.splice($,1);if(B.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}`)}}_0();var $O1={name:"@brains/atproto-registry",version:"0.2.0-alpha.151",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 YO1=Z.object({enabled:Z.boolean().default(!0)}),Pu0="/atproto/lexicons",uTQ=Z.strictObject({nsid:Z.string(),record:Z.record(Z.string(),Z.unknown())});function fO1(A){return new Response(`${JSON.stringify(A,null,2)}
|
|
5438
5438
|
`,{headers:{"Content-Type":"application/json"}})}class Mu0 extends tQ{constructor(A={}){super("atproto-registry",$O1,A,YO1)}getWebRoutes(){if(!this.config.enabled)return[];return[{path:`${Pu0}/index.json`,method:"GET",public:!0,handler:()=>fO1(this.getIndex())},...mI().map((A)=>({path:`${Pu0}/${A.id}.json`,method:"GET",public:!0,handler:()=>fO1(A)}))]}getIndex(){return{lexicons:s80().map((A)=>({...A,path:`${Pu0}/${A.id}.json`}))}}getLexicon(A){return o80(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:Z.string().describe("Canonical lexicon NSID"),record:Z.record(Z.string(),Z.unknown()).describe("Record payload to validate")},handler:async(A)=>{let Q=uTQ.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 xq(w,Q.data.record),{success:!0,data:{valid:!0}}}catch(B){return{success:!0,data:{valid:!1,error:B instanceof Error?B.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:mI().length,nsids:mI().map((A)=>A.id),metadata:s80()}})}}}function Ed(A={}){return new Mu0(A)}wA();class Ou0{logger;handleImport;handleDelete;deleteOnFileRemoval;fileOperations;constructor(A,Q,w,B,$=!0){if(this.logger=A,this.fileOperations=B,this.deleteOnFileRemoval=$,w)this.handleImport=async(f)=>{let Y=await w({type:"directory-import",data:{paths:[f]}});this.logger.debug("Queued import job for file change",{jobId:Y,path:f})},this.handleDelete=async(f)=>{if(!this.deleteOnFileRemoval){this.logger.warn("File deleted but deleteOnFileRemoval is disabled",{path:f});return}try{let{entityType:Y,id:X}=this.fileOperations.parseEntityFromPath(f),H=await w({type:"directory-delete",data:{entityId:X,entityType:Y,filePath:f}});this.logger.info("Queued delete job for removed file",{jobId:H,path:f,entityId:X,entityType:Y})}catch(Y){this.logger.warn("Could not extract entity info from deleted file",{path:f,error:Y})}};else this.handleImport=async(f)=>{await Q([f])},this.handleDelete=async(f)=>{this.logger.warn("File deleted but no job queue available",{path:f})}}async handleFileChange(A,Q){this.logger.debug("Processing file change",{event:A,path:Q});try{switch(A){case"add":case"change":await this.handleImport(Q);break;case"delete":case"unlink":await this.handleDelete(Q);break;default:this.logger.debug("Unhandled file event",{event:A,path:Q})}}catch(w){this.logger.error("Failed to handle file change",{event:A,path:Q,error:w})}}}import{EventEmitter as VSQ}from"events";import{stat as bSQ,Stats as sPB}from"fs";import{readdir as JSQ,stat as ISQ}from"fs/promises";import*as A6 from"path";import{lstat as XO1,readdir as cTQ,realpath as lTQ,stat as pTQ}from"fs/promises";import{join as iTQ,relative as dTQ,resolve as ZO1,sep as nTQ}from"path";import{Readable as rTQ}from"stream";var GZ={FILE_TYPE:"files",DIR_TYPE:"directories",FILE_DIR_TYPE:"files_directories",EVERYTHING_TYPE:"all"},xu0={root:".",fileFilter:(A)=>!0,directoryFilter:(A)=>!0,type:GZ.FILE_TYPE,lstat:!1,depth:2147483648,alwaysStat:!1,highWaterMark:4096};Object.freeze(xu0);var UO1="READDIRP_RECURSIVE_ERROR",oTQ=new Set(["ENOENT","EPERM","EACCES","ELOOP",UO1]),HO1=[GZ.DIR_TYPE,GZ.EVERYTHING_TYPE,GZ.FILE_DIR_TYPE,GZ.FILE_TYPE],sTQ=new Set([GZ.DIR_TYPE,GZ.EVERYTHING_TYPE,GZ.FILE_DIR_TYPE]),aTQ=new Set([GZ.EVERYTHING_TYPE,GZ.FILE_DIR_TYPE,GZ.FILE_TYPE]),tTQ=(A)=>oTQ.has(A.code),eTQ=process.platform==="win32",WO1=(A)=>!0,KO1=(A)=>{if(A===void 0)return WO1;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((B)=>w.basename===B)}return WO1};class vu0 extends rTQ{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={...xu0,...A},{root:w,type:B}=Q;this._fileFilter=KO1(Q.fileFilter),this._directoryFilter=KO1(Q.directoryFilter);let $=Q.lstat?XO1:pTQ;if(eTQ)this._stat=(f)=>$(f,{bigint:!0});else this._stat=$;this._maxDepth=Q.depth!=null&&Number.isSafeInteger(Q.depth)?Q.depth:xu0.depth,this._wantsDir=B?sTQ.has(B):!1,this._wantsFile=B?aTQ.has(B):!1,this._wantsEverything=B===GZ.EVERYTHING_TYPE,this._root=ZO1(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:B,depth:$}=Q,f=w.splice(0,A).map((X)=>this._formatEntry(X,B)),Y=await Promise.all(f);for(let X of Y){if(!X)continue;if(this.destroyed)return;let H=await this._getEntryType(X);if(H==="directory"&&this._directoryFilter(X)){if($<=this._maxDepth)this.parents.push(this._exploreDir(X.fullPath,$+1));if(this._wantsDir)this.push(X),A--}else if((H==="file"||this._includeAsFile(X))&&this._fileFilter(X)){if(this._wantsFile)this.push(X),A--}}}else{let B=this.parents.pop();if(!B){this.push(null);break}if(this.parent=await B,this.destroyed)return}}}catch(Q){this.destroy(Q)}finally{this.reading=!1}}async _exploreDir(A,Q){let w;try{w=await cTQ(A,this._rdOptions)}catch(B){this._onError(B)}return{files:w,depth:Q,path:A}}async _formatEntry(A,Q){let w,B=this._isDirent?A.name:A;try{let $=ZO1(iTQ(Q,B));w={path:dTQ(this._root,$),fullPath:$,basename:B},w[this._statsProp]=this._isDirent?A:await this._stat($)}catch($){this._onError($);return}return w}_onError(A){if(tTQ(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 B=await lTQ(w),$=await XO1(B);if($.isFile())return"file";if($.isDirectory()){let f=B.length;if(w.startsWith(B)&&w.substr(f,1)===nTQ){let Y=Error(`Circular symlink detected: "${w}" points to "${B}"`);return Y.code=UO1,this._onError(Y)}return"directory"}}catch(B){return this._onError(B),""}}}_includeAsFile(A){let Q=A&&A[this._statsProp];return Q&&this._wantsEverything&&!Q.isDirectory()}}function GO1(A,Q={}){let w=Q.entryType||Q.type;if(w==="both")w=GZ.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&&!HO1.includes(w))throw Error(`readdirp: Invalid type passed. Use one of ${HO1.join(", ")}`);return Q.root=A,new vu0(Q)}import{watch as ASQ,unwatchFile as DO1,watchFile as QSQ}from"fs";import{realpath as Ru0,lstat as wSQ,open as BSQ,stat as qO1}from"fs/promises";import{type as $SQ}from"os";import*as v$ from"path";var fSQ="data",gu0="end",VO1="close",Q90=()=>{};var w90=process.platform,yu0=w90==="win32",YSQ=w90==="darwin",XSQ=w90==="linux",ZSQ=w90==="freebsd",bO1=$SQ()==="OS400",X$={ALL:"all",READY:"ready",ADD:"add",CHANGE:"change",ADD_DIR:"addDir",UNLINK:"unlink",UNLINK_DIR:"unlinkDir",RAW:"raw",ERROR:"error"},fU=X$,HSQ="watch",WSQ={lstat:wSQ,stat:qO1},Aj="listeners",t80="errHandlers",gC="rawEmitters",KSQ=[Aj,t80,gC],USQ=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"]),GSQ=(A)=>USQ.has(v$.extname(A).slice(1).toLowerCase()),Cu0=(A,Q)=>{if(A instanceof Set)A.forEach(Q);else Q(A)},Td=(A,Q,w)=>{let B=A[Q];if(!(B instanceof Set))A[Q]=B=new Set([B]);B.add(w)},DSQ=(A)=>(Q)=>{let w=A[Q];if(w instanceof Set)w.clear();else delete A[Q]},Sd=(A,Q,w)=>{let B=A[Q];if(B instanceof Set)B.delete(w);else if(B===w)delete A[Q]},JO1=(A)=>A instanceof Set?A.size===0:!A,e80=new Map;function zO1(A,Q,w,B,$){let f=(Y,X)=>{if(w(A),$(Y,X,{watchedPath:A}),X&&A!==X)A90(v$.resolve(A,X),Aj,v$.join(A,X))};try{return ASQ(A,{persistent:Q.persistent},f)}catch(Y){B(Y);return}}var A90=(A,Q,w,B,$)=>{let f=e80.get(A);if(!f)return;Cu0(f[Q],(Y)=>{Y(w,B,$)})},zSQ=(A,Q,w,B)=>{let{listener:$,errHandler:f,rawEmitter:Y}=B,X=e80.get(Q),H;if(!w.persistent){if(H=zO1(A,w,$,f,Y),!H)return;return H.close.bind(H)}if(X)Td(X,Aj,$),Td(X,t80,f),Td(X,gC,Y);else{if(H=zO1(A,w,A90.bind(null,Q,Aj),f,A90.bind(null,Q,gC)),!H)return;H.on(fU.ERROR,async(W)=>{let K=A90.bind(null,Q,t80);if(X)X.watcherUnusable=!0;if(yu0&&W.code==="EPERM")try{await(await BSQ(A,"r")).close(),K(W)}catch(U){}else K(W)}),X={listeners:$,errHandlers:f,rawEmitters:Y,watcher:H},e80.set(Q,X)}return()=>{if(Sd(X,Aj,$),Sd(X,t80,f),Sd(X,gC,Y),JO1(X.listeners))X.watcher.close(),e80.delete(Q),KSQ.forEach(DSQ(X)),X.watcher=void 0,Object.freeze(X)}},hu0=new Map,qSQ=(A,Q,w,B)=>{let{listener:$,rawEmitter:f}=B,Y=hu0.get(Q),X=Y&&Y.options;if(X&&(X.persistent<w.persistent||X.interval>w.interval))DO1(Q),Y=void 0;if(Y)Td(Y,Aj,$),Td(Y,gC,f);else Y={listeners:$,rawEmitters:f,options:w,watcher:QSQ(Q,w,(H,W)=>{Cu0(Y.rawEmitters,(U)=>{U(fU.CHANGE,Q,{curr:H,prev:W})});let K=H.mtimeMs;if(H.size!==W.size||K>W.mtimeMs||K===0)Cu0(Y.listeners,(U)=>U(A,H))})},hu0.set(Q,Y);return()=>{if(Sd(Y,Aj,$),Sd(Y,gC,f),JO1(Y.listeners))hu0.delete(Q),DO1(Q),Y.options=Y.watcher=void 0,Object.freeze(Y)}};class Eu0{fsw;_boundHandleError;constructor(A){this.fsw=A,this._boundHandleError=(Q)=>A._handleError(Q)}_watchWithNodeFs(A,Q){let w=this.fsw.options,B=v$.dirname(A),$=v$.basename(A);this.fsw._getWatchedDir(B).add($);let Y=v$.resolve(A),X={persistent:w.persistent};if(!Q)Q=Q90;let H;if(w.usePolling){let W=w.interval!==w.binaryInterval;X.interval=W&&GSQ($)?w.binaryInterval:w.interval,H=qSQ(A,Y,X,{listener:Q,rawEmitter:this.fsw._emitRaw})}else H=zSQ(A,Y,X,{listener:Q,errHandler:this._boundHandleError,rawEmitter:this.fsw._emitRaw});return H}_handleFile(A,Q,w){if(this.fsw.closed)return;let B=v$.dirname(A),$=v$.basename(A),f=this.fsw._getWatchedDir(B),Y=Q;if(f.has($))return;let X=async(W,K)=>{if(!this.fsw._throttle(HSQ,A,5))return;if(!K||K.mtimeMs===0)try{let U=await qO1(A);if(this.fsw.closed)return;let{atimeMs:G,mtimeMs:q}=U;if(!G||G<=q||q!==Y.mtimeMs)this.fsw._emit(fU.CHANGE,A,U);if((YSQ||XSQ||ZSQ)&&Y.ino!==U.ino){this.fsw._closeFile(W),Y=U;let V=this._watchWithNodeFs(A,X);if(V)this.fsw._addPathCloser(W,V)}else Y=U}catch(U){this.fsw._remove(B,$)}else if(f.has($)){let{atimeMs:U,mtimeMs:G}=K;if(!U||U<=G||G!==Y.mtimeMs)this.fsw._emit(fU.CHANGE,A,K);Y=K}},H=this._watchWithNodeFs(A,X);if(!(w&&this.fsw.options.ignoreInitial)&&this.fsw._isntIgnored(A)){if(!this.fsw._throttle(fU.ADD,A,0))return;this.fsw._emit(fU.ADD,A,Q)}return H}async _handleSymlink(A,Q,w,B){if(this.fsw.closed)return;let $=A.fullPath,f=this.fsw._getWatchedDir(Q);if(!this.fsw.options.followSymlinks){this.fsw._incrReadyCount();let Y;try{Y=await Ru0(w)}catch(X){return this.fsw._emitReady(),!0}if(this.fsw.closed)return;if(f.has(B)){if(this.fsw._symlinkPaths.get($)!==Y)this.fsw._symlinkPaths.set($,Y),this.fsw._emit(fU.CHANGE,w,A.stats)}else f.add(B),this.fsw._symlinkPaths.set($,Y),this.fsw._emit(fU.ADD,w,A.stats);return this.fsw._emitReady(),!0}if(this.fsw._symlinkPaths.has($))return!0;this.fsw._symlinkPaths.set($,!0)}_handleRead(A,Q,w,B,$,f,Y){A=v$.join(A,"");let X=B?`${A}:${B}`:A;if(Y=this.fsw._throttle("readdir",X,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(fSQ,async(U)=>{if(this.fsw.closed){K=void 0;return}let G=U.path,q=v$.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===B||!B&&!H.has(G))this.fsw._incrReadyCount(),q=v$.join($,v$.relative($,q)),this._addToNodeFs(q,Q,w,f+1)}).on(fU.ERROR,this._boundHandleError),new Promise((U,G)=>{if(!K)return G();K.once(gu0,()=>{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,$,f,Y)})})}async _handleDir(A,Q,w,B,$,f,Y){let X=this.fsw._getWatchedDir(v$.dirname(A)),H=X.has(v$.basename(A));if(!(w&&this.fsw.options.ignoreInitial)&&!$&&!H)this.fsw._emit(fU.ADD_DIR,A,Q);X.add(v$.basename(A)),this.fsw._getWatchedDir(A);let W,K,U=this.fsw.options.depth;if((U==null||B<=U)&&!this.fsw._symlinkPaths.has(Y)){if(!$){if(await this._handleRead(A,w,f,$,A,B,W),this.fsw.closed)return}K=this._watchWithNodeFs(A,(G,q)=>{if(q&&q.mtimeMs===0)return;this._handleRead(G,!1,f,$,A,B,W)})}return K}async _addToNodeFs(A,Q,w,B,$){let f=this.fsw._emitReady;if(this.fsw._isIgnored(A)||this.fsw.closed)return f(),!1;let Y=this.fsw._getWatchHelpers(A);if(w)Y.filterPath=(X)=>w.filterPath(X),Y.filterDir=(X)=>w.filterDir(X);try{let X=await WSQ[Y.statMethod](Y.watchPath);if(this.fsw.closed)return;if(this.fsw._isIgnored(Y.watchPath,X))return f(),!1;let H=this.fsw.options.followSymlinks,W;if(X.isDirectory()){let K=v$.resolve(A),U=H?await Ru0(A):A;if(this.fsw.closed)return;if(W=await this._handleDir(Y.watchPath,X,Q,B,$,Y,U),this.fsw.closed)return;if(K!==U&&U!==void 0)this.fsw._symlinkPaths.set(K,U)}else if(X.isSymbolicLink()){let K=H?await Ru0(A):A;if(this.fsw.closed)return;let U=v$.dirname(Y.watchPath);if(this.fsw._getWatchedDir(U).add(Y.watchPath),this.fsw._emit(fU.ADD,Y.watchPath,X),W=await this._handleDir(U,X,Q,B,A,Y,K),this.fsw.closed)return;if(K!==void 0)this.fsw._symlinkPaths.set(v$.resolve(A),K)}else W=this._handleFile(Y.watchPath,X,Q);if(f(),W)this.fsw._addPathCloser(A,W);return!1}catch(X){if(this.fsw._handleError(X))return f(),A}}}/*! chokidar - MIT License (c) 2012 Paul Miller (paulmillr.com) */var Tu0="/",FSQ="//",_O1=".",LSQ="..",kSQ="string",_SQ=/\\/g,NO1=/\/\//g,NSQ=/\..*\.(sw[px])$|~$|\.subl.*\.tmp/,jSQ=/^\.[/\\]/;function B90(A){return Array.isArray(A)?A:[A]}var Su0=(A)=>typeof A==="object"&&A!==null&&!(A instanceof RegExp);function PSQ(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=A6.relative(A.path,Q);if(!w)return!1;return!w.startsWith("..")&&!A6.isAbsolute(w)}return!1};return()=>!1}function MSQ(A){if(typeof A!=="string")throw Error("string expected");A=A6.normalize(A),A=A.replace(/\\/g,"/");let Q=!1;if(A.startsWith("//"))Q=!0;if(A=A.replace(NO1,"/"),Q)A="/"+A;return A}function IO1(A,Q,w){let B=MSQ(Q);for(let $=0;$<A.length;$++){let f=A[$];if(f(B,w))return!0}return!1}function OSQ(A,Q){if(A==null)throw TypeError("anymatch: specify first argument");let B=B90(A).map(($)=>PSQ($));if(Q==null)return($,f)=>{return IO1(B,$,f)};return IO1(B,Q)}var FO1=(A)=>{let Q=B90(A).flat();if(!Q.every((w)=>typeof w===kSQ))throw TypeError(`Non-string provided as watch path: ${Q}`);return Q.map(jO1)},LO1=(A)=>{let Q=A.replace(_SQ,Tu0),w=!1;if(Q.startsWith(FSQ))w=!0;if(Q=Q.replace(NO1,Tu0),w)Q=Tu0+Q;return Q},jO1=(A)=>LO1(A6.normalize(LO1(A))),kO1=(A="")=>(Q)=>{if(typeof Q==="string")return jO1(A6.isAbsolute(Q)?Q:A6.join(A,Q));else return Q},xSQ=(A,Q)=>{if(A6.isAbsolute(A))return A;return A6.join(Q,A)},vSQ=Object.freeze(new Set);class PO1{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!==_O1&&A!==LSQ)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 JSQ(w)}catch(B){if(this._removeWatcher)this._removeWatcher(A6.dirname(w),A6.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=Q90,this.items=vSQ,Object.freeze(this)}}var RSQ="stat",hSQ="lstat";class MO1{fsw;path;watchPath;fullWatchPath;dirParts;followSymlinks;statMethod;constructor(A,Q,w){this.fsw=w;let B=A;this.path=A=A.replace(jSQ,""),this.watchPath=B,this.fullWatchPath=A6.resolve(B),this.dirParts=[],this.dirParts.forEach(($)=>{if($.length>1)$.pop()}),this.followSymlinks=Q,this.statMethod=Q?RSQ:hSQ}entryPath(A){return A6.join(this.watchPath,A6.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 mu0 extends VSQ{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},B={persistent:!0,ignoreInitial:!1,ignorePermissionErrors:!1,interval:100,binaryInterval:300,followSymlinks:!0,usePolling:!1,atomic:!0,...A,ignored:A.ignored?B90(A.ignored):B90([]),awaitWriteFinish:Q===!0?w:typeof Q==="object"?{...w,...Q}:!1};if(bO1)B.usePolling=!0;if(B.atomic===void 0)B.atomic=!B.usePolling;let $=process.env.CHOKIDAR_USEPOLLING;if($!==void 0){let X=$.toLowerCase();if(X==="false"||X==="0")B.usePolling=!1;else if(X==="true"||X==="1")B.usePolling=!0;else B.usePolling=!!X}let f=process.env.CHOKIDAR_INTERVAL;if(f)B.interval=Number.parseInt(f,10);let Y=0;this._emitReady=()=>{if(Y++,Y>=this._readyCount)this._emitReady=Q90,this._readyEmitted=!0,process.nextTick(()=>this.emit(X$.READY))},this._emitRaw=(...X)=>this.emit(X$.RAW,...X),this._boundRemove=this._remove.bind(this),this.options=B,this._nodeFsHandler=new Eu0(this),Object.freeze(B)}_addIgnoredPath(A){if(Su0(A)){for(let Q of this._ignoredPaths)if(Su0(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(Su0(Q)&&Q.path===A)this._ignoredPaths.delete(Q)}}add(A,Q,w){let{cwd:B}=this.options;this.closed=!1,this._closePromise=void 0;let $=FO1(A);if(B)$=$.map((f)=>{return xSQ(f,B)});if($.forEach((f)=>{this._removeIgnoredPath(f)}),this._userIgnored=void 0,!this._readyCount)this._readyCount=0;return this._readyCount+=$.length,Promise.all($.map(async(f)=>{let Y=await this._nodeFsHandler._addToNodeFs(f,!w,void 0,0,Q);if(Y)this._emitReady();return Y})).then((f)=>{if(this.closed)return;f.forEach((Y)=>{if(Y)this.add(A6.dirname(Y),A6.basename(Q||Y))})}),this}unwatch(A){if(this.closed)return this;let Q=FO1(A),{cwd:w}=this.options;return Q.forEach((B)=>{if(!A6.isAbsolute(B)&&!this._closers.has(B)){if(w)B=A6.join(w,B);B=A6.resolve(B)}if(this._closePath(B),this._addIgnoredPath(B),this._watched.has(B))this._addIgnoredPath({path:B,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 B=w();if(B instanceof Promise)A.push(B)})),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 $=(this.options.cwd?A6.relative(this.options.cwd,w):w)||_O1;A[$]=Q.getChildren().sort()}),A}emitWithAll(A,Q){if(this.emit(A,...Q),A!==X$.ERROR)this.emit(X$.ALL,A,...Q)}async _emit(A,Q,w){if(this.closed)return;let B=this.options;if(yu0)Q=A6.normalize(Q);if(B.cwd)Q=A6.relative(B.cwd,Q);let $=[Q];if(w!=null)$.push(w);let f=B.awaitWriteFinish,Y;if(f&&(Y=this._pendingWrites.get(Q)))return Y.lastChange=new Date,this;if(B.atomic){if(A===X$.UNLINK)return this._pendingUnlinks.set(Q,[A,...$]),setTimeout(()=>{this._pendingUnlinks.forEach((X,H)=>{this.emit(...X),this.emit(X$.ALL,...X),this._pendingUnlinks.delete(H)})},typeof B.atomic==="number"?B.atomic:100),this;if(A===X$.ADD&&this._pendingUnlinks.has(Q))A=X$.CHANGE,this._pendingUnlinks.delete(Q)}if(f&&(A===X$.ADD||A===X$.CHANGE)&&this._readyEmitted){let X=(H,W)=>{if(H)A=X$.ERROR,$[0]=H,this.emitWithAll(A,$);else if(W){if($.length>1)$[1]=W;else $.push(W);this.emitWithAll(A,$)}};return this._awaitWriteFinish(Q,f.stabilityThreshold,A,X),this}if(A===X$.CHANGE){if(!this._throttle(X$.CHANGE,Q,50))return this}if(B.alwaysStat&&w===void 0&&(A===X$.ADD||A===X$.ADD_DIR||A===X$.CHANGE)){let X=B.cwd?A6.join(B.cwd,Q):Q,H;try{H=await ISQ(X)}catch(W){}if(!H||this.closed)return;$.push(H)}return this.emitWithAll(A,$),this}_handleError(A){let Q=A&&A.code;if(A&&Q!=="ENOENT"&&Q!=="ENOTDIR"&&(!this.options.ignorePermissionErrors||Q!=="EPERM"&&Q!=="EACCES"))this.emit(X$.ERROR,A);return A||this.closed}_throttle(A,Q,w){if(!this._throttled.has(A))this._throttled.set(A,new Map);let B=this._throttled.get(A);if(!B)throw Error("invalid throttle");let $=B.get(Q);if($)return $.count++,!1;let f,Y=()=>{let H=B.get(Q),W=H?H.count:0;if(B.delete(Q),clearTimeout(f),H)clearTimeout(H.timeoutObject);return W};f=setTimeout(Y,w);let X={timeoutObject:f,clear:Y,count:0};return B.set(Q,X),X}_incrReadyCount(){return this._readyCount++}_awaitWriteFinish(A,Q,w,B){let $=this.options.awaitWriteFinish;if(typeof $!=="object")return;let f=$.pollInterval,Y,X=A;if(this.options.cwd&&!A6.isAbsolute(A))X=A6.join(this.options.cwd,A);let H=new Date,W=this._pendingWrites;function K(U){bSQ(X,(G,q)=>{if(G||!W.has(A)){if(G&&G.code!=="ENOENT")B(G);return}let V=Number(new Date);if(U&&q.size!==U.size)W.get(A).lastChange=V;let J=W.get(A);if(V-J.lastChange>=Q)W.delete(A),B(void 0,q);else Y=setTimeout(K,f,q)})}if(!W.has(A))W.set(A,{lastChange:H,cancelWait:()=>{return W.delete(A),clearTimeout(Y),w}}),Y=setTimeout(K,f)}_isIgnored(A,Q){if(this.options.atomic&&NSQ.test(A))return!0;if(!this._userIgnored){let{cwd:w}=this.options,$=(this.options.ignored||[]).map(kO1(w)),Y=[...[...this._ignoredPaths].map(kO1(w)),...$];this._userIgnored=OSQ(Y,void 0)}return this._userIgnored(A,Q)}_isntIgnored(A,Q){return!this._isIgnored(A,Q)}_getWatchHelpers(A){return new MO1(A,this.options.followSymlinks,this)}_getWatchedDir(A){let Q=A6.resolve(A);if(!this._watched.has(Q))this._watched.set(Q,new PO1(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 B=A6.join(A,Q),$=A6.resolve(B);if(w=w!=null?w:this._watched.has(B)||this._watched.has($),!this._throttle("remove",B,100))return;if(!w&&this._watched.size===1)this.add(A,Q,!0);this._getWatchedDir(B).getChildren().forEach((U)=>this._remove(B,U));let X=this._getWatchedDir(A),H=X.has(Q);if(X.remove(Q),this._symlinkPaths.has($))this._symlinkPaths.delete($);let W=B;if(this.options.cwd)W=A6.relative(this.options.cwd,B);if(this.options.awaitWriteFinish&&this._pendingWrites.has(W)){if(this._pendingWrites.get(W).cancelWait()===X$.ADD)return}this._watched.delete(B),this._watched.delete($);let K=w?X$.UNLINK_DIR:X$.UNLINK;if(H&&!this._isIgnored(B))this._emit(K,B);this._closePath(B)}_closePath(A){this._closeFile(A);let Q=A6.dirname(A);this._getWatchedDir(Q).remove(A6.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:X$.ALL,alwaysStat:!0,lstat:!0,...Q,depth:0},B=GO1(A,w);return this._streams.add(B),B.once(VO1,()=>{B=void 0}),B.once(gu0,()=>{if(B)this._streams.delete(B),B=void 0}),B}}function CSQ(A,Q={}){let w=new mu0(Q);return w.add(A),w}var OO1={watch:CSQ,FSWatcher:mu0};import{extname as gSQ}from"path";var $90=[".png",".jpg",".jpeg",".webp",".gif",".svg"];function Qj(A){let Q=gSQ(A).toLowerCase();return $90.includes(Q)}function xO1(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 uu0(A){switch(A.toLowerCase()){case"jpeg":return".jpg";case"svg+xml":return".svg";default:return`.${A.toLowerCase()}`}}import{isAbsolute as ySQ,relative as ESQ,sep as vO1,join as TSQ}from"path";function UW(A,Q){return ySQ(Q)?Q:TSQ(A,Q)}function yC(A,Q){let w=UW(A,Q),B=ESQ(A,w);return vO1==="/"?B:B.split(vO1).join("/")}function SSQ(A,Q){if(!yC(Q,A).startsWith("image/"))return!1;return Qj(A)}function mSQ(A,Q){if(yC(Q,A).split("/")[0]?.startsWith("_"))return!1;if(A.endsWith(".md"))return!0;return SSQ(A,Q)}class cu0{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=OO1.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(!mSQ(Q,this.syncPath))return;this.logger.debug("File change detected",{event:A,path:Q});let w=yC(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 B=UW(this.syncPath,Q);try{if(this.onFileChange)await this.onFileChange(w,B)}catch($){this.logger.error("Error processing file change",{path:Q,event:w,error:$})}}}isWatching(){return!!this.watcher}getPendingChangesCount(){return this.pendingChanges.size}}async function RO1(A,Q){if(A?.isWatching())return Q.logger.debug("Already watching directory"),A;return uSQ(Q)}function hO1(A){if(A)A.stop();return}function CO1(A,Q){if(A)A.setCallback(Q)}async function uSQ(A){let{logger:Q,syncPath:w,watchInterval:B,importEntities:$,jobQueueCallback:f,fileOperations:Y,deleteOnFileRemoval:X}=A,H=new Ou0(Q,$,f,Y,X),W=new cu0({syncPath:w,watchInterval:B,logger:Q,onFileChange:async(K,U)=>{await H.handleFileChange(K,U)}});return await W.start(),W}async function gO1(A){let Q=Date.now();A.logger.debug("Starting sync (import only)");let w=await A.importEntities(),B=await A.removeOrphanedEntities(),$=Date.now()-Q;return A.markSynced(new Date),A.logger.debug("Sync completed",{duration:$,imported:w.imported,orphansDeleted:B.deleted}),{export:{exported:0,failed:0,errors:[]},import:w,duration:$}}wA();class lu0{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 B=w.length;if(this.deleteOnFileRemoval)Q.push({type:"directory-cleanup",data:{}});let $=A.length;return this.logger.debug("Prepared batch operations",{exportOperationsCount:0,importOperationsCount:B,totalFiles:$}),{operations:Q,exportOperationsCount:0,importOperationsCount:B,totalFiles:$}}async queueSyncBatch(A,Q,w,B){let $=this.prepareBatchOperations(w);if($.operations.length===0)return this.logger.debug("No sync operations needed",{source:Q}),null;return{batchId:await A.jobs.enqueueBatch($.operations,{source:Q,rootJobId:B?.rootJobId??H4(),metadata:{progressToken:B?.progressToken,operationType:"file_operations",operationTarget:this.syncPath,pluginId:B?.pluginId??"directory-sync",interfaceType:B?.interfaceType,channelId:B?.channelId}}),operationCount:$.operations.length,exportOperationsCount:$.exportOperationsCount,importOperationsCount:$.importOperationsCount,totalFiles:$.totalFiles}}createImportOperations(A){if(A.length===0)return[];let Q=50,w=[];for(let B=0;B<A.length;B+=Q){let $=A.slice(B,B+Q);w.push({type:"directory-import",data:{batchIndex:Math.floor(B/Q),paths:$,batchSize:$.length}})}return w}}class pu0{syncInProgress=!1;logger;fileOperations;batchOperationsManager;constructor(A){this.logger=A.logger,this.fileOperations=A.fileOperations,this.batchOperationsManager=new lu0({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 B=await this.fileOperations.getAllSyncFiles();return await this.batchOperationsManager.queueSyncBatch(A,Q,B,w)}finally{this.syncInProgress=!1}}}class iu0{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 nSQ,dirname as rSQ,extname as oSQ}from"path";import{extname as cSQ}from"path";var f90=[".pdf"],yO1=".meta.json";function wj(A){let Q=cSQ(A).toLowerCase();return f90.includes(Q)}function EO1(A){return A.toLowerCase().endsWith(yO1)}function du0(A){return`${A}${yO1}`}function TO1(A){switch(A.toLowerCase().replace(".","")){case"pdf":default:return"application/pdf"}}import{extname as lSQ,join as Y90}from"path";function X90(A,Q){let B=yC(A,Q).split("/"),$,f;if(B.length===1)$="note",f=B;else if(B.length>1&&B[0])$=B[0],f=B.slice(1);else $="note",f=B;let Y;if(f.length>1){let X=f[f.length-1];if(X)f[f.length-1]=SO1(X);Y=f.join(":")}else Y=SO1(f[0]??"");return{entityType:$,id:Y}}function mO1(A,Q,w,B=".md"){let $=Q.split(":").filter((W)=>W.length>0),f=w==="note";if($.length===1)return f?Y90(A,`${$[0]}${B}`):Y90(A,w,`${$[0]}${B}`);let Y=$;if($[0]===w)Y=$.slice(1);let X=Y[Y.length-1],H=Y.slice(0,-1);if(f)return Y90(A,...H,`${X}${B}`);return Y90(A,w,...H,`${X}${B}`)}function uO1(A){if(A.entityType==="document")return".pdf";if(A.entityType!=="image")return".md";let Q=A.metadata.format;if(Q)return uu0(Q);let w=A.content.match(/^data:image\/([a-z+]+);base64,/i);return w?.[1]?uu0(w[1]):".md"}function SO1(A){let Q=lSQ(A).toLowerCase();return Q===".md"||$90.includes(Q)||f90.includes(Q)?A.slice(0,-Q.length):A}_0();xX();import{mkdir as sSQ,readFile as EC,writeFile as ru0,stat as aSQ,utimes as tSQ}from"fs/promises";import{join as Z90}from"path";import{mkdir as cO1,readdir as iSQ,stat as dSQ}from"fs/promises";import{access as pSQ}from"fs/promises";async function n5(A){try{return await pSQ(A),!0}catch{return!1}}async function nu0(A,Q){return dO1(A,Q,{includeDocuments:!1,includeImages:!1})}async function lO1(A,Q){return dO1(A,Q,{includeDocuments:!0,includeImages:!0})}async function pO1(A,Q){if(!await n5(A))await cO1(A,{recursive:!0});for(let w of Q)if(w!=="note")await cO1(Z90(A,w),{recursive:!0})}async function iO1(A,Q){let w=[],B={totalFiles:0,byEntityType:{}};if(!await n5(A))return{files:w,stats:B};let $=await nu0(A,Q);for(let f of $)try{let Y=Z90(A,f),X=await dSQ(Y),{entityType:H}=X90(A,f);w.push({path:f,entityType:H,modified:X.mtime}),B.totalFiles++,B.byEntityType[H]=(B.byEntityType[H]??0)+1}catch{continue}return{files:w,stats:B}}async function dO1(A,Q,w){let B=[];if(!await n5(A))return B;let $=async(f,Y="",X=!1,H=!1)=>{let W=await iSQ(f,{withFileTypes:!0});for(let K of W){let U=Y?Z90(Y,K.name):K.name;if(K.isFile()&&!K.name.endsWith(".invalid")&&!EO1(K.name)){if(K.name.endsWith(".md"))B.push(U);else if(w.includeImages&&X&&Qj(K.name))B.push(U);else if(w.includeDocuments&&H&&wj(K.name))B.push(U)}else if(K.isDirectory()&&!K.name.startsWith(".")){if(Y===""&&!Q.hasEntityType(K.name))continue;let G=Z90(f,K.name),q=K.name==="image"&&Y==="",V=K.name==="document"&&Y==="";await $(G,U,X||q,H||V)}}};return await $(A),B}var eSQ=Z.record(Z.string(),Z.unknown());class ou0{syncPath;entityService;constructor(A,Q){this.syncPath=A,this.entityService=Q}parseEntityFromPath(A){return X90(this.syncPath,A)}async readEntity(A){let Q=UW(this.syncPath,A),w=await aSQ(Q),{entityType:B,id:$}=this.parseEntityFromPath(A),f=w.birthtime.getTime()>0?w.birthtime:w.mtime,Y=w.mtime,X,H;if(Qj(A)||wj(A)){let U=(await EC(Q)).toString("base64"),G=oSQ(A);if(X=`data:${wj(A)?TO1(G):xO1(G)};base64,${U}`,wj(A))H=await this.readDocumentSidecar(Q,A)}else X=await EC(Q,"utf-8");let W={entityType:B,id:$,content:X,created:f,updated:Y};if(H)W.metadata=H;return W}async readDocumentSidecar(A,Q){let w={mimeType:"application/pdf",filename:nSQ(Q)},B=du0(A);if(!await n5(B))return w;try{let $=await EC(B,"utf-8"),f=eSQ.safeParse(JSON.parse($));return{...w,...f.success?f.data:{}}}catch{return w}}async writeEntity(A){let Q=this.getEntityFilePath(A),w=A.entityType==="image",B=A.entityType==="document";if(w||B){let f=w?/^data:image\/[a-z+]+;base64,(.+)$/i:/^data:application\/pdf;base64,(.+)$/i,Y=A.content.match(f),X=Y?.[1]?Buffer.from(Y[1],"base64"):Buffer.from(A.content,"base64"),H=!1;if(await n5(Q)){let W=await EC(Q),K=B6(W.toString("base64")),U=B6(X.toString("base64"));if(K===U)H=!0}if(!H)await this.ensureEntityDirectory(A,Q),await ru0(Q,X);if(B)await this.writeDocumentSidecar(A,Q);if(H)return}else{let f=this.entityService.serializeEntity(A);if(await n5(Q)){let Y=await EC(Q,"utf-8"),X=B6(Y),H=B6(f);if(X===H)return}await this.ensureEntityDirectory(A,Q),await ru0(Q,f,"utf-8")}let $=new Date(A.updated);await tSQ(Q,$,$)}async ensureEntityDirectory(A,Q){if(A.entityType!=="note")await sSQ(rSQ(Q),{recursive:!0})}async writeDocumentSidecar(A,Q){let w=A.metadata,B={};for(let[Y,X]of Object.entries(w)){if(Y==="mimeType")continue;if(X===void 0)continue;B[Y]=X}let $=du0(Q),f=`${JSON.stringify(B,null,2)}
|
|
5439
5439
|
`;if(await n5($)){if(await EC($,"utf-8")===f)return}await this.ensureEntityDirectory(A,$),await ru0($,f,"utf-8")}getFilePath(A,Q,w=".md"){return mO1(this.syncPath,A,Q,w)}getEntityFilePath(A){return this.getFilePath(A.id,A.entityType,uO1(A))}async getAllMarkdownFiles(){return nu0(this.syncPath,this.entityService)}async getAllSyncFiles(){return lO1(this.syncPath,this.entityService)}async ensureDirectoryStructure(A){await pO1(this.syncPath,A)}shouldUpdateEntity(A,Q){let w=B6(Q.content);return A.contentHash!==w}async gatherFileStatus(){return iO1(this.syncPath,this.entityService)}async syncDirectoryExists(){return n5(this.syncPath)}async fileExists(A){return n5(A)}}F4();_0();u9();U2();F4();async function H90(A,Q,w,B){let{sourceUrl:$}=A,f=await Q.listEntities({entityType:"image",options:{filter:{metadata:{sourceUrl:$}},limit:1}});if(f[0])return B.debug("Reusing existing image entity",{sourceUrl:$,imageId:f[0].id}),f[0].id;let Y=await w($),{base64:X}=ob(Y),H=ik(X),W=sb(X);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:$}}});return B.debug("Created image entity from URL",{sourceUrl:$,imageId:K.entityId}),K.entityId}var nO1=Z.object({title:Z.string(),slug:Z.string().optional(),coverImageUrl:Z.url(),coverImageId:Z.string().optional(),coverImageAlt:Z.string().optional()});class su0{entityService;fetcher;logger;constructor(A,Q,w=TH){this.entityService=A,this.fetcher=w,this.logger=Q.child("FrontmatterImageConverter")}detectCoverImageUrl(A){let Q;try{Q=P6(A)}catch{return null}let{frontmatter:w}=Q,B=nO1.safeParse(w);if(!B.success)return null;if(B.data.coverImageId)return null;let{title:$,slug:f,coverImageUrl:Y,coverImageAlt:X}=B.data;if(!pk(Y))return null;return{sourceUrl:Y,postTitle:$,postSlug:f??H1($),customAlt:X}}async convert(A){let Q;try{Q=P6(A)}catch(W){return this.logger.debug("Parse failed",{error:W}),{content:A,converted:!1}}let{frontmatter:w}=Q,B=nO1.safeParse(w);if(!B.success)return{content:A,converted:!1};if(B.data.coverImageId)return{content:A,converted:!1};let{title:$,slug:f,coverImageUrl:Y,coverImageAlt:X}=B.data;if(!pk(Y))return{content:A,converted:!1};let H={postTitle:$,postSlug:f??H1($),sourceUrl:Y,customAlt:X};try{let W=await this.createImageEntity(H),K={...w};return delete K.coverImageUrl,delete K.coverImageAlt,K.coverImageId=W,{content:Dk(K,Q.content),converted:!0,imageId:W}}catch(W){return this.logger.warn("Failed to convert coverImageUrl",{url:Y,error:SA(W)}),{content:A,converted:!1}}}async createImageEntity(A){let{postTitle:Q,postSlug:w,sourceUrl:B,customAlt:$}=A,f=`Cover image for ${Q}`;return H90({id:`${w}-cover`,title:f,alt:$??f,sourceUrl:B},this.entityService,this.fetcher,this.logger)}}F4();class md{entityService;fetcher;logger;constructor(A,Q,w=TH){this.entityService=A,this.fetcher=w,this.logger=Q.child("MarkdownImageConverter")}detectInlineImages(A,Q){let w=[],B=XN0(A);for(let $ of B){if(!pk($.url))continue;if($.url.startsWith("entity://"))continue;let f=this.reconstructMarkdown($);w.push({sourceUrl:$.url,alt:$.alt,originalMarkdown:f,postSlug:Q})}return w}reconstructMarkdown(A){if(A.title)return``;return``}async convert(A,Q){let w=this.detectInlineImages(A,Q);if(w.length===0)return{content:A,converted:!1,convertedCount:0};let B=A,$=0,f=0;for(let Y of w)try{let X=await this.createImageEntity(Y,f++),H=``;B=B.replace(Y.originalMarkdown,H),$++,this.logger.debug("Converted inline image",{sourceUrl:Y.sourceUrl,imageId:X})}catch(X){this.logger.warn("Failed to convert inline image",{sourceUrl:Y.sourceUrl,error:SA(X)})}return{content:B,converted:$>0,convertedCount:$}}async createImageEntity(A,Q){let{sourceUrl:w,alt:B,postSlug:$}=A;return H90({id:`${$}-inline-${Q}`,title:B||`Inline image ${Q+1} for ${$}`,alt:B||"",sourceUrl:w},this.entityService,this.fetcher,this.logger)}}class au0{logger;entityService;fileOperations;constructor(A,Q,w){this.logger=A,this.entityService=Q,this.fileOperations=w}async importEntitiesWithProgress(A,Q,w,B){this.logger.debug("Importing entities with progress reporting");let $={imported:0,skipped:0,failed:0,quarantined:0,quarantinedFiles:[],errors:[],jobIds:[]},f=A??await this.fileOperations.getAllSyncFiles(),Y=f.length;await Q.report({progress:0,message:`Starting import of ${Y} files`});for(let X=0;X<Y;X+=w){let H=f.slice(X,X+w),W=await B(H);$.imported+=W.imported,$.skipped+=W.skipped,$.failed+=W.failed,$.quarantined+=W.quarantined,$.errors.push(...W.errors),$.quarantinedFiles.push(...W.quarantinedFiles),$.jobIds.push(...W.jobIds);let K=Math.min(X+w,Y),U=Math.round(K/Y*40);await Q.report({progress:U,message:`Imported ${K}/${Y} files`})}return $}async exportEntitiesWithProgress(A,Q,w,B){this.logger.debug("Exporting entities with progress reporting");let $=A??this.entityService.getEntityTypes();await Q.report({progress:50,message:`Starting export of ${$.length} entity types`});let f=await B(A);return await Q.report({progress:100,message:`Exported ${f.exported} entities`}),this.logger.debug("Export completed",f),f}}wA();import{rename as AmQ,appendFile as QmQ,readFile as wmQ,writeFile as BmQ,access as $mQ}from"fs/promises";import{join as rO1}from"path";class tu0{logger;syncPath;constructor(A,Q){this.logger=A,this.syncPath=Q}isValidationError(A){return KA0(A)}async quarantineInvalidFile(A,Q,w,B){let $=B(A),f=`${$}.invalid`;try{await AmQ($,f),w.quarantined++,w.quarantinedFiles.push(A);let Y=rO1(this.syncPath,".import-errors.log"),X=new Date().toISOString(),H=SA(Q),W=`${X} - ${A}: ${H}
|
|
5440
5440
|
\u2192 ${A}.invalid
|
|
@@ -5463,7 +5463,7 @@ ${DM1}</style></head><body>${hd(A)}<main id="root" data-web-chat-root>Brain Chat
|
|
|
5463
5463
|
*...and ${A.files.length-10} more files*`)}if(A.exists&&A.stats.totalFiles===0)Q.push(`
|
|
5464
5464
|
## Getting Started
|
|
5465
5465
|
`),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(`
|
|
5466
|
-
`)}}wA();class C90 extends tw{directorySync;constructor(A,Q,w){super(A,{schema:Al0,jobTypeName:"directory-export"});this.directorySync=w}async process(A,Q,w){this.logger.debug("Processing directory export job",{jobId:Q,data:A});let B=Date.now();try{let $=await this.directorySync.exportEntitiesWithProgress(A.entityTypes,w,A.batchSize??100);return this.logger.debug("Directory export job completed",{jobId:Q,exported:$.exported,failed:$.failed,duration:Date.now()-B}),$}catch($){throw this.logger.error("Directory export job failed",{jobId:Q,error:$}),$}}summarizeDataForLog(A){return{entityTypes:A.entityTypes??"all",batchSize:A.batchSize}}}wA();class g90 extends tw{directorySync;constructor(A,Q,w){super(A,{schema:ec0,jobTypeName:"directory-import"});this.directorySync=w}async process(A,Q,w){this.logger.debug("Processing directory import job",{jobId:Q,data:A});let B=Date.now();try{let $=await this.directorySync.importEntitiesWithProgress(A.paths,w,A.batchSize??100);return this.logger.debug("Directory import job completed",{jobId:Q,imported:$.imported,skipped:$.skipped,failed:$.failed,quarantined:$.quarantined,duration:Date.now()-B}),$}catch($){throw this.logger.error("Directory import job failed",{jobId:Q,error:$}),$}}summarizeDataForLog(A){return{pathCount:A.paths?.length??"all",batchSize:A.batchSize}}}wA();class y90 extends tw{directorySync;context;constructor(A,Q,w){super(A,{schema:ac0,jobTypeName:"directory-sync"});this.context=Q,this.directorySync=w}async process(A,Q,w){let B=Date.now(),$=A.syncDirection??"both";this.logger.info("Starting directory sync job",{jobId:Q,operation:A.operation,syncDirection:$});let f={imported:0,skipped:0,failed:0,quarantined:0,quarantinedFiles:[],errors:[],jobIds:[]},Y={exported:0,failed:0,errors:[]};if($!=="export")if(await w.report({progress:10,message:"Scanning directory for changes"}),f=await this.importWithProgress(A.paths,w),$==="import")await this.waitForImportJobs(f.jobIds,w),await w.report({progress:100,message:`Import complete: ${f.imported} imported`});else await w.report({progress:50,message:`Imported ${f.imported} entities`}),await this.waitForImportJobs(f.jobIds,w),await w.report({progress:56,message:"Processing complete, starting export"});if($!=="import"){let H=$==="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:$==="export"?`Export complete: ${Y.exported} exported`:`Sync complete: ${f.imported} imported, ${Y.exported} exported`})}let X=Date.now()-B;return this.logger.info("Directory sync job completed",{jobId:Q,duration:X,imported:f.imported,exported:Y.exported}),{import:f,export:Y,duration:X}}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,B=300000,$=500,f=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()-f>B){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,$)),Y()};return Y()}summarizeDataForLog(A){return{operation:A.operation,syncDirection:A.syncDirection}}}wA();class E90 extends tw{context;directorySync;gitSync;constructor(A,Q,w,B){super(A,{schema:tc0,jobTypeName:"sync-request"});this.context=Q,this.directorySync=w,this.gitSync=B}async process(A,Q,w){await w.report({progress:5,message:"Pulling latest content from git"});let B=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(!B)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: ${B.importOperationsCount} import jobs for ${B.totalFiles} files`}),LpQ(B)}summarizeDataForLog(A){return{source:A.source,interfaceType:A.interfaceType,channelId:A.channelId}}}function LpQ(A){return{gitPulled:!0,batchQueued:!0,batchId:A.batchId,importOperations:A.importOperationsCount,totalFiles:A.totalFiles}}wA();class T90 extends tw{context;constructor(A,Q,w){super(A,{schema:R90,jobTypeName:"directory-delete"});this.context=Q}async process(A,Q,w){let B=R90.parse(A);this.logger.info("Processing entity deletion for removed file",{entityId:B.entityId,entityType:B.entityType,filePath:B.filePath}),await w.report({progress:0,total:1,message:`Deleting ${B.entityType}:${B.entityId}`});try{let $=await this.context.entityService.deleteEntity({entityType:B.entityType,id:B.entityId});if($)this.logger.info("Successfully deleted entity for removed file",{entityId:B.entityId,entityType:B.entityType});else this.logger.warn("Entity not found in database",{entityId:B.entityId,entityType:B.entityType});return await w.report({progress:1,total:1,message:`Deleted ${B.entityType}:${B.entityId}`}),{deleted:$,entityId:B.entityId,entityType:B.entityType,filePath:B.filePath}}catch($){throw this.logger.error("Failed to delete entity",{entityId:B.entityId,entityType:B.entityType,error:$}),$}}summarizeDataForLog(A){return{entityId:A.entityId,entityType:A.entityType,filePath:A.filePath}}}wA();_0();var kpQ=Z.object({});class S90 extends tw{directorySync;constructor(A,Q){super(A,{schema:kpQ,jobTypeName:"directory-cleanup"});this.directorySync=Q}async process(A,Q,w){await w.report({progress:0,message:"Removing orphaned entities"});let B=await this.directorySync.removeOrphanedEntities();return await w.report({progress:100,message:`Cleanup complete: ${B.deleted} orphans removed`}),B}}wA();F4();u9();y6();_0();F4();import{readFile as _pQ,writeFile as NpQ}from"fs/promises";var jpQ=Ql0,PpQ=Z.record(Z.string(),Z.unknown());class m90 extends tw{context;fetcher;constructor(A,Q,w=TH){super(Q,{schema:jpQ,jobTypeName:"cover-image-convert"});this.context=A,this.fetcher=w}async process(A,Q,w){let{filePath:B,sourceUrl:$,postTitle:f,postSlug:Y,customAlt:X}=A;this.logger.debug("Starting image conversion job",{jobId:Q,filePath:B,sourceUrl:$,postSlug:Y});try{await this.reportProgress(w,{progress:nQ.INIT,message:`Reading file: ${B}`});let H;try{H=await _pQ(B,"utf-8")}catch(b){return this.logger.error("Failed to read file",{filePath:B,error:SA(b)}),w$.failure(b)}let W;try{W=P6(H)}catch(b){return this.logger.warn("Failed to parse markdown",{filePath:B,error:SA(b)}),w$.failure(b)}let K=PpQ.safeParse(W.frontmatter),U=K.success?K.data:{};if(U.coverImageId)return this.logger.debug("File already has coverImageId, skipping",{filePath:B}),await this.reportProgress(w,{progress:nQ.COMPLETE,message:"Already converted"}),{success:!0,skipped:!0};await this.reportProgress(w,{progress:nQ.FETCH,message:"Checking for existing image"});let G=await this.context.entityService.listEntities({entityType:"image",options:{filter:{metadata:{sourceUrl:$}},limit:1}}),q;if(G[0])q=G[0].id,this.logger.debug("Reusing existing image entity",{sourceUrl:$,imageId:q}),await this.reportProgress(w,{progress:nQ.EXTRACT,message:`Reusing existing image: ${q}`});else{await this.reportProgress(w,{progress:nQ.PROCESS,message:`Fetching image from ${$}`});let b;try{b=await this.fetcher($)}catch(h){return this.logger.error("Failed to fetch image",{sourceUrl:$,error:SA(h)}),w$.failure(h)}await this.reportProgress(w,{progress:nQ.GENERATE,message:"Creating image entity"});let{base64:L}=ob(b),N=ik(L),k=sb(L);if(!N||!k)return this.logger.error("Could not detect image format or dimensions",{sourceUrl:$}),w$.failure(Error("Could not detect image format or dimensions"));q=`${Y}-cover`;let x=`Cover image for ${f}`,v=X??x;await this.context.entityService.createEntity({entity:{id:q,entityType:"image",content:b,metadata:{title:x,alt:v,format:N,width:k.width,height:k.height,sourceUrl:$}}}),this.logger.debug("Created image entity",{imageId:q,sourceUrl:$}),await this.reportProgress(w,{progress:nQ.EXTRACT,message:`Created image: ${q}`})}await this.reportProgress(w,{progress:nQ.SAVE,message:"Updating file"});let V={...U};delete V.coverImageUrl,delete V.coverImageAlt,V.coverImageId=q;let J=Dk(V,W.content);try{await NpQ(B,J,"utf-8")}catch(b){return this.logger.error("Failed to write file",{filePath:B,error:SA(b)}),w$.failure(b)}return await this.reportProgress(w,{progress:nQ.COMPLETE,message:"Conversion complete"}),this.logger.info("Image conversion complete",{filePath:B,imageId:q,sourceUrl:$}),{success:!0,imageId:q}}catch(H){return this.logger.error("Image conversion job failed",{jobId:Q,filePath:B,error:SA(H)}),w$.failure(H)}}summarizeDataForLog(A){return{filePath:A.filePath,sourceUrl:A.sourceUrl,postSlug:A.postSlug}}}wA();F4();y6();import{readFile as MpQ,writeFile as OpQ}from"fs/promises";class u90 extends tw{converter;constructor(A,Q,w=TH){super(Q,{schema:wl0,jobTypeName:"inline-image-convert"});this.converter=new md(A.entityService,Q,w)}async process(A,Q,w){let{filePath:B,postSlug:$}=A;this.logger.debug("Starting inline image conversion job",{jobId:Q,filePath:B,postSlug:$});try{await this.reportProgress(w,{progress:nQ.INIT,message:`Reading file: ${B}`});let f;try{f=await MpQ(B,"utf-8")}catch(H){let W=SA(H);return this.logger.error("Failed to read file",{filePath:B,error:W}),{success:!1,error:W}}await this.reportProgress(w,{progress:nQ.FETCH,message:"Detecting inline images"});let Y=this.converter.detectInlineImages(f,$);if(Y.length===0)return this.logger.debug("No inline images to convert",{filePath:B}),await this.reportProgress(w,{progress:nQ.COMPLETE,message:"No images to convert"}),{success:!0,skipped:!0,convertedCount:0};this.logger.debug("Found inline images to convert",{filePath:B,count:Y.length}),await this.reportProgress(w,{progress:nQ.PROCESS,message:`Converting ${Y.length} images`});let X=await this.converter.convert(f,$);if(!X.converted)return this.logger.debug("No images were converted",{filePath:B}),await this.reportProgress(w,{progress:nQ.COMPLETE,message:"No images converted"}),{success:!0,skipped:!0,convertedCount:0};await this.reportProgress(w,{progress:nQ.SAVE,message:"Writing updated file"});try{await OpQ(B,X.content,"utf-8")}catch(H){let W=SA(H);return this.logger.error("Failed to write file",{filePath:B,error:W}),{success:!1,error:W}}return await this.reportProgress(w,{progress:nQ.COMPLETE,message:"Conversion complete"}),this.logger.info("Inline image conversion complete",{filePath:B,convertedCount:X.convertedCount}),{success:!0,convertedCount:X.convertedCount}}catch(f){let Y=SA(f);return this.logger.error("Inline image conversion job failed",{jobId:Q,filePath:B,error:Y}),{success:!1,error:Y}}}summarizeDataForLog(A){return{filePath:A.filePath,postSlug:A.postSlug}}}function Rh1(A,Q,w){let B=($)=>w.child($);A.jobs.registerHandler("directory-sync",new y90(B("DirectorySyncJobHandler"),A,Q)),A.jobs.registerHandler("directory-export",new C90(B("DirectoryExportJobHandler"),A,Q)),A.jobs.registerHandler("directory-import",new g90(B("DirectoryImportJobHandler"),A,Q)),A.jobs.registerHandler("directory-delete",new T90(B("DirectoryDeleteJobHandler"),A,Q)),A.jobs.registerHandler("directory-cleanup",new S90(B("DirectoryCleanupJobHandler"),Q)),A.jobs.registerHandler("cover-image-convert",new m90(A,B("CoverImageConversionJobHandler"))),A.jobs.registerHandler("inline-image-convert",new u90(A,B("InlineImageConversionJobHandler"))),w.debug("Registered async job handlers")}wA();_0();import{unlink as xpQ,access as vpQ}from"fs/promises";var RpQ=Z.record(Z.string(),Z.unknown());function hh1(A,Q,w,B){let{subscribe:$}=A.messaging,{entityService:f}=A;$("entity:created",async(Y)=>{let{entity:X}=Y.payload;try{await Q.fileOps.writeEntity(X),w.debug("Auto-exported created entity",{id:X.id,entityType:X.entityType})}catch(H){w.error("Auto-export FAILED for created entity",{id:X.id,entityType:X.entityType,error:H instanceof Error?H.message:String(H),stack:H instanceof Error?H.stack:void 0})}return{success:!0}}),$("entity:updated",async(Y)=>{let{entityType:X,entityId:H}=Y.payload;try{let W=await f.getEntity({entityType:X,id:H});if(!W)return w.debug("Entity not found in DB, skipping export",{entityType:X,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:X,entityId:H,error:W instanceof Error?W.message:String(W),stack:W instanceof Error?W.stack:void 0})}return{success:!0}}),$("entity:deleted",async(Y)=>{let{entityId:X,entityType:H}=Y.payload,W=Q.fileOps.getFilePath(X,H);if(await vpQ(W).then(()=>!0,()=>!1))await xpQ(W),w.debug("Auto-deleted entity file",{id:X,entityType:H,path:W});return{success:!0}}),w.debug("Setup auto-sync for entity events",{entityTypes:B})}function Ch1(A,Q,w){Q.setJobQueueCallback(async(B)=>{let $=[{type:B.type,data:RpQ.parse(B.data)}];return A.jobs.enqueueBatch($,{priority:5,source:"directory-sync-watcher",rootJobId:H4(),metadata:{operationType:"file_operations",operationTarget:w,pluginId:"directory-sync"}})})}wA();import{readdir as Eh1,mkdir as CpQ,copyFile as gpQ}from"fs/promises";import{join as yh1,resolve as Bl0}from"path";import{join as hpQ}from"path";async function gh1(A){if(!await n5(hpQ(A,".git")))return!1;try{return await YU(A).revparse(["--verify","HEAD"]),!0}catch{return!1}}async function ypQ(A,Q){if(!await n5(A))return!0;if((await Eh1(A)).filter(($)=>!$.startsWith(".")&&!$.startsWith("_")).length>0)return!1;if(await gh1(A))return Q.debug("Git repository with history detected - skipping seed content",{path:A}),!1;return!0}async function Th1(A,Q){let w=await Eh1(A,{withFileTypes:!0});for(let B of w){let $=yh1(A,B.name),f=yh1(Q,B.name);if(B.isDirectory()){if(!await n5(f))await CpQ(f,{recursive:!0});await Th1($,f)}else await gpQ($,f)}}async function Sh1(A,Q,w){let B=Bl0(process.cwd(),A);w=w?Bl0(w):Bl0(process.cwd(),"seed-content");let $=await ypQ(B,Q);if($&&await n5(w))Q.debug("Copying seed content to brain-data directory"),await Th1(w,B),Q.debug("Seed content copied successfully");else if($)Q.debug("No seed content directory found, starting with empty brain-data");else Q.debug("brain-data directory not empty, skipping seed content")}function mh1(A,Q,w,B,$){let f=!1,Y=async()=>{if(f)return;f=!0;let X=Q();if(w.seedContent){let H=w.syncPath??A.dataDir;await Sh1(H,B,w.seedContentPath)}try{if($){B.debug("Git enabled \u2014 pulling before import");let W=await $.pull();if(W.files.length>0)B.info("Pulled changes from remote",{filesChanged:W.files.length})}B.debug("Starting initial sync");let H=await X.sync();B.debug("Initial sync completed",{imported:H.import.imported,failed:H.import.failed,duration:H.duration}),await A.messaging.send({type:bk.initialSyncCompleted,payload:{success:!0},...{broadcast:!0}})}catch(H){B.error("Initial sync failed",H),await A.messaging.send({type:bk.initialSyncCompleted,payload:{success:!1,error:SA(H)},...{broadcast:!0}})}};A.messaging.subscribe(bk.pluginsRegistered,async()=>{return B.debug("Plugins registered, starting initial sync"),await Y(),{success:!0}})}class $l0{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 fl0{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 uh1(A,Q,w,B){let $=new fl0(()=>{Q.withLock(async()=>{try{await Q.commit(),await Q.push()}catch(X){B.error("Git auto-commit failed",{error:X})}})},w),f=["entity:created","entity:updated","entity:deleted"],Y=[];for(let X of f){let H=A.subscribe(X,async()=>{return $.trigger(),{success:!0}});Y.push(H)}return()=>{$.dispose();for(let X of Y)X()}}function ch1(A,Q,w,B,$){if(B<=0)return()=>{};let f=B*60*1000,Y=!1,X=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)$.info("Periodic sync: pulled changes",{filesChanged:W.length});if(K)$.debug("Periodic sync: queued imports",{importOperations:K.importOperationsCount,totalFiles:K.totalFiles})}catch(W){$.error("Periodic git sync failed",{error:W})}finally{Y=!1}},H=setInterval(()=>{X()},f);return $.info("Started periodic git sync",{intervalMinutes:B}),()=>{clearInterval(H)}}import{spawnSync as ph1}from"child_process";import{cpSync as EpQ,existsSync as lh1,mkdirSync as TpQ,mkdtempSync as SpQ,rmSync as mpQ}from"fs";import{tmpdir as upQ}from"os";import{fileURLToPath as cpQ}from"url";import{join as lpQ,resolve as ppQ}from"path";function lI(A,Q){let w=ph1("git",Q,{cwd:A,stdio:"pipe"});if(w.status!==0){let B=w.stderr.toString().trim(),$=w.stdout.toString().trim();throw Error(B||$||`git ${Q.join(" ")} failed`)}}function ipQ(A){return A.startsWith("file://")}function dpQ(A){return cpQ(A)}function npQ(A,Q){return ph1("git",["--git-dir",A,"show-ref","--verify","--quiet",`refs/heads/${Q}`]).status===0}async function ih1(A){if(!A.bootstrapFromSeed)return;if(!A.gitUrl||!ipQ(A.gitUrl))return;if(!A.seedContentPath)throw Error("directory-sync git.bootstrapFromSeed requires seedContentPath for local file:// remotes");let Q=A.branch??"main",w=dpQ(A.gitUrl),B=ppQ(A.seedContentPath);if(!lh1(B))throw Error(`Seed content path not found: ${B}`);if(!lh1(w))A.logger.debug("Creating local bare content remote",{remotePath:w,branch:Q}),TpQ(w,{recursive:!0}),lI(process.cwd(),["init","--bare",`--initial-branch=${Q}`,w]);if(npQ(w,Q)){A.logger.debug("Content remote already initialized",{remotePath:w,branch:Q});return}A.logger.debug("Seeding local content remote",{remotePath:w,seedPath:B,branch:Q});let $=SpQ(lpQ(upQ(),"directory-sync-seed-"));try{lI($,["init",`--initial-branch=${Q}`]),lI($,["config","user.name",A.authorName??"Brain"]),lI($,["config","user.email",A.authorEmail??"brain@localhost"]),EpQ(B,$,{recursive:!0}),lI($,["add","."]),lI($,["commit","-m","seed content remote"]),lI($,["remote","add","origin",A.gitUrl]),lI($,["push","-u","origin",Q])}finally{mpQ($,{recursive:!0,force:!0})}}function dh1(A,Q,w,B,$,f){let{subscribe:Y}=A.messaging;Y("entity:export:request",async(X)=>{try{return{success:!0,data:await Q().exportEntities(X.payload.entityTypes)}}catch(H){return{success:!1,error:H instanceof Error?H.message:"Export failed"}}}),Y("entity:import:request",async(X)=>{try{let H=Q(),W=X.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 rpQ(f?.(),B)}}}catch(X){return{success:!1,error:X instanceof Error?X.message:"Status check failed"}}}),Y("sync:configure:request",async(X)=>{try{return await w({syncPath:X.payload.syncPath}),{success:!0,data:{syncPath:X.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(!$?.repo)return{success:!1,error:"Git not configured"};return{success:!0,data:{repo:$.repo,branch:$.branch??"main"}}}),B.debug("Registered message handlers")}async function rpQ(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}}wA();_0();wA();_0();function nh1(A,Q){return M6(A,"history","Get version history for an entity from git. Without sha: returns commit list. With sha: returns entity content at that version.",Z.object({entityType:Z.string().describe("Entity type (e.g. post, note, link)"),id:Z.string().describe("Entity ID"),sha:Z.string().optional().describe("Commit SHA to retrieve content at. Omit to list commit history."),limit:Z.number().int().positive().optional().default(10).describe("Max commits to return (list mode only)")}),async(w)=>{let B=`${w.entityType}/${w.id}.md`;try{if(w.sha){let f=await Q.show(w.sha,B);return b8({sha:w.sha,entityType:w.entityType,id:w.id,content:f},`Content at ${w.sha.slice(0,7)}`)}let $=await Q.log(B,w.limit);if($.length===0)return b8({commits:[]},`No history found for ${w.entityType}/${w.id}`);return b8({commits:$,entityType:w.entityType,id:w.id},`${$.length} version${$.length===1?"":"s"} found`)}catch($){return _7($ instanceof Error?$.message:"History lookup failed")}},{visibility:"anchor",sideEffects:"none"})}function rh1(A,Q,w,B){let $=[M6(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.",Z.object({}),async(f,Y)=>{try{let X=Y.channelId?`${Y.interfaceType}:${Y.channelId}`:`plugin:${w}`,H={interfaceType:Y.interfaceType,channelId:Y.channelId};if(B){let K=await Q.jobs.enqueue({type:"sync-request",data:{source:X,interfaceType:H.interfaceType,channelId:H.channelId},toolContext:Y});return b8({jobId:K,status:"queued",gitPulled:!0},"Sync queued: git pull and filesystem scan will run in the background")}let W=await A.queueSyncBatch(Q,X,H);if(!W)return b8({gitPulled:!1},"No files to sync");return b8({batchId:W.batchId,importOperations:W.importOperationsCount,totalFiles:W.totalFiles,gitPulled:!1},`Sync started: ${W.importOperationsCount} import jobs queued for ${W.totalFiles} files`)}catch(X){return _7(X instanceof Error?X.message:"Sync failed")}},{visibility:"anchor",sideEffects:"external",cli:{name:"sync"}}),M6(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.",Z.object({}),async()=>{try{let f=await A.getStatus(),Y={syncPath:f.syncPath,lastSync:f.lastSync?.toISOString(),watching:f.watching};if(B){let X=await B.getStatus();Y.git={isRepo:X.isRepo,branch:X.branch,hasChanges:X.hasChanges,ahead:X.ahead,behind:X.behind,remote:X.remote}}return b8(Y)}catch(f){return _7(f instanceof Error?f.message:"Status check failed")}},{visibility:"anchor",sideEffects:"none"})];if(B)$.push(nh1(w,B));return $}var oh1={name:"@brains/directory-sync",version:"0.2.0-alpha.150",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:"^6.0.3"},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 Yl0 extends tQ{directorySync;gitSync;gitCleanups=[];constructor(A={}){super("directory-sync",oh1,A,ed)}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:An,basePrompt:"",formatter:new h90,requiredPermission:"anchor"}});let B=this.config.syncPath??A.dataDir;this.directorySync=new ud({syncPath:B,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:B})}catch(Y){throw this.logger.error("Failed to initialize directory",Y),Y}await this.registerJobHandlers(A);let $=this.requireDirectorySync();if(hh1(A,$,this.logger,this.config.entityTypes),this.config.autoSync)Ch1(A,$,this.config.syncPath??A.dataDir);let f=this.config.git!==void 0&&(this.config.git.repo!==void 0||this.config.git.gitUrl!==void 0);if(this.config.git&&!f)this.logger.debug("Git block present but no repo/gitUrl configured \u2014 git sync disabled");if(f&&this.config.git){await ih1({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 sc0({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 E90(this.logger.child("DirectorySyncRequestJobHandler"),A,this.requireDirectorySync(),this.gitSync)),this.gitCleanups.push(uh1(A.messaging,this.gitSync,this.config.commitDebounce,this.logger.child("GitAutoCommit"))),this.config.autoSync)this.gitCleanups.push(ch1(this.gitSync,this.requireDirectorySync(),A,this.config.syncInterval,this.logger.child("GitPeriodicSync")))}if(this.config.initialSync)mh1(A,()=>this.requireDirectorySync(),this.config,this.logger,this.gitSync);dh1(A,()=>this.requireDirectorySync(),(Y)=>this.configure(Y),this.logger,this.config.git,()=>this.gitSync)}async getTools(){let A=this.requireDirectorySync();return rh1(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 ud({...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){Rh1(A,this.requireDirectorySync(),this.logger)}}function Yj(A={}){return new Yl0(A)}wA();_0();var sh1={name:"@brains/email-resend",version:"0.2.0-alpha.150",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:"^6.0.3"},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 apQ=Z.object({apiKey:Z.string().min(1).optional(),from:Z.string().min(1).optional()}),tpQ=Z.looseObject({id:Z.string().optional()});class ah1 extends tQ{fetchImpl;constructor(A={},Q={}){super("email-resend",sh1,A,apQ);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(l60,async(w)=>{let B=egA.parse(w.payload);try{return{success:!0,data:await this.sendWithResend(B)}}catch($){if(B.sensitivity==="secret")Q.warn("Email delivery failed for a secret message");else Q.warn("Email delivery failed",{to:B.to,subject:B.subject,error:$ instanceof Error?$.message:String($)});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 B=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(!B.ok)throw Error("Resend email request failed");let $=tpQ.parse(await B.json());return $.id?{status:"sent",id:$.id}:{status:"sent"}}}function c90(A={}){return new ah1(A)}wA();import{render as Eo1}from"preact-render-to-string";import{h as cj}from"preact";function th1(A){var Q,w,B="";if(typeof A=="string"||typeof A=="number")B+=A;else if(typeof A=="object")if(Array.isArray(A)){var $=A.length;for(Q=0;Q<$;Q++)A[Q]&&(w=th1(A[Q]))&&(B&&(B+=" "),B+=w)}else for(w in A)A[w]&&(B&&(B+=" "),B+=w);return B}function rC(){for(var A,Q,w=0,B="",$=arguments.length;w<$;w++)(A=arguments[w])&&(Q=th1(A))&&(B&&(B+=" "),B+=Q);return B}var epQ=(A,Q)=>{let w=Array(A.length+Q.length);for(let B=0;B<A.length;B++)w[B]=A[B];for(let B=0;B<Q.length;B++)w[A.length+B]=Q[B];return w},AiQ=(A,Q)=>({classGroupId:A,validator:Q}),YC1=(A=new Map,Q=null,w)=>({nextPart:A,validators:Q,classGroupId:w});var eh1=[];var QiQ=(A)=>{let Q=BiQ(A),{conflictingClassGroups:w,conflictingClassGroupModifiers:B}=A;return{getClassGroupId:(Y)=>{if(Y.startsWith("[")&&Y.endsWith("]"))return wiQ(Y);let X=Y.split("-"),H=X[0]===""&&X.length>1?1:0;return XC1(X,H,Q)},getConflictingClassGroupIds:(Y,X)=>{if(X){let H=B[Y],W=w[Y];if(H){if(W)return epQ(W,H);return H}return W||eh1}return w[Y]||eh1}}},XC1=(A,Q,w)=>{if(A.length-Q===0)return w.classGroupId;let $=A[Q],f=w.nextPart.get($);if(f){let W=XC1(A,Q+1,f);if(W)return W}let Y=w.validators;if(Y===null)return;let X=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(X))return K.classGroupId}return},wiQ=(A)=>A.slice(1,-1).indexOf(":")===-1?void 0:(()=>{let Q=A.slice(1,-1),w=Q.indexOf(":"),B=Q.slice(0,w);return B?"arbitrary.."+B:void 0})(),BiQ=(A)=>{let{theme:Q,classGroups:w}=A;return $iQ(w,Q)},$iQ=(A,Q)=>{let w=YC1();for(let B in A){let $=A[B];Hl0($,w,B,Q)}return w},Hl0=(A,Q,w,B)=>{let $=A.length;for(let f=0;f<$;f++){let Y=A[f];fiQ(Y,Q,w,B)}},fiQ=(A,Q,w,B)=>{if(typeof A==="string"){YiQ(A,Q,w);return}if(typeof A==="function"){XiQ(A,Q,w,B);return}ZiQ(A,Q,w,B)},YiQ=(A,Q,w)=>{let B=A===""?Q:ZC1(Q,A);B.classGroupId=w},XiQ=(A,Q,w,B)=>{if(HiQ(A)){Hl0(A(B),Q,w,B);return}if(Q.validators===null)Q.validators=[];Q.validators.push(AiQ(w,A))},ZiQ=(A,Q,w,B)=>{let $=Object.entries(A),f=$.length;for(let Y=0;Y<f;Y++){let[X,H]=$[Y];Hl0(H,ZC1(Q,X),w,B)}},ZC1=(A,Q)=>{let w=A,B=Q.split("-"),$=B.length;for(let f=0;f<$;f++){let Y=B[f],X=w.nextPart.get(Y);if(!X)X=YC1(),w.nextPart.set(Y,X);w=X}return w},HiQ=(A)=>("isThemeGetter"in A)&&A.isThemeGetter===!0,WiQ=(A)=>{if(A<1)return{get:()=>{return},set:()=>{}};let Q=0,w=Object.create(null),B=Object.create(null),$=(f,Y)=>{if(w[f]=Y,Q++,Q>A)Q=0,B=w,w=Object.create(null)};return{get(f){let Y=w[f];if(Y!==void 0)return Y;if((Y=B[f])!==void 0)return $(f,Y),Y},set(f,Y){if(f in w)w[f]=Y;else $(f,Y)}}};var KiQ=[],AC1=(A,Q,w,B,$)=>({modifiers:A,hasImportantModifier:Q,baseClassName:w,maybePostfixModifierPosition:B,isExternal:$}),UiQ=(A)=>{let{prefix:Q,experimentalParseClassName:w}=A,B=($)=>{let f=[],Y=0,X=0,H=0,W,K=$.length;for(let J=0;J<K;J++){let b=$[J];if(Y===0&&X===0){if(b===":"){f.push($.slice(H,J)),H=J+1;continue}if(b==="/"){W=J;continue}}if(b==="[")Y++;else if(b==="]")Y--;else if(b==="(")X++;else if(b===")")X--}let U=f.length===0?$:$.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 AC1(f,q,G,V)};if(Q){let $=Q+":",f=B;B=(Y)=>Y.startsWith($)?f(Y.slice($.length)):AC1(KiQ,!1,Y,void 0,!0)}if(w){let $=B;B=(f)=>w({className:f,parseClassName:$})}return B},GiQ=(A)=>{let Q=new Map;return A.orderSensitiveModifiers.forEach((w,B)=>{Q.set(w,1e6+B)}),(w)=>{let B=[],$=[];for(let f=0;f<w.length;f++){let Y=w[f],X=Y[0]==="[",H=Q.has(Y);if(X||H){if($.length>0)$.sort(),B.push(...$),$=[];B.push(Y)}else $.push(Y)}if($.length>0)$.sort(),B.push(...$);return B}},DiQ=(A)=>({cache:WiQ(A.cacheSize),parseClassName:UiQ(A),sortModifiers:GiQ(A),postfixLookupClassGroupIds:ziQ(A),...QiQ(A)}),ziQ=(A)=>{let Q=Object.create(null),w=A.postfixLookupClassGroups;if(w)for(let B=0;B<w.length;B++)Q[w[B]]=!0;return Q},qiQ=/\s+/,ViQ=(A,Q)=>{let{parseClassName:w,getClassGroupId:B,getConflictingClassGroupIds:$,sortModifiers:f,postfixLookupClassGroupIds:Y}=Q,X=[],H=A.trim().split(qiQ),W="";for(let K=H.length-1;K>=0;K-=1){let U=H[K],{isExternal:G,modifiers:q,hasImportantModifier:V,baseClassName:J,maybePostfixModifierPosition:b}=w(U);if(G){W=U+(W.length>0?" "+W:W);continue}let L=!!b,N;if(L){let P=J.substring(0,b);N=B(P);let E=N&&Y[N]?B(J):void 0;if(E&&E!==N)N=E,L=!1}else N=B(J);if(!N){if(!L){W=U+(W.length>0?" "+W:W);continue}if(N=B(J),!N){W=U+(W.length>0?" "+W:W);continue}L=!1}let k=q.length===0?"":q.length===1?q[0]:f(q).join(":"),x=V?k+"!":k,v=x+N;if(X.indexOf(v)>-1)continue;X.push(v);let h=$(N,L);for(let P=0;P<h.length;++P){let E=h[P];X.push(x+E)}W=U+(W.length>0?" "+W:W)}return W},biQ=(...A)=>{let Q=0,w,B,$="";while(Q<A.length)if(w=A[Q++]){if(B=HC1(w))$&&($+=" "),$+=B}return $},HC1=(A)=>{if(typeof A==="string")return A;let Q,w="";for(let B=0;B<A.length;B++)if(A[B]){if(Q=HC1(A[B]))w&&(w+=" "),w+=Q}return w},QC1=(A,...Q)=>{let w,B,$,f,Y=(H)=>{let W=Q.reduce((K,U)=>U(K),A());return w=DiQ(W),B=w.cache.get,$=w.cache.set,f=X,X(H)},X=(H)=>{let W=B(H);if(W)return W;let K=ViQ(H,w);return $(H,K),K};return f=Y,(...H)=>f(biQ(...H))},JiQ=[],J9=(A)=>{let Q=(w)=>w[A]||JiQ;return Q.isThemeGetter=!0,Q},WC1=/^\[(?:(\w[\w-]*):)?(.+)\]$/i,KC1=/^\((?:(\w[\w-]*):)?(.+)\)$/i,IiQ=/^\d+(?:\.\d+)?\/\d+(?:\.\d+)?$/,FiQ=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,LiQ=/\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$/,kiQ=/^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/,_iQ=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,NiQ=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,pI=(A)=>IiQ.test(A),gw=(A)=>!!A&&!Number.isNaN(Number(A)),kD=(A)=>!!A&&Number.isInteger(Number(A)),Xl0=(A)=>A.endsWith("%")&&gw(A.slice(0,-1)),Rq=(A)=>FiQ.test(A),UC1=()=>!0,jiQ=(A)=>LiQ.test(A)&&!kiQ.test(A),Wl0=()=>!1,PiQ=(A)=>_iQ.test(A),MiQ=(A)=>NiQ.test(A),OiQ=(A)=>!I2(A)&&!_2(A),xiQ=(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)),viQ=(A)=>iI(A,zC1,Wl0),I2=(A)=>WC1.test(A),Xj=(A)=>iI(A,qC1,jiQ),wC1=(A)=>iI(A,SiQ,gw),RiQ=(A)=>iI(A,bC1,UC1),hiQ=(A)=>iI(A,VC1,Wl0),BC1=(A)=>iI(A,GC1,Wl0),CiQ=(A)=>iI(A,DC1,MiQ),l90=(A)=>iI(A,JC1,PiQ),_2=(A)=>KC1.test(A),Qn=(A)=>Zj(A,qC1),giQ=(A)=>Zj(A,VC1),$C1=(A)=>Zj(A,GC1),yiQ=(A)=>Zj(A,zC1),EiQ=(A)=>Zj(A,DC1),p90=(A)=>Zj(A,JC1,!0),TiQ=(A)=>Zj(A,bC1,!0),iI=(A,Q,w)=>{let B=WC1.exec(A);if(B){if(B[1])return Q(B[1]);return w(B[2])}return!1},Zj=(A,Q,w=!1)=>{let B=KC1.exec(A);if(B){if(B[1])return Q(B[1]);return w}return!1},GC1=(A)=>A==="position"||A==="percentage",DC1=(A)=>A==="image"||A==="url",zC1=(A)=>A==="length"||A==="size"||A==="bg-size",qC1=(A)=>A==="length",SiQ=(A)=>A==="number",VC1=(A)=>A==="family-name",bC1=(A)=>A==="number"||A==="weight",JC1=(A)=>A==="shadow";var fC1=()=>{let A=J9("color"),Q=J9("font"),w=J9("text"),B=J9("font-weight"),$=J9("tracking"),f=J9("leading"),Y=J9("breakpoint"),X=J9("container"),H=J9("spacing"),W=J9("radius"),K=J9("shadow"),U=J9("inset-shadow"),G=J9("text-shadow"),q=J9("drop-shadow"),V=J9("blur"),J=J9("perspective"),b=J9("aspect"),L=J9("ease"),N=J9("animate"),k=()=>["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(),_2,I2],h=()=>["auto","hidden","clip","visible","scroll"],P=()=>["auto","contain","none"],E=()=>[_2,I2,H],S=()=>[pI,"full","auto",...E()],p=()=>[kD,"none","subgrid",_2,I2],e=()=>["auto",{span:["full",kD,_2,I2]},kD,_2,I2],Y0=()=>[kD,"auto",_2,I2],l=()=>["auto","min","max","fr",_2,I2],j=()=>["start","end","center","between","around","evenly","stretch","baseline","center-safe","end-safe"],g=()=>["start","end","center","stretch","center-safe","end-safe"],y=()=>["auto",...E()],n=()=>[pI,"auto","full","dvw","dvh","lvw","lvh","svw","svh","min","max","fit",...E()],o=()=>[pI,"screen","full","dvw","lvw","svw","min","max","fit",...E()],K0=()=>[pI,"screen","full","lh","dvh","lvh","svh","min","max","fit",...E()],c=()=>[A,_2,I2],X0=()=>[...x(),$C1,BC1,{position:[_2,I2]}],V0=()=>["no-repeat",{repeat:["","x","y","space","round"]}],w0=()=>["auto","cover","contain",yiQ,viQ,{size:[_2,I2]}],h0=()=>[Xl0,Qn,Xj],S0=()=>["","none","full",W,_2,I2],b0=()=>["",gw,Qn,Xj],J0=()=>["solid","dashed","dotted","double"],j0=()=>["normal","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity"],C0=()=>[gw,Xl0,$C1,BC1],k0=()=>["","none",V,_2,I2],N0=()=>["none",gw,_2,I2],P0=()=>["none",gw,_2,I2],M0=()=>[gw,_2,I2],T0=()=>[pI,"full",...E()];return{cacheSize:500,theme:{animate:["spin","ping","pulse","bounce"],aspect:["video"],blur:[Rq],breakpoint:[Rq],color:[UC1],container:[Rq],"drop-shadow":[Rq],ease:["in","out","in-out"],font:[OiQ],"font-weight":["thin","extralight","light","normal","medium","semibold","bold","extrabold","black"],"inset-shadow":[Rq],leading:["none","tight","snug","normal","relaxed","loose"],perspective:["dramatic","near","normal","midrange","distant","none"],radius:[Rq],shadow:[Rq],spacing:["px",gw],text:[Rq],"text-shadow":[Rq],tracking:["tighter","tight","normal","wide","wider","widest"]},classGroups:{aspect:[{aspect:["auto","square",pI,I2,_2,b]}],container:["container"],"container-type":[{"@container":["","normal","size",_2,I2]}],"container-named":[xiQ],columns:[{columns:[gw,I2,_2,X]}],"break-after":[{"break-after":k()}],"break-before":[{"break-before":k()}],"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:h()}],"overflow-x":[{"overflow-x":h()}],"overflow-y":[{"overflow-y":h()}],overscroll:[{overscroll:P()}],"overscroll-x":[{"overscroll-x":P()}],"overscroll-y":[{"overscroll-y":P()}],position:["static","fixed","absolute","relative","sticky"],inset:[{inset:S()}],"inset-x":[{"inset-x":S()}],"inset-y":[{"inset-y":S()}],start:[{"inset-s":S(),start:S()}],end:[{"inset-e":S(),end:S()}],"inset-bs":[{"inset-bs":S()}],"inset-be":[{"inset-be":S()}],top:[{top:S()}],right:[{right:S()}],bottom:[{bottom:S()}],left:[{left:S()}],visibility:["visible","invisible","collapse"],z:[{z:[kD,"auto",_2,I2]}],basis:[{basis:[pI,"full","auto",X,...E()]}],"flex-direction":[{flex:["row","row-reverse","col","col-reverse"]}],"flex-wrap":[{flex:["nowrap","wrap","wrap-reverse"]}],flex:[{flex:[gw,pI,"auto","initial","none",I2]}],grow:[{grow:["",gw,_2,I2]}],shrink:[{shrink:["",gw,_2,I2]}],order:[{order:[kD,"first","last","none",_2,I2]}],"grid-cols":[{"grid-cols":p()}],"col-start-end":[{col:e()}],"col-start":[{"col-start":Y0()}],"col-end":[{"col-end":Y0()}],"grid-rows":[{"grid-rows":p()}],"row-start-end":[{row:e()}],"row-start":[{"row-start":Y0()}],"row-end":[{"row-end":Y0()}],"grid-flow":[{"grid-flow":["row","col","dense","row-dense","col-dense"]}],"auto-cols":[{"auto-cols":l()}],"auto-rows":[{"auto-rows":l()}],gap:[{gap:E()}],"gap-x":[{"gap-x":E()}],"gap-y":[{"gap-y":E()}],"justify-content":[{justify:[...j(),"normal"]}],"justify-items":[{"justify-items":[...g(),"normal"]}],"justify-self":[{"justify-self":["auto",...g()]}],"align-content":[{content:["normal",...j()]}],"align-items":[{items:[...g(),{baseline:["","last"]}]}],"align-self":[{self:["auto",...g(),{baseline:["","last"]}]}],"place-content":[{"place-content":j()}],"place-items":[{"place-items":[...g(),"baseline"]}],"place-self":[{"place-self":["auto",...g()]}],p:[{p:E()}],px:[{px:E()}],py:[{py:E()}],ps:[{ps:E()}],pe:[{pe:E()}],pbs:[{pbs:E()}],pbe:[{pbe:E()}],pt:[{pt:E()}],pr:[{pr:E()}],pb:[{pb:E()}],pl:[{pl:E()}],m:[{m:y()}],mx:[{mx:y()}],my:[{my:y()}],ms:[{ms:y()}],me:[{me:y()}],mbs:[{mbs:y()}],mbe:[{mbe:y()}],mt:[{mt:y()}],mr:[{mr:y()}],mb:[{mb:y()}],ml:[{ml:y()}],"space-x":[{"space-x":E()}],"space-x-reverse":["space-x-reverse"],"space-y":[{"space-y":E()}],"space-y-reverse":["space-y-reverse"],size:[{size:n()}],"inline-size":[{inline:["auto",...o()]}],"min-inline-size":[{"min-inline":["auto",...o()]}],"max-inline-size":[{"max-inline":["none",...o()]}],"block-size":[{block:["auto",...K0()]}],"min-block-size":[{"min-block":["auto",...K0()]}],"max-block-size":[{"max-block":["none",...K0()]}],w:[{w:[X,"screen",...n()]}],"min-w":[{"min-w":[X,"screen","none",...n()]}],"max-w":[{"max-w":[X,"screen","none","prose",{screen:[Y]},...n()]}],h:[{h:["screen","lh",...n()]}],"min-h":[{"min-h":["screen","lh","none",...n()]}],"max-h":[{"max-h":["screen","lh",...n()]}],"font-size":[{text:["base",w,Qn,Xj]}],"font-smoothing":["antialiased","subpixel-antialiased"],"font-style":["italic","not-italic"],"font-weight":[{font:[B,TiQ,RiQ]}],"font-stretch":[{"font-stretch":["ultra-condensed","extra-condensed","condensed","semi-condensed","normal","semi-expanded","expanded","extra-expanded","ultra-expanded",Xl0,I2]}],"font-family":[{font:[giQ,hiQ,Q]}],"font-features":[{"font-features":[I2]}],"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:[$,_2,I2]}],"line-clamp":[{"line-clamp":[gw,"none",_2,wC1]}],leading:[{leading:[f,...E()]}],"list-image":[{"list-image":["none",_2,I2]}],"list-style-position":[{list:["inside","outside"]}],"list-style-type":[{list:["disc","decimal","none",_2,I2]}],"text-alignment":[{text:["left","center","right","justify","start","end"]}],"placeholder-color":[{placeholder:c()}],"text-color":[{text:c()}],"text-decoration":["underline","overline","line-through","no-underline"],"text-decoration-style":[{decoration:[...J0(),"wavy"]}],"text-decoration-thickness":[{decoration:[gw,"from-font","auto",_2,Xj]}],"text-decoration-color":[{decoration:c()}],"underline-offset":[{"underline-offset":[gw,"auto",_2,I2]}],"text-transform":["uppercase","lowercase","capitalize","normal-case"],"text-overflow":["truncate","text-ellipsis","text-clip"],"text-wrap":[{text:["wrap","nowrap","balance","pretty"]}],indent:[{indent:E()}],"tab-size":[{tab:[kD,_2,I2]}],"vertical-align":[{align:["baseline","top","middle","bottom","text-top","text-bottom","sub","super",_2,I2]}],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",_2,I2]}],"bg-attachment":[{bg:["fixed","local","scroll"]}],"bg-clip":[{"bg-clip":["border","padding","content","text"]}],"bg-origin":[{"bg-origin":["border","padding","content"]}],"bg-position":[{bg:X0()}],"bg-repeat":[{bg:V0()}],"bg-size":[{bg:w0()}],"bg-image":[{bg:["none",{linear:[{to:["t","tr","r","br","b","bl","l","tl"]},kD,_2,I2],radial:["",_2,I2],conic:[kD,_2,I2]},EiQ,CiQ]}],"bg-color":[{bg:c()}],"gradient-from-pos":[{from:h0()}],"gradient-via-pos":[{via:h0()}],"gradient-to-pos":[{to:h0()}],"gradient-from":[{from:c()}],"gradient-via":[{via:c()}],"gradient-to":[{to:c()}],rounded:[{rounded:S0()}],"rounded-s":[{"rounded-s":S0()}],"rounded-e":[{"rounded-e":S0()}],"rounded-t":[{"rounded-t":S0()}],"rounded-r":[{"rounded-r":S0()}],"rounded-b":[{"rounded-b":S0()}],"rounded-l":[{"rounded-l":S0()}],"rounded-ss":[{"rounded-ss":S0()}],"rounded-se":[{"rounded-se":S0()}],"rounded-ee":[{"rounded-ee":S0()}],"rounded-es":[{"rounded-es":S0()}],"rounded-tl":[{"rounded-tl":S0()}],"rounded-tr":[{"rounded-tr":S0()}],"rounded-br":[{"rounded-br":S0()}],"rounded-bl":[{"rounded-bl":S0()}],"border-w":[{border:b0()}],"border-w-x":[{"border-x":b0()}],"border-w-y":[{"border-y":b0()}],"border-w-s":[{"border-s":b0()}],"border-w-e":[{"border-e":b0()}],"border-w-bs":[{"border-bs":b0()}],"border-w-be":[{"border-be":b0()}],"border-w-t":[{"border-t":b0()}],"border-w-r":[{"border-r":b0()}],"border-w-b":[{"border-b":b0()}],"border-w-l":[{"border-l":b0()}],"divide-x":[{"divide-x":b0()}],"divide-x-reverse":["divide-x-reverse"],"divide-y":[{"divide-y":b0()}],"divide-y-reverse":["divide-y-reverse"],"border-style":[{border:[...J0(),"hidden","none"]}],"divide-style":[{divide:[...J0(),"hidden","none"]}],"border-color":[{border:c()}],"border-color-x":[{"border-x":c()}],"border-color-y":[{"border-y":c()}],"border-color-s":[{"border-s":c()}],"border-color-e":[{"border-e":c()}],"border-color-bs":[{"border-bs":c()}],"border-color-be":[{"border-be":c()}],"border-color-t":[{"border-t":c()}],"border-color-r":[{"border-r":c()}],"border-color-b":[{"border-b":c()}],"border-color-l":[{"border-l":c()}],"divide-color":[{divide:c()}],"outline-style":[{outline:[...J0(),"none","hidden"]}],"outline-offset":[{"outline-offset":[gw,_2,I2]}],"outline-w":[{outline:["",gw,Qn,Xj]}],"outline-color":[{outline:c()}],shadow:[{shadow:["","none",K,p90,l90]}],"shadow-color":[{shadow:c()}],"inset-shadow":[{"inset-shadow":["none",U,p90,l90]}],"inset-shadow-color":[{"inset-shadow":c()}],"ring-w":[{ring:b0()}],"ring-w-inset":["ring-inset"],"ring-color":[{ring:c()}],"ring-offset-w":[{"ring-offset":[gw,Xj]}],"ring-offset-color":[{"ring-offset":c()}],"inset-ring-w":[{"inset-ring":b0()}],"inset-ring-color":[{"inset-ring":c()}],"text-shadow":[{"text-shadow":["none",G,p90,l90]}],"text-shadow-color":[{"text-shadow":c()}],opacity:[{opacity:[gw,_2,I2]}],"mix-blend":[{"mix-blend":[...j0(),"plus-darker","plus-lighter"]}],"bg-blend":[{"bg-blend":j0()}],"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":[gw]}],"mask-image-linear-from-pos":[{"mask-linear-from":C0()}],"mask-image-linear-to-pos":[{"mask-linear-to":C0()}],"mask-image-linear-from-color":[{"mask-linear-from":c()}],"mask-image-linear-to-color":[{"mask-linear-to":c()}],"mask-image-t-from-pos":[{"mask-t-from":C0()}],"mask-image-t-to-pos":[{"mask-t-to":C0()}],"mask-image-t-from-color":[{"mask-t-from":c()}],"mask-image-t-to-color":[{"mask-t-to":c()}],"mask-image-r-from-pos":[{"mask-r-from":C0()}],"mask-image-r-to-pos":[{"mask-r-to":C0()}],"mask-image-r-from-color":[{"mask-r-from":c()}],"mask-image-r-to-color":[{"mask-r-to":c()}],"mask-image-b-from-pos":[{"mask-b-from":C0()}],"mask-image-b-to-pos":[{"mask-b-to":C0()}],"mask-image-b-from-color":[{"mask-b-from":c()}],"mask-image-b-to-color":[{"mask-b-to":c()}],"mask-image-l-from-pos":[{"mask-l-from":C0()}],"mask-image-l-to-pos":[{"mask-l-to":C0()}],"mask-image-l-from-color":[{"mask-l-from":c()}],"mask-image-l-to-color":[{"mask-l-to":c()}],"mask-image-x-from-pos":[{"mask-x-from":C0()}],"mask-image-x-to-pos":[{"mask-x-to":C0()}],"mask-image-x-from-color":[{"mask-x-from":c()}],"mask-image-x-to-color":[{"mask-x-to":c()}],"mask-image-y-from-pos":[{"mask-y-from":C0()}],"mask-image-y-to-pos":[{"mask-y-to":C0()}],"mask-image-y-from-color":[{"mask-y-from":c()}],"mask-image-y-to-color":[{"mask-y-to":c()}],"mask-image-radial":[{"mask-radial":[_2,I2]}],"mask-image-radial-from-pos":[{"mask-radial-from":C0()}],"mask-image-radial-to-pos":[{"mask-radial-to":C0()}],"mask-image-radial-from-color":[{"mask-radial-from":c()}],"mask-image-radial-to-color":[{"mask-radial-to":c()}],"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":[gw]}],"mask-image-conic-from-pos":[{"mask-conic-from":C0()}],"mask-image-conic-to-pos":[{"mask-conic-to":C0()}],"mask-image-conic-from-color":[{"mask-conic-from":c()}],"mask-image-conic-to-color":[{"mask-conic-to":c()}],"mask-mode":[{mask:["alpha","luminance","match"]}],"mask-origin":[{"mask-origin":["border","padding","content","fill","stroke","view"]}],"mask-position":[{mask:X0()}],"mask-repeat":[{mask:V0()}],"mask-size":[{mask:w0()}],"mask-type":[{"mask-type":["alpha","luminance"]}],"mask-image":[{mask:["none",_2,I2]}],filter:[{filter:["","none",_2,I2]}],blur:[{blur:k0()}],brightness:[{brightness:[gw,_2,I2]}],contrast:[{contrast:[gw,_2,I2]}],"drop-shadow":[{"drop-shadow":["","none",q,p90,l90]}],"drop-shadow-color":[{"drop-shadow":c()}],grayscale:[{grayscale:["",gw,_2,I2]}],"hue-rotate":[{"hue-rotate":[gw,_2,I2]}],invert:[{invert:["",gw,_2,I2]}],saturate:[{saturate:[gw,_2,I2]}],sepia:[{sepia:["",gw,_2,I2]}],"backdrop-filter":[{"backdrop-filter":["","none",_2,I2]}],"backdrop-blur":[{"backdrop-blur":k0()}],"backdrop-brightness":[{"backdrop-brightness":[gw,_2,I2]}],"backdrop-contrast":[{"backdrop-contrast":[gw,_2,I2]}],"backdrop-grayscale":[{"backdrop-grayscale":["",gw,_2,I2]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[gw,_2,I2]}],"backdrop-invert":[{"backdrop-invert":["",gw,_2,I2]}],"backdrop-opacity":[{"backdrop-opacity":[gw,_2,I2]}],"backdrop-saturate":[{"backdrop-saturate":[gw,_2,I2]}],"backdrop-sepia":[{"backdrop-sepia":["",gw,_2,I2]}],"border-collapse":[{border:["collapse","separate"]}],"border-spacing":[{"border-spacing":E()}],"border-spacing-x":[{"border-spacing-x":E()}],"border-spacing-y":[{"border-spacing-y":E()}],"table-layout":[{table:["auto","fixed"]}],caption:[{caption:["top","bottom"]}],transition:[{transition:["","all","colors","opacity","shadow","transform","none",_2,I2]}],"transition-behavior":[{transition:["normal","discrete"]}],duration:[{duration:[gw,"initial",_2,I2]}],ease:[{ease:["linear","initial",L,_2,I2]}],delay:[{delay:[gw,_2,I2]}],animate:[{animate:["none",N,_2,I2]}],backface:[{backface:["hidden","visible"]}],perspective:[{perspective:[J,_2,I2]}],"perspective-origin":[{"perspective-origin":v()}],rotate:[{rotate:N0()}],"rotate-x":[{"rotate-x":N0()}],"rotate-y":[{"rotate-y":N0()}],"rotate-z":[{"rotate-z":N0()}],scale:[{scale:P0()}],"scale-x":[{"scale-x":P0()}],"scale-y":[{"scale-y":P0()}],"scale-z":[{"scale-z":P0()}],"scale-3d":["scale-3d"],skew:[{skew:M0()}],"skew-x":[{"skew-x":M0()}],"skew-y":[{"skew-y":M0()}],transform:[{transform:[_2,I2,"","none","gpu","cpu"]}],"transform-origin":[{origin:v()}],"transform-style":[{transform:["3d","flat"]}],translate:[{translate:T0()}],"translate-x":[{"translate-x":T0()}],"translate-y":[{"translate-y":T0()}],"translate-z":[{"translate-z":T0()}],"translate-none":["translate-none"],zoom:[{zoom:[kD,_2,I2]}],accent:[{accent:c()}],appearance:[{appearance:["none","auto"]}],"caret-color":[{caret:c()}],"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",_2,I2]}],"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":c()}],"scrollbar-track-color":[{"scrollbar-track":c()}],"scrollbar-gutter":[{"scrollbar-gutter":["auto","stable","both"]}],"scrollbar-w":[{scrollbar:["auto","thin","none"]}],"scroll-m":[{"scroll-m":E()}],"scroll-mx":[{"scroll-mx":E()}],"scroll-my":[{"scroll-my":E()}],"scroll-ms":[{"scroll-ms":E()}],"scroll-me":[{"scroll-me":E()}],"scroll-mbs":[{"scroll-mbs":E()}],"scroll-mbe":[{"scroll-mbe":E()}],"scroll-mt":[{"scroll-mt":E()}],"scroll-mr":[{"scroll-mr":E()}],"scroll-mb":[{"scroll-mb":E()}],"scroll-ml":[{"scroll-ml":E()}],"scroll-p":[{"scroll-p":E()}],"scroll-px":[{"scroll-px":E()}],"scroll-py":[{"scroll-py":E()}],"scroll-ps":[{"scroll-ps":E()}],"scroll-pe":[{"scroll-pe":E()}],"scroll-pbs":[{"scroll-pbs":E()}],"scroll-pbe":[{"scroll-pbe":E()}],"scroll-pt":[{"scroll-pt":E()}],"scroll-pr":[{"scroll-pr":E()}],"scroll-pb":[{"scroll-pb":E()}],"scroll-pl":[{"scroll-pl":E()}],"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",_2,I2]}],fill:[{fill:["none",...c()]}],"stroke-w":[{stroke:[gw,Qn,Xj,wC1]}],stroke:[{stroke:["none",...c()]}],"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"]}},miQ=(A,{cacheSize:Q,prefix:w,experimentalParseClassName:B,extend:$={},override:f={}})=>{return oC(A,"cacheSize",Q),oC(A,"prefix",w),oC(A,"experimentalParseClassName",B),i90(A.theme,f.theme),i90(A.classGroups,f.classGroups),i90(A.conflictingClassGroups,f.conflictingClassGroups),i90(A.conflictingClassGroupModifiers,f.conflictingClassGroupModifiers),oC(A,"postfixLookupClassGroups",f.postfixLookupClassGroups),oC(A,"orderSensitiveModifiers",f.orderSensitiveModifiers),d90(A.theme,$.theme),d90(A.classGroups,$.classGroups),d90(A.conflictingClassGroups,$.conflictingClassGroups),d90(A.conflictingClassGroupModifiers,$.conflictingClassGroupModifiers),Zl0(A,$,"postfixLookupClassGroups"),Zl0(A,$,"orderSensitiveModifiers"),A},oC=(A,Q,w)=>{if(w!==void 0)A[Q]=w},i90=(A,Q)=>{if(Q)for(let w in Q)oC(A,w,Q[w])},d90=(A,Q)=>{if(Q)for(let w in Q)Zl0(A,Q,w)},Zl0=(A,Q,w)=>{let B=Q[w];if(B!==void 0)A[w]=A[w]?A[w].concat(B):B},n90=(A,...Q)=>typeof A==="function"?QC1(fC1,A,...Q):QC1(()=>miQ(fC1(),A),...Q);var uiQ=n90({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 N2(...A){return uiQ(rC(A))}var IC1=(A)=>typeof A==="boolean"?`${A}`:A===0?"0":A,FC1=rC,FB=(A,Q)=>(w)=>{var B;if((Q===null||Q===void 0?void 0:Q.variants)==null)return FC1(A,w===null||w===void 0?void 0:w.class,w===null||w===void 0?void 0:w.className);let{variants:$,defaultVariants:f}=Q,Y=Object.keys($).map((W)=>{let K=w===null||w===void 0?void 0:w[W],U=f===null||f===void 0?void 0:f[W];if(K===null)return null;let G=IC1(K)||IC1(U);return $[W][G]}),X=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:(B=Q.compoundVariants)===null||B===void 0?void 0:B.reduce((W,K)=>{let{class:U,className:G,...q}=K;return Object.entries(q).every((V)=>{let[J,b]=V;return Array.isArray(b)?b.includes({...f,...X}[J]):{...f,...X}[J]===b})?[...W,U,G]:W},[]);return FC1(A,Y,H,w===null||w===void 0?void 0:w.class,w===null||w===void 0?void 0:w.className)};import{jsxDEV as Kl0}from"preact/jsx-dev-runtime";var LC1=FB("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 Ul0({variant:A,title:Q,children:w,className:B}){return Kl0("div",{className:N2(LC1({variant:A}),B),role:"alert",children:[Q&&Kl0("p",{className:"font-medium text-current opacity-90",children:Q},void 0,!1,void 0,this),Kl0("div",{className:N2(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 ciQ}from"preact/jsx-dev-runtime";var kC1=FB("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 Hj({variant:A,size:Q,className:w,children:B,ssrOnClick:$,type:f="button",...Y}){return ciQ("button",{type:f,className:N2(kC1({variant:A,size:Q}),w),...Y,...$&&{onclick:$},children:B},void 0,!1,void 0,this)}import{jsxDEV as liQ}from"preact/jsx-dev-runtime";var _C1=FB("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 I9({href:A,children:Q,variant:w,size:B,external:$=!1,className:f,"aria-label":Y}){let X=$?{target:"_blank",rel:"noopener noreferrer"}:{};return liQ("a",{href:A,className:N2(_C1({variant:w,size:B}),f),"aria-label":Y,...X,children:Q},void 0,!1,void 0,this)}import{jsxDEV as r90}from"preact/jsx-dev-runtime";var NC1=FB("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"}}),piQ={sm:"w-4 h-4",md:"w-5 h-5",lg:"w-6 h-6"};function sC({variant:A,size:Q,className:w}){let B=piQ[Q??"md"];return r90("button",{onclick:"toggleTheme()",type:"button",className:N2(NC1({variant:A,size:Q}),w),"aria-label":"Toggle dark mode",children:r90("svg",{className:N2(B,"transition-colors"),fill:"none",stroke:"currentColor",strokeWidth:1.6,viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:[r90("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),r90("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 Gl0}from"preact/jsx-dev-runtime";var jC1=FB("flex flex-wrap",{variants:{orientation:{horizontal:"justify-center gap-6 items-center",vertical:"flex-col gap-2.5"}},defaultVariants:{orientation:"horizontal"}});function o90({items:A,className:Q,linkClassName:w="hover:text-accent transition-colors",orientation:B,children:$}){if(A.length===0&&!$)return null;let f=[...A].sort((Y,X)=>Y.priority-X.priority);return Gl0("ul",{className:N2(jC1({orientation:B}),Q),children:[f.map((Y)=>Gl0("li",{children:Gl0("a",{href:Y.href,className:w,children:Y.label},void 0,!1,void 0,this)},Y.href,!1,void 0,this)),$]},void 0,!0,void 0,this)}import{jsxDEV as pCB}from"preact/jsx-dev-runtime";import{jsxDEV as nCB}from"preact/jsx-dev-runtime";import{createContext as iiQ,h as diQ}from"preact";import{useContext as niQ}from"preact/hooks";var Dl0=iiQ(null);function aC({headCollector:A,children:Q}){return diQ(Dl0.Provider,{value:A},Q)}function PC1(){return niQ(Dl0)}function pQ(A){let Q=PC1();if(Q)Q.setHeadProps(A);return null}import{createContext as _tQ,h as NtQ}from"preact";import{useContext as jtQ}from"preact/hooks";VP0();var ET1=Z1(yT1(),1),LtQ=new lQ0({gfm:!0,breaks:!0}),ktQ={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 Sp0(A,Q){let{imageRenderer:w}=Q??{},$=(w?new lQ0({gfm:!0,breaks:!0}).use({renderer:{image({href:f,title:Y,text:X}){return w(f,Y,X)??!1}}}):LtQ).parse(A);return $=$.replace(/<\/blockquote>\s*<p>(\u2014|--|\u2013)([\s\S]*?)<\/p>/g,`</blockquote>
|
|
5466
|
+
`)}}wA();class C90 extends tw{directorySync;constructor(A,Q,w){super(A,{schema:Al0,jobTypeName:"directory-export"});this.directorySync=w}async process(A,Q,w){this.logger.debug("Processing directory export job",{jobId:Q,data:A});let B=Date.now();try{let $=await this.directorySync.exportEntitiesWithProgress(A.entityTypes,w,A.batchSize??100);return this.logger.debug("Directory export job completed",{jobId:Q,exported:$.exported,failed:$.failed,duration:Date.now()-B}),$}catch($){throw this.logger.error("Directory export job failed",{jobId:Q,error:$}),$}}summarizeDataForLog(A){return{entityTypes:A.entityTypes??"all",batchSize:A.batchSize}}}wA();class g90 extends tw{directorySync;constructor(A,Q,w){super(A,{schema:ec0,jobTypeName:"directory-import"});this.directorySync=w}async process(A,Q,w){this.logger.debug("Processing directory import job",{jobId:Q,data:A});let B=Date.now();try{let $=await this.directorySync.importEntitiesWithProgress(A.paths,w,A.batchSize??100);return this.logger.debug("Directory import job completed",{jobId:Q,imported:$.imported,skipped:$.skipped,failed:$.failed,quarantined:$.quarantined,duration:Date.now()-B}),$}catch($){throw this.logger.error("Directory import job failed",{jobId:Q,error:$}),$}}summarizeDataForLog(A){return{pathCount:A.paths?.length??"all",batchSize:A.batchSize}}}wA();class y90 extends tw{directorySync;context;constructor(A,Q,w){super(A,{schema:ac0,jobTypeName:"directory-sync"});this.context=Q,this.directorySync=w}async process(A,Q,w){let B=Date.now(),$=A.syncDirection??"both";this.logger.info("Starting directory sync job",{jobId:Q,operation:A.operation,syncDirection:$});let f={imported:0,skipped:0,failed:0,quarantined:0,quarantinedFiles:[],errors:[],jobIds:[]},Y={exported:0,failed:0,errors:[]};if($!=="export")if(await w.report({progress:10,message:"Scanning directory for changes"}),f=await this.importWithProgress(A.paths,w),$==="import")await this.waitForImportJobs(f.jobIds,w),await w.report({progress:100,message:`Import complete: ${f.imported} imported`});else await w.report({progress:50,message:`Imported ${f.imported} entities`}),await this.waitForImportJobs(f.jobIds,w),await w.report({progress:56,message:"Processing complete, starting export"});if($!=="import"){let H=$==="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:$==="export"?`Export complete: ${Y.exported} exported`:`Sync complete: ${f.imported} imported, ${Y.exported} exported`})}let X=Date.now()-B;return this.logger.info("Directory sync job completed",{jobId:Q,duration:X,imported:f.imported,exported:Y.exported}),{import:f,export:Y,duration:X}}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,B=300000,$=500,f=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()-f>B){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,$)),Y()};return Y()}summarizeDataForLog(A){return{operation:A.operation,syncDirection:A.syncDirection}}}wA();class E90 extends tw{context;directorySync;gitSync;constructor(A,Q,w,B){super(A,{schema:tc0,jobTypeName:"sync-request"});this.context=Q,this.directorySync=w,this.gitSync=B}async process(A,Q,w){await w.report({progress:5,message:"Pulling latest content from git"});let B=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(!B)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: ${B.importOperationsCount} import jobs for ${B.totalFiles} files`}),LpQ(B)}summarizeDataForLog(A){return{source:A.source,interfaceType:A.interfaceType,channelId:A.channelId}}}function LpQ(A){return{gitPulled:!0,batchQueued:!0,batchId:A.batchId,importOperations:A.importOperationsCount,totalFiles:A.totalFiles}}wA();class T90 extends tw{context;constructor(A,Q,w){super(A,{schema:R90,jobTypeName:"directory-delete"});this.context=Q}async process(A,Q,w){let B=R90.parse(A);this.logger.info("Processing entity deletion for removed file",{entityId:B.entityId,entityType:B.entityType,filePath:B.filePath}),await w.report({progress:0,total:1,message:`Deleting ${B.entityType}:${B.entityId}`});try{let $=await this.context.entityService.deleteEntity({entityType:B.entityType,id:B.entityId});if($)this.logger.info("Successfully deleted entity for removed file",{entityId:B.entityId,entityType:B.entityType});else this.logger.warn("Entity not found in database",{entityId:B.entityId,entityType:B.entityType});return await w.report({progress:1,total:1,message:`Deleted ${B.entityType}:${B.entityId}`}),{deleted:$,entityId:B.entityId,entityType:B.entityType,filePath:B.filePath}}catch($){throw this.logger.error("Failed to delete entity",{entityId:B.entityId,entityType:B.entityType,error:$}),$}}summarizeDataForLog(A){return{entityId:A.entityId,entityType:A.entityType,filePath:A.filePath}}}wA();_0();var kpQ=Z.object({});class S90 extends tw{directorySync;constructor(A,Q){super(A,{schema:kpQ,jobTypeName:"directory-cleanup"});this.directorySync=Q}async process(A,Q,w){await w.report({progress:0,message:"Removing orphaned entities"});let B=await this.directorySync.removeOrphanedEntities();return await w.report({progress:100,message:`Cleanup complete: ${B.deleted} orphans removed`}),B}}wA();F4();u9();y6();_0();F4();import{readFile as _pQ,writeFile as NpQ}from"fs/promises";var jpQ=Ql0,PpQ=Z.record(Z.string(),Z.unknown());class m90 extends tw{context;fetcher;constructor(A,Q,w=TH){super(Q,{schema:jpQ,jobTypeName:"cover-image-convert"});this.context=A,this.fetcher=w}async process(A,Q,w){let{filePath:B,sourceUrl:$,postTitle:f,postSlug:Y,customAlt:X}=A;this.logger.debug("Starting image conversion job",{jobId:Q,filePath:B,sourceUrl:$,postSlug:Y});try{await this.reportProgress(w,{progress:nQ.INIT,message:`Reading file: ${B}`});let H;try{H=await _pQ(B,"utf-8")}catch(b){return this.logger.error("Failed to read file",{filePath:B,error:SA(b)}),w$.failure(b)}let W;try{W=P6(H)}catch(b){return this.logger.warn("Failed to parse markdown",{filePath:B,error:SA(b)}),w$.failure(b)}let K=PpQ.safeParse(W.frontmatter),U=K.success?K.data:{};if(U.coverImageId)return this.logger.debug("File already has coverImageId, skipping",{filePath:B}),await this.reportProgress(w,{progress:nQ.COMPLETE,message:"Already converted"}),{success:!0,skipped:!0};await this.reportProgress(w,{progress:nQ.FETCH,message:"Checking for existing image"});let G=await this.context.entityService.listEntities({entityType:"image",options:{filter:{metadata:{sourceUrl:$}},limit:1}}),q;if(G[0])q=G[0].id,this.logger.debug("Reusing existing image entity",{sourceUrl:$,imageId:q}),await this.reportProgress(w,{progress:nQ.EXTRACT,message:`Reusing existing image: ${q}`});else{await this.reportProgress(w,{progress:nQ.PROCESS,message:`Fetching image from ${$}`});let b;try{b=await this.fetcher($)}catch(h){return this.logger.error("Failed to fetch image",{sourceUrl:$,error:SA(h)}),w$.failure(h)}await this.reportProgress(w,{progress:nQ.GENERATE,message:"Creating image entity"});let{base64:L}=ob(b),N=ik(L),k=sb(L);if(!N||!k)return this.logger.error("Could not detect image format or dimensions",{sourceUrl:$}),w$.failure(Error("Could not detect image format or dimensions"));q=`${Y}-cover`;let x=`Cover image for ${f}`,v=X??x;await this.context.entityService.createEntity({entity:{id:q,entityType:"image",content:b,metadata:{title:x,alt:v,format:N,width:k.width,height:k.height,sourceUrl:$}}}),this.logger.debug("Created image entity",{imageId:q,sourceUrl:$}),await this.reportProgress(w,{progress:nQ.EXTRACT,message:`Created image: ${q}`})}await this.reportProgress(w,{progress:nQ.SAVE,message:"Updating file"});let V={...U};delete V.coverImageUrl,delete V.coverImageAlt,V.coverImageId=q;let J=Dk(V,W.content);try{await NpQ(B,J,"utf-8")}catch(b){return this.logger.error("Failed to write file",{filePath:B,error:SA(b)}),w$.failure(b)}return await this.reportProgress(w,{progress:nQ.COMPLETE,message:"Conversion complete"}),this.logger.info("Image conversion complete",{filePath:B,imageId:q,sourceUrl:$}),{success:!0,imageId:q}}catch(H){return this.logger.error("Image conversion job failed",{jobId:Q,filePath:B,error:SA(H)}),w$.failure(H)}}summarizeDataForLog(A){return{filePath:A.filePath,sourceUrl:A.sourceUrl,postSlug:A.postSlug}}}wA();F4();y6();import{readFile as MpQ,writeFile as OpQ}from"fs/promises";class u90 extends tw{converter;constructor(A,Q,w=TH){super(Q,{schema:wl0,jobTypeName:"inline-image-convert"});this.converter=new md(A.entityService,Q,w)}async process(A,Q,w){let{filePath:B,postSlug:$}=A;this.logger.debug("Starting inline image conversion job",{jobId:Q,filePath:B,postSlug:$});try{await this.reportProgress(w,{progress:nQ.INIT,message:`Reading file: ${B}`});let f;try{f=await MpQ(B,"utf-8")}catch(H){let W=SA(H);return this.logger.error("Failed to read file",{filePath:B,error:W}),{success:!1,error:W}}await this.reportProgress(w,{progress:nQ.FETCH,message:"Detecting inline images"});let Y=this.converter.detectInlineImages(f,$);if(Y.length===0)return this.logger.debug("No inline images to convert",{filePath:B}),await this.reportProgress(w,{progress:nQ.COMPLETE,message:"No images to convert"}),{success:!0,skipped:!0,convertedCount:0};this.logger.debug("Found inline images to convert",{filePath:B,count:Y.length}),await this.reportProgress(w,{progress:nQ.PROCESS,message:`Converting ${Y.length} images`});let X=await this.converter.convert(f,$);if(!X.converted)return this.logger.debug("No images were converted",{filePath:B}),await this.reportProgress(w,{progress:nQ.COMPLETE,message:"No images converted"}),{success:!0,skipped:!0,convertedCount:0};await this.reportProgress(w,{progress:nQ.SAVE,message:"Writing updated file"});try{await OpQ(B,X.content,"utf-8")}catch(H){let W=SA(H);return this.logger.error("Failed to write file",{filePath:B,error:W}),{success:!1,error:W}}return await this.reportProgress(w,{progress:nQ.COMPLETE,message:"Conversion complete"}),this.logger.info("Inline image conversion complete",{filePath:B,convertedCount:X.convertedCount}),{success:!0,convertedCount:X.convertedCount}}catch(f){let Y=SA(f);return this.logger.error("Inline image conversion job failed",{jobId:Q,filePath:B,error:Y}),{success:!1,error:Y}}}summarizeDataForLog(A){return{filePath:A.filePath,postSlug:A.postSlug}}}function Rh1(A,Q,w){let B=($)=>w.child($);A.jobs.registerHandler("directory-sync",new y90(B("DirectorySyncJobHandler"),A,Q)),A.jobs.registerHandler("directory-export",new C90(B("DirectoryExportJobHandler"),A,Q)),A.jobs.registerHandler("directory-import",new g90(B("DirectoryImportJobHandler"),A,Q)),A.jobs.registerHandler("directory-delete",new T90(B("DirectoryDeleteJobHandler"),A,Q)),A.jobs.registerHandler("directory-cleanup",new S90(B("DirectoryCleanupJobHandler"),Q)),A.jobs.registerHandler("cover-image-convert",new m90(A,B("CoverImageConversionJobHandler"))),A.jobs.registerHandler("inline-image-convert",new u90(A,B("InlineImageConversionJobHandler"))),w.debug("Registered async job handlers")}wA();_0();import{unlink as xpQ,access as vpQ}from"fs/promises";var RpQ=Z.record(Z.string(),Z.unknown());function hh1(A,Q,w,B){let{subscribe:$}=A.messaging,{entityService:f}=A;$("entity:created",async(Y)=>{let{entity:X}=Y.payload;try{await Q.fileOps.writeEntity(X),w.debug("Auto-exported created entity",{id:X.id,entityType:X.entityType})}catch(H){w.error("Auto-export FAILED for created entity",{id:X.id,entityType:X.entityType,error:H instanceof Error?H.message:String(H),stack:H instanceof Error?H.stack:void 0})}return{success:!0}}),$("entity:updated",async(Y)=>{let{entityType:X,entityId:H}=Y.payload;try{let W=await f.getEntity({entityType:X,id:H});if(!W)return w.debug("Entity not found in DB, skipping export",{entityType:X,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:X,entityId:H,error:W instanceof Error?W.message:String(W),stack:W instanceof Error?W.stack:void 0})}return{success:!0}}),$("entity:deleted",async(Y)=>{let{entityId:X,entityType:H}=Y.payload,W=Q.fileOps.getFilePath(X,H);if(await vpQ(W).then(()=>!0,()=>!1))await xpQ(W),w.debug("Auto-deleted entity file",{id:X,entityType:H,path:W});return{success:!0}}),w.debug("Setup auto-sync for entity events",{entityTypes:B})}function Ch1(A,Q,w){Q.setJobQueueCallback(async(B)=>{let $=[{type:B.type,data:RpQ.parse(B.data)}];return A.jobs.enqueueBatch($,{priority:5,source:"directory-sync-watcher",rootJobId:H4(),metadata:{operationType:"file_operations",operationTarget:w,pluginId:"directory-sync"}})})}wA();import{readdir as Eh1,mkdir as CpQ,copyFile as gpQ}from"fs/promises";import{join as yh1,resolve as Bl0}from"path";import{join as hpQ}from"path";async function gh1(A){if(!await n5(hpQ(A,".git")))return!1;try{return await YU(A).revparse(["--verify","HEAD"]),!0}catch{return!1}}async function ypQ(A,Q){if(!await n5(A))return!0;if((await Eh1(A)).filter(($)=>!$.startsWith(".")&&!$.startsWith("_")).length>0)return!1;if(await gh1(A))return Q.debug("Git repository with history detected - skipping seed content",{path:A}),!1;return!0}async function Th1(A,Q){let w=await Eh1(A,{withFileTypes:!0});for(let B of w){let $=yh1(A,B.name),f=yh1(Q,B.name);if(B.isDirectory()){if(!await n5(f))await CpQ(f,{recursive:!0});await Th1($,f)}else await gpQ($,f)}}async function Sh1(A,Q,w){let B=Bl0(process.cwd(),A);w=w?Bl0(w):Bl0(process.cwd(),"seed-content");let $=await ypQ(B,Q);if($&&await n5(w))Q.debug("Copying seed content to brain-data directory"),await Th1(w,B),Q.debug("Seed content copied successfully");else if($)Q.debug("No seed content directory found, starting with empty brain-data");else Q.debug("brain-data directory not empty, skipping seed content")}function mh1(A,Q,w,B,$){let f=!1,Y=async()=>{if(f)return;f=!0;let X=Q();if(w.seedContent){let H=w.syncPath??A.dataDir;await Sh1(H,B,w.seedContentPath)}try{if($){B.debug("Git enabled \u2014 pulling before import");let W=await $.pull();if(W.files.length>0)B.info("Pulled changes from remote",{filesChanged:W.files.length})}B.debug("Starting initial sync");let H=await X.sync();B.debug("Initial sync completed",{imported:H.import.imported,failed:H.import.failed,duration:H.duration}),await A.messaging.send({type:bk.initialSyncCompleted,payload:{success:!0},...{broadcast:!0}})}catch(H){B.error("Initial sync failed",H),await A.messaging.send({type:bk.initialSyncCompleted,payload:{success:!1,error:SA(H)},...{broadcast:!0}})}};A.messaging.subscribe(bk.pluginsRegistered,async()=>{return B.debug("Plugins registered, starting initial sync"),await Y(),{success:!0}})}class $l0{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 fl0{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 uh1(A,Q,w,B){let $=new fl0(()=>{Q.withLock(async()=>{try{await Q.commit(),await Q.push()}catch(X){B.error("Git auto-commit failed",{error:X})}})},w),f=["entity:created","entity:updated","entity:deleted"],Y=[];for(let X of f){let H=A.subscribe(X,async()=>{return $.trigger(),{success:!0}});Y.push(H)}return()=>{$.dispose();for(let X of Y)X()}}function ch1(A,Q,w,B,$){if(B<=0)return()=>{};let f=B*60*1000,Y=!1,X=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)$.info("Periodic sync: pulled changes",{filesChanged:W.length});if(K)$.debug("Periodic sync: queued imports",{importOperations:K.importOperationsCount,totalFiles:K.totalFiles})}catch(W){$.error("Periodic git sync failed",{error:W})}finally{Y=!1}},H=setInterval(()=>{X()},f);return $.info("Started periodic git sync",{intervalMinutes:B}),()=>{clearInterval(H)}}import{spawnSync as ph1}from"child_process";import{cpSync as EpQ,existsSync as lh1,mkdirSync as TpQ,mkdtempSync as SpQ,rmSync as mpQ}from"fs";import{tmpdir as upQ}from"os";import{fileURLToPath as cpQ}from"url";import{join as lpQ,resolve as ppQ}from"path";function lI(A,Q){let w=ph1("git",Q,{cwd:A,stdio:"pipe"});if(w.status!==0){let B=w.stderr.toString().trim(),$=w.stdout.toString().trim();throw Error(B||$||`git ${Q.join(" ")} failed`)}}function ipQ(A){return A.startsWith("file://")}function dpQ(A){return cpQ(A)}function npQ(A,Q){return ph1("git",["--git-dir",A,"show-ref","--verify","--quiet",`refs/heads/${Q}`]).status===0}async function ih1(A){if(!A.bootstrapFromSeed)return;if(!A.gitUrl||!ipQ(A.gitUrl))return;if(!A.seedContentPath)throw Error("directory-sync git.bootstrapFromSeed requires seedContentPath for local file:// remotes");let Q=A.branch??"main",w=dpQ(A.gitUrl),B=ppQ(A.seedContentPath);if(!lh1(B))throw Error(`Seed content path not found: ${B}`);if(!lh1(w))A.logger.debug("Creating local bare content remote",{remotePath:w,branch:Q}),TpQ(w,{recursive:!0}),lI(process.cwd(),["init","--bare",`--initial-branch=${Q}`,w]);if(npQ(w,Q)){A.logger.debug("Content remote already initialized",{remotePath:w,branch:Q});return}A.logger.debug("Seeding local content remote",{remotePath:w,seedPath:B,branch:Q});let $=SpQ(lpQ(upQ(),"directory-sync-seed-"));try{lI($,["init",`--initial-branch=${Q}`]),lI($,["config","user.name",A.authorName??"Brain"]),lI($,["config","user.email",A.authorEmail??"brain@localhost"]),EpQ(B,$,{recursive:!0}),lI($,["add","."]),lI($,["commit","-m","seed content remote"]),lI($,["remote","add","origin",A.gitUrl]),lI($,["push","-u","origin",Q])}finally{mpQ($,{recursive:!0,force:!0})}}function dh1(A,Q,w,B,$,f){let{subscribe:Y}=A.messaging;Y("entity:export:request",async(X)=>{try{return{success:!0,data:await Q().exportEntities(X.payload.entityTypes)}}catch(H){return{success:!1,error:H instanceof Error?H.message:"Export failed"}}}),Y("entity:import:request",async(X)=>{try{let H=Q(),W=X.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 rpQ(f?.(),B)}}}catch(X){return{success:!1,error:X instanceof Error?X.message:"Status check failed"}}}),Y("sync:configure:request",async(X)=>{try{return await w({syncPath:X.payload.syncPath}),{success:!0,data:{syncPath:X.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(!$?.repo)return{success:!1,error:"Git not configured"};return{success:!0,data:{repo:$.repo,branch:$.branch??"main"}}}),B.debug("Registered message handlers")}async function rpQ(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}}wA();_0();wA();_0();function nh1(A,Q){return M6(A,"history","Get version history for an entity from git. Without sha: returns commit list. With sha: returns entity content at that version.",Z.object({entityType:Z.string().describe("Entity type (e.g. post, note, link)"),id:Z.string().describe("Entity ID"),sha:Z.string().optional().describe("Commit SHA to retrieve content at. Omit to list commit history."),limit:Z.number().int().positive().optional().default(10).describe("Max commits to return (list mode only)")}),async(w)=>{let B=`${w.entityType}/${w.id}.md`;try{if(w.sha){let f=await Q.show(w.sha,B);return b8({sha:w.sha,entityType:w.entityType,id:w.id,content:f},`Content at ${w.sha.slice(0,7)}`)}let $=await Q.log(B,w.limit);if($.length===0)return b8({commits:[]},`No history found for ${w.entityType}/${w.id}`);return b8({commits:$,entityType:w.entityType,id:w.id},`${$.length} version${$.length===1?"":"s"} found`)}catch($){return _7($ instanceof Error?$.message:"History lookup failed")}},{visibility:"anchor",sideEffects:"none"})}function rh1(A,Q,w,B){let $=[M6(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.",Z.object({}),async(f,Y)=>{try{let X=Y.channelId?`${Y.interfaceType}:${Y.channelId}`:`plugin:${w}`,H={interfaceType:Y.interfaceType,channelId:Y.channelId};if(B){let K=await Q.jobs.enqueue({type:"sync-request",data:{source:X,interfaceType:H.interfaceType,channelId:H.channelId},toolContext:Y});return b8({jobId:K,status:"queued",gitPulled:!0},"Sync queued: git pull and filesystem scan will run in the background")}let W=await A.queueSyncBatch(Q,X,H);if(!W)return b8({gitPulled:!1},"No files to sync");return b8({batchId:W.batchId,importOperations:W.importOperationsCount,totalFiles:W.totalFiles,gitPulled:!1},`Sync started: ${W.importOperationsCount} import jobs queued for ${W.totalFiles} files`)}catch(X){return _7(X instanceof Error?X.message:"Sync failed")}},{visibility:"anchor",sideEffects:"external",cli:{name:"sync"}}),M6(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.",Z.object({}),async()=>{try{let f=await A.getStatus(),Y={syncPath:f.syncPath,lastSync:f.lastSync?.toISOString(),watching:f.watching};if(B){let X=await B.getStatus();Y.git={isRepo:X.isRepo,branch:X.branch,hasChanges:X.hasChanges,ahead:X.ahead,behind:X.behind,remote:X.remote}}return b8(Y)}catch(f){return _7(f instanceof Error?f.message:"Status check failed")}},{visibility:"anchor",sideEffects:"none"})];if(B)$.push(nh1(w,B));return $}var oh1={name:"@brains/directory-sync",version:"0.2.0-alpha.151",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 Yl0 extends tQ{directorySync;gitSync;gitCleanups=[];constructor(A={}){super("directory-sync",oh1,A,ed)}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:An,basePrompt:"",formatter:new h90,requiredPermission:"anchor"}});let B=this.config.syncPath??A.dataDir;this.directorySync=new ud({syncPath:B,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:B})}catch(Y){throw this.logger.error("Failed to initialize directory",Y),Y}await this.registerJobHandlers(A);let $=this.requireDirectorySync();if(hh1(A,$,this.logger,this.config.entityTypes),this.config.autoSync)Ch1(A,$,this.config.syncPath??A.dataDir);let f=this.config.git!==void 0&&(this.config.git.repo!==void 0||this.config.git.gitUrl!==void 0);if(this.config.git&&!f)this.logger.debug("Git block present but no repo/gitUrl configured \u2014 git sync disabled");if(f&&this.config.git){await ih1({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 sc0({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 E90(this.logger.child("DirectorySyncRequestJobHandler"),A,this.requireDirectorySync(),this.gitSync)),this.gitCleanups.push(uh1(A.messaging,this.gitSync,this.config.commitDebounce,this.logger.child("GitAutoCommit"))),this.config.autoSync)this.gitCleanups.push(ch1(this.gitSync,this.requireDirectorySync(),A,this.config.syncInterval,this.logger.child("GitPeriodicSync")))}if(this.config.initialSync)mh1(A,()=>this.requireDirectorySync(),this.config,this.logger,this.gitSync);dh1(A,()=>this.requireDirectorySync(),(Y)=>this.configure(Y),this.logger,this.config.git,()=>this.gitSync)}async getTools(){let A=this.requireDirectorySync();return rh1(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 ud({...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){Rh1(A,this.requireDirectorySync(),this.logger)}}function Yj(A={}){return new Yl0(A)}wA();_0();var sh1={name:"@brains/email-resend",version:"0.2.0-alpha.151",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 apQ=Z.object({apiKey:Z.string().min(1).optional(),from:Z.string().min(1).optional()}),tpQ=Z.looseObject({id:Z.string().optional()});class ah1 extends tQ{fetchImpl;constructor(A={},Q={}){super("email-resend",sh1,A,apQ);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(l60,async(w)=>{let B=egA.parse(w.payload);try{return{success:!0,data:await this.sendWithResend(B)}}catch($){if(B.sensitivity==="secret")Q.warn("Email delivery failed for a secret message");else Q.warn("Email delivery failed",{to:B.to,subject:B.subject,error:$ instanceof Error?$.message:String($)});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 B=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(!B.ok)throw Error("Resend email request failed");let $=tpQ.parse(await B.json());return $.id?{status:"sent",id:$.id}:{status:"sent"}}}function c90(A={}){return new ah1(A)}wA();import{render as Eo1}from"preact-render-to-string";import{h as cj}from"preact";function th1(A){var Q,w,B="";if(typeof A=="string"||typeof A=="number")B+=A;else if(typeof A=="object")if(Array.isArray(A)){var $=A.length;for(Q=0;Q<$;Q++)A[Q]&&(w=th1(A[Q]))&&(B&&(B+=" "),B+=w)}else for(w in A)A[w]&&(B&&(B+=" "),B+=w);return B}function rC(){for(var A,Q,w=0,B="",$=arguments.length;w<$;w++)(A=arguments[w])&&(Q=th1(A))&&(B&&(B+=" "),B+=Q);return B}var epQ=(A,Q)=>{let w=Array(A.length+Q.length);for(let B=0;B<A.length;B++)w[B]=A[B];for(let B=0;B<Q.length;B++)w[A.length+B]=Q[B];return w},AiQ=(A,Q)=>({classGroupId:A,validator:Q}),YC1=(A=new Map,Q=null,w)=>({nextPart:A,validators:Q,classGroupId:w});var eh1=[];var QiQ=(A)=>{let Q=BiQ(A),{conflictingClassGroups:w,conflictingClassGroupModifiers:B}=A;return{getClassGroupId:(Y)=>{if(Y.startsWith("[")&&Y.endsWith("]"))return wiQ(Y);let X=Y.split("-"),H=X[0]===""&&X.length>1?1:0;return XC1(X,H,Q)},getConflictingClassGroupIds:(Y,X)=>{if(X){let H=B[Y],W=w[Y];if(H){if(W)return epQ(W,H);return H}return W||eh1}return w[Y]||eh1}}},XC1=(A,Q,w)=>{if(A.length-Q===0)return w.classGroupId;let $=A[Q],f=w.nextPart.get($);if(f){let W=XC1(A,Q+1,f);if(W)return W}let Y=w.validators;if(Y===null)return;let X=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(X))return K.classGroupId}return},wiQ=(A)=>A.slice(1,-1).indexOf(":")===-1?void 0:(()=>{let Q=A.slice(1,-1),w=Q.indexOf(":"),B=Q.slice(0,w);return B?"arbitrary.."+B:void 0})(),BiQ=(A)=>{let{theme:Q,classGroups:w}=A;return $iQ(w,Q)},$iQ=(A,Q)=>{let w=YC1();for(let B in A){let $=A[B];Hl0($,w,B,Q)}return w},Hl0=(A,Q,w,B)=>{let $=A.length;for(let f=0;f<$;f++){let Y=A[f];fiQ(Y,Q,w,B)}},fiQ=(A,Q,w,B)=>{if(typeof A==="string"){YiQ(A,Q,w);return}if(typeof A==="function"){XiQ(A,Q,w,B);return}ZiQ(A,Q,w,B)},YiQ=(A,Q,w)=>{let B=A===""?Q:ZC1(Q,A);B.classGroupId=w},XiQ=(A,Q,w,B)=>{if(HiQ(A)){Hl0(A(B),Q,w,B);return}if(Q.validators===null)Q.validators=[];Q.validators.push(AiQ(w,A))},ZiQ=(A,Q,w,B)=>{let $=Object.entries(A),f=$.length;for(let Y=0;Y<f;Y++){let[X,H]=$[Y];Hl0(H,ZC1(Q,X),w,B)}},ZC1=(A,Q)=>{let w=A,B=Q.split("-"),$=B.length;for(let f=0;f<$;f++){let Y=B[f],X=w.nextPart.get(Y);if(!X)X=YC1(),w.nextPart.set(Y,X);w=X}return w},HiQ=(A)=>("isThemeGetter"in A)&&A.isThemeGetter===!0,WiQ=(A)=>{if(A<1)return{get:()=>{return},set:()=>{}};let Q=0,w=Object.create(null),B=Object.create(null),$=(f,Y)=>{if(w[f]=Y,Q++,Q>A)Q=0,B=w,w=Object.create(null)};return{get(f){let Y=w[f];if(Y!==void 0)return Y;if((Y=B[f])!==void 0)return $(f,Y),Y},set(f,Y){if(f in w)w[f]=Y;else $(f,Y)}}};var KiQ=[],AC1=(A,Q,w,B,$)=>({modifiers:A,hasImportantModifier:Q,baseClassName:w,maybePostfixModifierPosition:B,isExternal:$}),UiQ=(A)=>{let{prefix:Q,experimentalParseClassName:w}=A,B=($)=>{let f=[],Y=0,X=0,H=0,W,K=$.length;for(let J=0;J<K;J++){let b=$[J];if(Y===0&&X===0){if(b===":"){f.push($.slice(H,J)),H=J+1;continue}if(b==="/"){W=J;continue}}if(b==="[")Y++;else if(b==="]")Y--;else if(b==="(")X++;else if(b===")")X--}let U=f.length===0?$:$.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 AC1(f,q,G,V)};if(Q){let $=Q+":",f=B;B=(Y)=>Y.startsWith($)?f(Y.slice($.length)):AC1(KiQ,!1,Y,void 0,!0)}if(w){let $=B;B=(f)=>w({className:f,parseClassName:$})}return B},GiQ=(A)=>{let Q=new Map;return A.orderSensitiveModifiers.forEach((w,B)=>{Q.set(w,1e6+B)}),(w)=>{let B=[],$=[];for(let f=0;f<w.length;f++){let Y=w[f],X=Y[0]==="[",H=Q.has(Y);if(X||H){if($.length>0)$.sort(),B.push(...$),$=[];B.push(Y)}else $.push(Y)}if($.length>0)$.sort(),B.push(...$);return B}},DiQ=(A)=>({cache:WiQ(A.cacheSize),parseClassName:UiQ(A),sortModifiers:GiQ(A),postfixLookupClassGroupIds:ziQ(A),...QiQ(A)}),ziQ=(A)=>{let Q=Object.create(null),w=A.postfixLookupClassGroups;if(w)for(let B=0;B<w.length;B++)Q[w[B]]=!0;return Q},qiQ=/\s+/,ViQ=(A,Q)=>{let{parseClassName:w,getClassGroupId:B,getConflictingClassGroupIds:$,sortModifiers:f,postfixLookupClassGroupIds:Y}=Q,X=[],H=A.trim().split(qiQ),W="";for(let K=H.length-1;K>=0;K-=1){let U=H[K],{isExternal:G,modifiers:q,hasImportantModifier:V,baseClassName:J,maybePostfixModifierPosition:b}=w(U);if(G){W=U+(W.length>0?" "+W:W);continue}let L=!!b,N;if(L){let P=J.substring(0,b);N=B(P);let E=N&&Y[N]?B(J):void 0;if(E&&E!==N)N=E,L=!1}else N=B(J);if(!N){if(!L){W=U+(W.length>0?" "+W:W);continue}if(N=B(J),!N){W=U+(W.length>0?" "+W:W);continue}L=!1}let k=q.length===0?"":q.length===1?q[0]:f(q).join(":"),x=V?k+"!":k,v=x+N;if(X.indexOf(v)>-1)continue;X.push(v);let h=$(N,L);for(let P=0;P<h.length;++P){let E=h[P];X.push(x+E)}W=U+(W.length>0?" "+W:W)}return W},biQ=(...A)=>{let Q=0,w,B,$="";while(Q<A.length)if(w=A[Q++]){if(B=HC1(w))$&&($+=" "),$+=B}return $},HC1=(A)=>{if(typeof A==="string")return A;let Q,w="";for(let B=0;B<A.length;B++)if(A[B]){if(Q=HC1(A[B]))w&&(w+=" "),w+=Q}return w},QC1=(A,...Q)=>{let w,B,$,f,Y=(H)=>{let W=Q.reduce((K,U)=>U(K),A());return w=DiQ(W),B=w.cache.get,$=w.cache.set,f=X,X(H)},X=(H)=>{let W=B(H);if(W)return W;let K=ViQ(H,w);return $(H,K),K};return f=Y,(...H)=>f(biQ(...H))},JiQ=[],J9=(A)=>{let Q=(w)=>w[A]||JiQ;return Q.isThemeGetter=!0,Q},WC1=/^\[(?:(\w[\w-]*):)?(.+)\]$/i,KC1=/^\((?:(\w[\w-]*):)?(.+)\)$/i,IiQ=/^\d+(?:\.\d+)?\/\d+(?:\.\d+)?$/,FiQ=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,LiQ=/\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$/,kiQ=/^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/,_iQ=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,NiQ=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,pI=(A)=>IiQ.test(A),gw=(A)=>!!A&&!Number.isNaN(Number(A)),kD=(A)=>!!A&&Number.isInteger(Number(A)),Xl0=(A)=>A.endsWith("%")&&gw(A.slice(0,-1)),Rq=(A)=>FiQ.test(A),UC1=()=>!0,jiQ=(A)=>LiQ.test(A)&&!kiQ.test(A),Wl0=()=>!1,PiQ=(A)=>_iQ.test(A),MiQ=(A)=>NiQ.test(A),OiQ=(A)=>!I2(A)&&!_2(A),xiQ=(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)),viQ=(A)=>iI(A,zC1,Wl0),I2=(A)=>WC1.test(A),Xj=(A)=>iI(A,qC1,jiQ),wC1=(A)=>iI(A,SiQ,gw),RiQ=(A)=>iI(A,bC1,UC1),hiQ=(A)=>iI(A,VC1,Wl0),BC1=(A)=>iI(A,GC1,Wl0),CiQ=(A)=>iI(A,DC1,MiQ),l90=(A)=>iI(A,JC1,PiQ),_2=(A)=>KC1.test(A),Qn=(A)=>Zj(A,qC1),giQ=(A)=>Zj(A,VC1),$C1=(A)=>Zj(A,GC1),yiQ=(A)=>Zj(A,zC1),EiQ=(A)=>Zj(A,DC1),p90=(A)=>Zj(A,JC1,!0),TiQ=(A)=>Zj(A,bC1,!0),iI=(A,Q,w)=>{let B=WC1.exec(A);if(B){if(B[1])return Q(B[1]);return w(B[2])}return!1},Zj=(A,Q,w=!1)=>{let B=KC1.exec(A);if(B){if(B[1])return Q(B[1]);return w}return!1},GC1=(A)=>A==="position"||A==="percentage",DC1=(A)=>A==="image"||A==="url",zC1=(A)=>A==="length"||A==="size"||A==="bg-size",qC1=(A)=>A==="length",SiQ=(A)=>A==="number",VC1=(A)=>A==="family-name",bC1=(A)=>A==="number"||A==="weight",JC1=(A)=>A==="shadow";var fC1=()=>{let A=J9("color"),Q=J9("font"),w=J9("text"),B=J9("font-weight"),$=J9("tracking"),f=J9("leading"),Y=J9("breakpoint"),X=J9("container"),H=J9("spacing"),W=J9("radius"),K=J9("shadow"),U=J9("inset-shadow"),G=J9("text-shadow"),q=J9("drop-shadow"),V=J9("blur"),J=J9("perspective"),b=J9("aspect"),L=J9("ease"),N=J9("animate"),k=()=>["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(),_2,I2],h=()=>["auto","hidden","clip","visible","scroll"],P=()=>["auto","contain","none"],E=()=>[_2,I2,H],S=()=>[pI,"full","auto",...E()],p=()=>[kD,"none","subgrid",_2,I2],e=()=>["auto",{span:["full",kD,_2,I2]},kD,_2,I2],Y0=()=>[kD,"auto",_2,I2],l=()=>["auto","min","max","fr",_2,I2],j=()=>["start","end","center","between","around","evenly","stretch","baseline","center-safe","end-safe"],g=()=>["start","end","center","stretch","center-safe","end-safe"],y=()=>["auto",...E()],n=()=>[pI,"auto","full","dvw","dvh","lvw","lvh","svw","svh","min","max","fit",...E()],o=()=>[pI,"screen","full","dvw","lvw","svw","min","max","fit",...E()],K0=()=>[pI,"screen","full","lh","dvh","lvh","svh","min","max","fit",...E()],c=()=>[A,_2,I2],X0=()=>[...x(),$C1,BC1,{position:[_2,I2]}],V0=()=>["no-repeat",{repeat:["","x","y","space","round"]}],w0=()=>["auto","cover","contain",yiQ,viQ,{size:[_2,I2]}],h0=()=>[Xl0,Qn,Xj],S0=()=>["","none","full",W,_2,I2],b0=()=>["",gw,Qn,Xj],J0=()=>["solid","dashed","dotted","double"],j0=()=>["normal","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity"],C0=()=>[gw,Xl0,$C1,BC1],k0=()=>["","none",V,_2,I2],N0=()=>["none",gw,_2,I2],P0=()=>["none",gw,_2,I2],M0=()=>[gw,_2,I2],T0=()=>[pI,"full",...E()];return{cacheSize:500,theme:{animate:["spin","ping","pulse","bounce"],aspect:["video"],blur:[Rq],breakpoint:[Rq],color:[UC1],container:[Rq],"drop-shadow":[Rq],ease:["in","out","in-out"],font:[OiQ],"font-weight":["thin","extralight","light","normal","medium","semibold","bold","extrabold","black"],"inset-shadow":[Rq],leading:["none","tight","snug","normal","relaxed","loose"],perspective:["dramatic","near","normal","midrange","distant","none"],radius:[Rq],shadow:[Rq],spacing:["px",gw],text:[Rq],"text-shadow":[Rq],tracking:["tighter","tight","normal","wide","wider","widest"]},classGroups:{aspect:[{aspect:["auto","square",pI,I2,_2,b]}],container:["container"],"container-type":[{"@container":["","normal","size",_2,I2]}],"container-named":[xiQ],columns:[{columns:[gw,I2,_2,X]}],"break-after":[{"break-after":k()}],"break-before":[{"break-before":k()}],"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:h()}],"overflow-x":[{"overflow-x":h()}],"overflow-y":[{"overflow-y":h()}],overscroll:[{overscroll:P()}],"overscroll-x":[{"overscroll-x":P()}],"overscroll-y":[{"overscroll-y":P()}],position:["static","fixed","absolute","relative","sticky"],inset:[{inset:S()}],"inset-x":[{"inset-x":S()}],"inset-y":[{"inset-y":S()}],start:[{"inset-s":S(),start:S()}],end:[{"inset-e":S(),end:S()}],"inset-bs":[{"inset-bs":S()}],"inset-be":[{"inset-be":S()}],top:[{top:S()}],right:[{right:S()}],bottom:[{bottom:S()}],left:[{left:S()}],visibility:["visible","invisible","collapse"],z:[{z:[kD,"auto",_2,I2]}],basis:[{basis:[pI,"full","auto",X,...E()]}],"flex-direction":[{flex:["row","row-reverse","col","col-reverse"]}],"flex-wrap":[{flex:["nowrap","wrap","wrap-reverse"]}],flex:[{flex:[gw,pI,"auto","initial","none",I2]}],grow:[{grow:["",gw,_2,I2]}],shrink:[{shrink:["",gw,_2,I2]}],order:[{order:[kD,"first","last","none",_2,I2]}],"grid-cols":[{"grid-cols":p()}],"col-start-end":[{col:e()}],"col-start":[{"col-start":Y0()}],"col-end":[{"col-end":Y0()}],"grid-rows":[{"grid-rows":p()}],"row-start-end":[{row:e()}],"row-start":[{"row-start":Y0()}],"row-end":[{"row-end":Y0()}],"grid-flow":[{"grid-flow":["row","col","dense","row-dense","col-dense"]}],"auto-cols":[{"auto-cols":l()}],"auto-rows":[{"auto-rows":l()}],gap:[{gap:E()}],"gap-x":[{"gap-x":E()}],"gap-y":[{"gap-y":E()}],"justify-content":[{justify:[...j(),"normal"]}],"justify-items":[{"justify-items":[...g(),"normal"]}],"justify-self":[{"justify-self":["auto",...g()]}],"align-content":[{content:["normal",...j()]}],"align-items":[{items:[...g(),{baseline:["","last"]}]}],"align-self":[{self:["auto",...g(),{baseline:["","last"]}]}],"place-content":[{"place-content":j()}],"place-items":[{"place-items":[...g(),"baseline"]}],"place-self":[{"place-self":["auto",...g()]}],p:[{p:E()}],px:[{px:E()}],py:[{py:E()}],ps:[{ps:E()}],pe:[{pe:E()}],pbs:[{pbs:E()}],pbe:[{pbe:E()}],pt:[{pt:E()}],pr:[{pr:E()}],pb:[{pb:E()}],pl:[{pl:E()}],m:[{m:y()}],mx:[{mx:y()}],my:[{my:y()}],ms:[{ms:y()}],me:[{me:y()}],mbs:[{mbs:y()}],mbe:[{mbe:y()}],mt:[{mt:y()}],mr:[{mr:y()}],mb:[{mb:y()}],ml:[{ml:y()}],"space-x":[{"space-x":E()}],"space-x-reverse":["space-x-reverse"],"space-y":[{"space-y":E()}],"space-y-reverse":["space-y-reverse"],size:[{size:n()}],"inline-size":[{inline:["auto",...o()]}],"min-inline-size":[{"min-inline":["auto",...o()]}],"max-inline-size":[{"max-inline":["none",...o()]}],"block-size":[{block:["auto",...K0()]}],"min-block-size":[{"min-block":["auto",...K0()]}],"max-block-size":[{"max-block":["none",...K0()]}],w:[{w:[X,"screen",...n()]}],"min-w":[{"min-w":[X,"screen","none",...n()]}],"max-w":[{"max-w":[X,"screen","none","prose",{screen:[Y]},...n()]}],h:[{h:["screen","lh",...n()]}],"min-h":[{"min-h":["screen","lh","none",...n()]}],"max-h":[{"max-h":["screen","lh",...n()]}],"font-size":[{text:["base",w,Qn,Xj]}],"font-smoothing":["antialiased","subpixel-antialiased"],"font-style":["italic","not-italic"],"font-weight":[{font:[B,TiQ,RiQ]}],"font-stretch":[{"font-stretch":["ultra-condensed","extra-condensed","condensed","semi-condensed","normal","semi-expanded","expanded","extra-expanded","ultra-expanded",Xl0,I2]}],"font-family":[{font:[giQ,hiQ,Q]}],"font-features":[{"font-features":[I2]}],"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:[$,_2,I2]}],"line-clamp":[{"line-clamp":[gw,"none",_2,wC1]}],leading:[{leading:[f,...E()]}],"list-image":[{"list-image":["none",_2,I2]}],"list-style-position":[{list:["inside","outside"]}],"list-style-type":[{list:["disc","decimal","none",_2,I2]}],"text-alignment":[{text:["left","center","right","justify","start","end"]}],"placeholder-color":[{placeholder:c()}],"text-color":[{text:c()}],"text-decoration":["underline","overline","line-through","no-underline"],"text-decoration-style":[{decoration:[...J0(),"wavy"]}],"text-decoration-thickness":[{decoration:[gw,"from-font","auto",_2,Xj]}],"text-decoration-color":[{decoration:c()}],"underline-offset":[{"underline-offset":[gw,"auto",_2,I2]}],"text-transform":["uppercase","lowercase","capitalize","normal-case"],"text-overflow":["truncate","text-ellipsis","text-clip"],"text-wrap":[{text:["wrap","nowrap","balance","pretty"]}],indent:[{indent:E()}],"tab-size":[{tab:[kD,_2,I2]}],"vertical-align":[{align:["baseline","top","middle","bottom","text-top","text-bottom","sub","super",_2,I2]}],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",_2,I2]}],"bg-attachment":[{bg:["fixed","local","scroll"]}],"bg-clip":[{"bg-clip":["border","padding","content","text"]}],"bg-origin":[{"bg-origin":["border","padding","content"]}],"bg-position":[{bg:X0()}],"bg-repeat":[{bg:V0()}],"bg-size":[{bg:w0()}],"bg-image":[{bg:["none",{linear:[{to:["t","tr","r","br","b","bl","l","tl"]},kD,_2,I2],radial:["",_2,I2],conic:[kD,_2,I2]},EiQ,CiQ]}],"bg-color":[{bg:c()}],"gradient-from-pos":[{from:h0()}],"gradient-via-pos":[{via:h0()}],"gradient-to-pos":[{to:h0()}],"gradient-from":[{from:c()}],"gradient-via":[{via:c()}],"gradient-to":[{to:c()}],rounded:[{rounded:S0()}],"rounded-s":[{"rounded-s":S0()}],"rounded-e":[{"rounded-e":S0()}],"rounded-t":[{"rounded-t":S0()}],"rounded-r":[{"rounded-r":S0()}],"rounded-b":[{"rounded-b":S0()}],"rounded-l":[{"rounded-l":S0()}],"rounded-ss":[{"rounded-ss":S0()}],"rounded-se":[{"rounded-se":S0()}],"rounded-ee":[{"rounded-ee":S0()}],"rounded-es":[{"rounded-es":S0()}],"rounded-tl":[{"rounded-tl":S0()}],"rounded-tr":[{"rounded-tr":S0()}],"rounded-br":[{"rounded-br":S0()}],"rounded-bl":[{"rounded-bl":S0()}],"border-w":[{border:b0()}],"border-w-x":[{"border-x":b0()}],"border-w-y":[{"border-y":b0()}],"border-w-s":[{"border-s":b0()}],"border-w-e":[{"border-e":b0()}],"border-w-bs":[{"border-bs":b0()}],"border-w-be":[{"border-be":b0()}],"border-w-t":[{"border-t":b0()}],"border-w-r":[{"border-r":b0()}],"border-w-b":[{"border-b":b0()}],"border-w-l":[{"border-l":b0()}],"divide-x":[{"divide-x":b0()}],"divide-x-reverse":["divide-x-reverse"],"divide-y":[{"divide-y":b0()}],"divide-y-reverse":["divide-y-reverse"],"border-style":[{border:[...J0(),"hidden","none"]}],"divide-style":[{divide:[...J0(),"hidden","none"]}],"border-color":[{border:c()}],"border-color-x":[{"border-x":c()}],"border-color-y":[{"border-y":c()}],"border-color-s":[{"border-s":c()}],"border-color-e":[{"border-e":c()}],"border-color-bs":[{"border-bs":c()}],"border-color-be":[{"border-be":c()}],"border-color-t":[{"border-t":c()}],"border-color-r":[{"border-r":c()}],"border-color-b":[{"border-b":c()}],"border-color-l":[{"border-l":c()}],"divide-color":[{divide:c()}],"outline-style":[{outline:[...J0(),"none","hidden"]}],"outline-offset":[{"outline-offset":[gw,_2,I2]}],"outline-w":[{outline:["",gw,Qn,Xj]}],"outline-color":[{outline:c()}],shadow:[{shadow:["","none",K,p90,l90]}],"shadow-color":[{shadow:c()}],"inset-shadow":[{"inset-shadow":["none",U,p90,l90]}],"inset-shadow-color":[{"inset-shadow":c()}],"ring-w":[{ring:b0()}],"ring-w-inset":["ring-inset"],"ring-color":[{ring:c()}],"ring-offset-w":[{"ring-offset":[gw,Xj]}],"ring-offset-color":[{"ring-offset":c()}],"inset-ring-w":[{"inset-ring":b0()}],"inset-ring-color":[{"inset-ring":c()}],"text-shadow":[{"text-shadow":["none",G,p90,l90]}],"text-shadow-color":[{"text-shadow":c()}],opacity:[{opacity:[gw,_2,I2]}],"mix-blend":[{"mix-blend":[...j0(),"plus-darker","plus-lighter"]}],"bg-blend":[{"bg-blend":j0()}],"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":[gw]}],"mask-image-linear-from-pos":[{"mask-linear-from":C0()}],"mask-image-linear-to-pos":[{"mask-linear-to":C0()}],"mask-image-linear-from-color":[{"mask-linear-from":c()}],"mask-image-linear-to-color":[{"mask-linear-to":c()}],"mask-image-t-from-pos":[{"mask-t-from":C0()}],"mask-image-t-to-pos":[{"mask-t-to":C0()}],"mask-image-t-from-color":[{"mask-t-from":c()}],"mask-image-t-to-color":[{"mask-t-to":c()}],"mask-image-r-from-pos":[{"mask-r-from":C0()}],"mask-image-r-to-pos":[{"mask-r-to":C0()}],"mask-image-r-from-color":[{"mask-r-from":c()}],"mask-image-r-to-color":[{"mask-r-to":c()}],"mask-image-b-from-pos":[{"mask-b-from":C0()}],"mask-image-b-to-pos":[{"mask-b-to":C0()}],"mask-image-b-from-color":[{"mask-b-from":c()}],"mask-image-b-to-color":[{"mask-b-to":c()}],"mask-image-l-from-pos":[{"mask-l-from":C0()}],"mask-image-l-to-pos":[{"mask-l-to":C0()}],"mask-image-l-from-color":[{"mask-l-from":c()}],"mask-image-l-to-color":[{"mask-l-to":c()}],"mask-image-x-from-pos":[{"mask-x-from":C0()}],"mask-image-x-to-pos":[{"mask-x-to":C0()}],"mask-image-x-from-color":[{"mask-x-from":c()}],"mask-image-x-to-color":[{"mask-x-to":c()}],"mask-image-y-from-pos":[{"mask-y-from":C0()}],"mask-image-y-to-pos":[{"mask-y-to":C0()}],"mask-image-y-from-color":[{"mask-y-from":c()}],"mask-image-y-to-color":[{"mask-y-to":c()}],"mask-image-radial":[{"mask-radial":[_2,I2]}],"mask-image-radial-from-pos":[{"mask-radial-from":C0()}],"mask-image-radial-to-pos":[{"mask-radial-to":C0()}],"mask-image-radial-from-color":[{"mask-radial-from":c()}],"mask-image-radial-to-color":[{"mask-radial-to":c()}],"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":[gw]}],"mask-image-conic-from-pos":[{"mask-conic-from":C0()}],"mask-image-conic-to-pos":[{"mask-conic-to":C0()}],"mask-image-conic-from-color":[{"mask-conic-from":c()}],"mask-image-conic-to-color":[{"mask-conic-to":c()}],"mask-mode":[{mask:["alpha","luminance","match"]}],"mask-origin":[{"mask-origin":["border","padding","content","fill","stroke","view"]}],"mask-position":[{mask:X0()}],"mask-repeat":[{mask:V0()}],"mask-size":[{mask:w0()}],"mask-type":[{"mask-type":["alpha","luminance"]}],"mask-image":[{mask:["none",_2,I2]}],filter:[{filter:["","none",_2,I2]}],blur:[{blur:k0()}],brightness:[{brightness:[gw,_2,I2]}],contrast:[{contrast:[gw,_2,I2]}],"drop-shadow":[{"drop-shadow":["","none",q,p90,l90]}],"drop-shadow-color":[{"drop-shadow":c()}],grayscale:[{grayscale:["",gw,_2,I2]}],"hue-rotate":[{"hue-rotate":[gw,_2,I2]}],invert:[{invert:["",gw,_2,I2]}],saturate:[{saturate:[gw,_2,I2]}],sepia:[{sepia:["",gw,_2,I2]}],"backdrop-filter":[{"backdrop-filter":["","none",_2,I2]}],"backdrop-blur":[{"backdrop-blur":k0()}],"backdrop-brightness":[{"backdrop-brightness":[gw,_2,I2]}],"backdrop-contrast":[{"backdrop-contrast":[gw,_2,I2]}],"backdrop-grayscale":[{"backdrop-grayscale":["",gw,_2,I2]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[gw,_2,I2]}],"backdrop-invert":[{"backdrop-invert":["",gw,_2,I2]}],"backdrop-opacity":[{"backdrop-opacity":[gw,_2,I2]}],"backdrop-saturate":[{"backdrop-saturate":[gw,_2,I2]}],"backdrop-sepia":[{"backdrop-sepia":["",gw,_2,I2]}],"border-collapse":[{border:["collapse","separate"]}],"border-spacing":[{"border-spacing":E()}],"border-spacing-x":[{"border-spacing-x":E()}],"border-spacing-y":[{"border-spacing-y":E()}],"table-layout":[{table:["auto","fixed"]}],caption:[{caption:["top","bottom"]}],transition:[{transition:["","all","colors","opacity","shadow","transform","none",_2,I2]}],"transition-behavior":[{transition:["normal","discrete"]}],duration:[{duration:[gw,"initial",_2,I2]}],ease:[{ease:["linear","initial",L,_2,I2]}],delay:[{delay:[gw,_2,I2]}],animate:[{animate:["none",N,_2,I2]}],backface:[{backface:["hidden","visible"]}],perspective:[{perspective:[J,_2,I2]}],"perspective-origin":[{"perspective-origin":v()}],rotate:[{rotate:N0()}],"rotate-x":[{"rotate-x":N0()}],"rotate-y":[{"rotate-y":N0()}],"rotate-z":[{"rotate-z":N0()}],scale:[{scale:P0()}],"scale-x":[{"scale-x":P0()}],"scale-y":[{"scale-y":P0()}],"scale-z":[{"scale-z":P0()}],"scale-3d":["scale-3d"],skew:[{skew:M0()}],"skew-x":[{"skew-x":M0()}],"skew-y":[{"skew-y":M0()}],transform:[{transform:[_2,I2,"","none","gpu","cpu"]}],"transform-origin":[{origin:v()}],"transform-style":[{transform:["3d","flat"]}],translate:[{translate:T0()}],"translate-x":[{"translate-x":T0()}],"translate-y":[{"translate-y":T0()}],"translate-z":[{"translate-z":T0()}],"translate-none":["translate-none"],zoom:[{zoom:[kD,_2,I2]}],accent:[{accent:c()}],appearance:[{appearance:["none","auto"]}],"caret-color":[{caret:c()}],"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",_2,I2]}],"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":c()}],"scrollbar-track-color":[{"scrollbar-track":c()}],"scrollbar-gutter":[{"scrollbar-gutter":["auto","stable","both"]}],"scrollbar-w":[{scrollbar:["auto","thin","none"]}],"scroll-m":[{"scroll-m":E()}],"scroll-mx":[{"scroll-mx":E()}],"scroll-my":[{"scroll-my":E()}],"scroll-ms":[{"scroll-ms":E()}],"scroll-me":[{"scroll-me":E()}],"scroll-mbs":[{"scroll-mbs":E()}],"scroll-mbe":[{"scroll-mbe":E()}],"scroll-mt":[{"scroll-mt":E()}],"scroll-mr":[{"scroll-mr":E()}],"scroll-mb":[{"scroll-mb":E()}],"scroll-ml":[{"scroll-ml":E()}],"scroll-p":[{"scroll-p":E()}],"scroll-px":[{"scroll-px":E()}],"scroll-py":[{"scroll-py":E()}],"scroll-ps":[{"scroll-ps":E()}],"scroll-pe":[{"scroll-pe":E()}],"scroll-pbs":[{"scroll-pbs":E()}],"scroll-pbe":[{"scroll-pbe":E()}],"scroll-pt":[{"scroll-pt":E()}],"scroll-pr":[{"scroll-pr":E()}],"scroll-pb":[{"scroll-pb":E()}],"scroll-pl":[{"scroll-pl":E()}],"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",_2,I2]}],fill:[{fill:["none",...c()]}],"stroke-w":[{stroke:[gw,Qn,Xj,wC1]}],stroke:[{stroke:["none",...c()]}],"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"]}},miQ=(A,{cacheSize:Q,prefix:w,experimentalParseClassName:B,extend:$={},override:f={}})=>{return oC(A,"cacheSize",Q),oC(A,"prefix",w),oC(A,"experimentalParseClassName",B),i90(A.theme,f.theme),i90(A.classGroups,f.classGroups),i90(A.conflictingClassGroups,f.conflictingClassGroups),i90(A.conflictingClassGroupModifiers,f.conflictingClassGroupModifiers),oC(A,"postfixLookupClassGroups",f.postfixLookupClassGroups),oC(A,"orderSensitiveModifiers",f.orderSensitiveModifiers),d90(A.theme,$.theme),d90(A.classGroups,$.classGroups),d90(A.conflictingClassGroups,$.conflictingClassGroups),d90(A.conflictingClassGroupModifiers,$.conflictingClassGroupModifiers),Zl0(A,$,"postfixLookupClassGroups"),Zl0(A,$,"orderSensitiveModifiers"),A},oC=(A,Q,w)=>{if(w!==void 0)A[Q]=w},i90=(A,Q)=>{if(Q)for(let w in Q)oC(A,w,Q[w])},d90=(A,Q)=>{if(Q)for(let w in Q)Zl0(A,Q,w)},Zl0=(A,Q,w)=>{let B=Q[w];if(B!==void 0)A[w]=A[w]?A[w].concat(B):B},n90=(A,...Q)=>typeof A==="function"?QC1(fC1,A,...Q):QC1(()=>miQ(fC1(),A),...Q);var uiQ=n90({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 N2(...A){return uiQ(rC(A))}var IC1=(A)=>typeof A==="boolean"?`${A}`:A===0?"0":A,FC1=rC,FB=(A,Q)=>(w)=>{var B;if((Q===null||Q===void 0?void 0:Q.variants)==null)return FC1(A,w===null||w===void 0?void 0:w.class,w===null||w===void 0?void 0:w.className);let{variants:$,defaultVariants:f}=Q,Y=Object.keys($).map((W)=>{let K=w===null||w===void 0?void 0:w[W],U=f===null||f===void 0?void 0:f[W];if(K===null)return null;let G=IC1(K)||IC1(U);return $[W][G]}),X=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:(B=Q.compoundVariants)===null||B===void 0?void 0:B.reduce((W,K)=>{let{class:U,className:G,...q}=K;return Object.entries(q).every((V)=>{let[J,b]=V;return Array.isArray(b)?b.includes({...f,...X}[J]):{...f,...X}[J]===b})?[...W,U,G]:W},[]);return FC1(A,Y,H,w===null||w===void 0?void 0:w.class,w===null||w===void 0?void 0:w.className)};import{jsxDEV as Kl0}from"preact/jsx-dev-runtime";var LC1=FB("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 Ul0({variant:A,title:Q,children:w,className:B}){return Kl0("div",{className:N2(LC1({variant:A}),B),role:"alert",children:[Q&&Kl0("p",{className:"font-medium text-current opacity-90",children:Q},void 0,!1,void 0,this),Kl0("div",{className:N2(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 ciQ}from"preact/jsx-dev-runtime";var kC1=FB("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 Hj({variant:A,size:Q,className:w,children:B,ssrOnClick:$,type:f="button",...Y}){return ciQ("button",{type:f,className:N2(kC1({variant:A,size:Q}),w),...Y,...$&&{onclick:$},children:B},void 0,!1,void 0,this)}import{jsxDEV as liQ}from"preact/jsx-dev-runtime";var _C1=FB("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 I9({href:A,children:Q,variant:w,size:B,external:$=!1,className:f,"aria-label":Y}){let X=$?{target:"_blank",rel:"noopener noreferrer"}:{};return liQ("a",{href:A,className:N2(_C1({variant:w,size:B}),f),"aria-label":Y,...X,children:Q},void 0,!1,void 0,this)}import{jsxDEV as r90}from"preact/jsx-dev-runtime";var NC1=FB("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"}}),piQ={sm:"w-4 h-4",md:"w-5 h-5",lg:"w-6 h-6"};function sC({variant:A,size:Q,className:w}){let B=piQ[Q??"md"];return r90("button",{onclick:"toggleTheme()",type:"button",className:N2(NC1({variant:A,size:Q}),w),"aria-label":"Toggle dark mode",children:r90("svg",{className:N2(B,"transition-colors"),fill:"none",stroke:"currentColor",strokeWidth:1.6,viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:[r90("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),r90("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 Gl0}from"preact/jsx-dev-runtime";var jC1=FB("flex flex-wrap",{variants:{orientation:{horizontal:"justify-center gap-6 items-center",vertical:"flex-col gap-2.5"}},defaultVariants:{orientation:"horizontal"}});function o90({items:A,className:Q,linkClassName:w="hover:text-accent transition-colors",orientation:B,children:$}){if(A.length===0&&!$)return null;let f=[...A].sort((Y,X)=>Y.priority-X.priority);return Gl0("ul",{className:N2(jC1({orientation:B}),Q),children:[f.map((Y)=>Gl0("li",{children:Gl0("a",{href:Y.href,className:w,children:Y.label},void 0,!1,void 0,this)},Y.href,!1,void 0,this)),$]},void 0,!0,void 0,this)}import{jsxDEV as pCB}from"preact/jsx-dev-runtime";import{jsxDEV as nCB}from"preact/jsx-dev-runtime";import{createContext as iiQ,h as diQ}from"preact";import{useContext as niQ}from"preact/hooks";var Dl0=iiQ(null);function aC({headCollector:A,children:Q}){return diQ(Dl0.Provider,{value:A},Q)}function PC1(){return niQ(Dl0)}function pQ(A){let Q=PC1();if(Q)Q.setHeadProps(A);return null}import{createContext as _tQ,h as NtQ}from"preact";import{useContext as jtQ}from"preact/hooks";VP0();var ET1=Z1(yT1(),1),LtQ=new lQ0({gfm:!0,breaks:!0}),ktQ={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 Sp0(A,Q){let{imageRenderer:w}=Q??{},$=(w?new lQ0({gfm:!0,breaks:!0}).use({renderer:{image({href:f,title:Y,text:X}){return w(f,Y,X)??!1}}}):LtQ).parse(A);return $=$.replace(/<\/blockquote>\s*<p>(\u2014|--|\u2013)([\s\S]*?)<\/p>/g,`</blockquote>
|
|
5467
5467
|
<cite class="block-attribution"><span class="emdash">$1</span>$2</cite>`),ET1.default($,ktQ)}var TT1=_tQ(null);function Dg({imageRenderer:A,children:Q}){return NtQ(TT1.Provider,{value:A??null},Q)}function ST1(){return jtQ(TT1)}function mq(){let A=ST1();return(Q)=>Sp0(Q,A?{imageRenderer:A}:void 0)}var PtQ=/<pre><code class="language-mermaid">([\s\S]*?)<\/code><\/pre>/g,MtQ={"&":"&","<":"<",">":">",""":'"',"'":"'"},OtQ=/&(?:amp|lt|gt|quot|#39);/g;function xtQ(A){return A.replace(OtQ,(Q)=>MtQ[Q]??Q)}function mp0(A){return A.replace(PtQ,(Q,w)=>{return`<div class="mermaid">${xtQ(w)}</div>`})}var mT1=/<!--\s*\.slide:\s*(.*?)\s*-->/g;function uT1(A){let Q={};for(let B of A.matchAll(mT1)){let $=B[1]??"";for(let Y of $.matchAll(/([\w-]+)=["']([^"']*?)["']/g)){let X=Y[1],H=Y[2];if(X&&H!==void 0)Q[X]=H}let f=$.replace(/([\w-]+)=["']([^"']*?)["']/g,"").trim();if(f)for(let Y of f.matchAll(/(?:^|\s)([\w-]+)(?=\s|$)/g)){let X=Y[1];if(X)Q[X]="true"}}let w=A.replace(mT1,"").replace(/^\n+/,"").replace(/\n{3,}/g,`
|
|
5468
5468
|
|
|
5469
5469
|
`).trim();return{attributes:Q,markdown:w}}var vtQ=/<!--\s*\.break\s*-->/;function cT1(A){let Q=A.split(vtQ);return Q.length>1?Q:null}import{jsxDEV as xD}from"preact/jsx-dev-runtime";var up0=({markdown:A,deck:Q})=>{let w=mq(),$=A.split(/^---$/gm).map((K)=>K.trim()).map((K)=>{let{attributes:U,markdown:G}=uT1(K),q=cT1(G),V;if(q)V=`<div class="slide-columns">${q.map((b)=>`<div class="slide-column">${mp0(w(b.trim()))}</div>`).join("")}</div>`;else V=mp0(w(G));return{attributes:U,htmlContent:V}}),f=$.some((K)=>K.htmlContent.includes('class="mermaid"')),Y=Q?.frontmatter?.title??Q?.metadata?.title,X=Q?.frontmatter?.description??Q?.metadata?.description,H=Q?.ogImageUrl??Q?.coverImageUrl,W=$.map(({attributes:K,htmlContent:U},G)=>xD("section",{...K,dangerouslySetInnerHTML:{__html:U}},G,!1,void 0,this));return xD("section",{className:"presentation-section",children:[Y&&xD(pQ,{title:Y,...X?{description:X}:{},...H?{ogImage:H}:{},ogType:"article"},void 0,!1,void 0,this),xD("link",{rel:"stylesheet",href:"https://cdn.jsdelivr.net/npm/reveal.js@5.1.0/dist/reveal.min.css"},void 0,!1,void 0,this),xD("div",{className:"reveal",children:xD("div",{className:"slides",children:W},void 0,!1,void 0,this)},void 0,!1,void 0,this),xD("script",{src:"https://cdn.jsdelivr.net/npm/reveal.js@5.1.0/dist/reveal.min.js",defer:!0},void 0,!1,void 0,this),f&&xD("script",{src:"https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js",defer:!0},void 0,!1,void 0,this),xD("script",{dangerouslySetInnerHTML:{__html:`
|
|
@@ -6450,13 +6450,13 @@ ${A.map((f)=>({url:`${Q}${f.path}`,lastmod:w,changefreq:f.path==="/"?"daily":"we
|
|
|
6450
6450
|
`+$:w,Y=cD(this.outputDir,"styles","main.css");await this.cssProcessor.process(f,Y,this.workingDir,this.outputDir,this.logger);let X=await c7.readFile(Y,"utf-8"),H=B.length>0?B:Q;if(H.length>0){let W=H.join(`
|
|
6451
6451
|
`)+`
|
|
6452
6452
|
|
|
6453
|
-
`+X;await c7.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=cD(process.cwd(),"public");try{await c7.access(A)}catch{this.logger.debug("No public/ directory found, skipping static assets");return}let Q=await c7.readdir(A,{withFileTypes:!0});for(let w of Q){let B=cD(A,w.name),$=cD(this.outputDir,w.name);if(w.isDirectory())await this.copyDirectory(B,$);else await c7.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,B])=>{let $=w.startsWith("/")?w.slice(1):w,f=cD(this.outputDir,$);await c7.mkdir(KXw(f),{recursive:!0}),await c7.writeFile(f,B,"utf-8"),this.logger.debug(`Wrote inline static asset: ${$}`)}))}async copyDirectory(A,Q){await c7.mkdir(Q,{recursive:!0});let w=await c7.readdir(A,{withFileTypes:!0});for(let B of w){let $=cD(A,B.name),f=cD(Q,B.name);if(B.isDirectory())await this.copyDirectory($,f);else await c7.copyFile($,f)}}}function Sn0(A){return new So1(A)}e8();_0();_0();var UXw=Z.object({heading:Z.string(),buttonText:Z.string(),buttonLink:Z.string()}),GXw=Z.object({blurb:Z.string().optional()}),rg=Z.object({title:Z.string(),description:Z.string(),url:Z.string().optional(),copyright:Z.string().optional(),logo:Z.boolean().optional(),themeMode:Z.enum(["light","dark"]).optional(),analyticsScript:Z.string().optional(),cta:UXw.optional(),sections:Z.record(Z.string(),GXw).optional()});var mo1=Z.object({environment:Z.enum(["preview","production"]),outputDir:Z.string(),workingDir:Z.string().optional(),sharedImagesDir:Z.string().default("./dist/images"),enableContentGeneration:Z.boolean().default(!1),cleanBeforeBuild:Z.boolean().default(!0),siteConfig:rg,layouts:Z.record(Z.string(),Z.any()),themeCSS:Z.string().optional()}),hnB=Z.object({success:Z.boolean(),outputDir:Z.string(),filesGenerated:Z.number(),routesBuilt:Z.number(),errors:Z.array(Z.string()).optional(),warnings:Z.array(Z.string()).optional()});function uo1(A){let Q=A.list(),w=Q.length===0?["No routes registered for site build"]:[];return{routes:Q,warnings:w}}function co1(A,Q,w){let B=Q.getProfile(),$=w.getNavigationItems("primary"),f=w.getNavigationItems("secondary");return{...A,...B.socialLinks!==void 0&&{socialLinks:B.socialLinks},navigation:{primary:$,secondary:f},copyright:A.copyright??"Powered by Rizom"}}e8();F4();e8();U2();_0();var DXw=Z.looseObject({id:Z.string(),entityType:Z.string(),content:Z.string(),metadata:Z.looseObject({slug:Z.string()})}),zXw=Z.looseObject({content:Z.string(),metadata:Z.looseObject({width:Z.number().optional(),height:Z.number().optional()})});async function Nf0(A,Q){let w=Q.urlGenerator??Z4.getInstance();if(A===null||A===void 0)return A;if(Array.isArray(A))return Promise.all(A.map((x)=>Nf0(x,{...Q,urlGenerator:w})));if(typeof A!=="object")return A;let B={},$=Object.entries(A),f=await Promise.all($.map(([,x])=>Nf0(x,{...Q,urlGenerator:w})));for(let x=0;x<$.length;x++){let v=$[x];if(v)B[v[0]]=f[x]}let Y=DXw.safeParse(A);if(!Y.success)return B;let X=Y.data,H=X.entityType,W=X.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":eW(H),q=`/${G}`,V=G.charAt(0).toUpperCase()+G.slice(1),J=vu(X),b=await qXw(J,Q),L=V20(X)??J,N=await VXw(L,Q);return{...B,...X,url:w.generateUrl(H,W),typeLabel:U,listUrl:q,listLabel:V,...b,...N&&{ogImageUrl:N}}}async function qXw(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 B=await po1(A,Q.pipelineContext.services.entityService);if(!B)return{};return{coverImageUrl:B.url,...B.width&&{coverImageWidth:B.width},...B.height&&{coverImageHeight:B.height}}}async function VXw(A,Q){if(!A)return;let w=Q.imageBuildService?.get(A);if(w)return lo1(w.src,Q.siteUrl);let B=await po1(A,Q.pipelineContext.services.entityService);if(!B)return;if(B.url.startsWith("data:"))return;return lo1(B.url,Q.siteUrl)}function lo1(A,Q){if(/^https?:\/\//i.test(A)||A.startsWith("data:"))return A;if(!Q)return A;return`${Q.replace(/\/$/,"")}/${A.replace(/^\//,"")}`}async function po1(A,Q){if(!A)return;let w=await Q.getEntity({entityType:"image",id:A}),B=zXw.safeParse(w);if(!B.success)return;return{url:B.data.content,...B.data.metadata.width&&{width:B.data.metadata.width},...B.data.metadata.height&&{height:B.data.metadata.height}}}async function io1(A,Q){let w=new Set;try{let B=A.getEntityTypes();for(let $ of B){if($==="image")continue;let f=await A.listEntities({entityType:$});for(let Y of f){let X=vu(Y);if(X)w.add(X);let H=V20(Y);if(H)w.add(H)}}}catch(B){Q.warn("Failed to collect image IDs for pre-resolution",{error:SA(B)})}return[...w]}async function do1(A,Q,w,B,$){if(!A.template)return A.content??null;let f=A.template,Y=A.dataQuery?{dataParams:A.dataQuery,fallback:A.content,publishedOnly:w,visibilityScope:B}:{savedContent:{entityType:"site-content",entityId:`${Q.id}:${A.id}`},fallback:A.content,visibilityScope:B},X=await $.pipelineContext.services.resolveTemplateContent(f,Y);if(!X)return null;return Nf0(X,{pipelineContext:$.pipelineContext,imageBuildService:$.imageBuildService,siteUrl:$.siteUrl,urlGenerator:Z4.getInstance()})}function no1(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 B=A.parsedOptions.environment==="production";return do1(w,Q,B,"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 co1(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 bXw}from"path";async function ro1(A){let Q=A.parsedOptions.workingDir??bXw(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 oo1(A){await new kf0({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 so1(A){let Q=new Lf0(A.pipelineContext.services.entityService,A.pipelineContext.logger,A.sharedImagesDir),w=await io1(A.pipelineContext.services.entityService,A.pipelineContext.logger);if(w.length>0)await Q.resolveAll(w);return Q}async function ao1(A){let Q=A.reporter?.createSub({scale:{start:85,end:95}});await A.staticSiteBuilder.build(A.buildContext,(w)=>{Q?.report(w).catch(()=>{})})}function to1(A){return{success:!0,outputDir:A.outputDir,filesGenerated:A.routesBuilt+1,routesBuilt:A.routesBuilt,...A.warnings.length>0&&{warnings:A.warnings}}}function eo1(A){return{success:!1,outputDir:A.outputDir,filesGenerated:0,routesBuilt:0,errors:[A.errorMessage]}}async function As1(A){let Q=mo1.parse(A.buildOptions),w=Zf.from(A.progress),B=[];try{await w?.report({message:"Starting site build",progress:0,total:100}),await w?.report({message:"Generating dynamic routes",progress:10,total:100}),await oo1({pipelineContext:A.pipelineContext,publishedOnly:Q.environment==="production"});let $=await ro1({logger:A.pipelineContext.logger,parsedOptions:Q,staticSiteBuilderFactory:A.staticSiteBuilderFactory}),f=uo1(A.pipelineContext.routeRegistry);B.push(...f.warnings);let{routes:Y}=f;await w?.report({message:`Building ${Y.length} routes`,progress:20,total:100}),await w?.report({message:"Resolving images",progress:25,total:100});let X=await so1({pipelineContext:A.pipelineContext,sharedImagesDir:Q.sharedImagesDir}),H=no1({routes:Y,parsedOptions:Q,buildOptions:A.buildOptions,pipelineContext:A.pipelineContext,imageBuildService:X,siteMetadata:Q.siteConfig});return await ao1({staticSiteBuilder:$,buildContext:H,reporter:w}),await w?.report({message:"Site build complete",progress:100,total:100}),to1({outputDir:Q.outputDir,routesBuilt:Y.length,warnings:B})}catch($){let f=Error("Site build process failed");return A.pipelineContext.logger.error("Site build failed",{error:f,originalError:$}),eo1({outputDir:Q.outputDir,errorMessage:f.message})}}class xZ{static instance=null;static defaultStaticSiteBuilderFactory=Sn0;pipelineContext;staticSiteBuilderFactory;static setDefaultStaticSiteBuilderFactory(A){xZ.defaultStaticSiteBuilderFactory=A}static getInstance(A,Q,w,B,$=void 0){return xZ.instance??=new xZ(A,xZ.defaultStaticSiteBuilderFactory,Q,w,B,$),xZ.instance}static resetInstance(){xZ.instance=null}static createFresh(A,Q,w,B,$,f=void 0){return new xZ(A,$??xZ.defaultStaticSiteBuilderFactory,Q,w,B,f)}constructor(A,Q,w,B,$,f){this.pipelineContext={logger:A,services:w,routeRegistry:B,profileService:$,entityDisplay:f},this.staticSiteBuilderFactory=Q,Z4.getInstance().configure(f)}async build(A,Q){return As1({buildOptions:A,progress:Q,pipelineContext:this.pipelineContext,staticSiteBuilderFactory:this.staticSiteBuilderFactory})}}class mn0{config;context;pluginId;logger;debounces=new Map;unsubscribeFunctions=[];constructor(A,Q,w,B){this.config=A,this.context=Q,this.pluginId=w,this.logger=B}requestBuild(A){let Q=A??(this.config.previewOutputDir?"preview":"production"),w=this.debounces.get(Q);if(!w)w=new $l0(()=>{this.enqueueBuild(Q)},this.config.rebuildDebounce),this.debounces.set(Q,w);w.trigger()}setupAutoRebuild(){let A=new Set(["note"]),Q=async(B)=>{let{entityType:$}=B.payload;if(!A.has($))this.logger.debug(`Entity type ${$} will trigger rebuild`),this.requestBuild();return{success:!0}},w=["entity:created","entity:updated","entity:deleted"];for(let B of w)this.unsubscribeFunctions.push(this.context.messaging.subscribe(B,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})}}}e8();function JXw(A,Q){return A.map((w)=>({...w,template:w.template.includes(":")?w.template:`${Q}:${w.template}`}))}function jf0(A,Q,w){for(let B of A)w.register({...B,pluginId:Q,sections:B.sections?JXw(B.sections,Q):[]})}function Qs1(A,Q,w){A.messaging.subscribe("plugin:site-builder:route:register",async(B)=>{try{let $=Xe.parse(B.payload),{routes:f,pluginId:Y}=$;return jf0(f,Y,Q),{success:!0}}catch($){return w.error("Failed to register routes",{error:$}),{success:!1,error:"Failed to register routes"}}}),A.messaging.subscribe("plugin:site-builder:route:unregister",async(B)=>{try{let $=Ze.parse(B.payload),{paths:f,pluginId:Y}=$;if(f)for(let X of f)Q.unregister(X);else if(Y)Q.unregisterByPlugin(Y);return{success:!0}}catch($){return w.error("Failed to unregister routes",{error:$}),{success:!1,error:"Failed to unregister routes"}}}),A.messaging.subscribe("plugin:site-builder:route:list",async(B)=>{try{let $=He.parse(B.payload);return{success:!0,data:{routes:Q.list($.pluginId?$:void 0)}}}catch($){return w.error("Failed to list routes",{error:$}),{success:!1,error:"Failed to list routes"}}}),A.messaging.subscribe("plugin:site-builder:route:get",async(B)=>{try{let $=We.parse(B.payload);return{success:!0,data:{route:Q.get($.path)}}}catch($){return w.error("Failed to get route",{error:$}),{success:!1,error:"Failed to get route"}}}),A.messaging.subscribe("site-builder:routes:list",async()=>{return{success:!0,data:Q.list()}})}import{promises as ws1}from"fs";import{join as Bs1}from"path";async function IXw(A,Q,w){let B=A.siteConfig.url??"https://example.com",$=Q.list(),f=En0(B,A.environment);await ws1.writeFile(Bs1(A.outputDir,"robots.txt"),f,"utf-8"),w.info(`Generated robots.txt for ${A.environment} environment`);let Y=Tn0($,B);await ws1.writeFile(Bs1(A.outputDir,"sitemap.xml"),Y,"utf-8"),w.info(`Generated sitemap.xml with ${$.length} URLs`)}function $s1(A){let{context:Q,routeRegistry:w,logger:B}=A;Q.messaging.subscribe("site:build:completed",async($)=>{try{let f=$.payload;return B.info(`Received site:build:completed event for ${f.environment} environment - generating SEO files`),await IXw(f,w,B),{success:!0}}catch(f){return B.error("Failed to generate SEO files",f),{success:!1}}})}wA();_0();var fs1=Z.object({environment:Z.enum(["preview","production"]).optional(),outputDir:Z.string(),workingDir:Z.string().optional(),enableContentGeneration:Z.boolean().optional(),siteConfig:rg.optional()});e8();e8();_0();var FXw=Z.object({heading:Z.string(),buttonText:Z.string(),buttonLink:Z.string()}),LXw=Z.object({blurb:Z.string().optional()}),Ys1=Z.object({title:Z.string(),description:Z.string(),url:Z.string().optional(),copyright:Z.string().optional(),logo:Z.boolean().optional(),themeMode:Z.enum(["light","dark"]).optional(),analyticsScript:Z.string().optional(),cta:FXw.optional(),sections:Z.record(Z.string(),LXw).optional()});async function Mr(A,Q){try{let w=await A({type:dT,payload:void 0});if("success"in w&&w.success&&w.data){let B=Ys1.safeParse(w.data);if(B.success)return Ys1.parse({...Q,...B.data})}}catch{}return Q}class un0 extends tw{sendMessage;cfg;constructor(A,Q,w){super(A,{schema:fs1,jobTypeName:"site-build"});this.sendMessage=Q,this.cfg=w}async process(A,Q,w){let B=A.environment??"preview",$=A.enableContentGeneration??!1;try{this.logger.debug("Starting site build job",{jobId:Q,environment:B,outputDir:A.outputDir}),await w.report({progress:0,total:100,message:`Starting site build for ${B} environment`});let f=w.createSub({scale:{start:10,end:90}}),Y=await Mr(this.sendMessage,A.siteConfig??this.cfg.defaultSiteConfig),X=await this.cfg.siteBuilder.build({outputDir:A.outputDir,workingDir:A.workingDir,sharedImagesDir:this.cfg.sharedImagesDir,enableContentGeneration:$,environment:B,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}},f.toCallback());if(await w.report({progress:100,total:100,message:`Site build completed: ${X.routesBuilt} routes built`}),this.logger.debug("Site build job completed",{jobId:Q,environment:B,routesBuilt:X.routesBuilt,success:X.success}),X.success){this.logger.info(`Emitting site:build:completed event for ${B} environment`);let H=B==="preview"?this.cfg.previewUrl??this.cfg.siteUrl:this.cfg.siteUrl;await this.sendMessage({type:"site:build:completed",payload:{outputDir:A.outputDir,environment:B,routesBuilt:X.routesBuilt,siteConfig:{...Y,url:H},generateEntityUrl:(W,K)=>Z4.getInstance().generateUrl(W,K)},broadcast:!0})}return{success:X.success,routesBuilt:X.routesBuilt,outputDir:A.outputDir,environment:B,...X.errors&&{errors:X.errors},...X.warnings&&{warnings:X.warnings}}}catch(f){throw this.logger.error("Site build job failed",f),f}}summarizeDataForLog(A){return{environment:A.environment,outputDir:A.outputDir}}}_0();e8();var kXw=Z.object({slot:Z.enum(Yb).optional().default("primary"),limit:Z.number().optional()});class cn0{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 B=kXw.parse(A??{});this.logger.debug("NavigationDataSource fetch called",{params:B});let $=this.routeRegistry.getNavigationItems(B.slot),f=B.limit?$.slice(0,B.limit):$,Y=f.map((H)=>({label:H.label,href:H.href}));this.logger.debug("NavigationDataSource returning",{slot:B.slot,itemCount:f.length,items:Y});let X={navigation:Y};return Q.parse(X)}}e8();wA();_0();var _Xw=Z.object({environment:Z.enum(["preview","production"]).optional().describe("Build environment (defaults to production, or preview if configured)")});function Xs1(A,Q){return[M6(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'.",_Xw,async(w)=>{return Q(w.environment),{success:!0,message:`Site build requested${w.environment?` for ${w.environment}`:""} (debounced)`,data:{}}},{sideEffects:"external",cli:{name:"build"}})]}_0();e8();var NXw=Z.object({id:Z.string(),template:Z.string(),content:Z.unknown().optional(),dataQuery:Z.looseObject({entityType:Z.string().optional(),template:Z.string().optional(),query:Z.looseObject({id:Z.string().optional(),limit:Z.number().optional(),offset:Z.number().optional()}).optional()}).optional(),order:Z.number().optional()}),jXw=Z.object({show:Z.boolean().default(!1),label:Z.string().optional(),slot:Z.enum(Yb).default("primary"),priority:Z.number().min(0).max(100).default(50)}).optional(),PXw=Z.object({id:Z.string(),path:Z.string(),title:Z.string().default(""),pageLabel:Z.string().optional(),description:Z.string().default(""),sections:Z.array(NXw).default([]),layout:Z.string().default("default"),fullscreen:Z.boolean().optional(),pluginId:Z.string().optional(),sourceEntityType:Z.string().optional(),external:Z.boolean().optional(),navigation:jXw}),Zs1=Z.object({previewOutputDir:Z.string().describe("Output directory for preview builds").default("./dist/site-preview"),productionOutputDir:Z.string().describe("Output directory for production builds").default("./dist/site-production"),sharedImagesDir:Z.string().describe("Shared directory for optimized images (used by both preview and production)").default("./dist/images"),workingDir:Z.string().optional().describe("Working directory for builds").default("./.preact-work"),siteInfo:rg.default({title:"Brain",description:"A knowledge management system"}),themeCSS:Z.string().describe("Custom CSS theme overrides to inject into builds").optional(),analyticsScript:Z.string().describe("Analytics tracking script to inject into page head (e.g., Cloudflare Web Analytics)").optional(),templates:Z.any().optional().describe("Template definitions to register"),routes:Z.array(PXw).optional().describe("Routes to register"),layouts:Z.record(Z.string(),Z.any()).optional().describe("Layout components (at least 'default' required)"),autoRebuild:Z.boolean().default(!0).describe("Automatically rebuild site when content changes"),rebuildDebounce:Z.number().min(100).describe("Debounce time in ms before triggering site rebuild after content changes").default(5000),entityDisplay:Z.record(Z.string(),Z.object({label:Z.string().describe("Display label for entity type (e.g., 'Essay')"),pluralName:Z.string().optional().describe("URL path segment (defaults to label.toLowerCase() + 's')"),layout:Z.string().optional().describe("Layout name for this entity type's generated routes (defaults to 'default')"),paginate:Z.boolean().optional().describe("Enable pagination for list pages"),pageSize:Z.number().optional().describe("Items per page (default: 10)"),navigation:Z.object({show:Z.boolean().optional().describe("Show in navigation"),slot:Z.enum(Yb).optional().describe("Navigation slot (primary or secondary)"),priority:Z.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:Z.record(Z.string(),Z.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 Hs1={name:"@brains/site-builder-plugin",version:"0.2.0-alpha.150",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:"^6.0.3"},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 ln0 extends tQ{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",Hs1,{...A,layouts:Q},Zs1);this.layouts=Q}async onRegister(A){if(this.pluginContext=A,this._routeRegistry=new _f0(A.logger),this._slotRegistry=new t40,A.messaging.subscribe("plugin:site-builder:slot:register",async(w)=>{let{slotName:B,pluginId:$,render:f,priority:Y}=w.payload;return this._slotRegistry?.register(B,{pluginId:$,render:f,...Y!==void 0&&{priority:Y}}),{success:!0}}),A.messaging.subscribe("plugin:site-builder:head-script:register",async(w)=>{let{pluginId:B,script:$}=w.payload;return this.headScripts.set(B,$),{success:!0}}),A.entities.registerDataSource(new cn0(this._routeRegistry,A.logger.child("NavigationDataSource"))),this.profileService=If.getInstance(A.entityService,A.logger),Qs1(A,this._routeRegistry,this.logger),this.config.templates)A.templates.register(this.config.templates);if(this.config.routes)jf0(this.config.routes,this.id,this.routeRegistry);let Q={entityService:A.entityService,sendMessage:A.messaging.send,resolveTemplateContent:(w,B)=>A.templates.resolve(w,B),getViewTemplate:(w)=>A.views.get(w),listViewTemplateNames:()=>A.views.list().map((w)=>w.name)};if(this.siteBuilder=xZ.getInstance(A.logger.child("SiteBuilder"),Q,this.routeRegistry,this.profileService,this.config.entityDisplay),A.jobs.registerHandler("site-build",new un0(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 mn0(this.config,A,this.id,this.logger),this.config.autoRebuild)this.logger.debug("Auto-rebuild enabled"),this.rebuildManager.setupAutoRebuild();A.messaging.subscribe(nT,async()=>{let w=await this.getInstructions();if(w)A.registerInstructions(w);return{success:!0}}),$s1({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 Xs1(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 Mr(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((B)=>({id:B.id,template:B.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 Mr(A.messaging.send,this.config.siteInfo);return`## Your Site
|
|
6453
|
+
`+X;await c7.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=cD(process.cwd(),"public");try{await c7.access(A)}catch{this.logger.debug("No public/ directory found, skipping static assets");return}let Q=await c7.readdir(A,{withFileTypes:!0});for(let w of Q){let B=cD(A,w.name),$=cD(this.outputDir,w.name);if(w.isDirectory())await this.copyDirectory(B,$);else await c7.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,B])=>{let $=w.startsWith("/")?w.slice(1):w,f=cD(this.outputDir,$);await c7.mkdir(KXw(f),{recursive:!0}),await c7.writeFile(f,B,"utf-8"),this.logger.debug(`Wrote inline static asset: ${$}`)}))}async copyDirectory(A,Q){await c7.mkdir(Q,{recursive:!0});let w=await c7.readdir(A,{withFileTypes:!0});for(let B of w){let $=cD(A,B.name),f=cD(Q,B.name);if(B.isDirectory())await this.copyDirectory($,f);else await c7.copyFile($,f)}}}function Sn0(A){return new So1(A)}e8();_0();_0();var UXw=Z.object({heading:Z.string(),buttonText:Z.string(),buttonLink:Z.string()}),GXw=Z.object({blurb:Z.string().optional()}),rg=Z.object({title:Z.string(),description:Z.string(),url:Z.string().optional(),copyright:Z.string().optional(),logo:Z.boolean().optional(),themeMode:Z.enum(["light","dark"]).optional(),analyticsScript:Z.string().optional(),cta:UXw.optional(),sections:Z.record(Z.string(),GXw).optional()});var mo1=Z.object({environment:Z.enum(["preview","production"]),outputDir:Z.string(),workingDir:Z.string().optional(),sharedImagesDir:Z.string().default("./dist/images"),enableContentGeneration:Z.boolean().default(!1),cleanBeforeBuild:Z.boolean().default(!0),siteConfig:rg,layouts:Z.record(Z.string(),Z.any()),themeCSS:Z.string().optional()}),hnB=Z.object({success:Z.boolean(),outputDir:Z.string(),filesGenerated:Z.number(),routesBuilt:Z.number(),errors:Z.array(Z.string()).optional(),warnings:Z.array(Z.string()).optional()});function uo1(A){let Q=A.list(),w=Q.length===0?["No routes registered for site build"]:[];return{routes:Q,warnings:w}}function co1(A,Q,w){let B=Q.getProfile(),$=w.getNavigationItems("primary"),f=w.getNavigationItems("secondary");return{...A,...B.socialLinks!==void 0&&{socialLinks:B.socialLinks},navigation:{primary:$,secondary:f},copyright:A.copyright??"Powered by Rizom"}}e8();F4();e8();U2();_0();var DXw=Z.looseObject({id:Z.string(),entityType:Z.string(),content:Z.string(),metadata:Z.looseObject({slug:Z.string()})}),zXw=Z.looseObject({content:Z.string(),metadata:Z.looseObject({width:Z.number().optional(),height:Z.number().optional()})});async function Nf0(A,Q){let w=Q.urlGenerator??Z4.getInstance();if(A===null||A===void 0)return A;if(Array.isArray(A))return Promise.all(A.map((x)=>Nf0(x,{...Q,urlGenerator:w})));if(typeof A!=="object")return A;let B={},$=Object.entries(A),f=await Promise.all($.map(([,x])=>Nf0(x,{...Q,urlGenerator:w})));for(let x=0;x<$.length;x++){let v=$[x];if(v)B[v[0]]=f[x]}let Y=DXw.safeParse(A);if(!Y.success)return B;let X=Y.data,H=X.entityType,W=X.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":eW(H),q=`/${G}`,V=G.charAt(0).toUpperCase()+G.slice(1),J=vu(X),b=await qXw(J,Q),L=V20(X)??J,N=await VXw(L,Q);return{...B,...X,url:w.generateUrl(H,W),typeLabel:U,listUrl:q,listLabel:V,...b,...N&&{ogImageUrl:N}}}async function qXw(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 B=await po1(A,Q.pipelineContext.services.entityService);if(!B)return{};return{coverImageUrl:B.url,...B.width&&{coverImageWidth:B.width},...B.height&&{coverImageHeight:B.height}}}async function VXw(A,Q){if(!A)return;let w=Q.imageBuildService?.get(A);if(w)return lo1(w.src,Q.siteUrl);let B=await po1(A,Q.pipelineContext.services.entityService);if(!B)return;if(B.url.startsWith("data:"))return;return lo1(B.url,Q.siteUrl)}function lo1(A,Q){if(/^https?:\/\//i.test(A)||A.startsWith("data:"))return A;if(!Q)return A;return`${Q.replace(/\/$/,"")}/${A.replace(/^\//,"")}`}async function po1(A,Q){if(!A)return;let w=await Q.getEntity({entityType:"image",id:A}),B=zXw.safeParse(w);if(!B.success)return;return{url:B.data.content,...B.data.metadata.width&&{width:B.data.metadata.width},...B.data.metadata.height&&{height:B.data.metadata.height}}}async function io1(A,Q){let w=new Set;try{let B=A.getEntityTypes();for(let $ of B){if($==="image")continue;let f=await A.listEntities({entityType:$});for(let Y of f){let X=vu(Y);if(X)w.add(X);let H=V20(Y);if(H)w.add(H)}}}catch(B){Q.warn("Failed to collect image IDs for pre-resolution",{error:SA(B)})}return[...w]}async function do1(A,Q,w,B,$){if(!A.template)return A.content??null;let f=A.template,Y=A.dataQuery?{dataParams:A.dataQuery,fallback:A.content,publishedOnly:w,visibilityScope:B}:{savedContent:{entityType:"site-content",entityId:`${Q.id}:${A.id}`},fallback:A.content,visibilityScope:B},X=await $.pipelineContext.services.resolveTemplateContent(f,Y);if(!X)return null;return Nf0(X,{pipelineContext:$.pipelineContext,imageBuildService:$.imageBuildService,siteUrl:$.siteUrl,urlGenerator:Z4.getInstance()})}function no1(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 B=A.parsedOptions.environment==="production";return do1(w,Q,B,"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 co1(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 bXw}from"path";async function ro1(A){let Q=A.parsedOptions.workingDir??bXw(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 oo1(A){await new kf0({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 so1(A){let Q=new Lf0(A.pipelineContext.services.entityService,A.pipelineContext.logger,A.sharedImagesDir),w=await io1(A.pipelineContext.services.entityService,A.pipelineContext.logger);if(w.length>0)await Q.resolveAll(w);return Q}async function ao1(A){let Q=A.reporter?.createSub({scale:{start:85,end:95}});await A.staticSiteBuilder.build(A.buildContext,(w)=>{Q?.report(w).catch(()=>{})})}function to1(A){return{success:!0,outputDir:A.outputDir,filesGenerated:A.routesBuilt+1,routesBuilt:A.routesBuilt,...A.warnings.length>0&&{warnings:A.warnings}}}function eo1(A){return{success:!1,outputDir:A.outputDir,filesGenerated:0,routesBuilt:0,errors:[A.errorMessage]}}async function As1(A){let Q=mo1.parse(A.buildOptions),w=Zf.from(A.progress),B=[];try{await w?.report({message:"Starting site build",progress:0,total:100}),await w?.report({message:"Generating dynamic routes",progress:10,total:100}),await oo1({pipelineContext:A.pipelineContext,publishedOnly:Q.environment==="production"});let $=await ro1({logger:A.pipelineContext.logger,parsedOptions:Q,staticSiteBuilderFactory:A.staticSiteBuilderFactory}),f=uo1(A.pipelineContext.routeRegistry);B.push(...f.warnings);let{routes:Y}=f;await w?.report({message:`Building ${Y.length} routes`,progress:20,total:100}),await w?.report({message:"Resolving images",progress:25,total:100});let X=await so1({pipelineContext:A.pipelineContext,sharedImagesDir:Q.sharedImagesDir}),H=no1({routes:Y,parsedOptions:Q,buildOptions:A.buildOptions,pipelineContext:A.pipelineContext,imageBuildService:X,siteMetadata:Q.siteConfig});return await ao1({staticSiteBuilder:$,buildContext:H,reporter:w}),await w?.report({message:"Site build complete",progress:100,total:100}),to1({outputDir:Q.outputDir,routesBuilt:Y.length,warnings:B})}catch($){let f=Error("Site build process failed");return A.pipelineContext.logger.error("Site build failed",{error:f,originalError:$}),eo1({outputDir:Q.outputDir,errorMessage:f.message})}}class xZ{static instance=null;static defaultStaticSiteBuilderFactory=Sn0;pipelineContext;staticSiteBuilderFactory;static setDefaultStaticSiteBuilderFactory(A){xZ.defaultStaticSiteBuilderFactory=A}static getInstance(A,Q,w,B,$=void 0){return xZ.instance??=new xZ(A,xZ.defaultStaticSiteBuilderFactory,Q,w,B,$),xZ.instance}static resetInstance(){xZ.instance=null}static createFresh(A,Q,w,B,$,f=void 0){return new xZ(A,$??xZ.defaultStaticSiteBuilderFactory,Q,w,B,f)}constructor(A,Q,w,B,$,f){this.pipelineContext={logger:A,services:w,routeRegistry:B,profileService:$,entityDisplay:f},this.staticSiteBuilderFactory=Q,Z4.getInstance().configure(f)}async build(A,Q){return As1({buildOptions:A,progress:Q,pipelineContext:this.pipelineContext,staticSiteBuilderFactory:this.staticSiteBuilderFactory})}}class mn0{config;context;pluginId;logger;debounces=new Map;unsubscribeFunctions=[];constructor(A,Q,w,B){this.config=A,this.context=Q,this.pluginId=w,this.logger=B}requestBuild(A){let Q=A??(this.config.previewOutputDir?"preview":"production"),w=this.debounces.get(Q);if(!w)w=new $l0(()=>{this.enqueueBuild(Q)},this.config.rebuildDebounce),this.debounces.set(Q,w);w.trigger()}setupAutoRebuild(){let A=new Set(["note"]),Q=async(B)=>{let{entityType:$}=B.payload;if(!A.has($))this.logger.debug(`Entity type ${$} will trigger rebuild`),this.requestBuild();return{success:!0}},w=["entity:created","entity:updated","entity:deleted"];for(let B of w)this.unsubscribeFunctions.push(this.context.messaging.subscribe(B,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})}}}e8();function JXw(A,Q){return A.map((w)=>({...w,template:w.template.includes(":")?w.template:`${Q}:${w.template}`}))}function jf0(A,Q,w){for(let B of A)w.register({...B,pluginId:Q,sections:B.sections?JXw(B.sections,Q):[]})}function Qs1(A,Q,w){A.messaging.subscribe("plugin:site-builder:route:register",async(B)=>{try{let $=Xe.parse(B.payload),{routes:f,pluginId:Y}=$;return jf0(f,Y,Q),{success:!0}}catch($){return w.error("Failed to register routes",{error:$}),{success:!1,error:"Failed to register routes"}}}),A.messaging.subscribe("plugin:site-builder:route:unregister",async(B)=>{try{let $=Ze.parse(B.payload),{paths:f,pluginId:Y}=$;if(f)for(let X of f)Q.unregister(X);else if(Y)Q.unregisterByPlugin(Y);return{success:!0}}catch($){return w.error("Failed to unregister routes",{error:$}),{success:!1,error:"Failed to unregister routes"}}}),A.messaging.subscribe("plugin:site-builder:route:list",async(B)=>{try{let $=He.parse(B.payload);return{success:!0,data:{routes:Q.list($.pluginId?$:void 0)}}}catch($){return w.error("Failed to list routes",{error:$}),{success:!1,error:"Failed to list routes"}}}),A.messaging.subscribe("plugin:site-builder:route:get",async(B)=>{try{let $=We.parse(B.payload);return{success:!0,data:{route:Q.get($.path)}}}catch($){return w.error("Failed to get route",{error:$}),{success:!1,error:"Failed to get route"}}}),A.messaging.subscribe("site-builder:routes:list",async()=>{return{success:!0,data:Q.list()}})}import{promises as ws1}from"fs";import{join as Bs1}from"path";async function IXw(A,Q,w){let B=A.siteConfig.url??"https://example.com",$=Q.list(),f=En0(B,A.environment);await ws1.writeFile(Bs1(A.outputDir,"robots.txt"),f,"utf-8"),w.info(`Generated robots.txt for ${A.environment} environment`);let Y=Tn0($,B);await ws1.writeFile(Bs1(A.outputDir,"sitemap.xml"),Y,"utf-8"),w.info(`Generated sitemap.xml with ${$.length} URLs`)}function $s1(A){let{context:Q,routeRegistry:w,logger:B}=A;Q.messaging.subscribe("site:build:completed",async($)=>{try{let f=$.payload;return B.info(`Received site:build:completed event for ${f.environment} environment - generating SEO files`),await IXw(f,w,B),{success:!0}}catch(f){return B.error("Failed to generate SEO files",f),{success:!1}}})}wA();_0();var fs1=Z.object({environment:Z.enum(["preview","production"]).optional(),outputDir:Z.string(),workingDir:Z.string().optional(),enableContentGeneration:Z.boolean().optional(),siteConfig:rg.optional()});e8();e8();_0();var FXw=Z.object({heading:Z.string(),buttonText:Z.string(),buttonLink:Z.string()}),LXw=Z.object({blurb:Z.string().optional()}),Ys1=Z.object({title:Z.string(),description:Z.string(),url:Z.string().optional(),copyright:Z.string().optional(),logo:Z.boolean().optional(),themeMode:Z.enum(["light","dark"]).optional(),analyticsScript:Z.string().optional(),cta:FXw.optional(),sections:Z.record(Z.string(),LXw).optional()});async function Mr(A,Q){try{let w=await A({type:dT,payload:void 0});if("success"in w&&w.success&&w.data){let B=Ys1.safeParse(w.data);if(B.success)return Ys1.parse({...Q,...B.data})}}catch{}return Q}class un0 extends tw{sendMessage;cfg;constructor(A,Q,w){super(A,{schema:fs1,jobTypeName:"site-build"});this.sendMessage=Q,this.cfg=w}async process(A,Q,w){let B=A.environment??"preview",$=A.enableContentGeneration??!1;try{this.logger.debug("Starting site build job",{jobId:Q,environment:B,outputDir:A.outputDir}),await w.report({progress:0,total:100,message:`Starting site build for ${B} environment`});let f=w.createSub({scale:{start:10,end:90}}),Y=await Mr(this.sendMessage,A.siteConfig??this.cfg.defaultSiteConfig),X=await this.cfg.siteBuilder.build({outputDir:A.outputDir,workingDir:A.workingDir,sharedImagesDir:this.cfg.sharedImagesDir,enableContentGeneration:$,environment:B,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}},f.toCallback());if(await w.report({progress:100,total:100,message:`Site build completed: ${X.routesBuilt} routes built`}),this.logger.debug("Site build job completed",{jobId:Q,environment:B,routesBuilt:X.routesBuilt,success:X.success}),X.success){this.logger.info(`Emitting site:build:completed event for ${B} environment`);let H=B==="preview"?this.cfg.previewUrl??this.cfg.siteUrl:this.cfg.siteUrl;await this.sendMessage({type:"site:build:completed",payload:{outputDir:A.outputDir,environment:B,routesBuilt:X.routesBuilt,siteConfig:{...Y,url:H},generateEntityUrl:(W,K)=>Z4.getInstance().generateUrl(W,K)},broadcast:!0})}return{success:X.success,routesBuilt:X.routesBuilt,outputDir:A.outputDir,environment:B,...X.errors&&{errors:X.errors},...X.warnings&&{warnings:X.warnings}}}catch(f){throw this.logger.error("Site build job failed",f),f}}summarizeDataForLog(A){return{environment:A.environment,outputDir:A.outputDir}}}_0();e8();var kXw=Z.object({slot:Z.enum(Yb).optional().default("primary"),limit:Z.number().optional()});class cn0{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 B=kXw.parse(A??{});this.logger.debug("NavigationDataSource fetch called",{params:B});let $=this.routeRegistry.getNavigationItems(B.slot),f=B.limit?$.slice(0,B.limit):$,Y=f.map((H)=>({label:H.label,href:H.href}));this.logger.debug("NavigationDataSource returning",{slot:B.slot,itemCount:f.length,items:Y});let X={navigation:Y};return Q.parse(X)}}e8();wA();_0();var _Xw=Z.object({environment:Z.enum(["preview","production"]).optional().describe("Build environment (defaults to production, or preview if configured)")});function Xs1(A,Q){return[M6(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'.",_Xw,async(w)=>{return Q(w.environment),{success:!0,message:`Site build requested${w.environment?` for ${w.environment}`:""} (debounced)`,data:{}}},{sideEffects:"external",cli:{name:"build"}})]}_0();e8();var NXw=Z.object({id:Z.string(),template:Z.string(),content:Z.unknown().optional(),dataQuery:Z.looseObject({entityType:Z.string().optional(),template:Z.string().optional(),query:Z.looseObject({id:Z.string().optional(),limit:Z.number().optional(),offset:Z.number().optional()}).optional()}).optional(),order:Z.number().optional()}),jXw=Z.object({show:Z.boolean().default(!1),label:Z.string().optional(),slot:Z.enum(Yb).default("primary"),priority:Z.number().min(0).max(100).default(50)}).optional(),PXw=Z.object({id:Z.string(),path:Z.string(),title:Z.string().default(""),pageLabel:Z.string().optional(),description:Z.string().default(""),sections:Z.array(NXw).default([]),layout:Z.string().default("default"),fullscreen:Z.boolean().optional(),pluginId:Z.string().optional(),sourceEntityType:Z.string().optional(),external:Z.boolean().optional(),navigation:jXw}),Zs1=Z.object({previewOutputDir:Z.string().describe("Output directory for preview builds").default("./dist/site-preview"),productionOutputDir:Z.string().describe("Output directory for production builds").default("./dist/site-production"),sharedImagesDir:Z.string().describe("Shared directory for optimized images (used by both preview and production)").default("./dist/images"),workingDir:Z.string().optional().describe("Working directory for builds").default("./.preact-work"),siteInfo:rg.default({title:"Brain",description:"A knowledge management system"}),themeCSS:Z.string().describe("Custom CSS theme overrides to inject into builds").optional(),analyticsScript:Z.string().describe("Analytics tracking script to inject into page head (e.g., Cloudflare Web Analytics)").optional(),templates:Z.any().optional().describe("Template definitions to register"),routes:Z.array(PXw).optional().describe("Routes to register"),layouts:Z.record(Z.string(),Z.any()).optional().describe("Layout components (at least 'default' required)"),autoRebuild:Z.boolean().default(!0).describe("Automatically rebuild site when content changes"),rebuildDebounce:Z.number().min(100).describe("Debounce time in ms before triggering site rebuild after content changes").default(5000),entityDisplay:Z.record(Z.string(),Z.object({label:Z.string().describe("Display label for entity type (e.g., 'Essay')"),pluralName:Z.string().optional().describe("URL path segment (defaults to label.toLowerCase() + 's')"),layout:Z.string().optional().describe("Layout name for this entity type's generated routes (defaults to 'default')"),paginate:Z.boolean().optional().describe("Enable pagination for list pages"),pageSize:Z.number().optional().describe("Items per page (default: 10)"),navigation:Z.object({show:Z.boolean().optional().describe("Show in navigation"),slot:Z.enum(Yb).optional().describe("Navigation slot (primary or secondary)"),priority:Z.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:Z.record(Z.string(),Z.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 Hs1={name:"@brains/site-builder-plugin",version:"0.2.0-alpha.151",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 ln0 extends tQ{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",Hs1,{...A,layouts:Q},Zs1);this.layouts=Q}async onRegister(A){if(this.pluginContext=A,this._routeRegistry=new _f0(A.logger),this._slotRegistry=new t40,A.messaging.subscribe("plugin:site-builder:slot:register",async(w)=>{let{slotName:B,pluginId:$,render:f,priority:Y}=w.payload;return this._slotRegistry?.register(B,{pluginId:$,render:f,...Y!==void 0&&{priority:Y}}),{success:!0}}),A.messaging.subscribe("plugin:site-builder:head-script:register",async(w)=>{let{pluginId:B,script:$}=w.payload;return this.headScripts.set(B,$),{success:!0}}),A.entities.registerDataSource(new cn0(this._routeRegistry,A.logger.child("NavigationDataSource"))),this.profileService=If.getInstance(A.entityService,A.logger),Qs1(A,this._routeRegistry,this.logger),this.config.templates)A.templates.register(this.config.templates);if(this.config.routes)jf0(this.config.routes,this.id,this.routeRegistry);let Q={entityService:A.entityService,sendMessage:A.messaging.send,resolveTemplateContent:(w,B)=>A.templates.resolve(w,B),getViewTemplate:(w)=>A.views.get(w),listViewTemplateNames:()=>A.views.list().map((w)=>w.name)};if(this.siteBuilder=xZ.getInstance(A.logger.child("SiteBuilder"),Q,this.routeRegistry,this.profileService,this.config.entityDisplay),A.jobs.registerHandler("site-build",new un0(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 mn0(this.config,A,this.id,this.logger),this.config.autoRebuild)this.logger.debug("Auto-rebuild enabled"),this.rebuildManager.setupAutoRebuild();A.messaging.subscribe(nT,async()=>{let w=await this.getInstructions();if(w)A.registerInstructions(w);return{success:!0}}),$s1({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 Xs1(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 Mr(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((B)=>({id:B.id,template:B.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 Mr(A.messaging.send,this.config.siteInfo);return`## Your Site
|
|
6454
6454
|
${[`**Title:** ${w.title}`,`**Description:** ${w.description}`,A.domain&&`**Domain:** ${A.domain}`,A.siteUrl&&`**URL:** ${A.siteUrl}`].filter(Boolean).join(`
|
|
6455
6455
|
`)}
|
|
6456
6456
|
|
|
6457
6457
|
## Site Builder Actions
|
|
6458
6458
|
- When the user asks to build, rebuild, publish, or build the website/site again, call \`site-builder_build-site\` immediately.
|
|
6459
|
-
- 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(),xZ.resetInstance(),this.logger.debug("Cleaned up all event subscriptions")}}function lj(A={}){return new ln0(A)}wA();wA();_0();var pn0=Z.object({routeId:Z.string(),sectionId:Z.string()}),OXw=Z.object({routeId:Z.string(),sectionId:Z.string()}),Or=_Q.extend({entityType:Z.literal("site-content"),template:Z.string().optional(),content:Z.string(),metadata:OXw});wA();class Ws1 extends g2{constructor(){super({entityType:"site-content",purpose:"A content section bound to a route on the published site.",schema:Or,frontmatterSchema:pn0})}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 in0=new Ws1;_0();var Pf0=Z.object({routeId:Z.string().optional().describe("Optional: specific route filter"),sectionId:Z.string().optional().describe("Optional: specific section filter"),dryRun:Z.boolean().optional().default(!1).describe("Optional: preview changes without executing"),force:Z.boolean().optional().default(!1).describe("Force regeneration even if content exists")}),LoB=Z.object({jobs:Z.array(Z.object({jobId:Z.string(),routeId:Z.string(),sectionId:Z.string()})),totalSections:Z.number(),queuedSections:Z.number(),skippedSections:Z.number().optional(),batchId:Z.string().optional()});_0();var xXw=Z.looseObject({id:Z.string(),template:Z.string().optional(),content:Z.unknown().optional()}),vXw=Z.looseObject({id:Z.string(),title:Z.string().optional(),description:Z.string().optional(),sections:Z.array(xXw)}),RXw=Z.array(vXw);class dn0{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=RXw.safeParse(A.data);if(!Q.success)throw Error("Failed to parse routes from site-builder");return Q.data}async generate(A,Q,w){let B=this.context.logger.child("SiteContentOperations"),$=await this.fetchRoutes(),f=$;if(A.routeId){if(f=$.filter((K)=>K.id===A.routeId),f.length===0)throw Error(`Route not found: ${A.routeId}`)}let Y=[];for(let K of f)for(let U of K.sections){if(A.sectionId&&U.id!==A.sectionId)continue;if(U.content){B.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){B.warn("Template not found, skipping section",{routeId:K.id,sectionId:U.id,templateName:U.template});continue}if(!G.canGenerate){B.debug("Template doesn't support generation, skipping",{routeId:K.id,sectionId:U.id,templateName:U.template,capabilities:G});continue}}else{B.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})){B.debug("Content already exists, skipping",{routeId:K.id,sectionId:U.id});continue}}Y.push({route:K,section:U})}let X=Y.length;if(A.dryRun)return{jobs:[],totalSections:X,queuedSections:X,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:X,queuedSections:H.length,batchId:U}}return{jobs:[],totalSections:X,queuedSections:0,batchId:`empty-${Date.now()}`}}}class nn0{siteConfig;operations;constructor(A,Q){this.siteConfig=Q,this.operations=new dn0(A)}async generateContent(A,Q){let w=Pf0.parse(A);return this.operations.generate(w,this.siteConfig,Q)}}e8();_0();var hXw=Z.object({namespace:Z.string(),sections:Z.record(Z.string(),Z.any())}),Ks1=Z.custom((A)=>hXw.safeParse(A).success),rn0=Z.object({definitions:Z.union([Ks1,Z.array(Ks1)]).optional()});wA();function Us1(A,Q){return[M6(Q,"generate","Generate content for all routes, a specific route, or a specific section",Pf0,async(w,B)=>{let $=A();if(!$)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 f={rootJobId:`generate-${Date.now()}`,progressToken:B.progressToken,pluginId:Q,operationType:"content_operations",interfaceType:B.interfaceType,channelId:B.channelId},Y=await $.generateContent(w,f);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 Gs1={name:"@brains/site-content",version:"0.2.0-alpha.150",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:"^6.0.3"},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 on0 extends tQ{siteContentService;constructor(A={}){super("site-content",Gs1,A,rn0)}async onRegister(A){A.entities.register("site-content",Or,in0);for(let Q of KJ(this.config.definitions))A.templates.register(zb(Q),Q.namespace);this.siteContentService=new nn0(A)}async getTools(){return Us1(()=>this.siteContentService,this.id)}}function pj(A={}){return new on0(A)}wA();e8();wA();_0();e8();var gXw=Z.object({}),yXw=Z.object({}),xr=_Q.extend({id:Z.literal("site-info"),entityType:Z.literal("site-info"),metadata:yXw});var og=Qq0.omit({url:!0,analyticsScript:!0});wA();_0();var EXw=Z.record(Z.string(),Z.unknown());class lD extends g2{constructor(){super({entityType:"site-info",purpose:"Singleton configuration describing the published site.",schema:xr,frontmatterSchema:og,isSingleton:!0,hasBody:!1})}createSiteInfoContent(A){let Q=og.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("",EXw.parse(Q))}}class pD{static instance=null;logger;entityService;adapter;defaultSiteInfo;static getDefaultSiteInfo(){return{title:"Brain",description:"A knowledge management system"}}static getInstance(A,Q,w){return pD.instance??=new pD(A,Q,w),pD.instance}static resetInstance(){pD.instance=null}static createFresh(A,Q,w){return new pD(A,Q,w)}constructor(A,Q,w){this.entityService=A,this.logger=Q.child("SiteInfoService"),this.adapter=new lD;let B=pD.getDefaultSiteInfo();this.defaultSiteInfo={...B,...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}}_0();var TXw=new lD,SXw=Z.looseObject({platform:Z.string(),url:Z.string(),label:Z.string().optional()}).transform((A)=>({platform:A.platform,url:A.url,...A.label!==void 0?{label:A.label}:{}})),mXw=Z.looseObject({socialLinks:Z.array(SXw).optional()});class Mf0{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:B}=w,$;try{let X=await B.getEntity({entityType:"site-info",id:"site-info"});$=X?TXw.parseSiteInfoBody(X.content):{title:"Brain",description:"A knowledge management system"}}catch{$={title:"Brain",description:"A knowledge management system"}}let f;try{let X=await B.getEntity({entityType:"anchor-profile",id:"anchor-profile"});if(X){let H=mXw.safeParse(X.metadata);f=H.success?H.data.socialLinks:void 0}}catch{}let Y={...$,socialLinks:f,copyright:$.copyright??"Powered by Rizom"};return this.logger.debug("SiteInfoDataSource returning",{title:Y.title,hasSocialLinks:!!Y.socialLinks}),Q.parse(Y)}}var Ds1={name:"@brains/site-info",version:"0.2.0-alpha.150",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:"^6.0.3"},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 cXw=new lD,lXw="site-info";class sn0 extends rQ{entityType=lXw;schema=xr;adapter=cXw;defaultSiteInfo;constructor(A){super("site-info",Ds1,{},k7);this.defaultSiteInfo=A?.siteInfo??{}}getEntityTypeConfig(){return{embeddable:!1}}getDataSources(){return[new Mf0(this.logger.child("SiteInfoDataSource"))]}async onRegister(A){let Q=pD.createFresh(A.entityService,this.logger,this.defaultSiteInfo);A.messaging.subscribe(dT,async()=>{return{success:!0,data:await Q.getSiteInfo()}}),A.messaging.subscribe("entity:updated",async(w)=>{if(w.payload.entityType==="site-info"){let $=await Q.getSiteInfo();await A.messaging.send({type:nT,payload:$,broadcast:!0})}return{success:!0}}),A.messaging.subscribe("sync:initial:completed",async()=>{return await Q.initialize(),{success:!0}})}}function ij(A){return new sn0(A)}var pXw=new lD;async function vr(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 pXw.parseSiteInfoBody(w.content)}function zs1(A,Q){let w=A.metadata.publishedAt??A.created,B=Q.metadata.publishedAt??Q.created;return new Date(B).getTime()-new Date(w).getTime()}async function Of0(A,Q){return(await A.listEntities({entityType:Q.entityType,options:{limit:20}})).sort(zs1).slice(0,Q.count).map(Q.parse)}function an0(A){if(!A)throw Error("CTA not configured in site-info");return A}_0();var qs1=Z.object({label:Z.string(),href:Z.string(),priority:Z.number()}),iXw=Z.object({primary:Z.array(qs1),secondary:Z.array(qs1)}),dXw=Z.object({platform:Z.enum(["github","instagram","linkedin","email","website"]).describe("Social media platform"),url:Z.string().describe("Profile or contact URL"),label:Z.string().optional().describe("Optional display label")}),nXw=og.extend({navigation:iXw,copyright:Z.string(),socialLinks:Z.array(dXw).optional().describe("Social media links from profile entity")});wA();kW();ag();_0();var tn0=Z.object({defaultPrompt:Z.string().default("Write a blog post about my recent work and insights"),paginate:Z.boolean().default(!0),pageSize:Z.number().default(10)});wA();y6();U2();_0();var tXw=Z.object({prompt:Z.string().optional(),title:Z.string().optional(),content:Z.string().optional(),excerpt:Z.string().optional(),coverImageId:Z.string().optional(),seriesName:Z.string().optional(),seriesIndex:Z.number().optional(),skipAi:Z.boolean().optional()}),tsB=LX.extend({title:Z.string().optional(),slug:Z.string().optional()});class en0 extends q4{constructor(A,Q){super(A,Q,{schema:tXw,jobTypeName:"blog-generation",entityType:"post"})}async generate(A,Q){let{prompt:w,coverImageId:B,seriesName:$,seriesIndex:f,skipAi:Y}=A,{title:X,content:H,excerpt:W}=A;if(Y){if(!X)this.failEarly("Title is required when skipAi is true");H=H??`## Introduction
|
|
6459
|
+
- 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(),xZ.resetInstance(),this.logger.debug("Cleaned up all event subscriptions")}}function lj(A={}){return new ln0(A)}wA();wA();_0();var pn0=Z.object({routeId:Z.string(),sectionId:Z.string()}),OXw=Z.object({routeId:Z.string(),sectionId:Z.string()}),Or=_Q.extend({entityType:Z.literal("site-content"),template:Z.string().optional(),content:Z.string(),metadata:OXw});wA();class Ws1 extends g2{constructor(){super({entityType:"site-content",purpose:"A content section bound to a route on the published site.",schema:Or,frontmatterSchema:pn0})}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 in0=new Ws1;_0();var Pf0=Z.object({routeId:Z.string().optional().describe("Optional: specific route filter"),sectionId:Z.string().optional().describe("Optional: specific section filter"),dryRun:Z.boolean().optional().default(!1).describe("Optional: preview changes without executing"),force:Z.boolean().optional().default(!1).describe("Force regeneration even if content exists")}),LoB=Z.object({jobs:Z.array(Z.object({jobId:Z.string(),routeId:Z.string(),sectionId:Z.string()})),totalSections:Z.number(),queuedSections:Z.number(),skippedSections:Z.number().optional(),batchId:Z.string().optional()});_0();var xXw=Z.looseObject({id:Z.string(),template:Z.string().optional(),content:Z.unknown().optional()}),vXw=Z.looseObject({id:Z.string(),title:Z.string().optional(),description:Z.string().optional(),sections:Z.array(xXw)}),RXw=Z.array(vXw);class dn0{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=RXw.safeParse(A.data);if(!Q.success)throw Error("Failed to parse routes from site-builder");return Q.data}async generate(A,Q,w){let B=this.context.logger.child("SiteContentOperations"),$=await this.fetchRoutes(),f=$;if(A.routeId){if(f=$.filter((K)=>K.id===A.routeId),f.length===0)throw Error(`Route not found: ${A.routeId}`)}let Y=[];for(let K of f)for(let U of K.sections){if(A.sectionId&&U.id!==A.sectionId)continue;if(U.content){B.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){B.warn("Template not found, skipping section",{routeId:K.id,sectionId:U.id,templateName:U.template});continue}if(!G.canGenerate){B.debug("Template doesn't support generation, skipping",{routeId:K.id,sectionId:U.id,templateName:U.template,capabilities:G});continue}}else{B.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})){B.debug("Content already exists, skipping",{routeId:K.id,sectionId:U.id});continue}}Y.push({route:K,section:U})}let X=Y.length;if(A.dryRun)return{jobs:[],totalSections:X,queuedSections:X,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:X,queuedSections:H.length,batchId:U}}return{jobs:[],totalSections:X,queuedSections:0,batchId:`empty-${Date.now()}`}}}class nn0{siteConfig;operations;constructor(A,Q){this.siteConfig=Q,this.operations=new dn0(A)}async generateContent(A,Q){let w=Pf0.parse(A);return this.operations.generate(w,this.siteConfig,Q)}}e8();_0();var hXw=Z.object({namespace:Z.string(),sections:Z.record(Z.string(),Z.any())}),Ks1=Z.custom((A)=>hXw.safeParse(A).success),rn0=Z.object({definitions:Z.union([Ks1,Z.array(Ks1)]).optional()});wA();function Us1(A,Q){return[M6(Q,"generate","Generate content for all routes, a specific route, or a specific section",Pf0,async(w,B)=>{let $=A();if(!$)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 f={rootJobId:`generate-${Date.now()}`,progressToken:B.progressToken,pluginId:Q,operationType:"content_operations",interfaceType:B.interfaceType,channelId:B.channelId},Y=await $.generateContent(w,f);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 Gs1={name:"@brains/site-content",version:"0.2.0-alpha.151",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 on0 extends tQ{siteContentService;constructor(A={}){super("site-content",Gs1,A,rn0)}async onRegister(A){A.entities.register("site-content",Or,in0);for(let Q of KJ(this.config.definitions))A.templates.register(zb(Q),Q.namespace);this.siteContentService=new nn0(A)}async getTools(){return Us1(()=>this.siteContentService,this.id)}}function pj(A={}){return new on0(A)}wA();e8();wA();_0();e8();var gXw=Z.object({}),yXw=Z.object({}),xr=_Q.extend({id:Z.literal("site-info"),entityType:Z.literal("site-info"),metadata:yXw});var og=Qq0.omit({url:!0,analyticsScript:!0});wA();_0();var EXw=Z.record(Z.string(),Z.unknown());class lD extends g2{constructor(){super({entityType:"site-info",purpose:"Singleton configuration describing the published site.",schema:xr,frontmatterSchema:og,isSingleton:!0,hasBody:!1})}createSiteInfoContent(A){let Q=og.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("",EXw.parse(Q))}}class pD{static instance=null;logger;entityService;adapter;defaultSiteInfo;static getDefaultSiteInfo(){return{title:"Brain",description:"A knowledge management system"}}static getInstance(A,Q,w){return pD.instance??=new pD(A,Q,w),pD.instance}static resetInstance(){pD.instance=null}static createFresh(A,Q,w){return new pD(A,Q,w)}constructor(A,Q,w){this.entityService=A,this.logger=Q.child("SiteInfoService"),this.adapter=new lD;let B=pD.getDefaultSiteInfo();this.defaultSiteInfo={...B,...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}}_0();var TXw=new lD,SXw=Z.looseObject({platform:Z.string(),url:Z.string(),label:Z.string().optional()}).transform((A)=>({platform:A.platform,url:A.url,...A.label!==void 0?{label:A.label}:{}})),mXw=Z.looseObject({socialLinks:Z.array(SXw).optional()});class Mf0{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:B}=w,$;try{let X=await B.getEntity({entityType:"site-info",id:"site-info"});$=X?TXw.parseSiteInfoBody(X.content):{title:"Brain",description:"A knowledge management system"}}catch{$={title:"Brain",description:"A knowledge management system"}}let f;try{let X=await B.getEntity({entityType:"anchor-profile",id:"anchor-profile"});if(X){let H=mXw.safeParse(X.metadata);f=H.success?H.data.socialLinks:void 0}}catch{}let Y={...$,socialLinks:f,copyright:$.copyright??"Powered by Rizom"};return this.logger.debug("SiteInfoDataSource returning",{title:Y.title,hasSocialLinks:!!Y.socialLinks}),Q.parse(Y)}}var Ds1={name:"@brains/site-info",version:"0.2.0-alpha.151",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 cXw=new lD,lXw="site-info";class sn0 extends rQ{entityType=lXw;schema=xr;adapter=cXw;defaultSiteInfo;constructor(A){super("site-info",Ds1,{},k7);this.defaultSiteInfo=A?.siteInfo??{}}getEntityTypeConfig(){return{embeddable:!1}}getDataSources(){return[new Mf0(this.logger.child("SiteInfoDataSource"))]}async onRegister(A){let Q=pD.createFresh(A.entityService,this.logger,this.defaultSiteInfo);A.messaging.subscribe(dT,async()=>{return{success:!0,data:await Q.getSiteInfo()}}),A.messaging.subscribe("entity:updated",async(w)=>{if(w.payload.entityType==="site-info"){let $=await Q.getSiteInfo();await A.messaging.send({type:nT,payload:$,broadcast:!0})}return{success:!0}}),A.messaging.subscribe("sync:initial:completed",async()=>{return await Q.initialize(),{success:!0}})}}function ij(A){return new sn0(A)}var pXw=new lD;async function vr(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 pXw.parseSiteInfoBody(w.content)}function zs1(A,Q){let w=A.metadata.publishedAt??A.created,B=Q.metadata.publishedAt??Q.created;return new Date(B).getTime()-new Date(w).getTime()}async function Of0(A,Q){return(await A.listEntities({entityType:Q.entityType,options:{limit:20}})).sort(zs1).slice(0,Q.count).map(Q.parse)}function an0(A){if(!A)throw Error("CTA not configured in site-info");return A}_0();var qs1=Z.object({label:Z.string(),href:Z.string(),priority:Z.number()}),iXw=Z.object({primary:Z.array(qs1),secondary:Z.array(qs1)}),dXw=Z.object({platform:Z.enum(["github","instagram","linkedin","email","website"]).describe("Social media platform"),url:Z.string().describe("Profile or contact URL"),label:Z.string().optional().describe("Optional display label")}),nXw=og.extend({navigation:iXw,copyright:Z.string(),socialLinks:Z.array(dXw).optional().describe("Social media links from profile entity")});wA();kW();ag();_0();var tn0=Z.object({defaultPrompt:Z.string().default("Write a blog post about my recent work and insights"),paginate:Z.boolean().default(!0),pageSize:Z.number().default(10)});wA();y6();U2();_0();var tXw=Z.object({prompt:Z.string().optional(),title:Z.string().optional(),content:Z.string().optional(),excerpt:Z.string().optional(),coverImageId:Z.string().optional(),seriesName:Z.string().optional(),seriesIndex:Z.number().optional(),skipAi:Z.boolean().optional()}),tsB=LX.extend({title:Z.string().optional(),slug:Z.string().optional()});class en0 extends q4{constructor(A,Q){super(A,Q,{schema:tXw,jobTypeName:"blog-generation",entityType:"post"})}async generate(A,Q){let{prompt:w,coverImageId:B,seriesName:$,seriesIndex:f,skipAi:Y}=A,{title:X,content:H,excerpt:W}=A;if(Y){if(!X)this.failEarly("Title is required when skipAi is true");H=H??`## Introduction
|
|
6460
6460
|
|
|
6461
6461
|
Add your introduction here.
|
|
6462
6462
|
|
|
@@ -6676,7 +6676,7 @@ ${w.content}`,templateName:"blog:excerpt"})})}wA();ag();kW();function LZw(A){let
|
|
|
6676
6676
|
letter-spacing: 0.02em;
|
|
6677
6677
|
}
|
|
6678
6678
|
.printable-footer a { color: inherit; text-decoration: none; overflow-wrap: anywhere; }
|
|
6679
|
-
`}},void 0,!1,void 0,this),l7("header",{className:"printable-hero",children:[l7("div",{className:"printable-masthead",children:Q.brandLabel&&l7("p",{className:"printable-kicker",children:Q.brandLabel},void 0,!1,void 0,this)},void 0,!1,void 0,this),l7("div",{children:[l7("h1",{className:"printable-title",children:Q.title},void 0,!1,void 0,this),Q.excerpt&&l7("p",{className:"printable-excerpt",children:Q.excerpt},void 0,!1,void 0,this),l7("div",{className:"printable-meta",children:[Q.author&&l7("span",{children:["By ",Q.author]},void 0,!0,void 0,this),w&&l7("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&&l7("figure",{className:"printable-cover-wrap",children:l7("img",{className:"printable-cover",src:Q.coverImageUrl,alt:""},void 0,!1,void 0,this)},void 0,!1,void 0,this),l7(F9,{markdown:Q.body,className:"printable-body"},void 0,!1,void 0,this),(Boolean(Q.canonicalUrl)||Boolean(Q.brandLabel))&&l7("footer",{className:"printable-footer",children:[l7("span",{children:Q.brandLabel??"Printable PDF"},void 0,!1,void 0,this),Q.canonicalUrl&&l7("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 $Hw=26214400,fHw=60000;class Wr0{metadata={outputEntityType:"document"};context;renderPdf;constructor(A,Q={}){this.context=A,this.renderPdf=Q.renderPdf??kU}async resolve(A){if(A.sourceEntityType!=="post"||A.attachmentType!==hf0)return;let Q=await this.context.entityService.getEntity({entityType:"post",id:A.sourceEntityId});if(!Q)return;let w=YHw(Q,{brandLabel:this.resolveBrandLabel(),coverImageUrl:await this.resolveCoverImageUrl(Q)}),B=await AHw(BHw(wHw(),"brain-blog-printable-"));try{let $=await RZ({outputDir:B,mediaPath:`/_media/printable/post/${Q.id}`,template:Es1,format:"pdf",content:w,siteConfig:{title:w.title,themeMode:"light"},themeCSS:this.context.themeCSS}),f=await hZ({rootDir:B});try{return{type:"document",data:await this.renderPdf(f.urlFor($.urlPath),{maxBytes:$Hw,timeoutMs:fHw,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${XHw(Q)}-printable.pdf`}}finally{await f.close()}}finally{await QHw(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.trim();return Q.length>0?Q:void 0}async resolveCoverImageUrl(A){let{frontmatter:Q}=P6(A.content),w=K$.parse(Q);if(!w.coverImageId)return;let B=await this.context.entityService.getEntity({entityType:"image",id:w.coverImageId});return B?.content.startsWith("data:image/")?B.content:void 0}}function YHw(A,Q={}){let{frontmatter:w,content:B}=P6(A.content),$=K$.parse(w);return{title:$.title,body:B,...$.excerpt?{excerpt:$.excerpt}:{},...$.author?{author:$.author}:{},...$.publishedAt?{publishedAt:$.publishedAt}:{},...$.canonicalUrl?{canonicalUrl:$.canonicalUrl}:{},...Q.coverImageUrl?{coverImageUrl:Q.coverImageUrl}:{},...Q.brandLabel?{brandLabel:Q.brandLabel}:{}}}function XHw(A){let Q=A.metadata.slug;return Q.length>0?Q:H1(A.metadata.title)}import{mkdtemp as UHw,rm as GHw}from"fs/promises";import{tmpdir as DHw}from"os";import{join as zHw}from"path";u9();U2();kW();_0();import{jsxDEV as KHw}from"preact/jsx-dev-runtime";var Er="og-image",ZHw="blog:og-image",Ts1=Z.object({title:Z.string().min(1),excerpt:Z.string().optional(),author:Z.string().optional(),publishedAt:Z.string().optional(),brandLabel:Z.string().optional(),coverImageUrl:Z.string().optional()}),Ss1={name:ZHw,pluginId:"blog",schema:Ts1,renderers:{image:WHw}};function HHw(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 WHw(A){let Q=Ts1.parse(A);return KHw(uq,{brandLabel:Q.brandLabel??Q.title,eyebrow:"Journal",title:Q.title,subtitle:Q.excerpt,meta:[Q.author],tag:HHw(Q.publishedAt)},void 0,!1,void 0,this)}var qHw={width:1200,height:630},VHw=60000;class Kr0{metadata={outputEntityType:"image",targetField:"ogImageId"};context;screenshotPng;constructor(A,Q={}){this.context=A,this.screenshotPng=Q.screenshotPng??yr}async resolve(A){if(A.sourceEntityType!=="post"||A.attachmentType!==Er)return;let Q=await this.context.entityService.getEntity({entityType:"post",id:A.sourceEntityId});if(!Q)return;let w=bHw(Q,{brandLabel:this.resolveBrandLabel(),coverImageUrl:await this.resolveCoverImageUrl(Q)}),B=await UHw(zHw(DHw(),"brain-blog-og-image-"));try{let $=await RZ({outputDir:B,mediaPath:`/_media/og/post/${Q.id}`,template:Ss1,format:"image",content:w,siteConfig:{title:w.title,themeMode:"light"},themeCSS:this.context.themeCSS}),f=await hZ({rootDir:B});try{return{type:"image",data:await this.screenshotPng(f.urlFor($.urlPath),qHw,{timeoutMs:VHw,fullPage:!1,omitBackground:!1}),mimeType:"image/png",filename:`${JHw(Q)}-og.png`}}finally{await f.close()}}finally{await GHw(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.trim();return Q.length>0?Q:void 0}async resolveCoverImageUrl(A){let{frontmatter:Q}=P6(A.content),w=K$.parse(Q);if(!w.coverImageId)return;let B=await this.context.entityService.getEntity({entityType:"image",id:w.coverImageId});return B?.content.startsWith("data:image/")?B.content:void 0}}function bHw(A,Q={}){let{frontmatter:w}=P6(A.content),B=K$.parse(w);return{title:B.title,...B.excerpt?{excerpt:B.excerpt}:{},...B.author?{author:B.author}:{},...B.publishedAt?{publishedAt:B.publishedAt}:{},...Q.coverImageUrl?{coverImageUrl:Q.coverImageUrl}:{},...Q.brandLabel?{brandLabel:Q.brandLabel}:{}}}function JHw(A){let Q=A.metadata.slug;return Q.length>0?Q:H1(A.metadata.title)}var ms1={name:"@brains/blog",version:"0.2.0-alpha.150",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:"^6.0.3"},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 Ur0 extends rQ{entityType=BV.entityType;schema=sg;adapter=BV;unregisterAtprotoProjection;unregisterPrintableAttachmentProvider;unregisterOgImageAttachmentProvider;constructor(A={}){super("blog",ms1,A,tn0)}getEntityTypeConfig(){return{weight:2,publish:{publishStatuses:["queued","published"]}}}createGenerationHandler(A){return new en0(this.logger.child("BlogGenerationJobHandler"),A)}getTemplates(){return Ls1()}getDataSources(){return[new Qr0(this.logger.child("BlogDataSource"))]}async onRegister(A){let{RSSDataSource:Q}=await Promise.resolve().then(() => (ls1(),cs1));A.entities.registerDataSource(new Q(this.logger.child("RSSDataSource"))),ks1(A,this.logger),_s1(A,this.logger),js1(A,this.logger),Ps1(A),this.unregisterPrintableAttachmentProvider=A.attachments.register("post",hf0,new Wr0(A)),this.unregisterOgImageAttachmentProvider=A.attachments.register("post",Er,new Kr0(A)),this.deferPublishAssetRegistration(A),this.unregisterAtprotoProjection=Q5.getInstance().register($r0()),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:Er,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 Gr0(A={}){return new Ur0(A)}kW();ag();wA();_0();t8();wA();_0();var _U=Z.object({title:Z.string(),slug:Z.string(),coverImageId:Z.string().optional()}),LHw=Z.object({title:Z.string(),slug:Z.string()}),kHw=Z.object({title:Z.string(),slug:Z.string()}),qF=_Q.extend({entityType:Z.literal("series"),metadata:kHw}),Cf0=qF.extend({frontmatter:_U}),_Hw=Cf0.extend({description:Z.string().optional(),postCount:Z.number(),coverImageUrl:Z.string().optional(),coverImageWidth:Z.number().optional(),coverImageHeight:Z.number().optional()}),ps1=Z.object({description:Z.string().optional()});function rj(A){return new z6(ps1,{title:A,mappings:[{key:"description",label:"Description",type:"string"}]})}wA();class Dr0 extends g2{constructor(){super({entityType:"series",purpose:"A series grouping related posts or content under one theme.",schema:qF,frontmatterSchema:_U,supportsCoverImage:!0,bodyFormatter:rj("")})}toMarkdown(A){let Q,w={};try{Q=this.parseFrontMatter(A.content,_U).coverImageId,w=rj(A.metadata.title).parse(this.extractBody(A.content))}catch{}let B={title:A.metadata.title,slug:A.metadata.slug,...Q&&{coverImageId:Q}},f=rj(A.metadata.title).format(w);return this.buildMarkdown(f,B)}fromMarkdown(A){let Q=this.parseFrontMatter(A,_U);return{content:A,entityType:"series",metadata:{title:Q.title,slug:Q.slug}}}parseBody(A){try{let Q=this.parseFrontMatter(A,_U);return rj(Q.title).parse(this.extractBody(A))}catch{return{}}}generateFrontMatter(){return""}}var VF=new Dr0;wA();U2();xX();_0();var NHw=Z.object({seriesName:Z.string().optional(),seriesIndex:Z.number().optional()});function gf0(A){let Q=NHw.safeParse(A);return Q.success?Q.data:{}}function oj(A){return gf0(A.metadata).seriesName}function is1(A){return gf0(A.metadata).seriesIndex}function ds1(A,Q){let w=is1(A)??Number.MAX_SAFE_INTEGER,B=is1(Q)??Number.MAX_SAFE_INTEGER;return w-B}class zr0{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(($)=>[$.id,$])),B=new Set;for(let $ of A){let f=H1($);B.add(f);let Y=w.get(f),X=Y?.content??this.createSeriesContent($),H=B6(X);if(Y?.contentHash===H)continue;let W={id:f,entityType:"series",content:X,contentHash:H,created:Y?.created??new Date().toISOString(),updated:new Date().toISOString(),visibility:"public",metadata:{title:$,slug:H1($)}};await this.entityService.upsertEntity({entity:W}),this.logger.debug(`Upserted series: ${$}`)}for(let $ of Q)if(!B.has($.id))await this.entityService.deleteEntity({entityType:"series",id:$.id}),this.logger.debug(`Deleted orphaned series: ${$.id}`)}async handleEntityChange(A,Q){let w=oj(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=H1(A);if(await this.entityService.getEntity({entityType:"series",id:Q}))return;let B=this.createSeriesContent(A),$={id:Q,entityType:"series",content:B,contentHash:B6(B),created:new Date().toISOString(),updated:new Date().toISOString(),visibility:"public",metadata:{title:A,slug:H1(A)}};await this.entityService.upsertEntity({entity:$}),this.logger.debug(`Created series: ${A}`)}async cleanupOrphanedSeries(A){let Q=H1(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 B=await this.entityService.listEntities({entityType:w});for(let $ of B){let f=oj($);if(f)A.add(f)}}return A}createSeriesContent(A){let Q={title:A,slug:H1(A)};return V8("",Q)}}wA();_0();var jHw=Z.object({entityType:Z.literal("series"),query:Z.looseObject({id:Z.string().optional(),limit:Z.number().optional(),page:Z.number().optional(),pageSize:Z.number().optional()})}),PHw=Z.object({type:Z.enum(["list","detail"]),seriesName:Z.string().optional()});function MHw(A){let Q=PHw.safeParse(A);if(Q.success)return{type:Q.data.type,seriesName:Q.data.seriesName};let w=jHw.safeParse(A);if(w.success){let{query:B}=w.data;if(B.id)return{type:"detail",seriesSlug:B.id};return{type:"list"}}throw Error('Invalid series query format. Expected { type: "list"|"detail" } or { entityType: "series", query: { id?: string } }')}function ns1(A){let Q=n2(A.content,_U);return Cf0.parse({...A,frontmatter:Q.metadata})}class qr0{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 B=MHw(A),$=w.entityService;if(B.type==="list")return this.fetchSeriesList(Q,$);if(B.seriesName)return this.fetchSeriesDetail(B.seriesName,Q,$);if(B.seriesSlug)return this.fetchSeriesDetailBySlug(B.seriesSlug,Q,$);throw Error("Invalid series query: must specify seriesName or slug for detail")}async fetchSeriesList(A,Q){let w=await Q.listEntities({entityType:"series"}),B=await this.countEntitiesPerSeries(Q),$=w.map((f)=>{let Y=ns1(f),X=VF.parseBody(f.content);return{...Y,description:X.description,postCount:B.get(f.metadata.title)??0}});return this.logger.debug(`Found ${$.length} series entities`),A.parse({series:$})}async fetchSeriesDetail(A,Q,w,B){if(!B)B=(await w.listEntities({entityType:"series",options:{filter:{metadata:{title:A}}}}))[0];if(!B)throw Error(`Series not found: ${A}`);let $=ns1(B),f=VF.parseBody(B.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:{...$,description:f.description,postCount:Y.length},description:f.description})}async fetchSeriesDetailBySlug(A,Q,w){let $=(await w.listEntities({entityType:"series",options:{filter:{metadata:{slug:A}}}}))[0];if(!$)throw Error(`Series not found with slug: ${A}`);return this.fetchSeriesDetail($.metadata.title,Q,w,$)}async countEntitiesPerSeries(A){let Q=new Map,w=A.getEntityTypes();for(let B of w){if(B==="series")continue;let $=await A.listEntities({entityType:B});for(let f of $){let Y=oj(f);if(Y)Q.set(Y,(Q.get(Y)??0)+1)}}return Q}async getSeriesMembers(A,Q){let w=[],B=Q.getEntityTypes();for(let $ of B){if($==="series")continue;let f=await Q.listEntities({entityType:$,options:{filter:{metadata:{seriesName:A}}}});w.push(...f)}return w.sort(ds1),w}}wA();_0();xX();var OHw=Z.object({prompt:Z.string().optional(),title:Z.string().optional(),seriesId:Z.string().optional()}),xHw=Z.object({title:Z.string().optional(),excerpt:Z.string().optional()});class yf0{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 B=await this.gatherMemberSummaries(w.metadata.title);if(B.length===0)return{success:!1,error:`No members found in series: ${w.metadata.title}`};let $=A.prompt??`Series name: ${w.metadata.title}
|
|
6679
|
+
`}},void 0,!1,void 0,this),l7("header",{className:"printable-hero",children:[l7("div",{className:"printable-masthead",children:Q.brandLabel&&l7("p",{className:"printable-kicker",children:Q.brandLabel},void 0,!1,void 0,this)},void 0,!1,void 0,this),l7("div",{children:[l7("h1",{className:"printable-title",children:Q.title},void 0,!1,void 0,this),Q.excerpt&&l7("p",{className:"printable-excerpt",children:Q.excerpt},void 0,!1,void 0,this),l7("div",{className:"printable-meta",children:[Q.author&&l7("span",{children:["By ",Q.author]},void 0,!0,void 0,this),w&&l7("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&&l7("figure",{className:"printable-cover-wrap",children:l7("img",{className:"printable-cover",src:Q.coverImageUrl,alt:""},void 0,!1,void 0,this)},void 0,!1,void 0,this),l7(F9,{markdown:Q.body,className:"printable-body"},void 0,!1,void 0,this),(Boolean(Q.canonicalUrl)||Boolean(Q.brandLabel))&&l7("footer",{className:"printable-footer",children:[l7("span",{children:Q.brandLabel??"Printable PDF"},void 0,!1,void 0,this),Q.canonicalUrl&&l7("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 $Hw=26214400,fHw=60000;class Wr0{metadata={outputEntityType:"document"};context;renderPdf;constructor(A,Q={}){this.context=A,this.renderPdf=Q.renderPdf??kU}async resolve(A){if(A.sourceEntityType!=="post"||A.attachmentType!==hf0)return;let Q=await this.context.entityService.getEntity({entityType:"post",id:A.sourceEntityId});if(!Q)return;let w=YHw(Q,{brandLabel:this.resolveBrandLabel(),coverImageUrl:await this.resolveCoverImageUrl(Q)}),B=await AHw(BHw(wHw(),"brain-blog-printable-"));try{let $=await RZ({outputDir:B,mediaPath:`/_media/printable/post/${Q.id}`,template:Es1,format:"pdf",content:w,siteConfig:{title:w.title,themeMode:"light"},themeCSS:this.context.themeCSS}),f=await hZ({rootDir:B});try{return{type:"document",data:await this.renderPdf(f.urlFor($.urlPath),{maxBytes:$Hw,timeoutMs:fHw,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${XHw(Q)}-printable.pdf`}}finally{await f.close()}}finally{await QHw(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.trim();return Q.length>0?Q:void 0}async resolveCoverImageUrl(A){let{frontmatter:Q}=P6(A.content),w=K$.parse(Q);if(!w.coverImageId)return;let B=await this.context.entityService.getEntity({entityType:"image",id:w.coverImageId});return B?.content.startsWith("data:image/")?B.content:void 0}}function YHw(A,Q={}){let{frontmatter:w,content:B}=P6(A.content),$=K$.parse(w);return{title:$.title,body:B,...$.excerpt?{excerpt:$.excerpt}:{},...$.author?{author:$.author}:{},...$.publishedAt?{publishedAt:$.publishedAt}:{},...$.canonicalUrl?{canonicalUrl:$.canonicalUrl}:{},...Q.coverImageUrl?{coverImageUrl:Q.coverImageUrl}:{},...Q.brandLabel?{brandLabel:Q.brandLabel}:{}}}function XHw(A){let Q=A.metadata.slug;return Q.length>0?Q:H1(A.metadata.title)}import{mkdtemp as UHw,rm as GHw}from"fs/promises";import{tmpdir as DHw}from"os";import{join as zHw}from"path";u9();U2();kW();_0();import{jsxDEV as KHw}from"preact/jsx-dev-runtime";var Er="og-image",ZHw="blog:og-image",Ts1=Z.object({title:Z.string().min(1),excerpt:Z.string().optional(),author:Z.string().optional(),publishedAt:Z.string().optional(),brandLabel:Z.string().optional(),coverImageUrl:Z.string().optional()}),Ss1={name:ZHw,pluginId:"blog",schema:Ts1,renderers:{image:WHw}};function HHw(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 WHw(A){let Q=Ts1.parse(A);return KHw(uq,{brandLabel:Q.brandLabel??Q.title,eyebrow:"Journal",title:Q.title,subtitle:Q.excerpt,meta:[Q.author],tag:HHw(Q.publishedAt)},void 0,!1,void 0,this)}var qHw={width:1200,height:630},VHw=60000;class Kr0{metadata={outputEntityType:"image",targetField:"ogImageId"};context;screenshotPng;constructor(A,Q={}){this.context=A,this.screenshotPng=Q.screenshotPng??yr}async resolve(A){if(A.sourceEntityType!=="post"||A.attachmentType!==Er)return;let Q=await this.context.entityService.getEntity({entityType:"post",id:A.sourceEntityId});if(!Q)return;let w=bHw(Q,{brandLabel:this.resolveBrandLabel(),coverImageUrl:await this.resolveCoverImageUrl(Q)}),B=await UHw(zHw(DHw(),"brain-blog-og-image-"));try{let $=await RZ({outputDir:B,mediaPath:`/_media/og/post/${Q.id}`,template:Ss1,format:"image",content:w,siteConfig:{title:w.title,themeMode:"light"},themeCSS:this.context.themeCSS}),f=await hZ({rootDir:B});try{return{type:"image",data:await this.screenshotPng(f.urlFor($.urlPath),qHw,{timeoutMs:VHw,fullPage:!1,omitBackground:!1}),mimeType:"image/png",filename:`${JHw(Q)}-og.png`}}finally{await f.close()}}finally{await GHw(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.trim();return Q.length>0?Q:void 0}async resolveCoverImageUrl(A){let{frontmatter:Q}=P6(A.content),w=K$.parse(Q);if(!w.coverImageId)return;let B=await this.context.entityService.getEntity({entityType:"image",id:w.coverImageId});return B?.content.startsWith("data:image/")?B.content:void 0}}function bHw(A,Q={}){let{frontmatter:w}=P6(A.content),B=K$.parse(w);return{title:B.title,...B.excerpt?{excerpt:B.excerpt}:{},...B.author?{author:B.author}:{},...B.publishedAt?{publishedAt:B.publishedAt}:{},...Q.coverImageUrl?{coverImageUrl:Q.coverImageUrl}:{},...Q.brandLabel?{brandLabel:Q.brandLabel}:{}}}function JHw(A){let Q=A.metadata.slug;return Q.length>0?Q:H1(A.metadata.title)}var ms1={name:"@brains/blog",version:"0.2.0-alpha.151",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 Ur0 extends rQ{entityType=BV.entityType;schema=sg;adapter=BV;unregisterAtprotoProjection;unregisterPrintableAttachmentProvider;unregisterOgImageAttachmentProvider;constructor(A={}){super("blog",ms1,A,tn0)}getEntityTypeConfig(){return{weight:2,publish:{publishStatuses:["queued","published"]}}}createGenerationHandler(A){return new en0(this.logger.child("BlogGenerationJobHandler"),A)}getTemplates(){return Ls1()}getDataSources(){return[new Qr0(this.logger.child("BlogDataSource"))]}async onRegister(A){let{RSSDataSource:Q}=await Promise.resolve().then(() => (ls1(),cs1));A.entities.registerDataSource(new Q(this.logger.child("RSSDataSource"))),ks1(A,this.logger),_s1(A,this.logger),js1(A,this.logger),Ps1(A),this.unregisterPrintableAttachmentProvider=A.attachments.register("post",hf0,new Wr0(A)),this.unregisterOgImageAttachmentProvider=A.attachments.register("post",Er,new Kr0(A)),this.deferPublishAssetRegistration(A),this.unregisterAtprotoProjection=Q5.getInstance().register($r0()),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:Er,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 Gr0(A={}){return new Ur0(A)}kW();ag();wA();_0();t8();wA();_0();var _U=Z.object({title:Z.string(),slug:Z.string(),coverImageId:Z.string().optional()}),LHw=Z.object({title:Z.string(),slug:Z.string()}),kHw=Z.object({title:Z.string(),slug:Z.string()}),qF=_Q.extend({entityType:Z.literal("series"),metadata:kHw}),Cf0=qF.extend({frontmatter:_U}),_Hw=Cf0.extend({description:Z.string().optional(),postCount:Z.number(),coverImageUrl:Z.string().optional(),coverImageWidth:Z.number().optional(),coverImageHeight:Z.number().optional()}),ps1=Z.object({description:Z.string().optional()});function rj(A){return new z6(ps1,{title:A,mappings:[{key:"description",label:"Description",type:"string"}]})}wA();class Dr0 extends g2{constructor(){super({entityType:"series",purpose:"A series grouping related posts or content under one theme.",schema:qF,frontmatterSchema:_U,supportsCoverImage:!0,bodyFormatter:rj("")})}toMarkdown(A){let Q,w={};try{Q=this.parseFrontMatter(A.content,_U).coverImageId,w=rj(A.metadata.title).parse(this.extractBody(A.content))}catch{}let B={title:A.metadata.title,slug:A.metadata.slug,...Q&&{coverImageId:Q}},f=rj(A.metadata.title).format(w);return this.buildMarkdown(f,B)}fromMarkdown(A){let Q=this.parseFrontMatter(A,_U);return{content:A,entityType:"series",metadata:{title:Q.title,slug:Q.slug}}}parseBody(A){try{let Q=this.parseFrontMatter(A,_U);return rj(Q.title).parse(this.extractBody(A))}catch{return{}}}generateFrontMatter(){return""}}var VF=new Dr0;wA();U2();xX();_0();var NHw=Z.object({seriesName:Z.string().optional(),seriesIndex:Z.number().optional()});function gf0(A){let Q=NHw.safeParse(A);return Q.success?Q.data:{}}function oj(A){return gf0(A.metadata).seriesName}function is1(A){return gf0(A.metadata).seriesIndex}function ds1(A,Q){let w=is1(A)??Number.MAX_SAFE_INTEGER,B=is1(Q)??Number.MAX_SAFE_INTEGER;return w-B}class zr0{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(($)=>[$.id,$])),B=new Set;for(let $ of A){let f=H1($);B.add(f);let Y=w.get(f),X=Y?.content??this.createSeriesContent($),H=B6(X);if(Y?.contentHash===H)continue;let W={id:f,entityType:"series",content:X,contentHash:H,created:Y?.created??new Date().toISOString(),updated:new Date().toISOString(),visibility:"public",metadata:{title:$,slug:H1($)}};await this.entityService.upsertEntity({entity:W}),this.logger.debug(`Upserted series: ${$}`)}for(let $ of Q)if(!B.has($.id))await this.entityService.deleteEntity({entityType:"series",id:$.id}),this.logger.debug(`Deleted orphaned series: ${$.id}`)}async handleEntityChange(A,Q){let w=oj(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=H1(A);if(await this.entityService.getEntity({entityType:"series",id:Q}))return;let B=this.createSeriesContent(A),$={id:Q,entityType:"series",content:B,contentHash:B6(B),created:new Date().toISOString(),updated:new Date().toISOString(),visibility:"public",metadata:{title:A,slug:H1(A)}};await this.entityService.upsertEntity({entity:$}),this.logger.debug(`Created series: ${A}`)}async cleanupOrphanedSeries(A){let Q=H1(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 B=await this.entityService.listEntities({entityType:w});for(let $ of B){let f=oj($);if(f)A.add(f)}}return A}createSeriesContent(A){let Q={title:A,slug:H1(A)};return V8("",Q)}}wA();_0();var jHw=Z.object({entityType:Z.literal("series"),query:Z.looseObject({id:Z.string().optional(),limit:Z.number().optional(),page:Z.number().optional(),pageSize:Z.number().optional()})}),PHw=Z.object({type:Z.enum(["list","detail"]),seriesName:Z.string().optional()});function MHw(A){let Q=PHw.safeParse(A);if(Q.success)return{type:Q.data.type,seriesName:Q.data.seriesName};let w=jHw.safeParse(A);if(w.success){let{query:B}=w.data;if(B.id)return{type:"detail",seriesSlug:B.id};return{type:"list"}}throw Error('Invalid series query format. Expected { type: "list"|"detail" } or { entityType: "series", query: { id?: string } }')}function ns1(A){let Q=n2(A.content,_U);return Cf0.parse({...A,frontmatter:Q.metadata})}class qr0{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 B=MHw(A),$=w.entityService;if(B.type==="list")return this.fetchSeriesList(Q,$);if(B.seriesName)return this.fetchSeriesDetail(B.seriesName,Q,$);if(B.seriesSlug)return this.fetchSeriesDetailBySlug(B.seriesSlug,Q,$);throw Error("Invalid series query: must specify seriesName or slug for detail")}async fetchSeriesList(A,Q){let w=await Q.listEntities({entityType:"series"}),B=await this.countEntitiesPerSeries(Q),$=w.map((f)=>{let Y=ns1(f),X=VF.parseBody(f.content);return{...Y,description:X.description,postCount:B.get(f.metadata.title)??0}});return this.logger.debug(`Found ${$.length} series entities`),A.parse({series:$})}async fetchSeriesDetail(A,Q,w,B){if(!B)B=(await w.listEntities({entityType:"series",options:{filter:{metadata:{title:A}}}}))[0];if(!B)throw Error(`Series not found: ${A}`);let $=ns1(B),f=VF.parseBody(B.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:{...$,description:f.description,postCount:Y.length},description:f.description})}async fetchSeriesDetailBySlug(A,Q,w){let $=(await w.listEntities({entityType:"series",options:{filter:{metadata:{slug:A}}}}))[0];if(!$)throw Error(`Series not found with slug: ${A}`);return this.fetchSeriesDetail($.metadata.title,Q,w,$)}async countEntitiesPerSeries(A){let Q=new Map,w=A.getEntityTypes();for(let B of w){if(B==="series")continue;let $=await A.listEntities({entityType:B});for(let f of $){let Y=oj(f);if(Y)Q.set(Y,(Q.get(Y)??0)+1)}}return Q}async getSeriesMembers(A,Q){let w=[],B=Q.getEntityTypes();for(let $ of B){if($==="series")continue;let f=await Q.listEntities({entityType:$,options:{filter:{metadata:{seriesName:A}}}});w.push(...f)}return w.sort(ds1),w}}wA();_0();xX();var OHw=Z.object({prompt:Z.string().optional(),title:Z.string().optional(),seriesId:Z.string().optional()}),xHw=Z.object({title:Z.string().optional(),excerpt:Z.string().optional()});class yf0{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 B=await this.gatherMemberSummaries(w.metadata.title);if(B.length===0)return{success:!1,error:`No members found in series: ${w.metadata.title}`};let $=A.prompt??`Series name: ${w.metadata.title}
|
|
6680
6680
|
|
|
6681
6681
|
Content in this series:
|
|
6682
6682
|
${B.join(`
|
|
@@ -6688,7 +6688,7 @@ Your task is to write a series description (2-3 sentences) that:
|
|
|
6688
6688
|
3. Is engaging and makes readers want to explore the content
|
|
6689
6689
|
4. Works well as a series overview on a website
|
|
6690
6690
|
|
|
6691
|
-
Be concise and focus on what makes this series unique and valuable.`});async function Qa1({entity:A,config:Q}){let w=qF.parse(A),B=VF.parseBody(w.content);return{$type:"ai.rizom.brain.series",title:w.metadata.title,slug:w.metadata.slug,...B.description&&{description:B.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 Vr0(){return{entityType:"series",collection:"ai.rizom.brain.series",lexicon:k6["ai.rizom.brain.series"],validate:!1,buildRecord:Qa1}}var wa1={name:"@brains/series",version:"0.2.0-alpha.
|
|
6691
|
+
Be concise and focus on what makes this series unique and valuable.`});async function Qa1({entity:A,config:Q}){let w=qF.parse(A),B=VF.parseBody(w.content);return{$type:"ai.rizom.brain.series",title:w.metadata.title,slug:w.metadata.slug,...B.description&&{description:B.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 Vr0(){return{entityType:"series",collection:"ai.rizom.brain.series",lexicon:k6["ai.rizom.brain.series"],validate:!1,buildRecord:Qa1}}var wa1={name:"@brains/series",version:"0.2.0-alpha.151",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 Ba1=Z.discriminatedUnion("mode",[Z.object({mode:Z.literal("derive"),reason:Z.string().optional()}),Z.object({mode:Z.literal("source"),entityId:Z.string(),entityType:Z.string(),seriesName:Z.string().optional(),previousSeriesName:Z.string().optional()})]);class br0 extends rQ{entityType="series";schema=qF;adapter=VF;manager;unregisterAtprotoProjection;constructor(){super("series",wa1,{},k7)}getEntityTypeConfig(){return{weight:0.5}}createGenerationHandler(A){return new yf0(this.logger.child("SeriesGenerationHandler"),A)}getTemplates(){return{...es1(),description:Aa1}}getDataSources(){return[new qr0(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=oj(Q.entity),B=gf0(Q.previousMetadata).seriesName;if(!w&&!B)return null;return{mode:"source",entityId:Q.entity.id,entityType:Q.entity.entityType,...w?{seriesName:w}:{},...B&&B!==w?{previousSeriesName:B}:{}}},jobOptions:(Q)=>{if(!Q.entity)return;return this.getSourceProjectionJobOptions(Q.entity)}}}]}async onRegister(A){this.manager=new zr0(A.entityService,this.logger.child("SeriesManager")),this.unregisterAtprotoProjection=Q5.getInstance().register(Vr0())}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}createSeriesProjectionHandler(A){return{process:async(Q)=>{let w=Ba1.parse(Q);if(w.mode==="derive")return await this.projectAll(A),{success:!0};let B=await A.entityService.getEntity({entityType:w.entityType,id:w.entityId});if(B)await this.projectSource(B,w.previousSeriesName);else{let $=this.requireManager();for(let f of[w.seriesName,w.previousSeriesName])if(f)await $.cleanupOrphanedSeries(f)}return{success:!0}},validateAndParse:(Q)=>{let w=Ba1.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 yf0(this.logger.child("SeriesGenerationHandler"),A),w=await A.entityService.listEntities({entityType:"series"});for(let B of w)try{if(!this.adapter.parseBody(B.content).description)this.logger.info(`Generating description for series: ${B.metadata.title}`),await Q.process({seriesId:B.id})}catch($){this.logger.error(`Failed to generate description for series: ${B.id}`,{error:$})}}}function Jr0(){return new br0}wA();_0();wA();U2();_0();wA();var $a1=Z.enum(["generating","draft","queued","published","failed"]),fa1=Z.enum(["generating","draft","queued","published","failed"]),Ir0="publishedAt is required when deck status is published",Fr0=(A)=>A.status==="published"&&!A.publishedAt,Lr0=(A)=>{if(Fr0(A))throw Error(Ir0)},iD=Z.object({title:Z.string(),slug:Z.string().optional(),description:Z.string().optional(),author:Z.string().optional(),status:$a1,publishedAt:Z.string().datetime().optional(),event:Z.string().optional(),coverImageId:Z.string().optional(),ogImageId:Z.string().optional()}),i0$=Z.object({title:Z.string(),description:Z.string().optional(),status:$a1,publishedAt:Z.string().datetime().optional(),coverImageId:Z.string().optional(),slug:Z.string(),error:Z.string().optional()}).superRefine((A,Q)=>{if(!Fr0(A))return;Q.addIssue({code:Z.ZodIssueCode.custom,path:["publishedAt"],message:Ir0})}),SHw=Z.object({title:Z.string(),description:Z.string().optional(),status:fa1,publishedAt:Z.string().datetime().optional(),coverImageId:Z.string().optional(),slug:Z.string(),error:Z.string().optional()}).superRefine((A,Q)=>{if(!Fr0(A))return;Q.addIssue({code:"custom",path:["publishedAt"],message:Ir0})}),mHw=Z.object({title:Z.string(),slug:Z.string().optional(),description:Z.string().optional(),author:Z.string().optional(),status:fa1,publishedAt:Z.string().datetime().optional(),event:Z.string().optional(),coverImageId:Z.string().optional(),ogImageId:Z.string().optional()}),eg=_Q.extend({entityType:Z.literal("deck"),metadata:SHw}),Ef0=eg.extend({frontmatter:mHw,body:Z.string(),ogImageUrl:Z.string().optional()}),Tr=Ef0.extend({url:Z.string().optional(),typeLabel:Z.string().optional(),listUrl:Z.string().optional(),listLabel:Z.string().optional(),coverImageUrl:Z.string().optional(),ogImageUrl:Z.string().optional(),coverImageWidth:Z.number().optional(),coverImageHeight:Z.number().optional()});class kr0 extends g2{constructor(){super({entityType:"deck",purpose:"A slide-deck presentation.",schema:eg,frontmatterSchema:iD,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,iD);Lr0(w);let B={...w,slug:w.slug??A.metadata.slug};return this.buildMarkdown(Q,B)}fromMarkdown(A){let Q=this.parseFrontmatter(A),w=this.extractBody(A);Lr0(Q),this.validateSlideStructure(w);let B=Q.slug??H1(Q.title),$=Q.status;return{entityType:"deck",content:A,metadata:{slug:B,title:Q.title,description:Q.description,status:$,publishedAt:Q.publishedAt,coverImageId:Q.coverImageId}}}generateTitle(A){return A.metadata.title}generateSummary(A){if(A.metadata.description)return A.metadata.description;return`Presentation: ${A.metadata.title}`}generateFrontMatter(A){return this.toMarkdown(A)}buildStub(A){let Q={title:A.title,slug:A.id,status:"generating"};return{content:this.buildMarkdown(`---
|
|
6692
6692
|
`,Q),metadata:{title:A.title,slug:A.id,status:"generating"}}}}var Sr=new kr0;_0();jB();var uHw=Z.object({markdown:Z.string().describe("Markdown content with slide separators (---)"),deck:Tr.optional()}),_r0=d1({name:"deck-detail",description:"Render a presentation deck as Reveal.js slides",schema:uHw,dataSourceId:"decks:entities",requiredPermission:"public",layout:{component:up0,fullscreen:!0}});jB();_0();var Nr0=Z.object({decks:Z.array(Ef0)}),jr0=Z.object({decks:Z.array(Tr),pageTitle:Z.string().optional(),pageLabel:Z.string().optional()});import{jsxDEV as Pr0}from"preact/jsx-dev-runtime";var cHw="Presentations",Mr0=({decks:A,pageLabel:Q})=>{let w=A.map(($)=>({id:$.id,url:$.url,title:$.frontmatter.title,date:$.frontmatter.publishedAt??$.created,description:$.frontmatter.description}));return Pr0("div",{className:"deck-list bg-theme",children:Pr0("div",{className:"container mx-auto max-w-[1100px] px-6 py-16 md:px-12 md:py-24",children:Pr0(Mn,{label:Q&&Q!=="Decks"?Q:cHw,items:w},void 0,!1,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)};t8();class Tf0 extends z6{constructor(){super(Nr0,{title:"Deck List",mappings:[{key:"decks",label:"Decks",type:"array",itemType:"object"}]})}}var Or0=d1({name:"deck-list",description:"List view of all presentation decks",schema:jr0,dataSourceId:"decks:entities",requiredPermission:"public",formatter:new Tf0,layout:{component:Mr0}});_0();wA();var lHw=Z.object({title:Z.string().max(80).describe("A short, punchy title (2-5 words) that's memorable and evocative"),content:Z.string().describe("Full slide deck content in markdown format with slide separators (---). Each slide should have a header and focused content."),description:Z.string().describe("A concise 1-2 sentence summary that captures the essence of the talk")}),Ya1=d1({name:"decks:generation",description:"Template for AI to generate complete slide decks from prompts",schema:lHw,dataSourceId:"shell:ai-content",requiredPermission:"public",useKnowledgeContext:!0,basePrompt:`You are creating slide decks in a distinctive voice that blends philosophy, technology, and culture.
|
|
6693
6693
|
|
|
6694
6694
|
Your task is to generate a complete slide deck based on the user's prompt.
|
|
@@ -6996,7 +6996,7 @@ ${X}`,templateName:"decks:description"})).description,await this.reportProgress(
|
|
|
6996
6996
|
color: var(--carousel-accent);
|
|
6997
6997
|
font-weight: 600;
|
|
6998
6998
|
}
|
|
6999
|
-
`}},void 0,!1,void 0,this),$.map((W,K)=>p4("section",{className:`deck-carousel-slide${K===0?" is-cover":""}`,children:[p4("header",{className:"deck-carousel-header",children:p4("span",{className:"deck-carousel-wordmark","aria-label":w??Q,children:[p4("span",{className:"wm-primary",children:f.primary},void 0,!1,void 0,this),f.secondary!==void 0&&p4(oHw,{children:[p4("span",{className:"wm-dot",children:"."},void 0,!1,void 0,this),p4("span",{className:"wm-secondary",children:f.secondary},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),p4("div",{className:"deck-carousel-body",children:p4("div",{className:"deck-carousel-content",dangerouslySetInnerHTML:{__html:H(W.markdown)}},void 0,!1,void 0,this)},void 0,!1,void 0,this),p4("footer",{className:"deck-carousel-footer",children:[p4("span",{className:"deck-carousel-footer-meta",children:B??Q},void 0,!1,void 0,this),p4("span",{className:"deck-carousel-counter","aria-label":`Slide ${K+1} of ${Y}`,children:[p4("span",{className:"deck-carousel-counter-current",children:String(K+1).padStart(2,"0")},void 0,!1,void 0,this)," / ",p4("span",{children:X},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 sHw,rm as aHw}from"fs/promises";import{tmpdir as tHw}from"os";import{join as eHw}from"path";u9();U2();var AWw=26214400,QWw=60000,Ka1=20;class Rr0{metadata={outputEntityType:"document"};context;renderPdf;getThemeMode;constructor(A,Q={}){this.context=A,this.renderPdf=Q.renderPdf??kU,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=wWw(Q,{brandLabel:this.resolveBrandLabel()});if(w.slides.length>Ka1)throw Error(`Refusing to render carousel with ${w.slides.length} slides; maxSlides=${Ka1}`);let B=await this.getThemeMode(),$=await sHw(eHw(tHw(),"brain-deck-carousel-"));try{let f=await RZ({outputDir:$,mediaPath:`/_media/carousel/${Q.id}`,template:Wa1,format:"pdf",content:w,siteConfig:{title:w.title,themeMode:B},themeCSS:this.context.themeCSS}),Y=await hZ({rootDir:$});try{return{type:"document",data:await this.renderPdf(Y.urlFor(f.urlPath),{maxBytes:AWw,timeoutMs:QWw,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${BWw(Q)}-carousel.pdf`}}finally{await Y.close()}}finally{await aHw($,{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 wWw(A,Q={}){let{frontmatter:w,content:B}=P6(A.content),$=typeof w.title==="string"?w.title:A.metadata.title,f=typeof w.event==="string"&&w.event.length>0?w.event:void 0,Y=B.split(/^---$/gm).map((X)=>X.trim()).filter((X)=>X.length>0).map((X)=>({markdown:X}));return{title:$,slides:Y,...Q.brandLabel?{brandLabel:Q.brandLabel}:{},...f?{eyebrow:f}:{}}}function BWw(A){let Q=A.metadata.slug;return Q.length>0?Q:H1(A.metadata.title)}_0();import{jsxDEV as YWw}from"preact/jsx-dev-runtime";var Sf0="og-image",$Ww="decks:og-image",Ua1=Z.object({title:Z.string().min(1),description:Z.string().optional(),event:Z.string().optional(),brandLabel:Z.string().optional(),slideCount:Z.number().int().positive().optional(),coverImageUrl:Z.string().optional()}),Ga1={name:$Ww,pluginId:"decks",schema:Ua1,renderers:{image:fWw}};function fWw(A){let Q=Ua1.parse(A),w=Q.slideCount?`${Q.slideCount} slide${Q.slideCount===1?"":"s"}`:void 0;return YWw(uq,{brandLabel:Q.brandLabel??Q.title,eyebrow:"Deck",title:Q.title,subtitle:Q.description,meta:[Q.event],tag:w},void 0,!1,void 0,this)}u9();U2();class hr0{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!==Sf0)return;let Q=await this.context.entityService.getEntity({entityType:"deck",id:A.sourceEntityId});if(!Q)return;let{frontmatter:w,content:B}=P6(Q.content),$=iD.parse(w),f=XWw(B),Y=this.resolveBrandLabel(),X=await this.resolveCoverImageUrl($.coverImageId),H={title:$.title,...$.description?{description:$.description}:{},...$.event?{event:$.event}:{},...f?{slideCount:f}:{},...X?{coverImageUrl:X}:{},...Y?{brandLabel:Y}:{}};return{type:"image",data:await nj({mediaPath:`/_media/og/deck/${Q.id}`,template:Ga1,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:`${ZWw(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 XWw(A){return A.split(/^---$/gm).map((Q)=>Q.trim()).filter((Q)=>Q.length>0).length}function ZWw(A){let Q=A.metadata.slug;return Q.length>0?Q:H1(A.metadata.title)}wA();async function Da1({entity:A,config:Q}){let w=eg.parse(A),B=n2(w.content,iD),$=B.metadata;return{$type:"ai.rizom.brain.deck",title:$.title,...$.slug&&{slug:$.slug},...$.description&&{description:$.description},body:B.content,format:"text/markdown",...$.author&&{author:$.author},...$.event&&{event:$.event},...$.publishedAt&&{publishedAt:$.publishedAt},...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"deck",sourceEntityId:w.id,createdAt:w.created,...w.updated&&{updatedAt:w.updated}}}function Cr0(){return{entityType:"deck",collection:"ai.rizom.brain.deck",lexicon:k6["ai.rizom.brain.deck"],validate:!1,buildRecord:Da1}}var za1={name:"@brains/decks",version:"0.2.0-alpha.
|
|
6999
|
+
`}},void 0,!1,void 0,this),$.map((W,K)=>p4("section",{className:`deck-carousel-slide${K===0?" is-cover":""}`,children:[p4("header",{className:"deck-carousel-header",children:p4("span",{className:"deck-carousel-wordmark","aria-label":w??Q,children:[p4("span",{className:"wm-primary",children:f.primary},void 0,!1,void 0,this),f.secondary!==void 0&&p4(oHw,{children:[p4("span",{className:"wm-dot",children:"."},void 0,!1,void 0,this),p4("span",{className:"wm-secondary",children:f.secondary},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),p4("div",{className:"deck-carousel-body",children:p4("div",{className:"deck-carousel-content",dangerouslySetInnerHTML:{__html:H(W.markdown)}},void 0,!1,void 0,this)},void 0,!1,void 0,this),p4("footer",{className:"deck-carousel-footer",children:[p4("span",{className:"deck-carousel-footer-meta",children:B??Q},void 0,!1,void 0,this),p4("span",{className:"deck-carousel-counter","aria-label":`Slide ${K+1} of ${Y}`,children:[p4("span",{className:"deck-carousel-counter-current",children:String(K+1).padStart(2,"0")},void 0,!1,void 0,this)," / ",p4("span",{children:X},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 sHw,rm as aHw}from"fs/promises";import{tmpdir as tHw}from"os";import{join as eHw}from"path";u9();U2();var AWw=26214400,QWw=60000,Ka1=20;class Rr0{metadata={outputEntityType:"document"};context;renderPdf;getThemeMode;constructor(A,Q={}){this.context=A,this.renderPdf=Q.renderPdf??kU,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=wWw(Q,{brandLabel:this.resolveBrandLabel()});if(w.slides.length>Ka1)throw Error(`Refusing to render carousel with ${w.slides.length} slides; maxSlides=${Ka1}`);let B=await this.getThemeMode(),$=await sHw(eHw(tHw(),"brain-deck-carousel-"));try{let f=await RZ({outputDir:$,mediaPath:`/_media/carousel/${Q.id}`,template:Wa1,format:"pdf",content:w,siteConfig:{title:w.title,themeMode:B},themeCSS:this.context.themeCSS}),Y=await hZ({rootDir:$});try{return{type:"document",data:await this.renderPdf(Y.urlFor(f.urlPath),{maxBytes:AWw,timeoutMs:QWw,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${BWw(Q)}-carousel.pdf`}}finally{await Y.close()}}finally{await aHw($,{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 wWw(A,Q={}){let{frontmatter:w,content:B}=P6(A.content),$=typeof w.title==="string"?w.title:A.metadata.title,f=typeof w.event==="string"&&w.event.length>0?w.event:void 0,Y=B.split(/^---$/gm).map((X)=>X.trim()).filter((X)=>X.length>0).map((X)=>({markdown:X}));return{title:$,slides:Y,...Q.brandLabel?{brandLabel:Q.brandLabel}:{},...f?{eyebrow:f}:{}}}function BWw(A){let Q=A.metadata.slug;return Q.length>0?Q:H1(A.metadata.title)}_0();import{jsxDEV as YWw}from"preact/jsx-dev-runtime";var Sf0="og-image",$Ww="decks:og-image",Ua1=Z.object({title:Z.string().min(1),description:Z.string().optional(),event:Z.string().optional(),brandLabel:Z.string().optional(),slideCount:Z.number().int().positive().optional(),coverImageUrl:Z.string().optional()}),Ga1={name:$Ww,pluginId:"decks",schema:Ua1,renderers:{image:fWw}};function fWw(A){let Q=Ua1.parse(A),w=Q.slideCount?`${Q.slideCount} slide${Q.slideCount===1?"":"s"}`:void 0;return YWw(uq,{brandLabel:Q.brandLabel??Q.title,eyebrow:"Deck",title:Q.title,subtitle:Q.description,meta:[Q.event],tag:w},void 0,!1,void 0,this)}u9();U2();class hr0{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!==Sf0)return;let Q=await this.context.entityService.getEntity({entityType:"deck",id:A.sourceEntityId});if(!Q)return;let{frontmatter:w,content:B}=P6(Q.content),$=iD.parse(w),f=XWw(B),Y=this.resolveBrandLabel(),X=await this.resolveCoverImageUrl($.coverImageId),H={title:$.title,...$.description?{description:$.description}:{},...$.event?{event:$.event}:{},...f?{slideCount:f}:{},...X?{coverImageUrl:X}:{},...Y?{brandLabel:Y}:{}};return{type:"image",data:await nj({mediaPath:`/_media/og/deck/${Q.id}`,template:Ga1,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:`${ZWw(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 XWw(A){return A.split(/^---$/gm).map((Q)=>Q.trim()).filter((Q)=>Q.length>0).length}function ZWw(A){let Q=A.metadata.slug;return Q.length>0?Q:H1(A.metadata.title)}wA();async function Da1({entity:A,config:Q}){let w=eg.parse(A),B=n2(w.content,iD),$=B.metadata;return{$type:"ai.rizom.brain.deck",title:$.title,...$.slug&&{slug:$.slug},...$.description&&{description:$.description},body:B.content,format:"text/markdown",...$.author&&{author:$.author},...$.event&&{event:$.event},...$.publishedAt&&{publishedAt:$.publishedAt},...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"deck",sourceEntityId:w.id,createdAt:w.created,...w.updated&&{updatedAt:w.updated}}}function Cr0(){return{entityType:"deck",collection:"ai.rizom.brain.deck",lexicon:k6["ai.rizom.brain.deck"],validate:!1,buildRecord:Da1}}var za1={name:"@brains/decks",version:"0.2.0-alpha.151",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 WWw=Z.object({prompt:Z.string(),event:Z.string().optional()}),KWw=Z.object({title:Z.string(),content:Z.string()});class gr0 extends rQ{deps;entityType=Sr.entityType;schema=Sr.schema;adapter=Sr;unregisterCarouselAttachmentProvider;unregisterOgImageAttachmentProvider;unregisterAtprotoProjection;constructor(A={}){super("decks",za1,{},k7);this.deps=A}createGenerationHandler(A){return new vr0(this.logger.child("DeckGenerationJobHandler"),A)}getTemplates(){return{"deck-detail":_r0,"deck-list":Or0,generation:Ya1,description:Xa1}}getDataSources(){return[new xr0(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=Q5.getInstance().register(Cr0()),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:B}=Q.payload;if(w!=="deck")return{success:!0};try{let $=await A.entityService.getEntity({entityType:"deck",id:B});if(!$)return await A.messaging.send({type:"publish:report:failure",payload:{entityType:w,entityId:B,error:`Deck not found: ${B}`}}),{success:!0};if($.metadata.status==="published")return{success:!0};let f=new Date().toISOString(),Y={...$,metadata:{...$.metadata,status:"published",publishedAt:f}};await A.entityService.updateEntity({entity:{...Y,content:this.adapter.toMarkdown(Y)}}),await A.messaging.send({type:"publish:report:success",payload:{entityType:w,entityId:B,result:{id:B}}})}catch($){await A.messaging.send({type:"publish:report:failure",payload:{entityType:w,entityId:B,error:SA($)}})}return{success:!0}})}registerCarouselAttachmentProvider(A){let Q={...this.deps,getThemeMode:this.deps.getThemeMode??(async()=>{try{return(await vr(A.entityService)).themeMode??"dark"}catch{return"dark"}})};this.unregisterCarouselAttachmentProvider=A.attachments.register("deck",Za1,new Rr0(A,Q))}registerOgImageAttachmentProvider(A){this.unregisterOgImageAttachmentProvider=A.attachments.register("deck",Sf0,new hr0(A))}registerEvalHandlers(A){A.eval.registerHandler("generateDeck",async(Q)=>{let w=WWw.parse(Q);return A.ai.generate({prompt:`${w.prompt}${w.event?`
|
|
7000
7000
|
|
|
7001
7001
|
Note: This presentation is for "${w.event}".`:""}`,templateName:"decks:generation"})}),A.eval.registerHandler("generateDescription",async(Q)=>{let w=KWw.parse(Q);return A.ai.generate({prompt:`Title: ${w.title}
|
|
7002
7002
|
|
|
@@ -7153,9 +7153,9 @@ ${w.content}`,templateName:"decks:description"})})}}function ur(){return new gr0
|
|
|
7153
7153
|
background: transparent;
|
|
7154
7154
|
}
|
|
7155
7155
|
|
|
7156
|
-
`,Na1=()=>u8("style",{children:VWw},void 0,!1,void 0,this);import{jsxDEV as h2,Fragment as bWw}from"preact/jsx-dev-runtime";var pf0=({title:A,description:Q,children:w,detail:B=!1,footer:$=!1,contentClassName:f=""})=>h2(bWw,{children:[h2(pQ,{title:A,description:Q},void 0,!1,void 0,this),h2(Na1,{},void 0,!1,void 0,this),h2("div",{className:`docs-handbook${B?" docs-handbook--detail":""}`,children:[h2(ka1,{},void 0,!1,void 0,this),h2("div",{className:`${dD.wrap} ${f}`.trim(),children:[w,$&&h2(_a1,{},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),ja1=({docsCount:A,sectionsCount:Q,startDoc:w})=>h2("section",{className:"border-b border-[var(--docs-text)] py-14 md:py-24 md:pb-[72px]",children:[h2("p",{className:`${dD.label} mb-8`,children:"Handbook \xB7 Brains docs"},void 0,!1,void 0,this),h2("h1",{className:`${dD.display} m-0 max-w-[16ch] text-5xl leading-[1.05] tracking-[-0.02em] md:text-7xl`,children:["Build, run, and publish"," ",h2("em",{className:"text-[var(--docs-accent)]",children:"brains."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),h2("p",{className:"mt-8 max-w-[52ch] text-lg leading-[1.65] text-[var(--docs-text-muted)]",children:"Documentation for composing brain models, managing markdown entities, wiring interfaces, and shipping generated sites."},void 0,!1,void 0,this),h2("dl",{className:"mt-10 flex flex-wrap gap-7 docs-font-label text-xs tracking-[0.06em] text-[var(--docs-text-light)] md:mt-14 md:gap-12",children:[h2("div",{children:[h2("strong",{className:"mb-0.5 block font-medium text-[var(--docs-text)]",children:A},void 0,!1,void 0,this),"Documents"]},void 0,!0,void 0,this),h2("div",{children:[h2("strong",{className:"mb-0.5 block font-medium text-[var(--docs-text)]",children:Q},void 0,!1,void 0,this),"Sections"]},void 0,!0,void 0,this),h2("div",{children:[h2("strong",{className:"mb-0.5 block font-medium text-[var(--docs-text)]",children:"April 2026"},void 0,!1,void 0,this),"Updated"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),h2("div",{className:"mt-9 flex flex-wrap gap-3.5",children:[w&&h2("a",{className:dD.primaryButton,href:Qy(w),children:"Start reading"},void 0,!1,void 0,this),h2("a",{className:dD.button,href:"#sections",children:"Browse sections"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Pa1=({groups:A})=>h2("aside",{className:"docs-rail sticky top-8 hidden docs-font-label text-xs tracking-[0.06em] text-[var(--docs-text-light)] min-[861px]:block","aria-label":"Documentation sections",children:[h2("p",{className:"m-0 mb-3.5 font-medium text-[var(--docs-text)]",children:"Sections"},void 0,!1,void 0,this),h2("ol",{className:"m-0 list-none p-0",children:A.map((Q,w)=>h2("li",{className:"grid grid-cols-[32px_1fr] gap-2 py-1.5",children:[h2("span",{className:"docs-font-display text-[var(--docs-text-light)] italic",children:[wy(w),"."]},void 0,!0,void 0,this),h2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:`#${lf0(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),Ma1=({group:A,index:Q})=>h2("article",{className:"mb-16 last:mb-0",id:lf0(Q),children:[h2("header",{className:"mb-2 grid grid-cols-[36px_auto_1fr] items-baseline gap-x-3 border-b border-[var(--docs-border)] pb-3.5 md:grid-cols-[48px_auto_1fr] md:gap-x-5",children:[h2("span",{className:"text-right docs-font-display text-3xl leading-[1.1] text-[var(--docs-accent)] italic md:text-4xl",children:[wy(Q),"."]},void 0,!0,void 0,this),h2("h2",{className:`${dD.display} m-0 text-3xl leading-[1.1] tracking-[-0.015em] md:text-4xl`,children:A.section},void 0,!1,void 0,this),h2("span",{className:"docs-chapter__leader"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),h2("ol",{className:"m-0 list-none p-0",children:A.docs.map((w)=>h2("li",{className:"border-b border-[var(--docs-border-light)] last:border-b-0",children:h2("a",{className:"group block py-[18px] pl-12 md:pl-[68px]",href:Qy(w),children:[h2("p",{className:"m-0 text-[22px] leading-[1.2] tracking-[-0.005em] transition-colors duration-150 group-hover:text-[var(--docs-accent)]",children:w.metadata.title},void 0,!1,void 0,this),w.metadata.description&&h2("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),Oa1=({title:A})=>h2("nav",{className:"mb-8 flex flex-wrap items-baseline gap-2.5 docs-font-label text-[11px] uppercase tracking-[0.06em] text-[var(--docs-text-light)]","aria-label":"Breadcrumb",children:[h2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/",children:"Home"},void 0,!1,void 0,this),h2("span",{children:"/"},void 0,!1,void 0,this),h2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/docs",children:"Docs"},void 0,!1,void 0,this),h2("span",{children:"/"},void 0,!1,void 0,this),h2("span",{children:A},void 0,!1,void 0,this)]},void 0,!0,void 0,this),xa1=({groups:A,activeGroupIndex:Q,activeSlug:w})=>h2("aside",{className:"docs-detail-rail sticky top-24 hidden max-h-[calc(100vh-120px)] overflow-auto pr-2 min-[861px]:block","aria-label":"Documentation navigation",children:h2("nav",{className:"docs-font-label text-xs tracking-[0.06em] text-[var(--docs-text-light)]",children:[h2("p",{className:"m-0 mb-4 border-b border-[var(--docs-text)] pb-3 text-[11px] uppercase tracking-[0.08em] text-[var(--docs-text-light)]",children:"Documentation"},void 0,!1,void 0,this),h2("ol",{className:"m-0 list-none p-0",children:A.map((B,$)=>{let f=$===Q;return h2("li",{className:f?"mb-[22px]":"mb-3.5",children:[h2("a",{className:`mb-2 flex items-baseline gap-2.5 docs-font-label text-[11px] uppercase leading-[1.4] tracking-[0.06em] transition-colors duration-150 hover:text-[var(--docs-text)] ${f?"text-[var(--docs-text)]":"text-[var(--docs-text-muted)]"}`,href:`/docs#${lf0($)}`,children:[h2("span",{className:"docs-font-display text-sm text-[var(--docs-accent)] italic",children:[wy($),"."]},void 0,!0,void 0,this)," ",B.section]},void 0,!0,void 0,this),f&&h2("ol",{className:"mt-0.5 list-none p-0",children:B.docs.map((Y)=>{let X=Y.metadata.slug===w;return h2("li",{children:h2("a",{className:`docs-rail__doc relative block py-1.5 docs-font-body text-sm leading-[1.4] tracking-normal transition-[color,padding-left] duration-150 hover:text-[var(--docs-text)] ${X?"pl-3.5 font-medium text-[var(--docs-accent)]":"text-[var(--docs-text-muted)]"}`,href:Qy(Y),"aria-current":X?"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)]},B.section,!0,void 0,this)})},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),va1=({prevDoc:A,nextDoc:Q})=>{if(!A&&!Q)return null;return h2("nav",{className:"mt-12 grid grid-cols-1 gap-5 border-t border-[var(--docs-border)] pt-7 md:grid-cols-2","aria-label":"Previous and next docs",children:[A?h2("a",{className:"group border-t border-[var(--docs-border-light)] pt-[18px] transition-colors duration-150 hover:border-[var(--docs-accent)]",href:Qy(A),children:[h2("span",{className:"block docs-font-label text-[10.5px] uppercase tracking-[0.22em] text-[var(--docs-text-light)]",children:"Previous"},void 0,!1,void 0,this),h2("span",{className:"mt-2 block docs-font-display text-[22px] leading-[1.2] text-[var(--docs-heading)] transition-colors duration-150 group-hover:text-[var(--docs-accent)]",children:["\u2190 ",A.metadata.title]},void 0,!0,void 0,this)]},void 0,!0,void 0,this):h2("span",{},void 0,!1,void 0,this),Q&&h2("a",{className:"group border-t border-[var(--docs-border-light)] pt-[18px] text-left transition-colors duration-150 hover:border-[var(--docs-accent)] md:text-right",href:Qy(Q),children:[h2("span",{className:"block docs-font-label text-[10.5px] uppercase tracking-[0.22em] text-[var(--docs-text-light)]",children:"Next"},void 0,!1,void 0,this),h2("span",{className:"mt-2 block docs-font-display text-[22px] leading-[1.2] text-[var(--docs-heading)] transition-colors duration-150 group-hover:text-[var(--docs-accent)]",children:[Q.metadata.title," \u2192"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as By}from"preact/jsx-dev-runtime";var Sr0=({docs:A})=>{let Q=cr(A),w=cf0(Q),$=Q.filter((f)=>f.metadata.slug!=="index")[0]??Q[0];return By(pf0,{title:"Documentation",description:"Brains documentation",children:[By(ja1,{docsCount:A.length,sectionsCount:w.length,startDoc:$},void 0,!1,void 0,this),By("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:[By(Pa1,{groups:w},void 0,!1,void 0,this),By("div",{children:w.map((f,Y)=>By(Ma1,{group:f,index:Y},f.section,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as CZ}from"preact/jsx-dev-runtime";var mr0=({doc:A,docs:Q,prevDoc:w,nextDoc:B})=>{let $=cf0(Q.length>0?Q:[A]),f=cr(Q.length>0?Q:[A]),Y=f.findIndex((H)=>H.metadata.slug===A.metadata.slug),X=Math.max($.findIndex((H)=>H.docs.some((W)=>W.metadata.slug===A.metadata.slug)),0);return CZ(pf0,{title:A.metadata.title,description:A.metadata.description??A.metadata.section,detail:!0,footer:!0,contentClassName:"pt-16",children:[CZ(Oa1,{title:A.metadata.title},void 0,!1,void 0,this),CZ("div",{className:"grid items-start gap-10 py-8 pb-24 md:grid-cols-[240px_minmax(0,1fr)] md:gap-20",children:[CZ(xa1,{groups:$,activeGroupIndex:X,activeSlug:A.metadata.slug},void 0,!1,void 0,this),CZ("article",{className:"min-w-0",children:[CZ("header",{className:"mb-10 border-b border-[var(--docs-border)] pb-8",children:[CZ("p",{className:`${dD.label} m-0 mb-6 flex items-baseline gap-3`,children:[CZ("span",{className:"docs-font-display text-lg leading-none tracking-normal normal-case text-[var(--docs-accent)] italic",children:[wy(X),"."]},void 0,!0,void 0,this)," ",A.metadata.section,Y>=0?` \xB7 ${Y+1}/${f.length}`:""]},void 0,!0,void 0,this),CZ("h1",{className:`${dD.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&&CZ("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),CZ("div",{className:"docs-article__body",children:CZ(F9,{markdown:A.body},void 0,!1,void 0,this)},void 0,!1,void 0,this),CZ(va1,{prevDoc:w,nextDoc:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};var JWw=Z.object({currentPage:Z.number(),totalPages:Z.number(),totalItems:Z.number(),pageSize:Z.number(),hasNextPage:Z.boolean(),hasPrevPage:Z.boolean()}),IWw=Z.union([Z.enum(["public","shared","restricted"]),Z.literal("private")]).optional().transform((A)=>{if(A===void 0)return"public";if(A==="private")return"restricted";return A}),FWw=Z.object({title:Z.string(),section:Z.string(),order:Z.number().int(),sourcePath:Z.string(),description:Z.string().optional(),slug:Z.string().optional()}),LWw=Z.object({title:Z.string(),section:Z.string(),order:Z.number().int(),description:Z.string().optional(),slug:Z.string()}),lr=Z.object({id:Z.string(),entityType:Z.literal("doc"),content:Z.string(),created:Z.string(),updated:Z.string(),visibility:IWw,metadata:LWw,contentHash:Z.string(),frontmatter:FWw,body:Z.string()}),kWw=Z.object({docs:Z.array(lr),pagination:JWw.nullable(),baseUrl:Z.string().optional()}),_Ww=Z.object({doc:lr,docs:Z.array(lr),prevDoc:lr.nullable(),nextDoc:lr.nullable()});function Ra1(){return{"doc-list":d1({name:"doc-list",description:"Documentation index template",schema:kWw,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:Sr0}}),"doc-detail":d1({name:"doc-detail",description:"Documentation page template",schema:_Ww,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:mr0}})}}var ha1={name:"@brains/doc",version:"0.2.0-alpha.150",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:"^6.0.3"},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 ur0 extends rQ{entityType=mf0.entityType;schema=Ay;adapter=mf0;constructor(){super("docs",ha1,{},k7)}getTemplates(){return Ra1()}getDataSources(){return[new uf0(this.logger.child("DocDataSource"))]}}function pr(){return new ur0}wA();U2();_0();gB();_0();var cr0=Z.literal("application/pdf"),Ca1=Z.enum(["pending","draft","failed"]),lr0=Z.object({title:Z.string().optional(),mimeType:cr0,filename:Z.string().min(1),pageCount:Z.number().int().min(0).optional(),status:Ca1.optional(),processingJobId:Z.string().optional(),processingError:Z.string().optional(),sourceEntityType:Z.string().min(1).optional(),sourceEntityId:Z.string().min(1).optional(),sourceUploadId:Z.string().optional(),sourceFilename:Z.string().optional(),sourceMediaType:Z.string().optional(),attachmentType:Z.string().min(1).optional(),dedupKey:Z.string().min(1).optional()}),$y=_Q.extend({entityType:Z.literal("document"),content:Z.string().regex(/^data:application\/pdf;base64,.+$/),metadata:lr0});function ir(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 if0(A){return`data:application/pdf;base64,${Buffer.from(A).toString("base64")}`}function pr0(A){let Q=Buffer.from(A).toString("latin1"),w=0,B=/\/Type\s*\/Pages\b[^]*?\/Count\s+(\d+)|\/Count\s+(\d+)[^]*?\/Type\s*\/Pages\b/g;for(let f of Q.matchAll(B)){let Y=parseInt(f[1]??f[2]??"0",10);if(Y>w)w=Y}if(w>0)return w;return Q.match(/\/Type\s*\/Page(?!\w)/g)?.length??0}class df0{entityType="document";purpose="A durable rendered file artifact such as a printable or carousel PDF.";schema=$y;toMarkdown(A){return A.content}fromMarkdown(A){return ir(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:B}=ir(Q);return{entityType:"document",content:Q,metadata:{mimeType:B,...w}}}}var $V=new df0;async function xo0(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 $=(await Promise.resolve().then(() => (le1(),ce1))).getDocument({data:new Uint8Array(A),disableFontFace:!1,useSystemFonts:!0,useWorkerFetch:!1}),f=await $.promise;try{let Y=Q.maxPages??50;if(f.numPages>Y)throw Error(`Uploaded PDF has ${f.numPages} pages; maximum supported for synchronous markdown extraction is ${Y}`);let X=[];for(let W=1;W<=f.numPages;W+=1){let G=(await(await f.getPage(W)).getTextContent()).items.flatMap((q)=>("str"in q)?[q.str]:[]).join(" ").replace(/\s+/g," ").trim();if(G.length>0)X.push(G)}let H=X.join(`
|
|
7156
|
+
`,Na1=()=>u8("style",{children:VWw},void 0,!1,void 0,this);import{jsxDEV as h2,Fragment as bWw}from"preact/jsx-dev-runtime";var pf0=({title:A,description:Q,children:w,detail:B=!1,footer:$=!1,contentClassName:f=""})=>h2(bWw,{children:[h2(pQ,{title:A,description:Q},void 0,!1,void 0,this),h2(Na1,{},void 0,!1,void 0,this),h2("div",{className:`docs-handbook${B?" docs-handbook--detail":""}`,children:[h2(ka1,{},void 0,!1,void 0,this),h2("div",{className:`${dD.wrap} ${f}`.trim(),children:[w,$&&h2(_a1,{},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),ja1=({docsCount:A,sectionsCount:Q,startDoc:w})=>h2("section",{className:"border-b border-[var(--docs-text)] py-14 md:py-24 md:pb-[72px]",children:[h2("p",{className:`${dD.label} mb-8`,children:"Handbook \xB7 Brains docs"},void 0,!1,void 0,this),h2("h1",{className:`${dD.display} m-0 max-w-[16ch] text-5xl leading-[1.05] tracking-[-0.02em] md:text-7xl`,children:["Build, run, and publish"," ",h2("em",{className:"text-[var(--docs-accent)]",children:"brains."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),h2("p",{className:"mt-8 max-w-[52ch] text-lg leading-[1.65] text-[var(--docs-text-muted)]",children:"Documentation for composing brain models, managing markdown entities, wiring interfaces, and shipping generated sites."},void 0,!1,void 0,this),h2("dl",{className:"mt-10 flex flex-wrap gap-7 docs-font-label text-xs tracking-[0.06em] text-[var(--docs-text-light)] md:mt-14 md:gap-12",children:[h2("div",{children:[h2("strong",{className:"mb-0.5 block font-medium text-[var(--docs-text)]",children:A},void 0,!1,void 0,this),"Documents"]},void 0,!0,void 0,this),h2("div",{children:[h2("strong",{className:"mb-0.5 block font-medium text-[var(--docs-text)]",children:Q},void 0,!1,void 0,this),"Sections"]},void 0,!0,void 0,this),h2("div",{children:[h2("strong",{className:"mb-0.5 block font-medium text-[var(--docs-text)]",children:"April 2026"},void 0,!1,void 0,this),"Updated"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),h2("div",{className:"mt-9 flex flex-wrap gap-3.5",children:[w&&h2("a",{className:dD.primaryButton,href:Qy(w),children:"Start reading"},void 0,!1,void 0,this),h2("a",{className:dD.button,href:"#sections",children:"Browse sections"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Pa1=({groups:A})=>h2("aside",{className:"docs-rail sticky top-8 hidden docs-font-label text-xs tracking-[0.06em] text-[var(--docs-text-light)] min-[861px]:block","aria-label":"Documentation sections",children:[h2("p",{className:"m-0 mb-3.5 font-medium text-[var(--docs-text)]",children:"Sections"},void 0,!1,void 0,this),h2("ol",{className:"m-0 list-none p-0",children:A.map((Q,w)=>h2("li",{className:"grid grid-cols-[32px_1fr] gap-2 py-1.5",children:[h2("span",{className:"docs-font-display text-[var(--docs-text-light)] italic",children:[wy(w),"."]},void 0,!0,void 0,this),h2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:`#${lf0(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),Ma1=({group:A,index:Q})=>h2("article",{className:"mb-16 last:mb-0",id:lf0(Q),children:[h2("header",{className:"mb-2 grid grid-cols-[36px_auto_1fr] items-baseline gap-x-3 border-b border-[var(--docs-border)] pb-3.5 md:grid-cols-[48px_auto_1fr] md:gap-x-5",children:[h2("span",{className:"text-right docs-font-display text-3xl leading-[1.1] text-[var(--docs-accent)] italic md:text-4xl",children:[wy(Q),"."]},void 0,!0,void 0,this),h2("h2",{className:`${dD.display} m-0 text-3xl leading-[1.1] tracking-[-0.015em] md:text-4xl`,children:A.section},void 0,!1,void 0,this),h2("span",{className:"docs-chapter__leader"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),h2("ol",{className:"m-0 list-none p-0",children:A.docs.map((w)=>h2("li",{className:"border-b border-[var(--docs-border-light)] last:border-b-0",children:h2("a",{className:"group block py-[18px] pl-12 md:pl-[68px]",href:Qy(w),children:[h2("p",{className:"m-0 text-[22px] leading-[1.2] tracking-[-0.005em] transition-colors duration-150 group-hover:text-[var(--docs-accent)]",children:w.metadata.title},void 0,!1,void 0,this),w.metadata.description&&h2("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),Oa1=({title:A})=>h2("nav",{className:"mb-8 flex flex-wrap items-baseline gap-2.5 docs-font-label text-[11px] uppercase tracking-[0.06em] text-[var(--docs-text-light)]","aria-label":"Breadcrumb",children:[h2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/",children:"Home"},void 0,!1,void 0,this),h2("span",{children:"/"},void 0,!1,void 0,this),h2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/docs",children:"Docs"},void 0,!1,void 0,this),h2("span",{children:"/"},void 0,!1,void 0,this),h2("span",{children:A},void 0,!1,void 0,this)]},void 0,!0,void 0,this),xa1=({groups:A,activeGroupIndex:Q,activeSlug:w})=>h2("aside",{className:"docs-detail-rail sticky top-24 hidden max-h-[calc(100vh-120px)] overflow-auto pr-2 min-[861px]:block","aria-label":"Documentation navigation",children:h2("nav",{className:"docs-font-label text-xs tracking-[0.06em] text-[var(--docs-text-light)]",children:[h2("p",{className:"m-0 mb-4 border-b border-[var(--docs-text)] pb-3 text-[11px] uppercase tracking-[0.08em] text-[var(--docs-text-light)]",children:"Documentation"},void 0,!1,void 0,this),h2("ol",{className:"m-0 list-none p-0",children:A.map((B,$)=>{let f=$===Q;return h2("li",{className:f?"mb-[22px]":"mb-3.5",children:[h2("a",{className:`mb-2 flex items-baseline gap-2.5 docs-font-label text-[11px] uppercase leading-[1.4] tracking-[0.06em] transition-colors duration-150 hover:text-[var(--docs-text)] ${f?"text-[var(--docs-text)]":"text-[var(--docs-text-muted)]"}`,href:`/docs#${lf0($)}`,children:[h2("span",{className:"docs-font-display text-sm text-[var(--docs-accent)] italic",children:[wy($),"."]},void 0,!0,void 0,this)," ",B.section]},void 0,!0,void 0,this),f&&h2("ol",{className:"mt-0.5 list-none p-0",children:B.docs.map((Y)=>{let X=Y.metadata.slug===w;return h2("li",{children:h2("a",{className:`docs-rail__doc relative block py-1.5 docs-font-body text-sm leading-[1.4] tracking-normal transition-[color,padding-left] duration-150 hover:text-[var(--docs-text)] ${X?"pl-3.5 font-medium text-[var(--docs-accent)]":"text-[var(--docs-text-muted)]"}`,href:Qy(Y),"aria-current":X?"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)]},B.section,!0,void 0,this)})},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),va1=({prevDoc:A,nextDoc:Q})=>{if(!A&&!Q)return null;return h2("nav",{className:"mt-12 grid grid-cols-1 gap-5 border-t border-[var(--docs-border)] pt-7 md:grid-cols-2","aria-label":"Previous and next docs",children:[A?h2("a",{className:"group border-t border-[var(--docs-border-light)] pt-[18px] transition-colors duration-150 hover:border-[var(--docs-accent)]",href:Qy(A),children:[h2("span",{className:"block docs-font-label text-[10.5px] uppercase tracking-[0.22em] text-[var(--docs-text-light)]",children:"Previous"},void 0,!1,void 0,this),h2("span",{className:"mt-2 block docs-font-display text-[22px] leading-[1.2] text-[var(--docs-heading)] transition-colors duration-150 group-hover:text-[var(--docs-accent)]",children:["\u2190 ",A.metadata.title]},void 0,!0,void 0,this)]},void 0,!0,void 0,this):h2("span",{},void 0,!1,void 0,this),Q&&h2("a",{className:"group border-t border-[var(--docs-border-light)] pt-[18px] text-left transition-colors duration-150 hover:border-[var(--docs-accent)] md:text-right",href:Qy(Q),children:[h2("span",{className:"block docs-font-label text-[10.5px] uppercase tracking-[0.22em] text-[var(--docs-text-light)]",children:"Next"},void 0,!1,void 0,this),h2("span",{className:"mt-2 block docs-font-display text-[22px] leading-[1.2] text-[var(--docs-heading)] transition-colors duration-150 group-hover:text-[var(--docs-accent)]",children:[Q.metadata.title," \u2192"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as By}from"preact/jsx-dev-runtime";var Sr0=({docs:A})=>{let Q=cr(A),w=cf0(Q),$=Q.filter((f)=>f.metadata.slug!=="index")[0]??Q[0];return By(pf0,{title:"Documentation",description:"Brains documentation",children:[By(ja1,{docsCount:A.length,sectionsCount:w.length,startDoc:$},void 0,!1,void 0,this),By("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:[By(Pa1,{groups:w},void 0,!1,void 0,this),By("div",{children:w.map((f,Y)=>By(Ma1,{group:f,index:Y},f.section,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as CZ}from"preact/jsx-dev-runtime";var mr0=({doc:A,docs:Q,prevDoc:w,nextDoc:B})=>{let $=cf0(Q.length>0?Q:[A]),f=cr(Q.length>0?Q:[A]),Y=f.findIndex((H)=>H.metadata.slug===A.metadata.slug),X=Math.max($.findIndex((H)=>H.docs.some((W)=>W.metadata.slug===A.metadata.slug)),0);return CZ(pf0,{title:A.metadata.title,description:A.metadata.description??A.metadata.section,detail:!0,footer:!0,contentClassName:"pt-16",children:[CZ(Oa1,{title:A.metadata.title},void 0,!1,void 0,this),CZ("div",{className:"grid items-start gap-10 py-8 pb-24 md:grid-cols-[240px_minmax(0,1fr)] md:gap-20",children:[CZ(xa1,{groups:$,activeGroupIndex:X,activeSlug:A.metadata.slug},void 0,!1,void 0,this),CZ("article",{className:"min-w-0",children:[CZ("header",{className:"mb-10 border-b border-[var(--docs-border)] pb-8",children:[CZ("p",{className:`${dD.label} m-0 mb-6 flex items-baseline gap-3`,children:[CZ("span",{className:"docs-font-display text-lg leading-none tracking-normal normal-case text-[var(--docs-accent)] italic",children:[wy(X),"."]},void 0,!0,void 0,this)," ",A.metadata.section,Y>=0?` \xB7 ${Y+1}/${f.length}`:""]},void 0,!0,void 0,this),CZ("h1",{className:`${dD.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&&CZ("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),CZ("div",{className:"docs-article__body",children:CZ(F9,{markdown:A.body},void 0,!1,void 0,this)},void 0,!1,void 0,this),CZ(va1,{prevDoc:w,nextDoc:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};var JWw=Z.object({currentPage:Z.number(),totalPages:Z.number(),totalItems:Z.number(),pageSize:Z.number(),hasNextPage:Z.boolean(),hasPrevPage:Z.boolean()}),IWw=Z.union([Z.enum(["public","shared","restricted"]),Z.literal("private")]).optional().transform((A)=>{if(A===void 0)return"public";if(A==="private")return"restricted";return A}),FWw=Z.object({title:Z.string(),section:Z.string(),order:Z.number().int(),sourcePath:Z.string(),description:Z.string().optional(),slug:Z.string().optional()}),LWw=Z.object({title:Z.string(),section:Z.string(),order:Z.number().int(),description:Z.string().optional(),slug:Z.string()}),lr=Z.object({id:Z.string(),entityType:Z.literal("doc"),content:Z.string(),created:Z.string(),updated:Z.string(),visibility:IWw,metadata:LWw,contentHash:Z.string(),frontmatter:FWw,body:Z.string()}),kWw=Z.object({docs:Z.array(lr),pagination:JWw.nullable(),baseUrl:Z.string().optional()}),_Ww=Z.object({doc:lr,docs:Z.array(lr),prevDoc:lr.nullable(),nextDoc:lr.nullable()});function Ra1(){return{"doc-list":d1({name:"doc-list",description:"Documentation index template",schema:kWw,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:Sr0}}),"doc-detail":d1({name:"doc-detail",description:"Documentation page template",schema:_Ww,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:mr0}})}}var ha1={name:"@brains/doc",version:"0.2.0-alpha.151",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 ur0 extends rQ{entityType=mf0.entityType;schema=Ay;adapter=mf0;constructor(){super("docs",ha1,{},k7)}getTemplates(){return Ra1()}getDataSources(){return[new uf0(this.logger.child("DocDataSource"))]}}function pr(){return new ur0}wA();U2();_0();gB();_0();var cr0=Z.literal("application/pdf"),Ca1=Z.enum(["pending","draft","failed"]),lr0=Z.object({title:Z.string().optional(),mimeType:cr0,filename:Z.string().min(1),pageCount:Z.number().int().min(0).optional(),status:Ca1.optional(),processingJobId:Z.string().optional(),processingError:Z.string().optional(),sourceEntityType:Z.string().min(1).optional(),sourceEntityId:Z.string().min(1).optional(),sourceUploadId:Z.string().optional(),sourceFilename:Z.string().optional(),sourceMediaType:Z.string().optional(),attachmentType:Z.string().min(1).optional(),dedupKey:Z.string().min(1).optional()}),$y=_Q.extend({entityType:Z.literal("document"),content:Z.string().regex(/^data:application\/pdf;base64,.+$/),metadata:lr0});function ir(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 if0(A){return`data:application/pdf;base64,${Buffer.from(A).toString("base64")}`}function pr0(A){let Q=Buffer.from(A).toString("latin1"),w=0,B=/\/Type\s*\/Pages\b[^]*?\/Count\s+(\d+)|\/Count\s+(\d+)[^]*?\/Type\s*\/Pages\b/g;for(let f of Q.matchAll(B)){let Y=parseInt(f[1]??f[2]??"0",10);if(Y>w)w=Y}if(w>0)return w;return Q.match(/\/Type\s*\/Page(?!\w)/g)?.length??0}class df0{entityType="document";purpose="A durable rendered file artifact such as a printable or carousel PDF.";schema=$y;toMarkdown(A){return A.content}fromMarkdown(A){return ir(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:B}=ir(Q);return{entityType:"document",content:Q,metadata:{mimeType:B,...w}}}}var $V=new df0;async function xo0(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 $=(await Promise.resolve().then(() => (le1(),ce1))).getDocument({data:new Uint8Array(A),disableFontFace:!1,useSystemFonts:!0,useWorkerFetch:!1}),f=await $.promise;try{let Y=Q.maxPages??50;if(f.numPages>Y)throw Error(`Uploaded PDF has ${f.numPages} pages; maximum supported for synchronous markdown extraction is ${Y}`);let X=[];for(let W=1;W<=f.numPages;W+=1){let G=(await(await f.getPage(W)).getTextContent()).items.flatMap((q)=>("str"in q)?[q.str]:[]).join(" ").replace(/\s+/g," ").trim();if(G.length>0)X.push(G)}let H=X.join(`
|
|
7157
7157
|
|
|
7158
|
-
`).trim();if(!H)throw Error("Could not extract text from the uploaded PDF");return H}finally{await $.destroy()}}wA();u9();U2();_0();import{createHash as KKw}from"crypto";var UKw=26214400,GKw=20,DKw=60000,pe1=80,zKw=10,qKw={renderUrl:Z.url().optional(),sourceEntityType:Z.string().min(1),sourceEntityId:Z.string().min(1),attachmentType:Z.string().min(1),documentId:Z.string().min(1).optional(),title:Z.string().min(1).optional(),filename:Z.string().min(1).optional(),dedupKey:Z.string().min(1).optional(),replace:Z.boolean().optional(),pageCount:Z.number().int().min(0).optional(),maxPageCount:Z.number().int().positive().optional(),maxBytes:Z.number().int().positive().optional(),timeoutMs:Z.number().int().positive().optional(),width:Z.union([Z.string(),Z.number()]).optional(),height:Z.union([Z.string(),Z.number()]).optional(),format:Z.string().optional(),targetEntityType:Z.string().min(1).optional(),targetEntityId:Z.string().min(1).optional()},de1=Z.object(qKw),RY0=de1.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 hY0 extends tw{context;renderPdf;constructor(A,Q,w={}){super(A,{schema:RY0,jobTypeName:"document-generate"});this.context=Q,this.renderPdf=w.renderPdf??kU}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 B=A.maxPageCount??GKw,$=A.maxBytes??UKw,f=A.timeoutMs??DKw;if(A.pageCount!==void 0&&A.pageCount>B)throw Error(`Refusing to render ${A.pageCount} page PDF; maxPageCount=${B}`);let Y=await this.getDedupKey(A),X=vo0(A,Y),H=A.documentId!==void 0||A.filename!==void 0;if(A.replace!==!0){let W=await this.findDocumentByDedupKey(Y,H?X:void 0);if(W&&(!H||W.id===X)){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,X,{timeoutMs:f,maxBytes:$}),K=W.data;if(K.byteLength>$)throw Error(`Rendered PDF exceeds maxBytes=${$}: ${K.byteLength} bytes`);let U=pr0(K);if(U>B)throw Error(`Rendered PDF has ${U} pages, exceeding maxPageCount=${B}`);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:`${X}.pdf`),V=$V.createDocumentEntity({dataUrl:if0(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 Jf({entityService:this.context.entityService,entity:{...V,id:X}}),A.targetEntityType&&A.targetEntityId)await this.attachDocumentToTarget(A.targetEntityType,A.targetEntityId,X,A);return await this.reportProgress(w,{progress:100,message:"PDF document generation complete"}),{success:!0,documentId:X,reused:!1}}catch(W){let K=SA(W);throw this.logger.error("Document generation failed",{jobId:Q,error:K}),await kG({entityService:this.context.entityService,entityType:"document",id:X,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 B=await this.context.attachments.resolve({sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType});if(!B)throw Error(`No attachment provider found for ${A.sourceEntityType}/${A.attachmentType}`);if(B.type!=="document")throw Error(`Attachment provider returned ${B.type}; expected document`);return B}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(($)=>$.id),preferredDocumentId:Q});let B=w.filter(($)=>$.metadata.status!=="pending"&&$.metadata.status!=="failed");return B.find(($)=>$.id===Q)??B[0]}async attachDocumentToTarget(A,Q,w,B){let $=await this.context.entityService.getEntity({entityType:A,id:Q});if(!$)throw Error(`Target entity not found: ${A}/${Q}`);let{frontmatter:f}=P6($.content),Y=Array.isArray(f.documents)?f.documents.filter(bKw):[],X=B.replace?await this.removeReferencesForSameSourceAttachment(Y,w,B):Y,H=X.some((W)=>W.id===w)?X:[...X,{id:w}];await this.context.entityService.updateEntity({entity:{...$,content:D4($.content,"documents",H)}})}async removeReferencesForSameSourceAttachment(A,Q,w){let B=[];for(let $ of A){if($.id===Q){B.push($);continue}let f=await this.context.entityService.getEntity({entityType:"document",id:$.id});if(!f||!JKw(f,w))B.push($)}return B}}function vo0(A,Q){let w=`${A.attachmentType}:${A.sourceEntityType}:${A.sourceEntityId}:${A.renderUrl??"resolved-attachment"}`,B=A.documentId??A.filename?.replace(/\.pdf$/i,"")??Q??w,$=A.replace===!0&&A.documentId===void 0?`${B}-${Date.now()}`:B;return VKw($)}function VKw(A){let Q=H1(A.replace(/[/:]+/g," "))||`document-${ie1(A)}`;if(Q.length<=pe1)return Q;let w=`-${ie1(A)}`;return`${Q.slice(0,pe1-w.length).replace(/-+$/g,"")}${w}`}function ie1(A){return KKw("sha256").update(A).digest("hex").slice(0,zKw)}function bKw(A){return typeof A==="object"&&A!==null&&"id"in A&&typeof A.id==="string"&&A.id.length>0}function JKw(A,Q){return A.metadata.sourceEntityType===Q.sourceEntityType&&A.metadata.sourceEntityId===Q.sourceEntityId&&A.metadata.attachmentType===Q.attachmentType}var ne1={name:"@brains/document-plugin",version:"0.2.0-alpha.
|
|
7158
|
+
`).trim();if(!H)throw Error("Could not extract text from the uploaded PDF");return H}finally{await $.destroy()}}wA();u9();U2();_0();import{createHash as KKw}from"crypto";var UKw=26214400,GKw=20,DKw=60000,pe1=80,zKw=10,qKw={renderUrl:Z.url().optional(),sourceEntityType:Z.string().min(1),sourceEntityId:Z.string().min(1),attachmentType:Z.string().min(1),documentId:Z.string().min(1).optional(),title:Z.string().min(1).optional(),filename:Z.string().min(1).optional(),dedupKey:Z.string().min(1).optional(),replace:Z.boolean().optional(),pageCount:Z.number().int().min(0).optional(),maxPageCount:Z.number().int().positive().optional(),maxBytes:Z.number().int().positive().optional(),timeoutMs:Z.number().int().positive().optional(),width:Z.union([Z.string(),Z.number()]).optional(),height:Z.union([Z.string(),Z.number()]).optional(),format:Z.string().optional(),targetEntityType:Z.string().min(1).optional(),targetEntityId:Z.string().min(1).optional()},de1=Z.object(qKw),RY0=de1.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 hY0 extends tw{context;renderPdf;constructor(A,Q,w={}){super(A,{schema:RY0,jobTypeName:"document-generate"});this.context=Q,this.renderPdf=w.renderPdf??kU}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 B=A.maxPageCount??GKw,$=A.maxBytes??UKw,f=A.timeoutMs??DKw;if(A.pageCount!==void 0&&A.pageCount>B)throw Error(`Refusing to render ${A.pageCount} page PDF; maxPageCount=${B}`);let Y=await this.getDedupKey(A),X=vo0(A,Y),H=A.documentId!==void 0||A.filename!==void 0;if(A.replace!==!0){let W=await this.findDocumentByDedupKey(Y,H?X:void 0);if(W&&(!H||W.id===X)){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,X,{timeoutMs:f,maxBytes:$}),K=W.data;if(K.byteLength>$)throw Error(`Rendered PDF exceeds maxBytes=${$}: ${K.byteLength} bytes`);let U=pr0(K);if(U>B)throw Error(`Rendered PDF has ${U} pages, exceeding maxPageCount=${B}`);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:`${X}.pdf`),V=$V.createDocumentEntity({dataUrl:if0(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 Jf({entityService:this.context.entityService,entity:{...V,id:X}}),A.targetEntityType&&A.targetEntityId)await this.attachDocumentToTarget(A.targetEntityType,A.targetEntityId,X,A);return await this.reportProgress(w,{progress:100,message:"PDF document generation complete"}),{success:!0,documentId:X,reused:!1}}catch(W){let K=SA(W);throw this.logger.error("Document generation failed",{jobId:Q,error:K}),await kG({entityService:this.context.entityService,entityType:"document",id:X,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 B=await this.context.attachments.resolve({sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType});if(!B)throw Error(`No attachment provider found for ${A.sourceEntityType}/${A.attachmentType}`);if(B.type!=="document")throw Error(`Attachment provider returned ${B.type}; expected document`);return B}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(($)=>$.id),preferredDocumentId:Q});let B=w.filter(($)=>$.metadata.status!=="pending"&&$.metadata.status!=="failed");return B.find(($)=>$.id===Q)??B[0]}async attachDocumentToTarget(A,Q,w,B){let $=await this.context.entityService.getEntity({entityType:A,id:Q});if(!$)throw Error(`Target entity not found: ${A}/${Q}`);let{frontmatter:f}=P6($.content),Y=Array.isArray(f.documents)?f.documents.filter(bKw):[],X=B.replace?await this.removeReferencesForSameSourceAttachment(Y,w,B):Y,H=X.some((W)=>W.id===w)?X:[...X,{id:w}];await this.context.entityService.updateEntity({entity:{...$,content:D4($.content,"documents",H)}})}async removeReferencesForSameSourceAttachment(A,Q,w){let B=[];for(let $ of A){if($.id===Q){B.push($);continue}let f=await this.context.entityService.getEntity({entityType:"document",id:$.id});if(!f||!JKw(f,w))B.push($)}return B}}function vo0(A,Q){let w=`${A.attachmentType}:${A.sourceEntityType}:${A.sourceEntityId}:${A.renderUrl??"resolved-attachment"}`,B=A.documentId??A.filename?.replace(/\.pdf$/i,"")??Q??w,$=A.replace===!0&&A.documentId===void 0?`${B}-${Date.now()}`:B;return VKw($)}function VKw(A){let Q=H1(A.replace(/[/:]+/g," "))||`document-${ie1(A)}`;if(Q.length<=pe1)return Q;let w=`-${ie1(A)}`;return`${Q.slice(0,pe1-w.length).replace(/-+$/g,"")}${w}`}function ie1(A){return KKw("sha256").update(A).digest("hex").slice(0,zKw)}function bKw(A){return typeof A==="object"&&A!==null&&"id"in A&&typeof A.id==="string"&&A.id.length>0}function JKw(A,Q){return A.metadata.sourceEntityType===Q.sourceEntityType&&A.metadata.sourceEntityId===Q.sourceEntityId&&A.metadata.attachmentType===Q.attachmentType}var ne1={name:"@brains/document-plugin",version:"0.2.0-alpha.151",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 FKw=`data:application/pdf;base64,${Buffer.from(`%PDF-1.4
|
|
7159
7159
|
% Pending document placeholder
|
|
7160
7160
|
%%EOF
|
|
7161
7161
|
`).toString("base64")}`,LKw=Z.object({}).catchall(Z.unknown()).transform(()=>({})),Ro0={namespace:"upload",refKind:"upload",routePath:"/api/chat/uploads"};function kKw(A,Q){let w=A.title?.trim();if(w)return w;return Q.replace(/\.[^.]+$/,"").trim()||Q}function _Kw(A,Q){return`data:${A};base64,${Q.toString("base64")}`}function NKw(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 ho0 extends tQ{entityType=$V.entityType;schema=$y;adapter=$V;pluginContext;constructor(){super("document",ne1,{},LKw)}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 hY0(this.logger.child("DocumentGenerationJobHandler"),A))}async interceptCreate(A){let Q=this.pluginContext;if(A.from?.kind===Ro0.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=RY0.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}}),B=await this.getDedupKey(w,Q),$=w.replace===!0?void 0:await this.findExistingDocument(B,Q),f=$?.id??vo0(w,B);if(!$)await this.createPendingDocument(Q,{id:f,title:w.title??f,filename:`${f}.pdf`,sourceEntityType:w.sourceEntityType,sourceEntityId:w.sourceEntityId,attachmentType:w.attachmentType,dedupKey:B});let Y=await Q.jobs.enqueue({type:"generate",data:{...w,dedupKey:B,documentId:f}}),X=`${f}.pdf`;return{kind:"handled",result:{success:!0,data:{entityId:f,jobId:Y,status:"generating",attachment:{mediaType:"application/pdf",url:`/api/chat/attachments/document?id=${encodeURIComponent(f)}`,downloadUrl:`/api/chat/attachments/document?id=${encodeURIComponent(f)}&download=1`,filename:X,source:{entityType:"document",entityId:f,attachmentType:w.attachmentType}}}}}}async promoteUpload(A,Q){let w=A.from;if(w?.kind!==Ro0.refKind)return{kind:"handled",result:{success:!1,error:"Unsupported upload ref kind"}};let B;try{B=await Q.uploads.scoped(Ro0).read(w.id)}catch{return{kind:"handled",result:{success:!1,error:"Upload ref not found"}}}if(B.record.mediaType!=="application/pdf")return{kind:"handled",result:{success:!1,error:"Only PDF uploads can be promoted to document entities"}};let $=kKw(A,B.record.filename),f=H1($);if(!f)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(),X=$V.createDocumentEntity({dataUrl:_Kw(B.record.mediaType,B.content),filename:B.record.filename,title:$,status:"draft",sourceUploadId:w.id,sourceFilename:B.record.filename,sourceMediaType:B.record.mediaType,attachmentType:"uploaded",dedupKey:`upload:${w.kind}:${w.id}`}),H=await Q.entityService.createEntity({entity:{id:f,...X,created:Y,updated:Y},options:{deduplicateId:!0}});return{kind:"handled",result:{success:!0,data:{entityId:H.entityId,status:"created",attachment:NKw({entityId:H.entityId,filename:B.record.filename})}}}}async createPendingDocument(A,Q){let w=new Date().toISOString(),B=$V.createDocumentEntity({dataUrl:FKw,filename:Q.filename,title:Q.title,status:"pending",sourceEntityType:Q.sourceEntityType,sourceEntityId:Q.sourceEntityId,attachmentType:Q.attachmentType,dedupKey:Q.dedupKey});await Vk({entityService:A.entityService,entity:{id:Q.id,...B,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`,B=await Q.entityService.getEntity({entityType:A.sourceEntityType,id:A.sourceEntityId});return B?`${w}:${B.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 Co0(){return new ho0}wA();_0();wA();_0();var re1=Z.enum(["generating","failed"]),jKw=Z.enum(["generating","failed"]),_F=Z.object({title:Z.string().optional(),status:re1.optional(),error:Z.string().optional()}),PKw=Z.object({title:Z.string(),status:re1.optional(),error:Z.string().optional()}),MKw=Z.object({title:Z.string(),status:jKw.optional(),error:Z.string().optional()}),NF=_Q.extend({entityType:Z.literal("note"),metadata:MKw}),OKw=NF.extend({frontmatter:_F,body:Z.string()});wA();_0();var xKw=Z.record(Z.string(),Z.unknown());class go0 extends g2{constructor(){super({entityType:"note",purpose:"A short, free-form captured thought, reference, or snippet the user wants to keep.",schema:NF,frontmatterSchema:_F})}toMarkdown(A){let Q=this.extractBody(A.content);try{let w=this.parseFrontMatter(A.content,_F);if(Object.values(w).some((B)=>B!==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,_F)}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,xKw);if(Object.keys(w).length===0)return Q;let B={...w,title:w.title??A},$=this.extractBody(Q);return this.buildMarkdown($,B)}catch{return Q}}extractH1(A){return A.match(/^#\s+(.+)$/m)?.[1]?.trim()??null}}var ZV=new go0;_0();var yo0=Z.object({defaultPrompt:Z.string().default("Create a note summarizing key concepts from my knowledge base")});_0();wA();var oe1=Z.object({title:Z.string().max(80).describe("A clear, descriptive title for the note (3-8 words)"),body:Z.string().describe("Note content in markdown format with clear organization and structure")}),Eo0=d1({name:"note:generation",description:"Template for AI to generate notes from prompts",schema:oe1,dataSourceId:"shell:ai-content",requiredPermission:"public",useKnowledgeContext:!0,basePrompt:`You are helping to create personal knowledge notes for research and reference.
|
|
@@ -7173,7 +7173,7 @@ title: ${JSON.stringify(A)}
|
|
|
7173
7173
|
---
|
|
7174
7174
|
|
|
7175
7175
|
${Q.trim()}
|
|
7176
|
-
`}var gKw={namespace:"upload",refKind:"upload",routePath:"/api/chat/uploads"},yKw=Z.object({uploadId:Z.string().min(1),entityId:Z.string().min(1),title:Z.string().optional()});class So0 extends tw{context;constructor(A,Q){super(A,{schema:yKw,jobTypeName:"upload-import"});this.context=Q}async process(A,Q,w){try{await this.reportProgress(w,{progress:10,message:"Reading uploaded file"});let B=await this.context.uploads.scoped(gKw).read(A.uploadId);await this.reportProgress(w,{progress:35,message:"Extracting markdown from upload"});let $=await ee1({upload:B,...A.title!==void 0?{title:A.title}:{}});await this.reportProgress(w,{progress:80,message:"Saving imported note"});let f=new Date().toISOString(),Y=ZV.fromMarkdown($.content),X=await Jf({entityService:this.context.entityService,entity:{id:A.entityId,entityType:"note",content:$.content,metadata:{title:$.title,...Y.metadata},created:f,updated:f}});return await this.reportProgress(w,{progress:100,message:"Upload imported as markdown note"}),{entityId:X.entityId,status:"created"}}catch(B){return await this.markStubFailed(A.entityId,SA(B)),w$.failure(B)}}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:D4(D4(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}}}wA();async function A02({entity:A,config:Q}){let w=NF.parse(A),B=n2(w.content,_F);return{$type:"ai.rizom.brain.note",title:w.metadata.title,body:B.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 mo0(){return{entityType:"note",collection:"ai.rizom.brain.note",lexicon:k6["ai.rizom.brain.note"],validate:!1,buildRecord:A02}}var Q02={name:"@brains/note",version:"0.2.0-alpha.
|
|
7176
|
+
`}var gKw={namespace:"upload",refKind:"upload",routePath:"/api/chat/uploads"},yKw=Z.object({uploadId:Z.string().min(1),entityId:Z.string().min(1),title:Z.string().optional()});class So0 extends tw{context;constructor(A,Q){super(A,{schema:yKw,jobTypeName:"upload-import"});this.context=Q}async process(A,Q,w){try{await this.reportProgress(w,{progress:10,message:"Reading uploaded file"});let B=await this.context.uploads.scoped(gKw).read(A.uploadId);await this.reportProgress(w,{progress:35,message:"Extracting markdown from upload"});let $=await ee1({upload:B,...A.title!==void 0?{title:A.title}:{}});await this.reportProgress(w,{progress:80,message:"Saving imported note"});let f=new Date().toISOString(),Y=ZV.fromMarkdown($.content),X=await Jf({entityService:this.context.entityService,entity:{id:A.entityId,entityType:"note",content:$.content,metadata:{title:$.title,...Y.metadata},created:f,updated:f}});return await this.reportProgress(w,{progress:100,message:"Upload imported as markdown note"}),{entityId:X.entityId,status:"created"}}catch(B){return await this.markStubFailed(A.entityId,SA(B)),w$.failure(B)}}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:D4(D4(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}}}wA();async function A02({entity:A,config:Q}){let w=NF.parse(A),B=n2(w.content,_F);return{$type:"ai.rizom.brain.note",title:w.metadata.title,body:B.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 mo0(){return{entityType:"note",collection:"ai.rizom.brain.note",lexicon:k6["ai.rizom.brain.note"],validate:!1,buildRecord:A02}}var Q02={name:"@brains/note",version:"0.2.0-alpha.151",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 w02={namespace:"upload",refKind:"upload",routePath:"/api/chat/uploads"},TKw=Z.object({prompt:Z.string()});class uo0 extends rQ{entityType=ZV.entityType;schema=NF;adapter=ZV;unregisterAtprotoProjection;constructor(A={}){super("note",Q02,A,yo0)}async interceptCreate(A,Q,w){if(A.from?.kind!==w02.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 B=A.from.id,$;try{$=await w.uploads.scoped(w02).readRecord(B)}catch{return{kind:"handled",result:{success:!1,error:"Upload ref not found"}}}try{if(!te1($.mediaType))return{kind:"handled",result:{success:!1,error:"Only text, JSON, and PDF uploads can be imported as markdown notes"}};let f=To0({filename:$.filename,...A.title!==void 0?{title:A.title}:{}}),Y=ZV.buildStub({id:f.id,title:f.title}),X=new Date().toISOString(),H=await w.entityService.createEntity({entity:{id:f.id,entityType:"note",content:Y.content,metadata:Y.metadata,created:X,updated:X},options:{deduplicateId:!0}}),W=await w.jobs.enqueue({type:"upload-import",data:{uploadId:B,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(f){return{kind:"handled",result:{success:!1,error:f instanceof Error?f.message:"Failed to import upload as markdown"}}}}createGenerationHandler(A){return new CY0(this.logger.child("NoteGenerationJobHandler"),A)}getTemplates(){return{generation:Eo0}}async onRegister(A){A.jobs.registerHandler("upload-import",new So0(this.logger.child("UploadMarkdownImportJobHandler"),A)),A.eval.registerHandler("generateNote",async(Q)=>{let w=TKw.parse(Q);return A.ai.generate({prompt:w.prompt,templateName:"note:generation"})}),this.unregisterAtprotoProjection=Q5.getInstance().register(mo0())}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 BP(A={}){return new uo0(A)}wA();_0();wA();var B02=Z.object({ref:Z.string(),label:Z.string()}),$02=Z.enum(["pending","draft","published"]),SKw=Z.enum(["pending","draft","published"]),Vo=Z.object({status:$02,title:Z.string(),url:Z.string().url(),description:Z.string().optional(),domain:Z.string(),capturedAt:Z.string().datetime(),source:B02}),mKw=Vo.pick({title:!0,status:!0}),uKw=Z.object({title:Z.string(),status:SKw}),$P=_Q.extend({entityType:Z.literal("link"),metadata:uKw});U2();_0();_0();var co0=Z.object({enableSummarization:Z.boolean().default(!0).describe("Generate AI summaries for captured links"),jinaApiKey:Z.string().optional().describe("Jina Reader API key for higher rate limits (500 RPM vs 20 RPM without key)")});wA();class jF extends g2{constructor(){super({entityType:"link",purpose:"A saved external URL or web resource captured for later reference.",schema:$P,frontmatterSchema:Vo})}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,Vo),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 by=new jF;wA();_0();var cKw=Z.object({success:Z.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:Z.string().describe("If success is false, explain why content could not be extracted. Use an empty string when success is true."),title:Z.string().max(80).describe("The page title - extract from the content or create a descriptive one. Leave empty string if success is false."),description:Z.string().describe("A one-sentence description of what the page is about. Leave empty string if success is false."),summary:Z.string().describe("A 1-2 paragraph summary of the main content. Leave empty string if success is false.")}),f02=d1({name:"link:extraction",description:"Extract structured content from webpage markdown",dataSourceId:"shell:ai-content",schema:cKw,basePrompt:`You are an expert at extracting key information from webpage content.
|
|
7177
7177
|
|
|
7178
7178
|
You will receive webpage content in markdown format. Your job is to extract structured information from it.
|
|
7179
7179
|
|
|
@@ -7195,7 +7195,7 @@ Accuracy rules:
|
|
|
7195
7195
|
|
|
7196
7196
|
`))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 rKw}from"crypto";class PF{static URL_PATTERN=/https?:\/\/[^\s<>"{}|\\^`[\]]+?(?=[,;:\s]|$)/gi;static extractUrls(A){let Q=A.match(PF.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=rKw("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}}}wA();_0();y6();var oKw=Z.object({interfaceId:Z.string().optional(),userId:Z.string().optional(),channelId:Z.string().optional(),channelName:Z.string().optional(),timestamp:Z.string().optional()}),sKw=Z.object({url:Z.url(),metadata:oKw.optional()}),n6$=Z.object({success:Z.boolean(),entityId:Z.string().optional(),title:Z.string().optional(),url:Z.string().optional(),status:Z.enum(["pending","draft","published"]).optional(),error:Z.string().optional()});class yY0 extends tw{context;linkAdapter;urlFetcher;constructor(A,Q,w){super(A,{schema:sKw,jobTypeName:"link-capture"});this.context=Q,this.linkAdapter=new jF,this.urlFetcher=new Jy(w?.jinaApiKey?{jinaApiKey:w.jinaApiKey}:void 0)}async process(A,Q,w){let{url:B,metadata:$}=A;try{await w.report({progress:nQ.START,total:100,message:"Starting link capture"});let f=PF.generateEntityId(B);await w.report({progress:nQ.INIT,total:100,message:"Checking for existing link"});let Y=await this.context.entityService.getEntity({entityType:"link",id:f});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:B,entityId:f}),{success:!0,entityId:Y.id,title:q.title,url:B,status:V};this.logger.info("Pending link exists, completing extraction",{url:B,entityId:f})}let X=this.resolveSource($),H=new Date().toISOString();await w.report({progress:nQ.FETCH,total:100,message:"Fetching webpage content"});let W=await this.urlFetcher.fetch(B);if(!W.success){if(W.errorType==="url_not_found"||W.errorType==="url_unreachable"){this.logger.warn("Link URL not accessible",{url:B,errorType:W.errorType,error:W.error});let q=new URL(B).hostname,V=`Could not capture link: ${W.error}`,J=this.linkAdapter.createLinkContent({status:"pending",title:q,url:B,description:V,summary:V,domain:q,capturedAt:H,source:X});return await Jf({entityService:this.context.entityService,entity:{id:f,entityType:"link",content:J,metadata:{status:"pending",title:q}}}),{success:!1,entityId:f,title:q,url:B,status:"pending",error:V}}}await w.report({progress:nQ.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:
|
|
7197
7197
|
|
|
7198
|
-
${W.content}`:`The URL ${B} could not be fetched. Return success: false with error: "${W.error}"`,data:{url:B,hasContent:W.success},interfacePermissionGrant:"public"});if(this.logger.debug("AI extraction result",{result:K}),await w.report({progress:nQ.EXTRACT,total:100,message:"Processing extraction results"}),K.success===!1||!K.title||!K.description||!K.summary){let q=K.title||new URL(B).hostname;this.logger.info("Incomplete extraction, saving as pending",{url:B}),await w.report({progress:nQ.SAVE,total:100,message:"Saving link as pending"});let V=this.linkAdapter.createLinkContent({status:"pending",title:q,url:B,description:K.description,summary:K.summary,domain:new URL(B).hostname,capturedAt:H,source:X}),J=await Jf({entityService:this.context.entityService,entity:{id:f,entityType:"link",content:V,metadata:{status:"pending",title:q}}});return await w.report({progress:nQ.COMPLETE,total:100,message:"Link saved (pending)"}),{success:!0,entityId:J.entityId,title:q,url:B,status:"pending"}}await w.report({progress:nQ.SAVE,total:100,message:`Saving link: "${K.title}"`});let U=this.linkAdapter.createLinkContent({status:"draft",title:K.title,url:B,description:K.description,summary:K.summary,domain:new URL(B).hostname,capturedAt:H,source:X}),G=await Jf({entityService:this.context.entityService,entity:{id:f,entityType:"link",content:U,metadata:{status:"draft",title:K.title}}});return await w.report({progress:nQ.COMPLETE,total:100,message:`Link captured: "${K.title}"`}),{success:!0,entityId:G.entityId,title:K.title,url:B,status:"draft"}}catch(f){return this.logger.error("Link capture job failed",{error:f,jobId:Q,data:A}),w$.failure(f)}}resolveSource(A){let Q=A?.channelId,w=A?.channelName;if(Q)return{ref:`matrix:${Q}`,label:w??Q};let B=A?.interfaceId??"cli";return{ref:`${B}:local`,label:B.toUpperCase()}}summarizeDataForLog(A){return{url:A.url,interfaceId:A.metadata?.interfaceId}}}async function Z02({entity:A,config:Q}){let w=$P.parse(A),{frontmatter:B,summary:$}=by.parseLinkContent(w.content);return{$type:"ai.rizom.brain.link",title:B.title,url:B.url,...B.description&&{description:B.description},...$&&{summary:$},domain:B.domain,capturedAt:B.capturedAt,source:B.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 ro0(){return{entityType:"link",collection:"ai.rizom.brain.link",lexicon:k6["ai.rizom.brain.link"],validate:!1,buildRecord:Z02}}var H02={name:"@brains/link",version:"0.2.0-alpha.
|
|
7198
|
+
${W.content}`:`The URL ${B} could not be fetched. Return success: false with error: "${W.error}"`,data:{url:B,hasContent:W.success},interfacePermissionGrant:"public"});if(this.logger.debug("AI extraction result",{result:K}),await w.report({progress:nQ.EXTRACT,total:100,message:"Processing extraction results"}),K.success===!1||!K.title||!K.description||!K.summary){let q=K.title||new URL(B).hostname;this.logger.info("Incomplete extraction, saving as pending",{url:B}),await w.report({progress:nQ.SAVE,total:100,message:"Saving link as pending"});let V=this.linkAdapter.createLinkContent({status:"pending",title:q,url:B,description:K.description,summary:K.summary,domain:new URL(B).hostname,capturedAt:H,source:X}),J=await Jf({entityService:this.context.entityService,entity:{id:f,entityType:"link",content:V,metadata:{status:"pending",title:q}}});return await w.report({progress:nQ.COMPLETE,total:100,message:"Link saved (pending)"}),{success:!0,entityId:J.entityId,title:q,url:B,status:"pending"}}await w.report({progress:nQ.SAVE,total:100,message:`Saving link: "${K.title}"`});let U=this.linkAdapter.createLinkContent({status:"draft",title:K.title,url:B,description:K.description,summary:K.summary,domain:new URL(B).hostname,capturedAt:H,source:X}),G=await Jf({entityService:this.context.entityService,entity:{id:f,entityType:"link",content:U,metadata:{status:"draft",title:K.title}}});return await w.report({progress:nQ.COMPLETE,total:100,message:`Link captured: "${K.title}"`}),{success:!0,entityId:G.entityId,title:K.title,url:B,status:"draft"}}catch(f){return this.logger.error("Link capture job failed",{error:f,jobId:Q,data:A}),w$.failure(f)}}resolveSource(A){let Q=A?.channelId,w=A?.channelName;if(Q)return{ref:`matrix:${Q}`,label:w??Q};let B=A?.interfaceId??"cli";return{ref:`${B}:local`,label:B.toUpperCase()}}summarizeDataForLog(A){return{url:A.url,interfaceId:A.metadata?.interfaceId}}}async function Z02({entity:A,config:Q}){let w=$P.parse(A),{frontmatter:B,summary:$}=by.parseLinkContent(w.content);return{$type:"ai.rizom.brain.link",title:B.title,url:B.url,...B.description&&{description:B.description},...$&&{summary:$},domain:B.domain,capturedAt:B.capturedAt,source:B.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 ro0(){return{entityType:"link",collection:"ai.rizom.brain.link",lexicon:k6["ai.rizom.brain.link"],validate:!1,buildRecord:Z02}}var H02={name:"@brains/link",version:"0.2.0-alpha.151",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 tKw=Z.object({url:Z.url()});class oo0 extends rQ{entityType=by.entityType;schema=$P;adapter=by;shell;unregisterAtprotoProjection;constructor(A={}){super("link",H02,A,co0)}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 yY0(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 f=this.adapter.fromMarkdown(A.content).metadata,Y=typeof f?.title==="string"?f.title:void 0,X=typeof f?.status==="string"?f.status:void 0,H=this.extractFirstUrl(A.content);if(Y&&X&&H){let W=H1(H)||H1(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:X},created:K,updated:K}})).entityId,status:"created"}}}}}catch{}let B=A.url??this.extractFirstUrl(A.content,A.prompt,A.title);if(B){if(!this.shell)throw Error("LinkPlugin shell was not initialized during register()");try{let $=await this.createPendingLink(B,A.title,Q,w),f=await this.shell.getJobQueueService().enqueue({type:"link-capture",data:{url:B,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:$,status:"generating",jobId:f}}}}catch($){return{kind:"handled",result:{success:!1,error:$ instanceof Error?$.message:"Failed to queue link capture job"}}}}if(A.content)return{kind:"handled",result:{success:!1,error:"Direct link creation requires full link markdown/frontmatter, or provide a URL to capture."}};if(A.prompt)return{kind:"handled",result:{success:!1,error:"Link creation requires a URL in the prompt, content, or title, or full link markdown content for direct creation."}};return{kind:"continue",input:A}}createGenerationHandler(A){return new yY0(this.logger.child("LinkCaptureJobHandler"),A,this.config.jinaApiKey?{jinaApiKey:this.config.jinaApiKey}:void 0)}getTemplates(){return{extraction:f02,"link-list":Y02,"link-detail":X02}}getDataSources(){return[new no0(this.logger.child("LinksDataSource"))]}async onRegister(A){this.unregisterAtprotoProjection=Q5.getInstance().register(ro0()),A.eval.registerHandler("extractContent",async(Q)=>{let{url:w}=tKw.parse(Q),$=await new Jy(this.config.jinaApiKey?{jinaApiKey:this.config.jinaApiKey}:void 0).fetch(w);if(!$.success)return{success:!1,error:$.error,errorType:$.errorType};return A.ai.generate({templateName:"link:extraction",prompt:`Extract structured information from this webpage content:
|
|
7199
7199
|
|
|
7200
7200
|
${$.content}`,data:{url:w,hasContent:!0},interfacePermissionGrant:"public"})})}async createPendingLink(A,Q,w,B){let $=PF.generateEntityId(A),f=new URL(A),Y=new Date().toISOString(),X=Q?.trim()?Q.trim():f.hostname,H=this.adapter.createLinkContent({status:"pending",title:X,url:A,description:"Link capture is in progress.",summary:`Pending link capture for ${A}.`,domain:f.hostname,capturedAt:Y,source:this.resolveSource(w)});return(await Vk({entityService:B.entityService,entity:{id:$,entityType:"link",content:H,metadata:{status:"pending",title:X},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]=PF.extractUrls(Q);if(w)return w}return}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}}function W02(A={}){return new oo0(A)}var fP=W02;_0();var eKw=Z.object({conversationId:Z.string().optional(),interfaceId:Z.string().optional(),userId:Z.string().optional(),messageId:Z.string().optional(),timestamp:Z.string().optional()}),FB$=Z.object({id:Z.string().optional(),metadata:eKw.optional()});wA();_0();jB();_0();wA();var K02=Z.enum(["generating","draft","published","failed"]),U02=Z.enum(["generating","draft","published","failed"]),K7=Z.object({title:Z.string(),slug:Z.string().optional(),status:K02,publishedAt:Z.string().datetime().optional(),description:Z.string(),year:Z.number(),coverImageId:Z.string().optional(),ogImageId:Z.string().optional(),url:Z.string().url().optional()}),AUw=K7.pick({title:!0,status:!0,publishedAt:!0,year:!0}).extend({slug:Z.string(),error:Z.string().optional()}),QUw=Z.object({title:Z.string(),status:U02,publishedAt:Z.string().datetime().optional(),year:Z.number(),slug:Z.string(),error:Z.string().optional()}),wUw=Z.object({title:Z.string(),slug:Z.string().optional(),status:U02,publishedAt:Z.string().datetime().optional(),description:Z.string(),year:Z.number(),coverImageId:Z.string().optional(),ogImageId:Z.string().optional(),url:Z.string().url().optional()}),MF=_Q.extend({entityType:Z.literal("project"),metadata:QUw}),EY0=Z.object({context:Z.string(),problem:Z.string(),solution:Z.string(),outcome:Z.string()}),Jo=MF.extend({frontmatter:wUw,body:Z.string(),structuredContent:EY0.optional(),coverImageUrl:Z.string().optional(),ogImageUrl:Z.string().optional()}),BUw=Jo.extend({url:Z.string().optional(),typeLabel:Z.string().optional(),coverImageUrl:Z.string().optional(),ogImageUrl:Z.string().optional(),coverImageWidth:Z.number().optional(),coverImageHeight:Z.number().optional()}),$Uw=Jo.extend({url:Z.string(),typeLabel:Z.string(),coverImageUrl:Z.string().optional(),ogImageUrl:Z.string().optional(),coverImageWidth:Z.number().optional(),coverImageHeight:Z.number().optional()});wA();U2();t8();class so0 extends z6{constructor(){super(EY0,{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 ao0=new so0;class to0 extends g2{constructor(){super({entityType:"project",purpose:"A project record in the user's portfolio.",schema:MF,frontmatterSchema:K7,supportsCoverImage:!0,bodyFormatter:ao0})}toMarkdown(A){let Q=this.extractBody(A.content);try{let w=this.parseFrontMatter(A.content,K7),B={...w,slug:w.slug??A.metadata.slug};return this.buildMarkdown(Q,B)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,K7),w=Q.slug??H1(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,K7)}parseStructuredContent(A){return ao0.parse(this.extractBody(A.content))}createProjectContent(A,Q){let w=ao0.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 YP=new to0;_0();var eo0=Z.looseObject({});import{jsxDEV as cZ,Fragment as YUw}from"preact/jsx-dev-runtime";var fUw=({project:A})=>{let{frontmatter:Q,url:w,coverImageUrl:B}=A;return cZ(G6,{href:w,children:[B&&cZ("img",{src:B,alt:Q.title,className:"w-full h-56 object-cover rounded-md mb-4"},void 0,!1,void 0,this),cZ(Y7,{children:Q.title},void 0,!1,void 0,this),cZ("p",{className:"text-theme leading-relaxed",children:Q.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},As0=({projects:A,pageTitle:Q,pagination:w,baseUrl:B="/projects"})=>{let $=Q??"Projects",f=w?.totalItems??A.length,Y=`Browse all ${f} ${f===1?"project":"projects"}`;return cZ(YUw,{children:[cZ(pQ,{title:$,description:Y},void 0,!1,void 0,this),cZ("div",{className:"project-list bg-theme",children:cZ("div",{className:"container mx-auto px-6 md:px-12 max-w-5xl py-16 md:py-24",children:[cZ("h1",{className:"text-4xl font-bold text-heading mb-12",children:$},void 0,!1,void 0,this),cZ("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-8",children:A.map((X)=>cZ(fUw,{project:X},X.id,!1,void 0,this))},void 0,!1,void 0,this),w&&w.totalPages>1&&cZ("div",{className:"mt-12",children:cZ(pq,{currentPage:w.currentPage,totalPages:w.totalPages,baseUrl:B},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 p6,Fragment as G02}from"preact/jsx-dev-runtime";var XUw=({prevProject:A,nextProject:Q})=>{if(!A&&!Q)return null;return p6("nav",{className:"pt-12 mt-12 border-t border-theme-muted",children:p6("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[A?p6(G6,{href:A.url,variant:"compact",children:[p6("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Previous"},void 0,!1,void 0,this),p6("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):p6("div",{},void 0,!1,void 0,this),Q&&p6(G6,{href:Q.url,variant:"compact",className:"md:text-right",children:[p6("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Next"},void 0,!1,void 0,this),p6("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)},TY0=({title:A,content:Q})=>{if(!Q)return null;return p6("section",{className:"mb-12",children:[p6("h2",{className:"text-2xl font-bold text-heading mb-4",children:A},void 0,!1,void 0,this),p6(F9,{markdown:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},Qs0=({project:A,prevProject:Q,nextProject:w})=>{let{frontmatter:B,structuredContent:$,metadata:f,coverImageUrl:Y}=A,X=A.ogImageUrl??Y;return p6(G02,{children:[p6(pQ,{title:B.title,description:B.description,...X?{ogImage:X}:{},ogType:"article"},void 0,!1,void 0,this),p6("article",{className:"project-detail",children:p6("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:p6("div",{className:"max-w-3xl mx-auto",children:[Y&&A.coverImageWidth&&A.coverImageHeight&&p6(cq,{src:Y,alt:B.title,width:A.coverImageWidth,height:A.coverImageHeight,className:"mb-8 shadow-lg"},void 0,!1,void 0,this),p6("h1",{className:"text-4xl md:text-5xl font-bold text-heading leading-tight tracking-tight mb-4",children:B.title},void 0,!1,void 0,this),p6("div",{className:"flex flex-wrap items-center gap-4 text-theme-muted mb-8",children:[p6("span",{className:"text-sm",children:f.year},void 0,!1,void 0,this),B.url&&p6(G02,{children:[p6("span",{className:"text-theme-muted",children:"|"},void 0,!1,void 0,this),p6("a",{href:B.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),p6("p",{className:"text-lg text-theme mb-12 leading-relaxed",children:B.description},void 0,!1,void 0,this),$&&p6("div",{className:"case-study",children:[p6(TY0,{title:"Context",content:$.context},void 0,!1,void 0,this),p6(TY0,{title:"Problem",content:$.problem},void 0,!1,void 0,this),p6(TY0,{title:"Solution",content:$.solution},void 0,!1,void 0,this),p6(TY0,{title:"Outcome",content:$.outcome},void 0,!1,void 0,this)]},void 0,!0,void 0,this),p6(XUw,{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)};_0();wA();var ZUw=Z.object({title:Z.string().max(80).describe("A clear, compelling project title (3-8 words). Should capture the essence of the project."),description:Z.string().describe("A 1-2 sentence summary of the project for portfolio cards. Focus on the core value delivered."),context:Z.string().describe("Background information: Who was the client/user? What was the situation? What constraints existed? (2-4 paragraphs)"),problem:Z.string().describe("The challenge: What specific problem needed solving? What were the pain points? (2-3 paragraphs)"),solution:Z.string().describe("The approach: What was built? What technologies/methods were used? How did it work? (3-5 paragraphs)"),outcome:Z.string().describe("The results: What impact did this have? What metrics improved? What was learned? (2-3 paragraphs)")}),ws0=d1({name:"portfolio:generation",description:"Template for AI to generate portfolio project case studies",schema:ZUw,dataSourceId:"shell:ai-content",requiredPermission:"public",useKnowledgeContext:!0,basePrompt:`You are helping to create a professional portfolio case study based on REAL project information.
|
|
7201
7201
|
|
|
@@ -7371,7 +7371,7 @@ Use the project request as the primary source of truth. If retrieved knowledge c
|
|
|
7371
7371
|
font: 10px/1.45 var(--font-mono, "JetBrains Mono", ui-monospace, monospace);
|
|
7372
7372
|
}
|
|
7373
7373
|
.printable-footer a { color: inherit; text-decoration: none; overflow-wrap: anywhere; }
|
|
7374
|
-
`}},void 0,!1,void 0,this),P9("section",{className:"project-shell",children:[P9("header",{className:"project-hero",children:[P9("div",{className:"project-index",children:[Q.brandLabel&&P9("p",{className:"printable-kicker",children:Q.brandLabel},void 0,!1,void 0,this),Q.year&&P9("span",{className:"project-year",children:Q.year},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P9("div",{className:"project-title-panel",children:[P9("span",{className:"printable-kind",children:"Case study dossier"},void 0,!1,void 0,this),P9("h1",{className:"printable-title",children:Q.title},void 0,!1,void 0,this),Q.description&&P9("p",{className:"printable-description",children:Q.description},void 0,!1,void 0,this),P9("div",{className:"printable-meta",children:[Q.year&&P9("span",{children:Q.year},void 0,!1,void 0,this),Q.url&&P9("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&&P9("img",{className:"printable-cover",src:Q.coverImageUrl,alt:""},void 0,!1,void 0,this),P9(F9,{markdown:Q.body,className:"printable-body"},void 0,!1,void 0,this),(Boolean(Q.canonicalUrl)||Boolean(Q.url)||Boolean(Q.brandLabel))&&P9("footer",{className:"printable-footer",children:[P9("span",{children:Q.brandLabel??"Project printable"},void 0,!1,void 0,this),Q.canonicalUrl||Q.url?P9("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 VUw=26214400,bUw=60000;class fs0{metadata={outputEntityType:"document"};context;renderPdf;constructor(A,Q={}){this.context=A,this.renderPdf=Q.renderPdf??kU}async resolve(A){if(A.sourceEntityType!=="project"||A.attachmentType!==uY0)return;let Q=await this.context.entityService.getEntity({entityType:"project",id:A.sourceEntityId});if(!Q)return;let w=JUw(Q,{brandLabel:this.resolveBrandLabel(),coverImageUrl:await this.resolveCoverImageUrl(Q)}),B=await GUw(qUw(zUw(),"brain-project-printable-"));try{let $=await RZ({outputDir:B,mediaPath:`/_media/printable/project/${Q.id}`,template:q02,format:"pdf",content:w,siteConfig:{title:w.title,themeMode:"light"},themeCSS:this.context.themeCSS}),f=await hZ({rootDir:B});try{return{type:"document",data:await this.renderPdf(f.urlFor($.urlPath),{maxBytes:VUw,timeoutMs:bUw,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${IUw(Q)}-printable.pdf`}}finally{await f.close()}}finally{await DUw(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.trim();return Q.length>0?Q:void 0}async resolveCoverImageUrl(A){let{frontmatter:Q}=P6(A.content),w=K7.parse(Q);if(!w.coverImageId)return;let B=await this.context.entityService.getEntity({entityType:"image",id:w.coverImageId});return B?.content.startsWith("data:image/")?B.content:void 0}}function JUw(A,Q={}){let{frontmatter:w,content:B}=P6(A.content),$=K7.parse(w);return{title:$.title,body:B,...$.description?{description:$.description}:{},year:$.year,...$.publishedAt?{publishedAt:$.publishedAt}:{},...$.url?{url:$.url,canonicalUrl:$.url}:{},...Q.coverImageUrl?{coverImageUrl:Q.coverImageUrl}:{},...Q.brandLabel?{brandLabel:Q.brandLabel}:{}}}function IUw(A){let Q=A.metadata.slug;return Q.length>0?Q:H1(A.metadata.title)}u9();U2();_0();import{jsxDEV as kUw}from"preact/jsx-dev-runtime";var cY0="og-image",FUw="portfolio:og-image",V02=Z.object({title:Z.string().min(1),description:Z.string().optional(),year:Z.number().optional(),brandLabel:Z.string().optional(),coverImageUrl:Z.string().optional()}),b02={name:FUw,pluginId:"portfolio",schema:V02,renderers:{image:LUw}};function LUw(A){let Q=V02.parse(A);return kUw(uq,{brandLabel:Q.brandLabel??Q.title,eyebrow:"Project",title:Q.title,subtitle:Q.description,tag:Q.year},void 0,!1,void 0,this)}class Ys0{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!==cY0)return;let Q=await this.context.entityService.getEntity({entityType:"project",id:A.sourceEntityId});if(!Q)return;let{frontmatter:w}=P6(Q.content),B=K7.parse(w),$=this.resolveBrandLabel(),f=await this.resolveCoverImageUrl(B.coverImageId),Y={title:B.title,...B.description?{description:B.description}:{},year:B.year,...f?{coverImageUrl:f}:{},...$?{brandLabel:$}:{}};return{type:"image",data:await nj({mediaPath:`/_media/og/project/${Q.id}`,template:b02,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:`${_Uw(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 _Uw(A){let Q=A.metadata.slug;return Q.length>0?Q:H1(A.metadata.title)}var J02={name:"@brains/portfolio",version:"0.2.0-alpha.150",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:"^6.0.3"},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 jUw=Z.object({currentPage:Z.number(),totalPages:Z.number(),totalItems:Z.number(),pageSize:Z.number(),hasNextPage:Z.boolean(),hasPrevPage:Z.boolean()}),PUw=Z.union([Z.enum(["public","shared","restricted"]),Z.literal("private")]).optional().transform((A)=>{if(A===void 0)return"public";if(A==="private")return"restricted";return A}),I02=Z.enum(["generating","draft","published","failed"]),MUw=Z.object({title:Z.string(),slug:Z.string().optional(),status:I02,publishedAt:Z.string().optional(),description:Z.string(),year:Z.number(),coverImageId:Z.string().optional(),ogImageId:Z.string().optional(),url:Z.url().optional()}),OUw=Z.object({title:Z.string(),status:I02,publishedAt:Z.string().optional(),year:Z.number(),slug:Z.string(),error:Z.string().optional()}),xUw=Z.object({context:Z.string(),problem:Z.string(),solution:Z.string(),outcome:Z.string()}),lY0=Z.object({id:Z.string(),entityType:Z.literal("project"),content:Z.string(),created:Z.string(),updated:Z.string(),visibility:PUw,metadata:OUw,contentHash:Z.string(),frontmatter:MUw,body:Z.string(),structuredContent:xUw.optional(),url:Z.string(),typeLabel:Z.string(),coverImageUrl:Z.string().optional(),ogImageUrl:Z.string().optional(),coverImageWidth:Z.number().optional(),coverImageHeight:Z.number().optional()}),vUw=Z.object({projects:Z.array(lY0),pageTitle:Z.string().optional(),pagination:jUw.nullable(),baseUrl:Z.string().optional()}),RUw=Z.object({prompt:Z.string(),year:Z.number()});function hUw(A,Q){for(let w of[A,Q]){let B=w?.match(/\b(19\d{2}|20\d{2})\b/);if(B?.[1])return Number(B[1])}return null}class Xs0 extends rQ{entityType="project";schema=MF;adapter=YP;unregisterAtprotoProjection;unregisterPrintableAttachmentProvider;unregisterOgImageAttachmentProvider;constructor(A={}){super("portfolio",J02,A,eo0)}async interceptCreate(A,Q,w){if(!A.prompt||A.content)return{kind:"continue",input:A};let B=hUw(A.title,A.prompt);if(!B)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:B},toolContext:Q,options:{source:this.id,metadata:{operationType:"content_operations"}}})}}}}createGenerationHandler(A){return new SY0(this.logger.child("ProjectGenerationJobHandler"),A)}getTemplates(){return{"project-list":d1({name:"project-list",description:"Portfolio project list page template",schema:vUw,dataSourceId:"portfolio:entities",requiredPermission:"public",layout:{component:As0}}),"project-detail":d1({name:"project-detail",description:"Individual project case study template",schema:Z.object({project:lY0,prevProject:lY0.nullable(),nextProject:lY0.nullable()}),dataSourceId:"portfolio:entities",requiredPermission:"public",layout:{component:Qs0}}),generation:ws0}}getDataSources(){return[new mY0(this.logger.child("ProjectDataSource"))]}async onRegister(A){this.registerEvalHandlers(A),this.unregisterPrintableAttachmentProvider=A.attachments.register("project",uY0,new fs0(A)),this.unregisterOgImageAttachmentProvider=A.attachments.register("project",cY0,new Ys0(A)),this.deferPublishRegistration(A),this.subscribeToPublishExecute(A),this.unregisterAtprotoProjection=Q5.getInstance().register($s0())}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=RUw.parse(Q);return A.ai.generate({prompt:Bs0(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:B}=Q.payload;if(w!=="project")return{success:!0};try{let $=await A.entityService.getEntity({entityType:"project",id:B});if(!$)return await A.messaging.send({type:"publish:report:failure",payload:{entityType:w,entityId:B,error:`Project not found: ${B}`}}),{success:!0};if($.metadata.status==="published")return{success:!0};let f=n2($.content,K7),Y=new Date().toISOString(),X=V8(f.content,{...f.metadata,status:"published",publishedAt:Y});await A.entityService.updateEntity({entity:{...$,content:X,metadata:{...$.metadata,status:"published",publishedAt:Y}}}),await A.messaging.send({type:"publish:report:success",payload:{entityType:w,entityId:B,publishedAt:Y}})}catch($){await A.messaging.send({type:"publish:report:failure",payload:{entityType:w,entityId:B,error:SA($)}})}return{success:!0}})}}function Zs0(A={}){return new Xs0(A)}wA();_0();_0();var CUw=Z.enum(["public","shared","restricted"]),F02=Z.object({includeEntityTypes:Z.array(Z.string()).default([]),minRelevanceScore:Z.number().min(0).max(1).default(0.5),mergeSimilarityThreshold:Z.number().min(0).max(1).default(0.85),autoMerge:Z.boolean().default(!0),extractableStatuses:Z.array(Z.string()).default(["published"]),enableAutoExtraction:Z.boolean().default(!0),extractionVisibility:CUw.default("public"),sourceChangeBatchDelayMs:Z.number().int().min(0).default(1000)});wA();_0();wA();var F5$=Z.object({}),gUw=Z.record(Z.string(),Z.unknown()).transform(()=>({})),Iy=_Q.extend({entityType:Z.literal("topic"),metadata:gUw}),L5$=Z.object({content:Z.string()}),L02=Z.object({title:Z.string().describe("Topic title")});var XP="topics",i6="topic",Hs0="topics-projection",k02="topic:project",pY0="topics-plugin",_02="topics:batch-completed",N02="topics-source-batch";class PU extends g2{constructor(){super({entityType:i6,purpose:"A recurring theme or subject derived from the user's content.",schema:Iy,frontmatterSchema:L02})}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:i6}}extractMetadata(A){return{}}generateFrontMatter(A){let Q=this.parseTopicBody(A.content),B=this.buildMarkdown("",this.buildFrontmatter(Q.title)).match(/^---\n[\s\S]*?\n---/);return B?B[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))}}wA();_0();_0();var yUw=Z.object({title:Z.string().max(100),content:Z.string(),relevanceScore:Z.number().min(0).max(1)}),j02=Z.array(yUw);var EUw=Z.object({topics:j02}),P02=d1({name:"topics:extraction",description:"Extract topics from conversation text",dataSourceId:"shell:ai-content",schema:EUw,basePrompt:`You are an expert at analyzing content and extracting key topics.
|
|
7374
|
+
`}},void 0,!1,void 0,this),P9("section",{className:"project-shell",children:[P9("header",{className:"project-hero",children:[P9("div",{className:"project-index",children:[Q.brandLabel&&P9("p",{className:"printable-kicker",children:Q.brandLabel},void 0,!1,void 0,this),Q.year&&P9("span",{className:"project-year",children:Q.year},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P9("div",{className:"project-title-panel",children:[P9("span",{className:"printable-kind",children:"Case study dossier"},void 0,!1,void 0,this),P9("h1",{className:"printable-title",children:Q.title},void 0,!1,void 0,this),Q.description&&P9("p",{className:"printable-description",children:Q.description},void 0,!1,void 0,this),P9("div",{className:"printable-meta",children:[Q.year&&P9("span",{children:Q.year},void 0,!1,void 0,this),Q.url&&P9("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&&P9("img",{className:"printable-cover",src:Q.coverImageUrl,alt:""},void 0,!1,void 0,this),P9(F9,{markdown:Q.body,className:"printable-body"},void 0,!1,void 0,this),(Boolean(Q.canonicalUrl)||Boolean(Q.url)||Boolean(Q.brandLabel))&&P9("footer",{className:"printable-footer",children:[P9("span",{children:Q.brandLabel??"Project printable"},void 0,!1,void 0,this),Q.canonicalUrl||Q.url?P9("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 VUw=26214400,bUw=60000;class fs0{metadata={outputEntityType:"document"};context;renderPdf;constructor(A,Q={}){this.context=A,this.renderPdf=Q.renderPdf??kU}async resolve(A){if(A.sourceEntityType!=="project"||A.attachmentType!==uY0)return;let Q=await this.context.entityService.getEntity({entityType:"project",id:A.sourceEntityId});if(!Q)return;let w=JUw(Q,{brandLabel:this.resolveBrandLabel(),coverImageUrl:await this.resolveCoverImageUrl(Q)}),B=await GUw(qUw(zUw(),"brain-project-printable-"));try{let $=await RZ({outputDir:B,mediaPath:`/_media/printable/project/${Q.id}`,template:q02,format:"pdf",content:w,siteConfig:{title:w.title,themeMode:"light"},themeCSS:this.context.themeCSS}),f=await hZ({rootDir:B});try{return{type:"document",data:await this.renderPdf(f.urlFor($.urlPath),{maxBytes:VUw,timeoutMs:bUw,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${IUw(Q)}-printable.pdf`}}finally{await f.close()}}finally{await DUw(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.trim();return Q.length>0?Q:void 0}async resolveCoverImageUrl(A){let{frontmatter:Q}=P6(A.content),w=K7.parse(Q);if(!w.coverImageId)return;let B=await this.context.entityService.getEntity({entityType:"image",id:w.coverImageId});return B?.content.startsWith("data:image/")?B.content:void 0}}function JUw(A,Q={}){let{frontmatter:w,content:B}=P6(A.content),$=K7.parse(w);return{title:$.title,body:B,...$.description?{description:$.description}:{},year:$.year,...$.publishedAt?{publishedAt:$.publishedAt}:{},...$.url?{url:$.url,canonicalUrl:$.url}:{},...Q.coverImageUrl?{coverImageUrl:Q.coverImageUrl}:{},...Q.brandLabel?{brandLabel:Q.brandLabel}:{}}}function IUw(A){let Q=A.metadata.slug;return Q.length>0?Q:H1(A.metadata.title)}u9();U2();_0();import{jsxDEV as kUw}from"preact/jsx-dev-runtime";var cY0="og-image",FUw="portfolio:og-image",V02=Z.object({title:Z.string().min(1),description:Z.string().optional(),year:Z.number().optional(),brandLabel:Z.string().optional(),coverImageUrl:Z.string().optional()}),b02={name:FUw,pluginId:"portfolio",schema:V02,renderers:{image:LUw}};function LUw(A){let Q=V02.parse(A);return kUw(uq,{brandLabel:Q.brandLabel??Q.title,eyebrow:"Project",title:Q.title,subtitle:Q.description,tag:Q.year},void 0,!1,void 0,this)}class Ys0{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!==cY0)return;let Q=await this.context.entityService.getEntity({entityType:"project",id:A.sourceEntityId});if(!Q)return;let{frontmatter:w}=P6(Q.content),B=K7.parse(w),$=this.resolveBrandLabel(),f=await this.resolveCoverImageUrl(B.coverImageId),Y={title:B.title,...B.description?{description:B.description}:{},year:B.year,...f?{coverImageUrl:f}:{},...$?{brandLabel:$}:{}};return{type:"image",data:await nj({mediaPath:`/_media/og/project/${Q.id}`,template:b02,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:`${_Uw(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 _Uw(A){let Q=A.metadata.slug;return Q.length>0?Q:H1(A.metadata.title)}var J02={name:"@brains/portfolio",version:"0.2.0-alpha.151",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 jUw=Z.object({currentPage:Z.number(),totalPages:Z.number(),totalItems:Z.number(),pageSize:Z.number(),hasNextPage:Z.boolean(),hasPrevPage:Z.boolean()}),PUw=Z.union([Z.enum(["public","shared","restricted"]),Z.literal("private")]).optional().transform((A)=>{if(A===void 0)return"public";if(A==="private")return"restricted";return A}),I02=Z.enum(["generating","draft","published","failed"]),MUw=Z.object({title:Z.string(),slug:Z.string().optional(),status:I02,publishedAt:Z.string().optional(),description:Z.string(),year:Z.number(),coverImageId:Z.string().optional(),ogImageId:Z.string().optional(),url:Z.url().optional()}),OUw=Z.object({title:Z.string(),status:I02,publishedAt:Z.string().optional(),year:Z.number(),slug:Z.string(),error:Z.string().optional()}),xUw=Z.object({context:Z.string(),problem:Z.string(),solution:Z.string(),outcome:Z.string()}),lY0=Z.object({id:Z.string(),entityType:Z.literal("project"),content:Z.string(),created:Z.string(),updated:Z.string(),visibility:PUw,metadata:OUw,contentHash:Z.string(),frontmatter:MUw,body:Z.string(),structuredContent:xUw.optional(),url:Z.string(),typeLabel:Z.string(),coverImageUrl:Z.string().optional(),ogImageUrl:Z.string().optional(),coverImageWidth:Z.number().optional(),coverImageHeight:Z.number().optional()}),vUw=Z.object({projects:Z.array(lY0),pageTitle:Z.string().optional(),pagination:jUw.nullable(),baseUrl:Z.string().optional()}),RUw=Z.object({prompt:Z.string(),year:Z.number()});function hUw(A,Q){for(let w of[A,Q]){let B=w?.match(/\b(19\d{2}|20\d{2})\b/);if(B?.[1])return Number(B[1])}return null}class Xs0 extends rQ{entityType="project";schema=MF;adapter=YP;unregisterAtprotoProjection;unregisterPrintableAttachmentProvider;unregisterOgImageAttachmentProvider;constructor(A={}){super("portfolio",J02,A,eo0)}async interceptCreate(A,Q,w){if(!A.prompt||A.content)return{kind:"continue",input:A};let B=hUw(A.title,A.prompt);if(!B)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:B},toolContext:Q,options:{source:this.id,metadata:{operationType:"content_operations"}}})}}}}createGenerationHandler(A){return new SY0(this.logger.child("ProjectGenerationJobHandler"),A)}getTemplates(){return{"project-list":d1({name:"project-list",description:"Portfolio project list page template",schema:vUw,dataSourceId:"portfolio:entities",requiredPermission:"public",layout:{component:As0}}),"project-detail":d1({name:"project-detail",description:"Individual project case study template",schema:Z.object({project:lY0,prevProject:lY0.nullable(),nextProject:lY0.nullable()}),dataSourceId:"portfolio:entities",requiredPermission:"public",layout:{component:Qs0}}),generation:ws0}}getDataSources(){return[new mY0(this.logger.child("ProjectDataSource"))]}async onRegister(A){this.registerEvalHandlers(A),this.unregisterPrintableAttachmentProvider=A.attachments.register("project",uY0,new fs0(A)),this.unregisterOgImageAttachmentProvider=A.attachments.register("project",cY0,new Ys0(A)),this.deferPublishRegistration(A),this.subscribeToPublishExecute(A),this.unregisterAtprotoProjection=Q5.getInstance().register($s0())}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=RUw.parse(Q);return A.ai.generate({prompt:Bs0(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:B}=Q.payload;if(w!=="project")return{success:!0};try{let $=await A.entityService.getEntity({entityType:"project",id:B});if(!$)return await A.messaging.send({type:"publish:report:failure",payload:{entityType:w,entityId:B,error:`Project not found: ${B}`}}),{success:!0};if($.metadata.status==="published")return{success:!0};let f=n2($.content,K7),Y=new Date().toISOString(),X=V8(f.content,{...f.metadata,status:"published",publishedAt:Y});await A.entityService.updateEntity({entity:{...$,content:X,metadata:{...$.metadata,status:"published",publishedAt:Y}}}),await A.messaging.send({type:"publish:report:success",payload:{entityType:w,entityId:B,publishedAt:Y}})}catch($){await A.messaging.send({type:"publish:report:failure",payload:{entityType:w,entityId:B,error:SA($)}})}return{success:!0}})}}function Zs0(A={}){return new Xs0(A)}wA();_0();_0();var CUw=Z.enum(["public","shared","restricted"]),F02=Z.object({includeEntityTypes:Z.array(Z.string()).default([]),minRelevanceScore:Z.number().min(0).max(1).default(0.5),mergeSimilarityThreshold:Z.number().min(0).max(1).default(0.85),autoMerge:Z.boolean().default(!0),extractableStatuses:Z.array(Z.string()).default(["published"]),enableAutoExtraction:Z.boolean().default(!0),extractionVisibility:CUw.default("public"),sourceChangeBatchDelayMs:Z.number().int().min(0).default(1000)});wA();_0();wA();var F5$=Z.object({}),gUw=Z.record(Z.string(),Z.unknown()).transform(()=>({})),Iy=_Q.extend({entityType:Z.literal("topic"),metadata:gUw}),L5$=Z.object({content:Z.string()}),L02=Z.object({title:Z.string().describe("Topic title")});var XP="topics",i6="topic",Hs0="topics-projection",k02="topic:project",pY0="topics-plugin",_02="topics:batch-completed",N02="topics-source-batch";class PU extends g2{constructor(){super({entityType:i6,purpose:"A recurring theme or subject derived from the user's content.",schema:Iy,frontmatterSchema:L02})}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:i6}}extractMetadata(A){return{}}generateFrontMatter(A){let Q=this.parseTopicBody(A.content),B=this.buildMarkdown("",this.buildFrontmatter(Q.title)).match(/^---\n[\s\S]*?\n---/);return B?B[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))}}wA();_0();_0();var yUw=Z.object({title:Z.string().max(100),content:Z.string(),relevanceScore:Z.number().min(0).max(1)}),j02=Z.array(yUw);var EUw=Z.object({topics:j02}),P02=d1({name:"topics:extraction",description:"Extract topics from conversation text",dataSourceId:"shell:ai-content",schema:EUw,basePrompt:`You are an expert at analyzing content and extracting key topics.
|
|
7375
7375
|
|
|
7376
7376
|
Analyze the provided content and extract meaningful topics discussed.
|
|
7377
7377
|
|
|
@@ -7474,13 +7474,13 @@ ${A.incomingTopic.content}`})}}function oUw(A){if(A.length===0)return"";return A
|
|
|
7474
7474
|
|
|
7475
7475
|
${Q.content}`}).join(`
|
|
7476
7476
|
|
|
7477
|
-
`)}async function ZP(A,Q,w,B={}){if(A.length===0)return{created:0,merged:0,skipped:0,batches:0};let $=B.minRelevanceScore??0,f=B.autoMerge??!1,Y=B.mergeSimilarityThreshold??0.85,X=B.targetVisibility??"public",H=T02(A),W=new MU(Q.entityService,w),K=B.topicMergeSynthesizer??new zs0(Q,w),U=await oY0(Q.entityService,void 0,X),G=new Map,q=0,V=0,J=0;for(let L of H){w.info(`Processing batch of ${L.length} entities`);let N=oUw(L),k=sY0({entityTitle:`Batch of ${L.length} entities`,entityType:"batch",content:N,existingTopicTitles:U});try{let v=(await Q.ai.generate({prompt:k,templateName:"topics:extraction"})).topics.filter((h)=>h.relevanceScore>=$);for(let h of v)try{if(f){let S=await W.findMergeCandidate({incoming:h,threshold:Y,additionalCandidates:Array.from(G.values()),targetVisibility:X});if(S){let p=await K.synthesize({existingTopic:S.topic,incomingTopic:h}),e=await W.applySynthesizedMerge({existingId:S.topic.id,synthesized:{...p,title:S.title},visibility:X});if(!e)throw Error(`Failed to merge topic: ${h.title}`);G.set(e.id,e),V++;continue}}let P=W.getTopicIdForTitle(h.title,X);if(G.has(P)){J++;continue}let E=await W.createTopicOptimistic({title:h.title,content:h.content,visibility:X});if(E.topic)G.set(E.topic.id,E.topic);if(E.created)q++;else J++}catch(P){w.error("Topic batch item failed",{title:h.title,error:SA(P)})}}catch(x){w.error("Batch topic extraction failed",{batchSize:L.length,promptChars:k.length,error:SA(x)})}}let b={created:q,merged:V,skipped:J,batches:H.length};if(q>0||V>0)await Q.messaging.send({type:_02,payload:b,broadcast:!0});return b}wA();_0();var sUw=Z.discriminatedUnion("mode",[Z.object({mode:Z.literal("derive"),reason:Z.string().optional()}),Z.object({mode:Z.literal("rebuild"),reason:Z.string().optional()}),Z.object({mode:Z.literal("source-batch"),minRelevanceScore:Z.number().min(0).max(1).optional()})]);class qs0{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 p02(A){let{context:Q,logger:w,config:B}=A;return{process:async($)=>{if($.mode==="derive")return await A.extractAllTopics(),{success:!0};if($.mode==="rebuild")return await A.rebuildAllTopics(),{success:!0};return aUw({context:Q,logger:w,config:B,sourceBatch:A.sourceBatch,isEntityPublished:A.isEntityPublished,minRelevanceScore:$.minRelevanceScore??B.minRelevanceScore})},validateAndParse:($)=>{let f=sUw.safeParse($??{});return f.success?f.data:null}}}async function aUw(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})}))),B=0,$=0,f=0,Y=0,X=[];for(let{ref:W,entity:K}of w){if(!K){$++;continue}if(K.contentHash!==W.contentHash){B++;continue}if(!A.isEntityPublished(K)){f++;continue}if(!Mb(K.visibility,A.config.extractionVisibility)){Y++;continue}X.push(K)}if(X.length===0)return{success:!0,sources:Q.length,created:0,merged:0,skipped:0,batches:0,stale:B,missing:$,unpublished:f,hidden:Y};let H=await ZP(X,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:B,missing:$,unpublished:f,hidden:Y}}function i02(){return{priority:5,source:pY0,deduplication:"coalesce",deduplicationKey:"topics-initial-derivation",metadata:{operationType:"data_processing",operationTarget:"topics-initial-derivation",pluginId:XP}}}async function d02(A){let Q=await r02(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 ZP(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 n02(A){let Q=await r02(A),w=await Vs0(Q,A.context,A.logger,A.config);A.logger.info("Topic rebuild complete",w)}async function Vs0(A,Q,w,B){let $=new MU(Q.entityService,w),f=await $.listTopics({visibility:B.extractionVisibility});for(let X of f)await $.deleteTopic(X.id);if(A.length===0)return{deleted:f.length,created:0,merged:0,skipped:0,batches:0};let Y=await ZP(A,Q,w,{minRelevanceScore:B.minRelevanceScore,autoMerge:B.autoMerge,mergeSimilarityThreshold:B.mergeSimilarityThreshold,targetVisibility:B.extractionVisibility});return{deleted:f.length,...Y}}async function r02(A){let Q=tUw(A),w=[];for(let B of Q){let $=await A.context.entityService.listEntities({entityType:B,options:{filter:{visibilityScope:A.config.extractionVisibility}}});for(let f of $){if(!A.isEntityPublished(f))continue;w.push(f)}}return w}function tUw(A){return A.context.entityService.getEntityTypes().filter((w)=>A.shouldProcessEntityType(w))}var ky=Z.object({entityType:Z.string(),content:Z.string(),metadata:Z.record(Z.string(),Z.unknown()).optional()}),eUw=ky.extend({minRelevanceScore:Z.number().optional()}),AGw=Z.object({contentA:ky,contentB:ky,minRelevanceScore:Z.number().optional(),threshold:Z.number().min(0).max(1).optional()}),ko=Z.object({title:Z.string(),content:Z.string()}),QGw=Z.object({existingTopics:Z.array(ko),incomingTopic:ko,threshold:Z.number().optional()}),wGw=Z.object({existingTopics:Z.array(ko).default([]),incomingTopic:ko.extend({relevanceScore:Z.number().min(0).max(1).optional()}),threshold:Z.number().optional()}),BGw=Z.object({entities:Z.array(ky).min(1),minRelevanceScore:Z.number().optional()}),$Gw=Z.object({existingTopics:Z.array(ko).optional(),entities:Z.array(ky)}),fGw=Z.object({entities:Z.array(ky)});function Ly(A,Q=""){return{id:`eval${Q}-${Date.now()}`,entityType:A.entityType,content:A.content,contentHash:B6(A.content),visibility:"public",metadata:A.metadata??{},created:new Date().toISOString(),updated:new Date().toISOString()}}function o02(A){return{title:A.title,relevanceScore:A.relevanceScore}}function YGw(A){let Q=A.metadata.title;return typeof Q==="string"?Q:A.id}function XGw(A,Q){return{...A,sources:[{id:Q.id,type:Q.entityType,title:YGw(Q)}]}}async function HP(A){let Q=await A.entityService.listEntities({entityType:i6});await Promise.all(Q.map((w)=>A.entityService.deleteEntity({entityType:i6,id:w.id})))}async function ZGw(A){for(;;){if((await A.jobs.getActiveJobs(["shell:embedding"])).length===0)return;await new Promise((w)=>setTimeout(w,100))}}function s02(A){let{context:Q,logger:w,config:B}=A,$=new Ds0(Q,w),f=async(Y,X,H="")=>{let W=Ly(Y,H);return $.extractFromEntity(W,X)};Q.eval.registerHandler("extractFromEntity",async(Y)=>{await HP(Q);let X=eUw.parse(Y),H=X.minRelevanceScore??B.minRelevanceScore,W=Ly(X);return(await $.extractFromEntity(W,H)).map((U)=>XGw(U,W))}),Q.eval.registerHandler("checkMergeSimilarity",async(Y)=>{await HP(Q);let X=AGw.parse(Y),H=X.minRelevanceScore??B.minRelevanceScore,W=X.threshold??B.mergeSimilarityThreshold,[K,U]=await Promise.all([f(X.contentA,H,"-a"),f(X.contentB,H,"-b")]),G=new MU(Q.entityService,w),q=[];for(let b of K){let L=await G.createTopic(b);if(L)q.push(L)}let V=(await Promise.all(U.map(async(b)=>{let L=await G.findMergeCandidate({incoming:b,threshold:W,additionalCandidates:q});if(!L)return null;return{incomingTitle:b.title,candidateTitle:L.title,candidateScore:L.score}}))).filter((b)=>b!==null),J=V.map((b)=>b.candidateTitle);return{topicsA:K.map(o02),topicsB:U.map(o02),matchingTitles:J,mergeCandidates:V,wouldMerge:V.length>0}}),Q.eval.registerHandler("detectMergeCandidate",async(Y)=>{await HP(Q);let X=QGw.parse(Y),H=X.threshold??B.mergeSimilarityThreshold,W=new MU(Q.entityService,w),K=[];for(let G of X.existingTopics){let q=await W.createTopic(G);if(q)K.push(q)}let U=await W.findMergeCandidate({incoming:{title:X.incomingTopic.title},threshold:H,additionalCandidates:K});return{found:U!==null,candidateTitle:U?.title,candidateScore:U?.score}}),Q.eval.registerHandler("processTopicWithAutoMerge",async(Y)=>{await HP(Q);let X=wGw.parse(Y),H=new MU(Q.entityService,w);for(let G of X.existingTopics)await H.createTopic({title:G.title,content:G.content});await ZGw(Q);let W=Ly({entityType:"post",content:X.incomingTopic.content,metadata:{title:X.incomingTopic.title}},"-source"),K=await ZP([W],Q,w,{minRelevanceScore:0,autoMerge:!0,mergeSimilarityThreshold:X.threshold??B.mergeSimilarityThreshold}),U=await Q.entityService.listEntities({entityType:i6});return{...K,topicCount:U.length,topics:U.map(Us0)}}),Q.eval.registerHandler("rebuildTopics",async(Y)=>{await HP(Q);let X=$Gw.parse(Y),H=new MU(Q.entityService,w);for(let G of X.existingTopics??[])await H.createTopic(G);let W=X.entities.map((G,q)=>Ly(G,`-rebuild-${q}`)),K=await Vs0(W,Q,w,B),U=await Q.entityService.listEntities({entityType:i6});return{...K,topicCount:U.length,topics:U.map(Us0)}}),Q.eval.registerHandler("extractSequentially",async(Y)=>{await HP(Q);let X=BGw.parse(Y),H=X.minRelevanceScore??B.minRelevanceScore,W=new MU(Q.entityService,w),K=[];for(let[G,q]of X.entities.entries()){let V=Ly(q,`-sequential-${G}`),J=await $.extractFromEntity(V,H);for(let b of J)await W.createTopic({title:b.title,content:b.content});K.push({extractedTitles:J.map((b)=>b.title)})}let U=await Q.entityService.listEntities({entityType:i6});return{totalTopics:U.length,perEntity:K,topics:U.map(Fy)}}),Q.eval.registerHandler("batchExtract",async(Y)=>{await HP(Q);let H=fGw.parse(Y).entities.map((U,G)=>Ly(U,`-batch-${G}`)),W=await ZP(H,Q,w,{minRelevanceScore:B.minRelevanceScore}),K=await Q.entityService.listEntities({entityType:i6});return{...W,topics:K.map(Fy)}})}var HGw=new PU;async function a02({entity:A,config:Q}){let w=Iy.parse(A),B=HGw.parseTopicBody(w.content);return{$type:"ai.rizom.brain.topic",title:B.title,body:B.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 bs0(){return{entityType:"topic",collection:"ai.rizom.brain.topic",lexicon:k6["ai.rizom.brain.topic"],validate:!1,buildRecord:a02}}var t02={name:"@brains/topics",version:"0.2.0-alpha.150",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:"^6.0.3"},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 KGw=new PU,UGw=Z.looseObject({status:Z.unknown().optional()});class e02 extends rQ{entityType=i6;schema=Iy;adapter=KGw;unregisterAtprotoProjection;sourceBatch=new qs0;constructor(A={}){super(XP,t02,A,F02)}getEntityTypeConfig(){return{weight:0.5,projectionSource:!1}}getTemplates(){return{extraction:P02,"merge-synthesis":M02,"topic-list":O02,"topic-detail":x02}}getDataSources(){return[new Gs0(this.logger.child("TopicsDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableAutoExtraction)return[];return[{id:Hs0,targetType:i6,job:{type:k02,handler:p02({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 qk(A,i6,{visibility:this.config.extractionVisibility}),jobData:{mode:"derive",reason:"initial-sync"},jobOptions:i02()},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(!Mb(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:pY0,delayMs:this.config.sourceChangeBatchDelayMs,deduplication:"skip",deduplicationKey:N02,metadata:{operationType:"data_processing",operationTarget:"topic-source-batch",pluginId:XP}})}}]}async onRegister(A){A.insights.register("topic-distribution",h02()),C02({context:A,pluginId:this.id}),s02({context:A,logger:this.logger,config:this.config}),this.unregisterAtprotoProjection=Q5.getInstance().register(bs0())}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}hasRunInitialDerivation(){return this.getDerivedEntityProjectionController(Hs0)?.hasQueuedInitialSync()??!1}shouldProcessEntityType(A,Q){if(A===i6)return!1;if(!this.config.includeEntityTypes.includes(A))return!1;return Q.getEntityTypeConfig(A).projectionSource!==!1}isEntityPublished(A){let Q=UGw.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 d02({context:A,logger:this.logger,config:this.config,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q,A.entityService),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}async rebuildAllTopics(A){await n02({context:A,logger:this.logger,config:this.config,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q,A.entityService),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}}function aY0(A={}){return new e02(A)}wA();_0();wA();var Js0=Z.enum(["linkedin"]),AA2=Z.enum(["linkedin"]),Is0=Z.enum(["generating","draft","queued","published","failed"]),QA2=Z.enum(["generating","draft","queued","published","failed"]),wA2=Z.enum(["post","deck"]),GGw=Z.enum(["post","deck"]),BA2=Z.object({id:Z.string().min(1).describe("Document entity ID")}),DGw=Z.object({id:Z.string().min(1)}),OU=Z.object({title:Z.string().describe("Short descriptive title (3-6 words) for file naming"),platform:Js0.describe("Target platform"),status:Is0,coverImageId:Z.string().optional().describe("Image entity ID for post image"),documents:Z.array(BA2).optional().describe("Document attachments for publishing"),publishedAt:Z.string().datetime().optional(),platformPostId:Z.string().optional().describe("ID from platform after publishing"),sourceEntityId:Z.string().optional().describe("Source entity ID if auto-generated"),sourceEntityType:wA2.optional().describe("Source entity type (post, deck)")}),$A2=OU.extend({platform:Js0.optional(),status:Is0.optional()}),zGw=OU.pick({title:!0,platform:!0,status:!0,publishedAt:!0,platformPostId:!0}).extend({slug:Z.string().describe("URL-friendly identifier: {platform}-{title}"),error:Z.string().optional()}),qGw=Z.object({title:Z.string(),platform:AA2,status:QA2,publishedAt:Z.string().datetime().optional(),platformPostId:Z.string().optional(),slug:Z.string(),error:Z.string().optional()}),VGw=Z.object({title:Z.string(),platform:AA2,status:QA2,coverImageId:Z.string().optional(),documents:Z.array(DGw).optional(),publishedAt:Z.string().datetime().optional(),platformPostId:Z.string().optional(),sourceEntityId:Z.string().optional(),sourceEntityType:GGw.optional()}),OF=_Q.extend({entityType:Z.literal("social-post"),metadata:qGw}),tY0=OF.extend({frontmatter:VGw,body:Z.string()}),bGw=tY0.extend({url:Z.string().optional(),listUrl:Z.string().optional(),listLabel:Z.string().optional(),typeLabel:Z.string().optional(),coverImageUrl:Z.string().optional(),coverImageWidth:Z.number().optional(),coverImageHeight:Z.number().optional()});wA();U2();class Fs0 extends g2{constructor(){super({entityType:"social-post",purpose:"A short post drafted for social media such as LinkedIn or X.",schema:OF,frontmatterSchema:OU,supportsCoverImage:!0})}toMarkdown(A){let Q,w={};try{w=this.parseFrontMatter(A.content,OU),Q=this.extractBody(A.content)}catch{Q=A.content}let B={...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,B)}fromMarkdown(A){let Q=this.parseFrontMatter(A,$A2),w=Q.platform??"linkedin",B=Q.status??"draft",$=`${w}-${H1(Q.title)}`;return{content:A,entityType:"social-post",metadata:{title:Q.title,slug:$,platform:w,status:B,publishedAt:Q.publishedAt,platformPostId:Q.platformPostId}}}parsePostFrontmatter(A){return this.parseFrontMatter(A.content,OU)}getPostContent(A){return this.extractBody(A.content)}createPostContent(A,Q){return this.buildMarkdown(Q,A)}buildStub(A){let w={title:A.title,platform:"linkedin",status:"generating"};return{content:this.buildMarkdown("",w),metadata:{title:A.title,slug:`linkedin-${H1(A.title)}`,platform:"linkedin",status:"generating"}}}}var i7=new Fs0;wA();wA();_0();var JGw=Z.looseObject({id:Z.string().optional(),limit:Z.number().optional(),page:Z.number().optional(),pageSize:Z.number().optional(),baseUrl:Z.string().optional(),platform:Z.enum(["linkedin"]).optional(),status:Z.enum(["generating","draft","queued","published","failed"]).optional(),sortByQueue:Z.boolean().optional(),nextInQueue:Z.boolean().optional()}),IGw=Z.looseObject({entityType:Z.string().optional(),query:JGw.optional()});function fA2(A){let Q=n2(A.content,OU);return tY0.parse({...A,frontmatter:Q.metadata,body:Q.content})}class eY0 extends J8{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=IGw.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}transformEntity(A){return fA2(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:B}=this.parseQuery(A),$=w.entityService;if(B.nextInQueue)return this.fetchNextInQueue(Q,$);if(B.id){let{item:K}=await this.fetchDetail(B.id,$);return Q.parse(this.buildDetailResult(K,null))}let f={};if(B.platform)f.platform=B.platform;if(B.status)f.status=B.status;let Y=Object.keys(f).length>0,X=B.sortByQueue?[{field:"queueOrder",direction:"asc"}]:this.config.defaultSort,{items:H,pagination:W}=await this.fetchList(B,$,{...Y&&{filter:{metadata:f}},sortFields:X});return Q.parse(this.buildListResult(H,W,B))}async fetchNextInQueue(A,Q){let B=(await Q.listEntities({entityType:this.config.entityType,options:{filter:{metadata:{status:"queued"}},sortFields:[{field:"queueOrder",direction:"asc"}],limit:1}}))[0],$=B?fA2(B):null;return A.parse({post:$})}}_0();var YA2=Z.object({accessToken:Z.string().optional(),refreshToken:Z.string().optional(),organizationId:Z.string().optional(),apiVersion:Z.string().regex(/^\d{6}$/).optional()}),Ls0=Z.object({linkedin:YA2.optional(),publishInterval:Z.number().default(3600000),enabled:Z.boolean().default(!0),defaultPrompt:Z.string().default("Create an engaging social media post that drives engagement"),maxRetries:Z.number().default(3),autoGenerateOnBlogPublish:Z.boolean().default(!1)});wA();U2();_0();y6();_s0();import{jsxDEV as e5,Fragment as kGw}from"preact/jsx-dev-runtime";function FGw(A,Q){if(A.length<=Q)return A;return A.slice(0,Q).trim()+"..."}function LGw(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"})}var QX0=({posts:A,pageTitle:Q,pagination:w,baseUrl:B="/social-posts"})=>{let $=Q??"Social Posts",f=w?.totalItems??A.length,Y=`Browse all ${f} social ${f===1?"post":"posts"}`;return e5(kGw,{children:[e5(pQ,{title:$,description:Y},void 0,!1,void 0,this),e5("div",{className:"social-post-list bg-theme",children:e5("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[e5("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:$},void 0,!1,void 0,this),A.length===0?e5("p",{className:"text-theme-muted italic",children:"No social posts yet."},void 0,!1,void 0,this):e5("ul",{className:"space-y-6",children:A.map((X)=>e5("li",{children:e5(G6,{href:X.url,variant:"horizontal",children:e5("div",{className:"flex flex-col sm:flex-row gap-4",children:[X.coverImageUrl&&e5("img",{src:X.coverImageUrl,alt:X.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),e5("div",{className:"flex-1 min-w-0",children:[e5("div",{className:"flex items-start justify-between gap-4 mb-2",children:[e5("h2",{className:"text-lg font-semibold text-heading",children:X.frontmatter.title},void 0,!1,void 0,this),e5("time",{className:"text-sm text-theme-muted shrink-0",children:LGw(X.frontmatter.publishedAt??X.created)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),e5("div",{className:"flex items-center gap-2 mb-3",children:[e5(iY,{status:X.frontmatter.status},void 0,!1,void 0,this),e5("span",{className:"text-xs text-theme-muted uppercase",children:X.frontmatter.platform},void 0,!1,void 0,this),e5("span",{className:"text-xs text-theme-muted font-mono",children:X.id},void 0,!1,void 0,this)]},void 0,!0,void 0,this),e5("p",{className:"text-theme leading-relaxed",children:FGw(X.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)},X.id,!1,void 0,this))},void 0,!1,void 0,this),w&&w.totalPages>1&&e5(pq,{currentPage:w.currentPage,totalPages:w.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)};import{jsxDEV as A8,Fragment as _Gw}from"preact/jsx-dev-runtime";function XA2(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric",hour:"numeric",minute:"2-digit"})}var wX0=({post:A})=>{let Q=`Social Post - ${A.frontmatter.platform}`,w=A.body.slice(0,160),B=[{label:"Home",href:"/"},{label:A.listLabel??"Social Posts",href:A.listUrl??"/social-posts"},{label:A.frontmatter.platform}];return A8(_Gw,{children:[A8(pQ,{title:Q,description:w},void 0,!1,void 0,this),A8("section",{className:"social-post-detail",children:A8("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:A8("div",{className:"max-w-3xl mx-auto",children:[A8(vD,{items:B},void 0,!1,void 0,this),A8("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-4",children:A.frontmatter.title},void 0,!1,void 0,this),A8("div",{className:"flex flex-wrap items-center gap-3 mb-6",children:[A8(iY,{status:A.frontmatter.status},void 0,!1,void 0,this),A8("span",{className:"text-sm text-theme-muted uppercase",children:A.frontmatter.platform},void 0,!1,void 0,this),A8("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&&A8(cq,{src:A.coverImageUrl,alt:A.frontmatter.title,width:A.coverImageWidth,height:A.coverImageHeight,className:"mb-8"},void 0,!1,void 0,this),A8(G6,{className:"p-8 mb-8",children:A8("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),A8("div",{className:"space-y-4 text-sm text-theme-muted",children:[A8("div",{children:[A8("span",{className:"font-medium",children:"Created:"},void 0,!1,void 0,this)," ",XA2(A.created)]},void 0,!0,void 0,this),A.frontmatter.publishedAt&&A8("div",{children:[A8("span",{className:"font-medium",children:"Published:"},void 0,!1,void 0,this)," ",XA2(A.frontmatter.publishedAt)]},void 0,!0,void 0,this),A.frontmatter.platformPostId&&A8("div",{children:A8("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 _o(A){return`social-media:${A}`}var NGw=Z.union([Z.boolean(),Z.object({generate:Z.boolean().optional(),prompt:Z.string().optional()})]),Ns0=Z.object({prompt:Z.string().optional(),platform:Z.enum(["linkedin"]).optional(),sourceEntityType:Z.enum(["post","deck"]).optional(),sourceEntityId:Z.string().optional(),title:Z.string().optional().describe("Required when content is provided directly"),content:Z.string().optional(),addToQueue:Z.boolean().optional(),generateImage:Z.boolean().optional().describe("Auto-generate cover image for post"),coverImage:NGw.optional().describe("Generic cover image generation request")}),jGw=LX.extend({slug:Z.string().optional()});class WP extends q4{constructor(A,Q){super(A,Q,{schema:Ns0,jobTypeName:"social-post-generation",entityType:"social-post"})}async generate(A,Q){let w=A.platform??"linkedin",B=A.addToQueue??!1,{prompt:$,sourceEntityType:f,sourceEntityId:Y}=A,{content:X,title:H}=A;if(X&&H)await this.reportProgress(Q,{progress:50,message:"Using provided content"});else if(X&&!H){await this.reportProgress(Q,{progress:10,message:"Shaping content with AI"});let b=await this.context.ai.generate({prompt:X,templateName:_o(w)});H=b.title,X=b.content,await this.reportProgress(Q,{progress:50,message:"Social post shaped from content"})}else if(Y&&f){await this.reportProgress(Q,{progress:10,message:`Fetching source ${f}`});let b=await this.context.entityService.getEntity({entityType:f,id:Y});if(!b)this.failEarly(`Source entity not found: ${f}/${Y}`);await this.reportProgress(Q,{progress:30,message:"Generating social post from source content"});let N=Z.looseObject({slug:Z.string()}).safeParse(b.metadata),k=N.success?N.data.slug:Y,x=await this.context.ai.generate({prompt:`Create an engaging ${w} post to promote this ${f}:
|
|
7477
|
+
`)}async function ZP(A,Q,w,B={}){if(A.length===0)return{created:0,merged:0,skipped:0,batches:0};let $=B.minRelevanceScore??0,f=B.autoMerge??!1,Y=B.mergeSimilarityThreshold??0.85,X=B.targetVisibility??"public",H=T02(A),W=new MU(Q.entityService,w),K=B.topicMergeSynthesizer??new zs0(Q,w),U=await oY0(Q.entityService,void 0,X),G=new Map,q=0,V=0,J=0;for(let L of H){w.info(`Processing batch of ${L.length} entities`);let N=oUw(L),k=sY0({entityTitle:`Batch of ${L.length} entities`,entityType:"batch",content:N,existingTopicTitles:U});try{let v=(await Q.ai.generate({prompt:k,templateName:"topics:extraction"})).topics.filter((h)=>h.relevanceScore>=$);for(let h of v)try{if(f){let S=await W.findMergeCandidate({incoming:h,threshold:Y,additionalCandidates:Array.from(G.values()),targetVisibility:X});if(S){let p=await K.synthesize({existingTopic:S.topic,incomingTopic:h}),e=await W.applySynthesizedMerge({existingId:S.topic.id,synthesized:{...p,title:S.title},visibility:X});if(!e)throw Error(`Failed to merge topic: ${h.title}`);G.set(e.id,e),V++;continue}}let P=W.getTopicIdForTitle(h.title,X);if(G.has(P)){J++;continue}let E=await W.createTopicOptimistic({title:h.title,content:h.content,visibility:X});if(E.topic)G.set(E.topic.id,E.topic);if(E.created)q++;else J++}catch(P){w.error("Topic batch item failed",{title:h.title,error:SA(P)})}}catch(x){w.error("Batch topic extraction failed",{batchSize:L.length,promptChars:k.length,error:SA(x)})}}let b={created:q,merged:V,skipped:J,batches:H.length};if(q>0||V>0)await Q.messaging.send({type:_02,payload:b,broadcast:!0});return b}wA();_0();var sUw=Z.discriminatedUnion("mode",[Z.object({mode:Z.literal("derive"),reason:Z.string().optional()}),Z.object({mode:Z.literal("rebuild"),reason:Z.string().optional()}),Z.object({mode:Z.literal("source-batch"),minRelevanceScore:Z.number().min(0).max(1).optional()})]);class qs0{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 p02(A){let{context:Q,logger:w,config:B}=A;return{process:async($)=>{if($.mode==="derive")return await A.extractAllTopics(),{success:!0};if($.mode==="rebuild")return await A.rebuildAllTopics(),{success:!0};return aUw({context:Q,logger:w,config:B,sourceBatch:A.sourceBatch,isEntityPublished:A.isEntityPublished,minRelevanceScore:$.minRelevanceScore??B.minRelevanceScore})},validateAndParse:($)=>{let f=sUw.safeParse($??{});return f.success?f.data:null}}}async function aUw(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})}))),B=0,$=0,f=0,Y=0,X=[];for(let{ref:W,entity:K}of w){if(!K){$++;continue}if(K.contentHash!==W.contentHash){B++;continue}if(!A.isEntityPublished(K)){f++;continue}if(!Mb(K.visibility,A.config.extractionVisibility)){Y++;continue}X.push(K)}if(X.length===0)return{success:!0,sources:Q.length,created:0,merged:0,skipped:0,batches:0,stale:B,missing:$,unpublished:f,hidden:Y};let H=await ZP(X,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:B,missing:$,unpublished:f,hidden:Y}}function i02(){return{priority:5,source:pY0,deduplication:"coalesce",deduplicationKey:"topics-initial-derivation",metadata:{operationType:"data_processing",operationTarget:"topics-initial-derivation",pluginId:XP}}}async function d02(A){let Q=await r02(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 ZP(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 n02(A){let Q=await r02(A),w=await Vs0(Q,A.context,A.logger,A.config);A.logger.info("Topic rebuild complete",w)}async function Vs0(A,Q,w,B){let $=new MU(Q.entityService,w),f=await $.listTopics({visibility:B.extractionVisibility});for(let X of f)await $.deleteTopic(X.id);if(A.length===0)return{deleted:f.length,created:0,merged:0,skipped:0,batches:0};let Y=await ZP(A,Q,w,{minRelevanceScore:B.minRelevanceScore,autoMerge:B.autoMerge,mergeSimilarityThreshold:B.mergeSimilarityThreshold,targetVisibility:B.extractionVisibility});return{deleted:f.length,...Y}}async function r02(A){let Q=tUw(A),w=[];for(let B of Q){let $=await A.context.entityService.listEntities({entityType:B,options:{filter:{visibilityScope:A.config.extractionVisibility}}});for(let f of $){if(!A.isEntityPublished(f))continue;w.push(f)}}return w}function tUw(A){return A.context.entityService.getEntityTypes().filter((w)=>A.shouldProcessEntityType(w))}var ky=Z.object({entityType:Z.string(),content:Z.string(),metadata:Z.record(Z.string(),Z.unknown()).optional()}),eUw=ky.extend({minRelevanceScore:Z.number().optional()}),AGw=Z.object({contentA:ky,contentB:ky,minRelevanceScore:Z.number().optional(),threshold:Z.number().min(0).max(1).optional()}),ko=Z.object({title:Z.string(),content:Z.string()}),QGw=Z.object({existingTopics:Z.array(ko),incomingTopic:ko,threshold:Z.number().optional()}),wGw=Z.object({existingTopics:Z.array(ko).default([]),incomingTopic:ko.extend({relevanceScore:Z.number().min(0).max(1).optional()}),threshold:Z.number().optional()}),BGw=Z.object({entities:Z.array(ky).min(1),minRelevanceScore:Z.number().optional()}),$Gw=Z.object({existingTopics:Z.array(ko).optional(),entities:Z.array(ky)}),fGw=Z.object({entities:Z.array(ky)});function Ly(A,Q=""){return{id:`eval${Q}-${Date.now()}`,entityType:A.entityType,content:A.content,contentHash:B6(A.content),visibility:"public",metadata:A.metadata??{},created:new Date().toISOString(),updated:new Date().toISOString()}}function o02(A){return{title:A.title,relevanceScore:A.relevanceScore}}function YGw(A){let Q=A.metadata.title;return typeof Q==="string"?Q:A.id}function XGw(A,Q){return{...A,sources:[{id:Q.id,type:Q.entityType,title:YGw(Q)}]}}async function HP(A){let Q=await A.entityService.listEntities({entityType:i6});await Promise.all(Q.map((w)=>A.entityService.deleteEntity({entityType:i6,id:w.id})))}async function ZGw(A){for(;;){if((await A.jobs.getActiveJobs(["shell:embedding"])).length===0)return;await new Promise((w)=>setTimeout(w,100))}}function s02(A){let{context:Q,logger:w,config:B}=A,$=new Ds0(Q,w),f=async(Y,X,H="")=>{let W=Ly(Y,H);return $.extractFromEntity(W,X)};Q.eval.registerHandler("extractFromEntity",async(Y)=>{await HP(Q);let X=eUw.parse(Y),H=X.minRelevanceScore??B.minRelevanceScore,W=Ly(X);return(await $.extractFromEntity(W,H)).map((U)=>XGw(U,W))}),Q.eval.registerHandler("checkMergeSimilarity",async(Y)=>{await HP(Q);let X=AGw.parse(Y),H=X.minRelevanceScore??B.minRelevanceScore,W=X.threshold??B.mergeSimilarityThreshold,[K,U]=await Promise.all([f(X.contentA,H,"-a"),f(X.contentB,H,"-b")]),G=new MU(Q.entityService,w),q=[];for(let b of K){let L=await G.createTopic(b);if(L)q.push(L)}let V=(await Promise.all(U.map(async(b)=>{let L=await G.findMergeCandidate({incoming:b,threshold:W,additionalCandidates:q});if(!L)return null;return{incomingTitle:b.title,candidateTitle:L.title,candidateScore:L.score}}))).filter((b)=>b!==null),J=V.map((b)=>b.candidateTitle);return{topicsA:K.map(o02),topicsB:U.map(o02),matchingTitles:J,mergeCandidates:V,wouldMerge:V.length>0}}),Q.eval.registerHandler("detectMergeCandidate",async(Y)=>{await HP(Q);let X=QGw.parse(Y),H=X.threshold??B.mergeSimilarityThreshold,W=new MU(Q.entityService,w),K=[];for(let G of X.existingTopics){let q=await W.createTopic(G);if(q)K.push(q)}let U=await W.findMergeCandidate({incoming:{title:X.incomingTopic.title},threshold:H,additionalCandidates:K});return{found:U!==null,candidateTitle:U?.title,candidateScore:U?.score}}),Q.eval.registerHandler("processTopicWithAutoMerge",async(Y)=>{await HP(Q);let X=wGw.parse(Y),H=new MU(Q.entityService,w);for(let G of X.existingTopics)await H.createTopic({title:G.title,content:G.content});await ZGw(Q);let W=Ly({entityType:"post",content:X.incomingTopic.content,metadata:{title:X.incomingTopic.title}},"-source"),K=await ZP([W],Q,w,{minRelevanceScore:0,autoMerge:!0,mergeSimilarityThreshold:X.threshold??B.mergeSimilarityThreshold}),U=await Q.entityService.listEntities({entityType:i6});return{...K,topicCount:U.length,topics:U.map(Us0)}}),Q.eval.registerHandler("rebuildTopics",async(Y)=>{await HP(Q);let X=$Gw.parse(Y),H=new MU(Q.entityService,w);for(let G of X.existingTopics??[])await H.createTopic(G);let W=X.entities.map((G,q)=>Ly(G,`-rebuild-${q}`)),K=await Vs0(W,Q,w,B),U=await Q.entityService.listEntities({entityType:i6});return{...K,topicCount:U.length,topics:U.map(Us0)}}),Q.eval.registerHandler("extractSequentially",async(Y)=>{await HP(Q);let X=BGw.parse(Y),H=X.minRelevanceScore??B.minRelevanceScore,W=new MU(Q.entityService,w),K=[];for(let[G,q]of X.entities.entries()){let V=Ly(q,`-sequential-${G}`),J=await $.extractFromEntity(V,H);for(let b of J)await W.createTopic({title:b.title,content:b.content});K.push({extractedTitles:J.map((b)=>b.title)})}let U=await Q.entityService.listEntities({entityType:i6});return{totalTopics:U.length,perEntity:K,topics:U.map(Fy)}}),Q.eval.registerHandler("batchExtract",async(Y)=>{await HP(Q);let H=fGw.parse(Y).entities.map((U,G)=>Ly(U,`-batch-${G}`)),W=await ZP(H,Q,w,{minRelevanceScore:B.minRelevanceScore}),K=await Q.entityService.listEntities({entityType:i6});return{...W,topics:K.map(Fy)}})}var HGw=new PU;async function a02({entity:A,config:Q}){let w=Iy.parse(A),B=HGw.parseTopicBody(w.content);return{$type:"ai.rizom.brain.topic",title:B.title,body:B.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 bs0(){return{entityType:"topic",collection:"ai.rizom.brain.topic",lexicon:k6["ai.rizom.brain.topic"],validate:!1,buildRecord:a02}}var t02={name:"@brains/topics",version:"0.2.0-alpha.151",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 KGw=new PU,UGw=Z.looseObject({status:Z.unknown().optional()});class e02 extends rQ{entityType=i6;schema=Iy;adapter=KGw;unregisterAtprotoProjection;sourceBatch=new qs0;constructor(A={}){super(XP,t02,A,F02)}getEntityTypeConfig(){return{weight:0.5,projectionSource:!1}}getTemplates(){return{extraction:P02,"merge-synthesis":M02,"topic-list":O02,"topic-detail":x02}}getDataSources(){return[new Gs0(this.logger.child("TopicsDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableAutoExtraction)return[];return[{id:Hs0,targetType:i6,job:{type:k02,handler:p02({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 qk(A,i6,{visibility:this.config.extractionVisibility}),jobData:{mode:"derive",reason:"initial-sync"},jobOptions:i02()},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(!Mb(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:pY0,delayMs:this.config.sourceChangeBatchDelayMs,deduplication:"skip",deduplicationKey:N02,metadata:{operationType:"data_processing",operationTarget:"topic-source-batch",pluginId:XP}})}}]}async onRegister(A){A.insights.register("topic-distribution",h02()),C02({context:A,pluginId:this.id}),s02({context:A,logger:this.logger,config:this.config}),this.unregisterAtprotoProjection=Q5.getInstance().register(bs0())}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}hasRunInitialDerivation(){return this.getDerivedEntityProjectionController(Hs0)?.hasQueuedInitialSync()??!1}shouldProcessEntityType(A,Q){if(A===i6)return!1;if(!this.config.includeEntityTypes.includes(A))return!1;return Q.getEntityTypeConfig(A).projectionSource!==!1}isEntityPublished(A){let Q=UGw.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 d02({context:A,logger:this.logger,config:this.config,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q,A.entityService),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}async rebuildAllTopics(A){await n02({context:A,logger:this.logger,config:this.config,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q,A.entityService),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}}function aY0(A={}){return new e02(A)}wA();_0();wA();var Js0=Z.enum(["linkedin"]),AA2=Z.enum(["linkedin"]),Is0=Z.enum(["generating","draft","queued","published","failed"]),QA2=Z.enum(["generating","draft","queued","published","failed"]),wA2=Z.enum(["post","deck"]),GGw=Z.enum(["post","deck"]),BA2=Z.object({id:Z.string().min(1).describe("Document entity ID")}),DGw=Z.object({id:Z.string().min(1)}),OU=Z.object({title:Z.string().describe("Short descriptive title (3-6 words) for file naming"),platform:Js0.describe("Target platform"),status:Is0,coverImageId:Z.string().optional().describe("Image entity ID for post image"),documents:Z.array(BA2).optional().describe("Document attachments for publishing"),publishedAt:Z.string().datetime().optional(),platformPostId:Z.string().optional().describe("ID from platform after publishing"),sourceEntityId:Z.string().optional().describe("Source entity ID if auto-generated"),sourceEntityType:wA2.optional().describe("Source entity type (post, deck)")}),$A2=OU.extend({platform:Js0.optional(),status:Is0.optional()}),zGw=OU.pick({title:!0,platform:!0,status:!0,publishedAt:!0,platformPostId:!0}).extend({slug:Z.string().describe("URL-friendly identifier: {platform}-{title}"),error:Z.string().optional()}),qGw=Z.object({title:Z.string(),platform:AA2,status:QA2,publishedAt:Z.string().datetime().optional(),platformPostId:Z.string().optional(),slug:Z.string(),error:Z.string().optional()}),VGw=Z.object({title:Z.string(),platform:AA2,status:QA2,coverImageId:Z.string().optional(),documents:Z.array(DGw).optional(),publishedAt:Z.string().datetime().optional(),platformPostId:Z.string().optional(),sourceEntityId:Z.string().optional(),sourceEntityType:GGw.optional()}),OF=_Q.extend({entityType:Z.literal("social-post"),metadata:qGw}),tY0=OF.extend({frontmatter:VGw,body:Z.string()}),bGw=tY0.extend({url:Z.string().optional(),listUrl:Z.string().optional(),listLabel:Z.string().optional(),typeLabel:Z.string().optional(),coverImageUrl:Z.string().optional(),coverImageWidth:Z.number().optional(),coverImageHeight:Z.number().optional()});wA();U2();class Fs0 extends g2{constructor(){super({entityType:"social-post",purpose:"A short post drafted for social media such as LinkedIn or X.",schema:OF,frontmatterSchema:OU,supportsCoverImage:!0})}toMarkdown(A){let Q,w={};try{w=this.parseFrontMatter(A.content,OU),Q=this.extractBody(A.content)}catch{Q=A.content}let B={...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,B)}fromMarkdown(A){let Q=this.parseFrontMatter(A,$A2),w=Q.platform??"linkedin",B=Q.status??"draft",$=`${w}-${H1(Q.title)}`;return{content:A,entityType:"social-post",metadata:{title:Q.title,slug:$,platform:w,status:B,publishedAt:Q.publishedAt,platformPostId:Q.platformPostId}}}parsePostFrontmatter(A){return this.parseFrontMatter(A.content,OU)}getPostContent(A){return this.extractBody(A.content)}createPostContent(A,Q){return this.buildMarkdown(Q,A)}buildStub(A){let w={title:A.title,platform:"linkedin",status:"generating"};return{content:this.buildMarkdown("",w),metadata:{title:A.title,slug:`linkedin-${H1(A.title)}`,platform:"linkedin",status:"generating"}}}}var i7=new Fs0;wA();wA();_0();var JGw=Z.looseObject({id:Z.string().optional(),limit:Z.number().optional(),page:Z.number().optional(),pageSize:Z.number().optional(),baseUrl:Z.string().optional(),platform:Z.enum(["linkedin"]).optional(),status:Z.enum(["generating","draft","queued","published","failed"]).optional(),sortByQueue:Z.boolean().optional(),nextInQueue:Z.boolean().optional()}),IGw=Z.looseObject({entityType:Z.string().optional(),query:JGw.optional()});function fA2(A){let Q=n2(A.content,OU);return tY0.parse({...A,frontmatter:Q.metadata,body:Q.content})}class eY0 extends J8{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=IGw.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}transformEntity(A){return fA2(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:B}=this.parseQuery(A),$=w.entityService;if(B.nextInQueue)return this.fetchNextInQueue(Q,$);if(B.id){let{item:K}=await this.fetchDetail(B.id,$);return Q.parse(this.buildDetailResult(K,null))}let f={};if(B.platform)f.platform=B.platform;if(B.status)f.status=B.status;let Y=Object.keys(f).length>0,X=B.sortByQueue?[{field:"queueOrder",direction:"asc"}]:this.config.defaultSort,{items:H,pagination:W}=await this.fetchList(B,$,{...Y&&{filter:{metadata:f}},sortFields:X});return Q.parse(this.buildListResult(H,W,B))}async fetchNextInQueue(A,Q){let B=(await Q.listEntities({entityType:this.config.entityType,options:{filter:{metadata:{status:"queued"}},sortFields:[{field:"queueOrder",direction:"asc"}],limit:1}}))[0],$=B?fA2(B):null;return A.parse({post:$})}}_0();var YA2=Z.object({accessToken:Z.string().optional(),refreshToken:Z.string().optional(),organizationId:Z.string().optional(),apiVersion:Z.string().regex(/^\d{6}$/).optional()}),Ls0=Z.object({linkedin:YA2.optional(),publishInterval:Z.number().default(3600000),enabled:Z.boolean().default(!0),defaultPrompt:Z.string().default("Create an engaging social media post that drives engagement"),maxRetries:Z.number().default(3),autoGenerateOnBlogPublish:Z.boolean().default(!1)});wA();U2();_0();y6();_s0();import{jsxDEV as e5,Fragment as kGw}from"preact/jsx-dev-runtime";function FGw(A,Q){if(A.length<=Q)return A;return A.slice(0,Q).trim()+"..."}function LGw(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"})}var QX0=({posts:A,pageTitle:Q,pagination:w,baseUrl:B="/social-posts"})=>{let $=Q??"Social Posts",f=w?.totalItems??A.length,Y=`Browse all ${f} social ${f===1?"post":"posts"}`;return e5(kGw,{children:[e5(pQ,{title:$,description:Y},void 0,!1,void 0,this),e5("div",{className:"social-post-list bg-theme",children:e5("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[e5("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:$},void 0,!1,void 0,this),A.length===0?e5("p",{className:"text-theme-muted italic",children:"No social posts yet."},void 0,!1,void 0,this):e5("ul",{className:"space-y-6",children:A.map((X)=>e5("li",{children:e5(G6,{href:X.url,variant:"horizontal",children:e5("div",{className:"flex flex-col sm:flex-row gap-4",children:[X.coverImageUrl&&e5("img",{src:X.coverImageUrl,alt:X.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),e5("div",{className:"flex-1 min-w-0",children:[e5("div",{className:"flex items-start justify-between gap-4 mb-2",children:[e5("h2",{className:"text-lg font-semibold text-heading",children:X.frontmatter.title},void 0,!1,void 0,this),e5("time",{className:"text-sm text-theme-muted shrink-0",children:LGw(X.frontmatter.publishedAt??X.created)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),e5("div",{className:"flex items-center gap-2 mb-3",children:[e5(iY,{status:X.frontmatter.status},void 0,!1,void 0,this),e5("span",{className:"text-xs text-theme-muted uppercase",children:X.frontmatter.platform},void 0,!1,void 0,this),e5("span",{className:"text-xs text-theme-muted font-mono",children:X.id},void 0,!1,void 0,this)]},void 0,!0,void 0,this),e5("p",{className:"text-theme leading-relaxed",children:FGw(X.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)},X.id,!1,void 0,this))},void 0,!1,void 0,this),w&&w.totalPages>1&&e5(pq,{currentPage:w.currentPage,totalPages:w.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)};import{jsxDEV as A8,Fragment as _Gw}from"preact/jsx-dev-runtime";function XA2(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric",hour:"numeric",minute:"2-digit"})}var wX0=({post:A})=>{let Q=`Social Post - ${A.frontmatter.platform}`,w=A.body.slice(0,160),B=[{label:"Home",href:"/"},{label:A.listLabel??"Social Posts",href:A.listUrl??"/social-posts"},{label:A.frontmatter.platform}];return A8(_Gw,{children:[A8(pQ,{title:Q,description:w},void 0,!1,void 0,this),A8("section",{className:"social-post-detail",children:A8("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:A8("div",{className:"max-w-3xl mx-auto",children:[A8(vD,{items:B},void 0,!1,void 0,this),A8("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-4",children:A.frontmatter.title},void 0,!1,void 0,this),A8("div",{className:"flex flex-wrap items-center gap-3 mb-6",children:[A8(iY,{status:A.frontmatter.status},void 0,!1,void 0,this),A8("span",{className:"text-sm text-theme-muted uppercase",children:A.frontmatter.platform},void 0,!1,void 0,this),A8("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&&A8(cq,{src:A.coverImageUrl,alt:A.frontmatter.title,width:A.coverImageWidth,height:A.coverImageHeight,className:"mb-8"},void 0,!1,void 0,this),A8(G6,{className:"p-8 mb-8",children:A8("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),A8("div",{className:"space-y-4 text-sm text-theme-muted",children:[A8("div",{children:[A8("span",{className:"font-medium",children:"Created:"},void 0,!1,void 0,this)," ",XA2(A.created)]},void 0,!0,void 0,this),A.frontmatter.publishedAt&&A8("div",{children:[A8("span",{className:"font-medium",children:"Published:"},void 0,!1,void 0,this)," ",XA2(A.frontmatter.publishedAt)]},void 0,!0,void 0,this),A.frontmatter.platformPostId&&A8("div",{children:A8("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 _o(A){return`social-media:${A}`}var NGw=Z.union([Z.boolean(),Z.object({generate:Z.boolean().optional(),prompt:Z.string().optional()})]),Ns0=Z.object({prompt:Z.string().optional(),platform:Z.enum(["linkedin"]).optional(),sourceEntityType:Z.enum(["post","deck"]).optional(),sourceEntityId:Z.string().optional(),title:Z.string().optional().describe("Required when content is provided directly"),content:Z.string().optional(),addToQueue:Z.boolean().optional(),generateImage:Z.boolean().optional().describe("Auto-generate cover image for post"),coverImage:NGw.optional().describe("Generic cover image generation request")}),jGw=LX.extend({slug:Z.string().optional()});class WP extends q4{constructor(A,Q){super(A,Q,{schema:Ns0,jobTypeName:"social-post-generation",entityType:"social-post"})}async generate(A,Q){let w=A.platform??"linkedin",B=A.addToQueue??!1,{prompt:$,sourceEntityType:f,sourceEntityId:Y}=A,{content:X,title:H}=A;if(X&&H)await this.reportProgress(Q,{progress:50,message:"Using provided content"});else if(X&&!H){await this.reportProgress(Q,{progress:10,message:"Shaping content with AI"});let b=await this.context.ai.generate({prompt:X,templateName:_o(w)});H=b.title,X=b.content,await this.reportProgress(Q,{progress:50,message:"Social post shaped from content"})}else if(Y&&f){await this.reportProgress(Q,{progress:10,message:`Fetching source ${f}`});let b=await this.context.entityService.getEntity({entityType:f,id:Y});if(!b)this.failEarly(`Source entity not found: ${f}/${Y}`);await this.reportProgress(Q,{progress:30,message:"Generating social post from source content"});let N=Z.looseObject({slug:Z.string()}).safeParse(b.metadata),k=N.success?N.data.slug:Y,x=await this.context.ai.generate({prompt:`Create an engaging ${w} post to promote this ${f}:
|
|
7478
7478
|
|
|
7479
7479
|
Source: ${f}/${k}
|
|
7480
7480
|
|
|
7481
7481
|
${b.content}`,templateName:_o(w)});H=x.title,X=x.content,await this.reportProgress(Q,{progress:50,message:"Social post generated from source"})}else if($){await this.reportProgress(Q,{progress:10,message:"Generating social post with AI"});let b=await this.context.ai.generate({prompt:$,templateName:_o(w)});H=b.title,X=b.content,await this.reportProgress(Q,{progress:50,message:"Social post generated"})}else this.failEarly("No content source provided (prompt, sourceEntityId, or content)");if(!X||!H)this.failEarly("Content or title was not generated");let K={title:H,platform:w,status:B?"queued":"draft",...Y&&{sourceEntityId:Y},...f&&{sourceEntityType:f}},U=i7.createPostContent(K,X),q=i7.fromMarkdown(U).metadata;if(!q)this.failEarly("Failed to parse social post metadata");let V=await KK({entityType:"social-post",title:H,deriveId:(b)=>`${w}-${H1(b)}`,regeneratePrompt:"Generate a different social media post title on the same topic.",context:this.context}),J=U;if(V!==H){q.title=V,q.slug=`${w}-${H1(V)}`;let b={...K,title:V};J=i7.createPostContent(b,X)}return{id:q.slug,content:J,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,B){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: ${$}`,title:`${$} Image`,aspectRatio:"16:9",targetEntityType:"social-post",targetEntityId:Q},toolContext:{interfaceType:"job",userId:"system"}})}await this.context.messaging.send({type:"generate:report:success",payload:{entityType:"social-post",entityId:Q}})}summarizeDataForLog(A){return{platform:A.platform??"linkedin",hasPrompt:!!A.prompt,sourceEntityType:A.sourceEntityType,addToQueue:A.addToQueue??!1,generateImage:A.generateImage??!1,coverImage:!!A.coverImage}}}_0();var ZA2=200,HA2="com.linkedin.digitalmedia.uploading.MediaUploadHttpRequest";function No(A){if(A.length<=ZA2)return A;return`${A.slice(0,ZA2)}\u2026 (truncated, ${A.length} bytes)`}var PGw=Z.looseObject({sub:Z.string()}),MGw=Z.looseObject({id:Z.string()}),OGw=Z.looseObject({value:Z.looseObject({asset:Z.string(),uploadMechanism:Z.looseObject({[HA2]:Z.looseObject({uploadUrl:Z.url()})})})}).transform((A)=>({uploadUrl:A.value.uploadMechanism[HA2].uploadUrl,assetUrn:A.value.asset})),xGw=Z.looseObject({value:Z.looseObject({uploadUrl:Z.url(),document:Z.string()})}).transform((A)=>({uploadUrl:A.value.uploadUrl,documentUrn:A.value.document}));function vGw(A){let Q={status:"READY",media:A.urn};if(A.title)Q.title={text:A.title};return Q}function RGw(A){let Q=OGw.safeParse(A);return Q.success?Q.data:null}function hGw(A){let Q=xGw.safeParse(A);return Q.success?Q.data:null}var CGw="202604";class js0{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,B){if(!this.config.accessToken)throw Error("LinkedIn access token not configured");let $=await this.getAuthor(),f=B?.[0];if(B&&B.length>1)this.logger.warn("LinkedIn document publishing supports one PDF",{count:B.length});let Y=null;if(f){let U=await this.uploadDocument($,f);return this.publishDocumentPost($,A,U,f.filename)}else if(w){let U=await this.uploadImage($,w);if(U)Y={category:"IMAGE",urn:U}}let X={shareCommentary:{text:A},shareMediaCategory:Y?.category??"NONE",...Y&&{media:[vGw(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:$,lifecycleState:"PUBLISHED",specificContent:{"com.linkedin.ugc.ShareContent":X},visibility:{"com.linkedin.ugc.MemberNetworkVisibility":"PUBLIC"}})});if(!H.ok){let U=No(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??CGw,"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 X=No(await w.text());return this.logger.warn("LinkedIn image upload registration failed",{status:w.status,error:X}),null}let B=RGw(await w.json());if(!B)return this.logger.warn("LinkedIn image upload registration was malformed"),null;let{uploadUrl:$,assetUrn:f}=B,Y=await this.fetch($,{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:f}),f}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 f=No(await w.text());throw Error(`LinkedIn document upload initialization failed: ${w.status} - ${f}`)}let B=hGw(await w.json());if(!B)throw Error("LinkedIn document upload initialization was malformed");let $=await this.fetch(B.uploadUrl,{method:"PUT",headers:{Authorization:`Bearer ${this.config.accessToken}`,"Content-Type":Q.mimeType},body:new Uint8Array(Q.data)});if(!$.ok)throw Error(`LinkedIn document binary upload failed: ${$.status}`);return this.logger.info("LinkedIn document uploaded",{documentUrn:B.documentUrn,filename:Q.filename}),B.documentUrn}async publishDocumentPost(A,Q,w,B){let $=await this.fetch(`${this.restApiBaseUrl}/posts`,{method:"POST",headers:this.getRestHeaders(),body:JSON.stringify({author:A,commentary:Q,visibility:"PUBLIC",distribution:{feedDistribution:"MAIN_FEED",targetEntities:[],thirdPartyDistributionChannels:[]},content:{media:{id:w,title:B}},lifecycleState:"PUBLISHED",isReshareDisabledByAuthor:!1})});if(!$.ok){let X=No(await $.text());throw this.logger.error("LinkedIn document post API error",{status:$.status,error:X}),Error(`LinkedIn document post API error: ${$.status} - ${X}`)}let f=$.headers.get("X-RestLi-Id")??"";this.logger.info("LinkedIn document post created",{postId:f,documentUrn:w});let Y={id:f};if(f)Y.url=`https://www.linkedin.com/feed/update/${f}`;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 B=PGw.safeParse(await w.json());if(B.success)return this.cachedUserId=`urn:li:person:${B.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=No(await A.text());throw Error(`Failed to get LinkedIn user ID: ${A.status} - ${w}`)}let Q=MGw.parse(await A.json());return this.cachedUserId=`urn:li:person:${Q.id}`,this.cachedUserId}}function Ps0(A,Q,w={}){return new js0(A,Q,w)}_0();jB();_s0();var gGw=Z.object({currentPage:Z.number(),totalPages:Z.number(),totalItems:Z.number(),pageSize:Z.number(),hasNextPage:Z.boolean(),hasPrevPage:Z.boolean()}),yGw=Z.union([Z.enum(["public","shared","restricted"]),Z.literal("private")]).optional().transform((A)=>{if(A===void 0)return"public";if(A==="private")return"restricted";return A}),WA2=Z.enum(["linkedin"]),KA2=Z.enum(["generating","draft","queued","published","failed"]),EGw=Z.enum(["post","deck"]),TGw=Z.object({id:Z.string().min(1)}),SGw=Z.object({title:Z.string(),platform:WA2,status:KA2,coverImageId:Z.string().optional(),documents:Z.array(TGw).optional(),publishedAt:Z.string().optional(),platformPostId:Z.string().optional(),sourceEntityId:Z.string().optional(),sourceEntityType:EGw.optional()}),mGw=Z.object({title:Z.string(),platform:WA2,status:KA2,publishedAt:Z.string().optional(),platformPostId:Z.string().optional(),slug:Z.string(),error:Z.string().optional()}),UA2=Z.object({id:Z.string(),entityType:Z.literal("social-post"),content:Z.string(),created:Z.string(),updated:Z.string(),visibility:yGw,metadata:mGw,contentHash:Z.string(),frontmatter:SGw,body:Z.string(),url:Z.string().optional(),listUrl:Z.string().optional(),listLabel:Z.string().optional(),typeLabel:Z.string().optional(),coverImageUrl:Z.string().optional(),coverImageWidth:Z.number().optional(),coverImageHeight:Z.number().optional()}),uGw=Z.object({posts:Z.array(UA2),totalCount:Z.number().optional(),pagination:gGw.nullable(),baseUrl:Z.string().optional()}),cGw=Z.object({post:UA2});function GA2(){return{linkedin:AX0,"social-post-list":d1({name:"social-post-list",description:"Social post list page template",schema:uGw,dataSourceId:"social-media:posts",requiredPermission:"public",layout:{component:QX0}}),"social-post-detail":d1({name:"social-post-detail",description:"Individual social post template",schema:cGw,dataSourceId:"social-media:posts",requiredPermission:"public",layout:{component:wX0}})}}_0();var lGw=Z.object({prompt:Z.string().optional(),content:Z.string().optional(),platform:Z.enum(["linkedin"]).default("linkedin")}),pGw=Z.object({prompt:Z.string().optional(),content:Z.string().optional(),title:Z.string().optional(),platform:Z.enum(["linkedin"]).optional()});function DA2(A){A.eval.registerHandler("generation",async(Q)=>{let w=lGw.parse(Q),B=w.content?`Create an engaging LinkedIn post to share this content:
|
|
7482
7482
|
|
|
7483
|
-
${w.content}`:w.prompt??"Write an engaging LinkedIn post";return A.ai.generate({prompt:B,templateName:`social-media:${w.platform}`})}),A.eval.registerHandler("create",async(Q)=>{let w=pGw.parse(Q),B=[],$=Zf.from(async(W)=>{let K={progress:W.progress};if(W.message!==void 0)K.message=W.message;B.push(K)});if(!$)throw Error("Failed to create progress reporter");let Y=await new WP(A.logger,A).process(w,`eval-${Date.now()}`,$),X=!1,H;if(Y.success&&Y.entityId){let W=await A.entityService.getEntity({entityType:"social-post",id:Y.entityId});X=!!W,H=W?.content.slice(0,300)}return{...Y,entityExists:X,entityPreview:H,progressSteps:B}})}wA();class jo{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 B=await this.entityService.getEntity({entityType:"social-post",id:w});if(!B){await this.reportFailure(Q,w,`Post not found: ${w}`);return}let $=B;if($.metadata.status==="published"){this.logger.debug("Post already published, skipping",{entityId:w});return}let f=$.metadata.platform,Y=this.providers.get(f);if(!Y){await this.reportFailure(Q,w,`No provider configured for platform: ${f}`);return}let X=n2($.content,OU),H;if(X.metadata.coverImageId)H=await this.fetchImageData(X.metadata.coverImageId);let W=X.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(X.metadata):[],G=K.length>0?K:U,q=G.length?await Y.publish(X.content,$.metadata,H,G):await Y.publish(X.content,$.metadata,H),V=new Date().toISOString(),J=q.id||void 0,b={...X.metadata,status:"published",publishedAt:V,...J&&{platformPostId:J}},L=i7.createPostContent(b,X.content);await this.entityService.updateEntity({entity:{...$,content:L,metadata:{...$.metadata,status:"published",publishedAt:V,platformPostId:J}}}),await this.reportSuccess(Q,w,q.id),this.logger.info(`Post published successfully: ${w}`,{platform:f,platformPostId:J})}catch(U){let G=U instanceof Error?U.message:String(U),q={...X.metadata,status:"failed"},V=i7.createPostContent(q,X.content);await this.entityService.updateEntity({entity:{...$,content:V,metadata:{...$.metadata,status:"failed"}}}),await this.reportFailure(Q,w,G),this.logger.error(`Post publish failed: ${w}`,{platform:f,error:G})}}catch(B){let $=SA(B);this.logger.error("Unexpected error in publish handler",{entityId:w,error:$}),await this.reportFailure(Q,w,$)}}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 B=await this.fetchSingleDocumentData(w.id);if(B)Q.push(B)}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 B=typeof Q.metadata.filename==="string"?Q.metadata.filename:`${A}.pdf`;return{type:"document",data:Buffer.from(w[1],"base64"),mimeType:"application/pdf",filename:B}}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 B=Q.content.match(/^data:([^;]+);base64,(.+)$/);if(!B?.[1]||!B[2]){this.logger.warn("Invalid image data URL format",{imageId:A});return}let $=B[1],f=B[2];return{data:Buffer.from(f,"base64"),mimeType:$}}catch(Q){this.logger.warn("Failed to fetch cover image",{imageId:A,error:Q});return}}}function zA2(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 B=Q.values().next().value;return await A.messaging.send({type:"publish:register",payload:{entityType:"social-post",provider:B,config:{publishResultIdField:"platformPostId"}}}),w.info("Registered social-post with publish-pipeline"),{success:!0}})}function qA2(A,Q,w){let B=new jo({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($)=>{return await B.handle($.payload),{success:!0}}),w.debug("Subscribed to publish:execute messages")}function VA2(A,Q){A.messaging.subscribe("entity:updated",async(w)=>{let{entityType:B,entityId:$,entity:f}=w.payload;if(B!=="post")return{success:!0};if(f.metadata?.status!=="queued")return{success:!0};try{if((await A.entityService.listEntities({entityType:"social-post",options:{filter:{metadata:{sourceEntityType:"post",sourceEntityId:$}},limit:1}})).length>0)return Q.debug(`Social post already exists for ${$}, skipping auto-generate`),{success:!0};return await A.messaging.send({type:"social:auto-generate",payload:{sourceEntityType:B,sourceEntityId:$,platform:"linkedin"}}),Q.info(`Auto-generate social post triggered for queued post ${$}`),{success:!0}}catch(X){let H=SA(X);return Q.error(`Failed to trigger auto-generate for ${$}:`,{error:H}),{success:!0}}}),Q.debug("Subscribed to entity:updated for auto-generation")}function bA2(A,Q){A.messaging.subscribe("social:auto-generate",async(w)=>{let{sourceEntityType:B,sourceEntityId:$,platform:f}=w.payload;try{let Y=await A.jobs.enqueue({type:`${i7.entityType}:generation`,data:{sourceEntityType:B,sourceEntityId:$,platform:f,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 X=SA(Y);return Q.error(`Failed to enqueue social post generation for ${$}:`,{error:X}),{success:!1}}}),Q.debug("Subscribed to social:auto-generate messages")}function JA2(A,Q){A.messaging.subscribe("generate:execute",async(w)=>{let{entityType:B}=w.payload;if(B!=="social-post")return{success:!0};Q.info("Received generate:execute for social-post");try{let $=await A.entityService.listEntities({entityType:"post",options:{filter:{metadata:{status:"published"}},limit:5}});if($.length===0)return Q.info("No published posts found for social post generation"),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:"No published posts available for social post generation"}}),{success:!0};let f=null;for(let X of $)if((await A.entityService.listEntities({entityType:"social-post",options:{filter:{metadata:{sourceEntityType:"post",sourceEntityId:X.id}},limit:1}})).length===0){f=X;break}if(!f)return Q.info("All recent posts already have social posts"),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:"All recent posts already have social posts generated"}}),{success:!0};let Y=await A.jobs.enqueue({type:`${i7.entityType}:generation`,data:{sourceEntityType:"post",sourceEntityId:f.id,platform:"linkedin",addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}});return Q.info("Social post generation job queued",{jobId:Y,sourcePostId:f.id}),{success:!0}}catch($){let f=SA($);return Q.error("Failed to handle generate:execute:",{error:f}),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:f}}),{success:!0}}}),Q.debug("Subscribed to generate:execute messages")}async function IA2({entity:A,config:Q}){let w=OF.parse(A),B=i7.parsePostFrontmatter(w),$=i7.getPostContent(w);return{$type:"ai.rizom.brain.socialPost",title:B.title,platform:B.platform,body:$,format:"text/markdown",status:B.status,...B.publishedAt&&{publishedAt:B.publishedAt},...B.platformPostId&&{platformPostId:B.platformPostId},...B.sourceEntityType&&{sourceLocalEntityType:B.sourceEntityType},...B.sourceEntityId&&{sourceLocalEntityId:B.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 Ms0(){return{entityType:"social-post",collection:"ai.rizom.brain.socialPost",lexicon:k6["ai.rizom.brain.socialPost"],validate:!1,buildRecord:IA2}}var FA2={name:"@brains/social-media",version:"0.2.0-alpha.150",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:"^6.0.3"},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 Os0 extends rQ{entityType=i7.entityType;schema=OF;adapter=i7;providers=new Map;unregisterAtprotoProjection;constructor(A={}){super("social-media",FA2,A,Ls0)}createGenerationHandler(A){return new WP(this.logger.child("GenerationJobHandler"),A)}getTemplates(){return GA2()}getDataSources(){return[new eY0(this.logger.child("SocialPostDataSource"))]}getEntityTypeConfig(){return{publish:{publishStatuses:["queued","published","failed"]}}}async onRegister(A){if(this.initializeProviders(),zA2(A,this.providers,this.logger),qA2(A,this.providers,this.logger),this.config.autoGenerateOnBlogPublish)VA2(A,this.logger),bA2(A,this.logger),this.logger.info("Auto-generate on blog publish enabled");JA2(A,this.logger),DA2(A),this.unregisterAtprotoProjection=Q5.getInstance().register(Ms0()),this.logger.info("Social media plugin registered successfully")}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}initializeProviders(){if(this.config.linkedin?.accessToken){let A=Ps0(this.config.linkedin,this.logger.child("LinkedInClient"));this.providers.set("linkedin",A),this.logger.info("LinkedIn provider initialized")}}}function Po(A={}){return new Os0(A)}_0();var dGw=Z.enum(["draft","queued","published","failed"]),LA2=Z.object({status:dGw.default("draft"),queueOrder:Z.number().optional().describe("Position in publish queue (lower = sooner)"),publishedAt:Z.string().datetime().optional()});class xs0{name="internal";async publish(A,Q){return{id:"internal"}}}var Mo={interfaceType:"system",userId:"system",userPermissionLevel:"anchor",authorization:"system"},sf={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"},xF={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"},kA2={REGISTER:"publish-assets:register"};_0();var nGw=Z.enum(["provider"]),_A2=Z.object({executionMode:nGw.optional(),publishResultIdField:Z.string().min(1).optional(),publishTimestampField:Z.string().min(1).optional(),enabled:Z.boolean().optional()}).strict();var rGw=Z.object({skipIfDraftExists:Z.boolean().optional(),minSourceEntities:Z.number().optional(),maxUnpublishedDrafts:Z.number().optional(),sourceEntityType:Z.string().optional()}),NA2=Z.object({entitySchedules:Z.record(Z.string(),Z.string()).optional(),generationSchedules:Z.record(Z.string(),Z.string()).optional(),generationConditions:Z.record(Z.string(),rGw).optional()});class A3{static instance=null;queues=new Map;static getInstance(){return A3.instance??=new A3,A3.instance}static resetInstance(){A3.instance=null}static createFresh(){return new A3}constructor(){}async add(A,Q,w=Mo){let B=this.getOrCreateQueue(A),$=B.find((X)=>X.entityId===Q);if($)return{position:$.position};let f=B.length+1,Y={entityId:Q,entityType:A,position:f,queuedAt:new Date().toISOString(),authContext:{...w}};return B.push(Y),{position:f}}async remove(A,Q){let w=this.queues.get(A);if(!w)return;let B=w.findIndex(($)=>$.entityId===Q);if(B===-1)return;w.splice(B,1),this.recalculatePositions(w)}async reorder(A,Q,w){let B=this.queues.get(A);if(!B)return;let $=B.findIndex((X)=>X.entityId===Q);if($===-1)return;let[f]=B.splice($,1);if(!f)return;let Y=Math.max(0,Math.min(w-1,B.length));B.splice(Y,0,f),this.recalculatePositions(B)}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 Q3{static instance=null;providers=new Map;executionModes=new Map;publishResultIdFields=new Map;publishTimestampFields=new Map;defaultProvider=new xs0;static getInstance(){return Q3.instance??=new Q3,Q3.instance}static resetInstance(){Q3.instance=null}static createFresh(){return new Q3}constructor(){}register(A,Q,w){let B=this.providers.get(A);if(B&&B.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 jA2(A,Q){if(!Q.publishExecutor){Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:"Publish executor not configured",retryCount:0,willRetry:!1});return}await oGw(A,Q)}async function oGw(A,Q){if(!Q.publishExecutor)return;try{let w=await Q.publishExecutor.publish({entityType:A.entityType,id:A.entityId});if("error"in w){let B={entityType:A.entityType,entityId:A.entityId,error:w.error,retryCount:0,willRetry:!1};if(Q.messageBus)await Q.messageBus.send({type:sf.FAILED,payload:B,sender:"publish-service",broadcast:!0});Q.onFailed?.(B);return}vs0(A.entityType,A.entityId,w.result,Q)}catch(w){let B=SA(w);Q.retryTracker.recordFailure(A.entityId,B);let $=Q.retryTracker.getRetryInfo(A.entityId);Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:B,retryCount:$?.retryCount??1,willRetry:!1})}}function vs0(A,Q,w,B){if(B.retryTracker.clearRetries(Q),B.messageBus)B.messageBus.send({type:sf.COMPLETED,payload:{entityType:A,entityId:Q,result:w},sender:"publish-service",broadcast:!0});B.onPublish?.({entityType:A,entityId:Q,result:w})}function PA2(A,Q,w,B){B.retryTracker.recordFailure(Q,w);let $=B.retryTracker.getRetryInfo(Q),f={entityType:A,entityId:Q,error:w,retryCount:$?.retryCount??1,willRetry:!1};if(B.messageBus)B.messageBus.send({type:sf.FAILED,payload:f,sender:"publish-service",broadcast:!0});B.onFailed?.(f)}async function MA2(A,Q){let w=Q.generationConditions[A];if(w&&Q.onCheckGenerationConditions){let $=await Q.onCheckGenerationConditions(A,w);if(!$.shouldGenerate){if(Q.messageBus)Q.messageBus.send({type:xF.SKIPPED,payload:{entityType:A,reason:$.reason??"Conditions not met"},sender:"content-pipeline"});return}}let B={entityType:A};if(Q.messageBus)await Q.messageBus.send({type:xF.EXECUTE,payload:B,sender:"content-pipeline"});Q.onGenerate?.(B)}function OA2(A,Q,w){if(w)w.send({type:xF.COMPLETED,payload:{entityType:A,entityId:Q},sender:"content-pipeline"})}function xA2(A,Q,w){if(w)w.send({type:xF.FAILED,payload:{entityType:A,error:Q},sender:"content-pipeline"})}var sGw=1000;class Rs0{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(sGw,()=>this.processUnscheduledTypes())}stop(){if(aGw(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 jA2(A,Q)}get entitySchedules(){return this.deps.config.entitySchedules}}function aGw(A){for(let Q of A.values())Q.stop();A.clear()}class hs0{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(){tGw(this.generationJobs)}async handleTriggerGeneration(A){if(!this.deps.isRunning())return;try{await MA2(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 tGw(A){for(let Q of A.values())Q.stop();A.clear()}class xU{static instance=null;config;publishRunner;generationRunner;running=!1;static getInstance(A){return xU.instance??=new xU(A),xU.instance}static resetInstance(){if(xU.instance)xU.instance.stop();xU.instance=null}static createFresh(A){return new xU(A)}constructor(A){this.config={...A,entitySchedules:A.entitySchedules??{},generationSchedules:A.generationSchedules??{},generationConditions:A.generationConditions??{}},this.validateCronExpressions(),this.publishRunner=new Rs0({config:this.config,getPublishDeps:()=>this.publishDeps,isRunning:()=>this.running}),this.generationRunner=new hs0({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){vs0(A,Q,w,this.publishDeps)}failPublish(A,Q,w){PA2(A,Q,w,this.publishDeps)}completeGeneration(A,Q){OA2(A,Q,this.config.messageBus)}failGeneration(A,Q){xA2(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(B){throw Error(`Invalid ${w} cron expression for ${A}: "${Q}" - ${SA(B)}`,{cause:B})}}}class w3{static instance=null;retries=new Map;static getInstance(){return w3.instance??=new w3,w3.instance}static resetInstance(){w3.instance=null}static createFresh(){return new w3}constructor(){}recordFailure(A,Q){let B=(this.retries.get(A)?.retryCount??0)+1;this.retries.set(A,{entityId:A,retryCount:B,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 Oo(A){return Date.UTC(A.y,A.m-1,A.d,A.h,A.i,A.s)}function Cs0(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 eGw(A,Q){let w=new Date(Date.parse(A));if(isNaN(w))throw Error("Invalid ISO8601 passed to timezone parser.");let B=A.substring(9);return B.includes("Z")||B.includes("+")||B.includes("-")?ys0(w.getUTCFullYear(),w.getUTCMonth()+1,w.getUTCDate(),w.getUTCHours(),w.getUTCMinutes(),w.getUTCSeconds(),"Etc/UTC"):ys0(w.getFullYear(),w.getMonth()+1,w.getDate(),w.getHours(),w.getMinutes(),w.getSeconds(),Q)}function vA2(A,Q,w){return CA2(eGw(A,Q),w)}function CA2(A,Q){let w=new Date(Oo(A)),B=xo(w,A.tz),$=Oo(A),f=Oo(B),Y=$-f,X=new Date(w.getTime()+Y),H=xo(X,A.tz);if(Cs0(H,A)){let U=new Date(X.getTime()-3600000),G=xo(U,A.tz);return Cs0(G,A)?U:X}let W=new Date(X.getTime()+Oo(A)-Oo(H)),K=xo(W,A.tz);if(Cs0(K,A))return W;if(Q)throw Error("Invalid date passed to fromTZ()");return X.getTime()>W.getTime()?X:W}function xo(A,Q){let w,B;try{w=new Intl.DateTimeFormat("en-US",{timeZone:Q,year:"numeric",month:"numeric",day:"numeric",hour:"numeric",minute:"numeric",second:"numeric",hour12:!1}),B=w.formatToParts(A)}catch(f){let Y=f instanceof Error?f.message:String(f);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 $={year:0,month:0,day:0,hour:0,minute:0,second:0};for(let f of B)(f.type==="year"||f.type==="month"||f.type==="day"||f.type==="hour"||f.type==="minute"||f.type==="second")&&($[f.type]=parseInt(f.value,10));if(isNaN($.year)||isNaN($.month)||isNaN($.day)||isNaN($.hour)||isNaN($.minute)||isNaN($.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($)}`);return $.hour===24&&($.hour=0),{y:$.year,m:$.month,d:$.day,h:$.hour,i:$.minute,s:$.second,tz:Q}}function ys0(A,Q,w,B,$,f,Y){return{y:A,m:Q,d:w,h:B,i:$,s:f,tz:Y}}var gA2=[1,2,4,8,16],RA2=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 B;switch(this.mode){case"5-part":B=5;break;case"6-part":B=6;break;case"7-part":B=7;break;case"5-or-6-parts":B=[5,6];break;case"6-or-7-parts":B=[6,7];break;default:B=0}if(!(Array.isArray(B)?B.includes(Q):Q===B)){let $=Array.isArray(B)?B.join(" or "):B.toString();throw TypeError(`CronPattern: mode '${this.mode}' requires exactly ${$} 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,B){let $=this[A],f=A==="day"&&this.lastDayOfMonth,Y=A==="day"&&this.lastWeekday;if(Q===""&&!f&&!Y)throw TypeError("CronPattern: configuration entry "+A+" ("+Q+") is empty, check for trailing spaces.");if(Q==="*")return $.fill(B);let X=Q.split(",");if(X.length>1)for(let H=0;H<X.length;H++)this.partToArray(A,X[H],w,B);else Q.indexOf("-")!==-1&&Q.indexOf("/")!==-1?this.handleRangeWithStepping(Q,A,w,B):Q.indexOf("-")!==-1?this.handleRange(Q,A,w,B):Q.indexOf("/")!==-1?this.handleStepping(Q,A,w,B):Q!==""&&this.handleNumber(Q,A,w,B)}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,B){let $=this.extractNth(A,Q),f=A.toUpperCase().includes("W");if(Q!=="day"&&f)throw TypeError("CronPattern: Nearest weekday modifier (W) only allowed in day-of-month.");f&&(Q="nearestWeekdays");let Y=parseInt($[0],10)+w;if(isNaN(Y))throw TypeError("CronPattern: "+Q+" is not a number: '"+A+"'");this.setPart(Q,Y,$[1]||B)}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: '"+$+"'");if(w!==void 0){if(w===0)throw TypeError("CronPattern: Syntax error, illegal stepping: 0");if(w>this[B].length)throw TypeError("CronPattern: Syntax error, steps cannot be greater than maximum value of part ("+this[B].length+")")}}handleRangeWithStepping(A,Q,w,B){if(A.toUpperCase().includes("W"))throw TypeError("CronPattern: Syntax error, W is not allowed in ranges with stepping.");let $=this.extractNth(A,Q),f=$[0].match(/^(\d+)-(\d+)\/(\d+)$/);if(f===null)throw TypeError("CronPattern: Syntax error, illegal range with stepping: '"+A+"'");let[,Y,X,H]=f,W=parseInt(Y,10)+w,K=parseInt(X,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,$[1]||B)}extractNth(A,Q){let w=A,B;if(w.includes("#")){if(Q!=="dayOfWeek")throw Error("CronPattern: nth (#) only allowed in day-of-week field");B=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)");B="L",w=w.slice(0,-1)}return[w,B]}handleRange(A,Q,w,B){if(A.toUpperCase().includes("W"))throw TypeError("CronPattern: Syntax error, W is not allowed in a range.");let $=this.extractNth(A,Q),f=$[0].split("-");if(f.length!==2)throw TypeError("CronPattern: Syntax error, illegal range: '"+A+"'");let Y=parseInt(f[0],10)+w,X=parseInt(f[1],10)+w;this.validateNotNaN(Y,"CronPattern: Syntax error, illegal lower range (NaN)"),this.validateNotNaN(X,"CronPattern: Syntax error, illegal upper range (NaN)"),this.validateRange(Y,X,void 0,Q,A);for(let H=Y;H<=X;H++)this.setPart(Q,H,$[1]||B)}handleStepping(A,Q,w,B){if(A.toUpperCase().includes("W"))throw TypeError("CronPattern: Syntax error, W is not allowed in parts with stepping.");let $=this.extractNth(A,Q),f=$[0].split("/");if(f.length!==2)throw TypeError("CronPattern: Syntax error, illegal stepping: '"+A+"'");if(this.sloppyRanges)f[0]===""&&(f[0]="*");else{if(f[0]==="")throw TypeError("CronPattern: Syntax error, stepping with missing prefix ('"+A+"') is not allowed. Use wildcard (*/step) or range (min-max/step) instead.");if(f[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;f[0]!=="*"&&(Y=parseInt(f[0],10)+w);let X=parseInt(f[1],10);this.validateNotNaN(X,"CronPattern: Syntax error, illegal stepping: (NaN)"),this.validateRange(0,this[Q].length-1,X,Q,A);for(let H=Y;H<this[Q].length;H+=X)this.setPart(Q,H,$[1]||B)}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]|gA2[Q-1];else throw TypeError(`CronPattern: nth weekday out of range, should be 1-5 or L. Value: ${Q}, Type: ${typeof Q}`)}},gs0=[31,28,31,30,31,30,31,31,30,31,30,31],U$=[["month","year",0],["day","month",-1],["hour","day",0],["minute","hour",0],["second","minute",0]],d7=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?gs0[w]:new Date(Date.UTC(Q,w+1,0)).getUTCDate()}getLastWeekday(Q,w){let B=this.getLastDayOfMonth(Q,w),$=new Date(Date.UTC(Q,w,B)).getUTCDay();return $===0?B-2:$===6?B-1:B}getNearestWeekday(Q,w,B){let $=this.getLastDayOfMonth(Q,w);if(B>$)return-1;let f=new Date(Date.UTC(Q,w,B)).getUTCDay();return f===0?B===$?B-2:B+1:f===6?B===1?B+2:B-1:B}isNthWeekdayOfMonth(Q,w,B,$){let f=new Date(Date.UTC(Q,w,B)).getUTCDay(),Y=0;for(let X=1;X<=B;X++)new Date(Date.UTC(Q,w,X)).getUTCDay()===f&&Y++;if($&63&&gA2[Y-1]&$)return!0;if($&32){let X=this.getLastDayOfMonth(Q,w);for(let H=B+1;H<=X;H++)if(new Date(Date.UTC(Q,w,H)).getUTCDay()===f)return!1;return!0}return!1}fromDate(Q){if(this.tz!==void 0)if(typeof this.tz=="number")this.ms=Q.getUTCMilliseconds(),this.second=Q.getUTCSeconds(),this.minute=Q.getUTCMinutes()+this.tz,this.hour=Q.getUTCHours(),this.day=Q.getUTCDate(),this.month=Q.getUTCMonth(),this.year=Q.getUTCFullYear(),this.apply();else try{let w=xo(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 B=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: ${B}`)}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>gs0[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=vA2(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(vA2(Q,this.tz))}findNext(Q,w,B,$){return this._findMatch(Q,w,B,$,1)}_findMatch(Q,w,B,$,f){let Y=this[w],X;B.lastDayOfMonth&&(X=this.getLastDayOfMonth(this.year,this.month));let H=!B.starDOW&&w=="day"?new Date(Date.UTC(this.year,this.month,1,0,0,0,0)).getUTCDay():void 0,W=this[w]+$,K=f===1?(U)=>U<B[w].length:(U)=>U>=0;for(let U=W;K(U);U+=f){let G=B[w][U];if(w==="day"&&!G){for(let q=0;q<B.nearestWeekdays.length;q++)if(B.nearestWeekdays[q]){let V=this.getNearestWeekday(this.year,this.month,q-$);if(V===-1)continue;if(V===U-$){G=1;break}}}if(w==="day"&&B.lastWeekday){let q=this.getLastWeekday(this.year,this.month);U-$===q&&(G=1)}if(w==="day"&&B.lastDayOfMonth&&U-$==X&&(G=1),w==="day"&&!B.starDOW){let q=B.dayOfWeek[(H+(U-$-1))%7];if(q&&q&63)q=this.isNthWeekdayOfMonth(this.year,this.month,U-$,q)?1:0;else if(q)throw Error(`CronDate: Invalid value for dayOfWeek encountered. ${q}`);B.useAndLogic?G=G&&q:!Q.domAndDow&&!B.starDOM?G=G||q:G=G&&q}if(G)return this[w]=U-$,Y!==this[w]?2:1}return 3}recurse(Q,w,B){if(B===0&&!Q.starYear){if(this.year>=0&&this.year<Q.year.length&&Q.year[this.year]===0){let f=-1;for(let Y=this.year+1;Y<Q.year.length&&Y<1e4;Y++)if(Q.year[Y]===1){f=Y;break}if(f===-1)return null;this.year=f,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 $=this.findNext(w,U$[B][0],Q,U$[B][2]);if($>1){let f=B+1;for(;f<U$.length;)this[U$[f][0]]=-U$[f][2],f++;if($===3){if(this[U$[B][1]]++,this[U$[B][0]]=-U$[B][2],this.apply(),B===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,B-1)}return B+=1,B>=U$.length?this:(Q.starYear?this.year>=3000:this.year>=1e4)?null:this.recurse(Q,w,B)}increment(Q,w,B){return this.second+=w.interval!==void 0&&w.interval>1&&B?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($>1e4)return null;if(B===0&&!Q.starYear){if(this.year>=0&&this.year<Q.year.length&&Q.year[this.year]===0){let Y=-1;for(let X=this.year-1;X>=0;X--)if(Q.year[X]===1){Y=X;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 f=this.findPrevious(w,U$[B][0],Q,U$[B][2]);if(f>1){let Y=B+1;for(;Y<U$.length;){let X=U$[Y][0],H=U$[Y][2],W=this.getMaxPatternValue(X,Q,H);this[X]=W,Y++}if(f===3){if(this[U$[B][1]]--,B===0){let K=this.getLastDayOfMonth(this.year,this.month);this.day>K&&(this.day=K)}if(B===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?gs0[U]:new Date(Date.UTC(K,U+1,0)).getUTCDate();this.day>G&&(this.day=G)}this.apply();let X=U$[B][0],H=U$[B][2],W=this.getMaxPatternValue(X,Q,H);if(X==="day"){let K=this.getLastDayOfMonth(this.year,this.month);this[X]=Math.min(W,K)}else this[X]=W;if(this.apply(),B===0){let K=U$[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,U$[2][2]),this.minute=this.getMaxPatternValue("minute",Q,U$[3][2]),this.second=this.getMaxPatternValue("second",Q,U$[4][2]))}if(B===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,$+1)}else if(this.apply())return this.recurseBackward(Q,w,B-1,$+1)}return B+=1,B>=U$.length?this:this.year<0?null:this.recurseBackward(Q,w,B,$+1)}getMaxPatternValue(Q,w,B){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 $=w[Q].length-1;$>=0;$--)if(w[Q][$])return $-B;return w[Q].length-1-B}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)):CA2(ys0(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 B=0;B<U$.length;B++){let $=U$[B][0],f=U$[B][2],Y=this[$];if(Y+f<0||Y+f>=Q[$].length)return!1;let X=Q[$][Y+f];if($==="day"){if(!X){for(let H=0;H<Q.nearestWeekdays.length;H++)if(Q.nearestWeekdays[H]){let W=this.getNearestWeekday(this.year,this.month,H-f);if(W!==-1&&W===Y){X=1;break}}}if(Q.lastWeekday){let H=this.getLastWeekday(this.year,this.month);Y===H&&(X=1)}if(Q.lastDayOfMonth){let H=this.getLastDayOfMonth(this.year,this.month);Y===H&&(X=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?X=X&&W:!w.domAndDow&&!Q.starDOM?X=X||W:X=X&&W}}if(!X)return!1}return!0}};function ADw(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 d7(A.startAt,A.timezone)),A.stopAt&&(A.stopAt=new d7(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 vo(A){return Object.prototype.toString.call(A)==="[object Function]"||typeof A=="function"||A instanceof Function}function QDw(A){return vo(A)}function wDw(A){typeof Deno<"u"&&typeof Deno.unrefTimer<"u"?Deno.unrefTimer(A):A&&typeof A.unref<"u"&&A.unref()}var hA2=30000,BX0=[],Es0=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(vo(Q))$=Q;else if(typeof Q=="object")B=Q;else if(Q!==void 0)throw Error("Cron: Invalid argument passed for optionsIn. Should be one of function, or object (options).");if(vo(w))$=w;else if(typeof w=="object")B=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=B?.name,this.options=ADw(B),this._states={kill:!1,blocking:!1,previousRun:void 0,currentRun:void 0,once:void 0,currentTimeout:void 0,maxRuns:B?B.maxRuns:void 0,paused:B?B.paused:!1,pattern:new RA2("* * * * *",void 0,{mode:"auto"})},A&&(A instanceof Date||typeof A=="string"&&A.indexOf(":")>0)?this._states.once=new d7(A,this.getTz()):this._states.pattern=new RA2(A,this.options.timezone,{mode:this.options.mode,alternativeWeekdays:this.options.alternativeWeekdays,sloppyRanges:this.options.sloppyRanges}),this.name){if(BX0.find((f)=>f.name===this.name))throw Error("Cron: Tried to initialize new named job '"+this.name+"', but name already taken.");BX0.push(this)}return $!==void 0&&QDw($)&&(this.fn=$,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 d7(Q,this.getTz()):null,f=w==="next"?this._next:this._previous;for(;A--;){let Y=f.call(this,$);if(!Y)break;let X=Y.getDate(!1);B.push(this.applyDayOffset(X)),$=Y}return B}match(A){if(this._states.once){let w=new d7(A,this.getTz());w.ms=0;let B=new d7(this._states.once,this.getTz());return B.ms=0,w.getTime()===B.getTime()}let Q=new d7(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,B=!this._states.kill;return Q&&w&&B&&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 d7||A instanceof Date?Q.getTime()-A.getTime():Q.getTime()-new d7(A).getTime():null}stop(){this._states.kill=!0,this._states.currentTimeout&&clearTimeout(this._states.currentTimeout);let A=BX0.indexOf(this);A>=0&&BX0.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>hA2&&(Q=hA2),this._states.currentTimeout=setTimeout(()=>this._checkTrigger(w),Q),this._states.currentTimeout&&this.options.unref&&wDw(this._states.currentTimeout),this)}async _trigger(A){this._states.blocking=!0,this._states.currentRun=new d7(void 0,this.getTz());try{if(this.options.catch)try{this.fn!==void 0&&await this.fn(this,this.options.context)}catch(Q){if(vo(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 d7(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(),B=this._states.blocking&&this.options.protect;w&&!B?(this._states.maxRuns!==void 0&&this._states.maxRuns--,this._trigger()):w&&B&&vo(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 d7(A,this.getTz()),this.options.startAt&&A&&A.getTime()<this.options.startAt.getTime()&&(A=this.options.startAt);let B=this._states.once||new d7(A,this.getTz());return!w&&B!==this._states.once&&(B=B.increment(this._states.pattern,this.options,Q)),this._states.once&&this._states.once.getTime()<=A.getTime()||B===null||this._states.maxRuns!==void 0&&this._states.maxRuns<=0||this._states.kill||this.options.stopAt&&B.getTime()>=this.options.stopAt.getTime()?null:B}_previous(A){let Q=new d7(A,this.getTz());this.options.stopAt&&Q.getTime()>this.options.stopAt.getTime()&&(Q=this.options.stopAt);let w=new d7(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 d7(void 0,this.getTz()),B=A;if(this.options.startAt.getTime()<=w.getTime()){B=this.options.startAt;let $=B.getTime()+this.options.interval*1000;for(;$<=w.getTime();)B=new d7(B,this.getTz()).increment(this._states.pattern,this.options,!0),$=B.getTime()+this.options.interval*1000;Q=!0}return B===null&&(B=void 0),[B,Q]}};class $X0{scheduleCron(A,Q){let w=new Es0(A,()=>{Q()});return{stop:()=>w.stop()}}scheduleInterval(A,Q){let w=setInterval(()=>{Q()},A);return{stop:()=>clearInterval(w)}}validateCron(A){new Es0(A).stop()}}_0();var yA2=Z.union([Z.string().min(1),Z.object({location:Z.enum(["metadata","frontmatter"]),field:Z.string().min(1)})]),fX0=Z.object({entityType:Z.string().min(1),attachmentType:Z.string().min(1),mediaEntityType:Z.enum(["image","document"]),targetEntityField:yA2.optional(),requiredWhen:Z.object({status:Z.string().min(1).optional(),visibility:Z.string().min(1).optional()}).optional(),autoGenerate:Z.boolean().optional(),requiredForPublish:Z.boolean().optional(),jobType:Z.string().min(1).optional()});function Ts0(A){return`${A.entityType}:${A.attachmentType}`}class B3{static instance=null;definitions=new Map;static getInstance(){return B3.instance??=new B3,B3.instance}static resetInstance(){B3.instance=null}static createFresh(){return new B3}constructor(){}register(A){let Q=fX0.parse(A),w=Ts0(Q);return this.definitions.set(w,Q),()=>this.unregister(Q.entityType,Q.attachmentType)}get(A,Q){return this.definitions.get(Ts0({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(Ts0({entityType:A,attachmentType:Q}))}clear(){this.definitions.clear()}}u9();U2();class YX0{deps;constructor(A){this.deps=A}async ensureForEntity(A,Q={}){let w=this.deps.registry.list(A.entityType).filter(($)=>$.autoGenerate===!0).filter(($)=>!Q.attachmentType||$.attachmentType===Q.attachmentType),B={checked:w.length,enqueued:0,skipped:0};for(let $ of w)if(await this.ensureDefinition(A,$))B.enqueued+=1;else B.skipped+=1;return B}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 B=this.getPredictedMediaId(A,Q),$=this.getDeduplicationKey(A,Q);return await this.deps.context.jobs.enqueue({type:w,data:{sourceEntityType:A.entityType,sourceEntityId:A.id,attachmentType:Q.attachmentType,imageId:B,dedupKey:$,targetEntityType:A.entityType,targetEntityId:A.id,...this.getTargetImageFieldData(Q.targetEntityField)},options:{source:"content-pipeline",metadata:{operationType:"content_operations"},deduplication:"skip",deduplicationKey:$}}),this.deps.context.logger.debug("Queued publish asset generation",{entityType:A.entityType,entityId:A.id,attachmentType:Q.attachmentType,jobType: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 Ss0(A.metadata[Q]);if(Q.location==="metadata")return Ss0(A.metadata[Q.field]);let{frontmatter:w}=P6(A.content);return Ss0(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 H1(`${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 Ss0(A){return typeof A==="string"?A.length>0:A!==void 0}wA();_0();var BDw=Z.object({id:Z.string().min(1)});async function TA2(A,Q){let{bodyContent:w,coverImageId:B,documents:$,sourceEntityType:f,sourceEntityId:Y}=$Dw(Q.content),X=B?await XDw(A,B):void 0,H;if($&&$.length>0){let K=await ZDw(A,$);if(K.length>0)H=K}H??=await YDw(A,f,Y);let W={bodyContent:w};if(X)W.imageData=X;if(H&&H.length>0)W.documentData=H;return W}function $Dw(A){try{let Q=n2(A,Z.record(Z.string(),Z.unknown())),w=Q.metadata.coverImageId,B=typeof w==="string"?w:void 0,$=fDw(Q.metadata.documents),f=EA2(Q.metadata.sourceEntityType),Y=EA2(Q.metadata.sourceEntityId);return{bodyContent:Q.content,...B&&{coverImageId:B},...$.length>0&&{documents:$},...f&&{sourceEntityType:f},...Y&&{sourceEntityId:Y}}}catch{return{bodyContent:A}}}function fDw(A){if(!Array.isArray(A))return[];return A.flatMap((Q)=>{let w=BDw.safeParse(Q);return w.success?[w.data]:[]})}function EA2(A){return typeof A==="string"&&A.length>0?A:void 0}async function YDw(A,Q,w){if(!Q||!w)return;let B=await A.attachments.resolve({sourceEntityType:Q,sourceEntityId:w,attachmentType:"carousel"});return B?[B]:void 0}async function XDw(A,Q){let w=await A.entityService.getEntity({entityType:"image",id:Q});if(!w?.content)return;let B=SA2(w.content);if(!B?.mimeType.startsWith("image/"))return;return{data:B.data,mimeType:B.mimeType}}async function ZDw(A,Q){return(await Promise.all(Q.map((B)=>HDw(A,B)))).filter((B)=>B!==void 0)}async function HDw(A,Q){let w=await A.entityService.getEntity({entityType:"document",id:Q.id});if(!w?.content)return;let B=SA2(w.content);if(B?.mimeType!=="application/pdf")return;return{type:"document",data:B.data,mimeType:"application/pdf",filename:WDw(w,Q.id)}}function SA2(A){let Q=A.match(/^data:([^;]+);base64,(.+)$/);if(!Q?.[1]||!Q[2])return;return{mimeType:Q[1],data:Buffer.from(Q[2],"base64")}}function WDw(A,Q){let w=A.metadata.filename;return typeof w==="string"&&w.length>0?w:`${Q}.pdf`}u9();var KDw=/^---\r?\n[\s\S]*?\r?\n---(?:\r?\n|$)/;async function ms0(A,Q,w,B={}){let $=B.publishTimestampField??"publishedAt",f=Q.metadata[$],Y=B.publishedAt??(typeof f==="string"?f:void 0)??new Date().toISOString(),X={...Q.metadata,status:"published",[$]:Y,platformId:w.id,...UDw(w.id,B.publishResultIdField)},H={...Q,content:mA2(Q.content,Y,w.id,B.publishResultIdField,$),metadata:X};return await A.entityService.updateEntity({entity:H}),H}function mA2(A,Q,w,B,$="publishedAt"){if(!KDw.test(A))return A;let f=D4(D4(A,"status","published"),$,Q);if(!w||!B)return f;return D4(f,B,w)}function UDw(A,Q){if(!Q||Q==="platformId")return{};return{[Q]:A}}class _y{deps;constructor(A){this.deps=A}async resolveCandidate(A){let{entityType:Q,id:w,slug:B}=A;if(!w&&!B)return{error:"Either 'id' or 'slug' must be provided"};let $=await this.findPublishableEntity(Q,w,B);if(!$)return{error:`Entity not found: ${Q}:${w??B}`};if($.visibility!=="public")return{error:`Cannot publish ${Q}:${$.id} to a public provider because visibility is ${$.visibility}`};if($.metadata.status==="published")return{error:"Entity is already published"};if(!this.deps.providerRegistry.has(Q))return{error:`No publish provider registered for ${Q}. Check that the required credentials are configured.`};return{entity:$}}async publish(A){let Q=await this.resolveCandidate(A);if("error"in Q)return Q;let{entity:w}=Q,{entityType:B}=A,$=this.deps.providerRegistry.get(B),{bodyContent:f,imageData:Y,documentData:X}=await TA2(this.deps.context,w),H=await $.publish(f,w.metadata,Y,X),W=this.deps.providerRegistry.getPublishResultIdField(B),K=this.deps.providerRegistry.getPublishTimestampField(B),U=await ms0(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}}wA();_0();var us0=Z.object({action:Z.enum(["list","add","remove","reorder"]).describe("Queue action to perform"),entityType:Z.string().optional().describe("Entity type (required for add/remove/reorder, optional for list)"),entityId:Z.string().optional().describe("Entity ID (required for add/remove/reorder)"),position:Z.number().optional().describe("New position for reorder action (1-based)")}),cs0=Z.object({position:Z.number(),entityType:Z.string(),entityId:Z.string(),queuedAt:Z.string()}),GDw=Z.object({success:Z.literal(!0),message:Z.string().optional(),data:Z.object({queue:Z.array(cs0).optional(),entityType:Z.string().optional(),entityId:Z.string().optional(),position:Z.number().optional()}).optional()}),DDw=Z.object({success:Z.literal(!1),error:Z.string(),code:Z.string().optional()}),ls0=Z.union([GDw,DDw]);function XX0(A,Q,w){return{...M6(Q,"queue","Manage the publish queue for all entity types (list, add, remove, reorder)",us0,async($,f)=>{let{action:Y,entityType:X,entityId:H,position:W}=$;switch(Y){case"list":return zDw(w,X);case"add":return qDw(A,w,X,H,f);case"remove":return VDw(A,w,X,H,f);case"reorder":return bDw(A,w,X,H,W,f);default:return{success:!1,error:`Unknown action: ${Y}`}}},{sideEffects:"writes"}),outputSchema:ls0}}async function zDw(A,Q){let w=[];if(Q)w=await A.list(Q);else{let $=A.getRegisteredTypes();for(let f of $){let Y=await A.list(f);w.push(...Y)}w.sort((f,Y)=>new Date(f.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(($,f)=>({position:f+1,entityType:$.entityType,entityId:$.entityId,queuedAt:$.queuedAt}))},message:`${w.length} items in queue`}}async function qDw(A,Q,w,B,$){let f=ps0("add",w,B);if(!f.success)return f.error;A.permissions.assertEntityActionAllowed(f.entityType,"publish",$??{});let Y=await Q.add(f.entityType,f.entityId,{...$,authorization:"user"});return{success:!0,data:{entityType:f.entityType,entityId:f.entityId,position:Y.position},message:`Added to queue at position ${Y.position}`}}async function VDw(A,Q,w,B,$){let f=ps0("remove",w,B);if(!f.success)return f.error;return A.permissions.assertEntityActionAllowed(f.entityType,"update",$??{}),await Q.remove(f.entityType,f.entityId),{success:!0,data:{entityType:f.entityType,entityId:f.entityId},message:"Removed from queue"}}async function bDw(A,Q,w,B,$,f){let Y=ps0("reorder",w,B);if(!Y.success)return Y.error;let X=JDw($);if(!X.success)return X.error;return A.permissions.assertEntityActionAllowed(Y.entityType,"update",f??{}),await Q.reorder(Y.entityType,Y.entityId,X.position),{success:!0,data:{entityType:Y.entityType,entityId:Y.entityId,position:X.position},message:`Moved to position ${X.position}`}}function ps0(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 JDw(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}}_0();import{createHash as IDw}from"crypto";var is0=Z.object({entityType:Z.string().describe("Entity type to publish (e.g., social-post, post, deck)"),id:Z.string().optional().describe("Entity ID to publish"),slug:Z.string().optional().describe("Entity slug to publish"),confirmed:Z.boolean().optional(),confirmationToken:Z.string().optional(),contentHash:Z.string().optional(),expiresAt:Z.string().datetime().optional()}),FDw=Z.object({entityType:Z.string(),id:Z.string().optional(),slug:Z.string().optional(),confirmed:Z.boolean().optional(),confirmationToken:Z.string().optional(),contentHash:Z.string().optional(),expiresAt:Z.string().datetime().optional()}),LDw=Z.object({success:Z.literal(!0),message:Z.string().optional(),data:Z.object({entityType:Z.string().optional(),entityId:Z.string().optional(),platformId:Z.string().optional(),url:Z.string().optional()}).optional()}),kDw=Z.object({success:Z.literal(!1),error:Z.string(),code:Z.string().optional()}),_Dw=Z.object({success:Z.literal(!1).optional(),error:Z.string().optional(),needsConfirmation:Z.literal(!0),toolName:Z.string(),summary:Z.string(),preview:Z.string().optional(),args:Z.unknown()}),ds0=Z.union([LDw,kDw,_Dw]),NDw=900000;function ZX0(A,Q,w,B){let $=B??new _y({context:A,providerRegistry:w}),f=`${Q}_publish`;return{name:f,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:is0.shape,outputSchema:ds0,visibility:"anchor",sideEffects:"external",handler:async(Y,X)=>{let H=FDw.safeParse(Y);if(!H.success)return{success:!1,error:`Invalid input: ${H.error.issues.map((J)=>`${J.path.join(".")}: ${J.message}`).join(", ")}`};let W=H.data,{entityType:K,id:U,slug:G}=W;try{A.permissions.assertEntityActionAllowed(K,"publish",X)}catch(J){return{success:!1,error:J instanceof Error?J.message:String(J)}}let q=await $.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 J=PDw(f,W,V);if(J!==null)return J;let b;try{b=await $.publish({entityType:K,id:V.id})}catch(k){return{success:!1,error:k instanceof Error?k.message:String(k)}}if("error"in b)return{success:!1,error:b.error};let{entity:L,result:N}=b;return{success:!0,data:{entityType:K,entityId:L.id,platformId:N.id,url:N.url},message:`Published ${K}:${L.id}`}}return jDw(f,W,V)}}}function jDw(A,Q,w){let B=new Date(Date.now()+NDw).toISOString(),$=uA2(A,w,B),f=MDw(w);return{needsConfirmation:!0,toolName:A,summary:`Publish "${f}"?`,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:$,contentHash:w.contentHash,expiresAt:B}}}function PDw(A,Q,w){let{confirmationToken:B,contentHash:$,expiresAt:f}=Q;if(!B||!f)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(f);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($&&$!==w.contentHash)return{success:!1,error:`Cannot publish ${w.entityType}:${w.id} because it changed after confirmation. Review it and try again.`};if(B!==uA2(A,w,f))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 uA2(A,Q,w){return IDw("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 MDw(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 B=A.metadata.slug;if(typeof B==="string"&&B.length>0)return B;return A.id}wA();_0();var ns0=Z.object({entityType:Z.string().min(1).describe("Entity type to reconcile"),status:Z.string().min(1).optional().describe("Optional metadata status filter, e.g. published"),assetType:Z.string().min(1).optional().describe("Optional attachment type filter, e.g. og-image")}),rs0=Z.object({success:Z.literal(!0),data:Z.object({entityType:Z.string(),assetType:Z.string().optional(),checkedEntities:Z.number(),checkedAssets:Z.number(),enqueued:Z.number(),skipped:Z.number()}),message:Z.string().optional()});function HX0(A,Q,w,B){return{...M6(Q,"ensure-assets","Reconcile configured publish assets for existing entities, queueing missing generated assets such as OG images.",ns0,async(f,Y)=>{if(A.permissions.assertEntityActionAllowed(f.entityType,"publish",Y),w.list(f.entityType).filter((G)=>G.autoGenerate===!0).filter((G)=>!f.assetType||G.attachmentType===f.assetType).length===0)return{success:!0,data:{entityType:f.entityType,...f.assetType&&{assetType:f.assetType},checkedEntities:0,checkedAssets:0,enqueued:0,skipped:0},message:`No publish assets configured for ${f.entityType}`};let H=await A.entityService.listEntities({entityType:f.entityType,options:{...f.status&&{filter:{metadata:{status:f.status}}}}}),W=0,K=0,U=0;for(let G of H){let q=await B.ensureForEntity(G,{...f.assetType&&{attachmentType:f.assetType}});W+=q.checked,K+=q.enqueued,U+=q.skipped}return{success:!0,data:{entityType:f.entityType,...f.assetType&&{assetType:f.assetType},checkedEntities:H.length,checkedAssets:W,enqueued:K,skipped:U},message:`Queued ${K} publish asset job(s)`}},{sideEffects:"writes"}),outputSchema:rs0}}wA();function cA2(A,Q){ODw(A,Q),xDw(A,Q),vDw(A,Q),RDw(A,Q)}function ODw(A,Q){A.messaging.subscribe(sf.REGISTER,async(w)=>hDw(Q,w.payload)),A.messaging.subscribe(sf.QUEUE,async(w)=>EDw(A,Q,w.payload)),A.messaging.subscribe(sf.DIRECT,async(w)=>TDw(A,Q,w.payload)),A.messaging.subscribe(sf.REMOVE,async(w)=>SDw(Q,w.payload)),A.messaging.subscribe(sf.REORDER,async(w)=>mDw(Q,w.payload)),A.messaging.subscribe(sf.LIST,async(w)=>uDw(A,Q,w.payload)),A.messaging.subscribe(sf.REPORT_SUCCESS,async(w)=>cDw(Q,w.payload)),A.messaging.subscribe(sf.REPORT_FAILURE,async(w)=>lDw(Q,w.payload)),Q.logger.debug("Subscribed to publish messages")}function xDw(A,Q){A.messaging.subscribe(xF.REPORT_SUCCESS,async(w)=>pDw(Q,w.payload)),A.messaging.subscribe(xF.REPORT_FAILURE,async(w)=>iDw(Q,w.payload)),Q.logger.debug("Subscribed to generation messages")}function vDw(A,Q){A.messaging.subscribe(kA2.REGISTER,async(w)=>CDw(Q,w.payload)),Q.logger.debug("Subscribed to publish asset messages")}function RDw(A,Q){let w=async(B)=>gDw(A,Q,B.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 hDw(A,Q){let{entityType:w,provider:B,config:$}=Q;try{let f=$?_A2.safeParse($):void 0;if(f&&!f.success)return A.logger.warn("Invalid publish provider config",{entityType:w,error:f.error.message}),{success:!1};if(B)A.providerRegistry.register(w,B,f?.data),A.logger.info(`Registered provider for entity type: ${w}`,{providerName:B.name,executionMode:A.providerRegistry.getExecutionMode(w)});return{success:!0}}catch(f){let Y=SA(f);return A.logger.error(`Failed to register provider: ${Y}`),{success:!1}}}async function CDw(A,Q){let w=fX0.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 gDw(A,Q,w){try{if(Q.publishAssetRegistry.list(w.entityType).length===0)return{success:!0};let B=w.entity??await A.entityService.getEntity({entityType:w.entityType,id:w.entityId});if(!yDw(B))return{success:!0};return await Q.publishAssetPreflight.ensureForEntity(B),{success:!0}}catch(B){return Q.logger.warn("Failed to run publish asset preflight for entity event",{entityType:w.entityType,entityId:w.entityId,error:SA(B)}),{success:!1}}}function yDw(A){if(!A)return!1;let Q=LA2.safeParse(A.metadata);return Q.success&&Q.data.status==="published"}async function EDw(A,Q,w){let{entityType:B,entityId:$}=w;try{let f=w.authContext??Mo;A.permissions.assertEntityActionAllowed(B,"publish",f);let Y=await Q.queueManager.add(B,$,f);return await A.messaging.send({type:sf.QUEUED,payload:{entityType:B,entityId:$,position:Y.position}}),Q.logger.debug(`Entity queued: ${$}`,{entityType:B,position:Y.position}),{success:!0}}catch(f){let Y=SA(f);return Q.logger.error(`Failed to queue entity: ${Y}`),{success:!1}}}async function TDw(A,Q,w){let{entityType:B,entityId:$}=w,f=w.authContext??Mo;try{if(A.permissions.assertEntityActionAllowed(B,"publish",f),!Q.providerRegistry.has(B))return Q.scheduler.failPublish(B,$,`No publish provider registered for ${B}`),{success:!1};let Y=await Q.publishExecutor.publish({entityType:B,id:$});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: ${$}`,{entityType:B}),{success:!0}}catch(Y){let X=SA(Y);return Q.logger.error(`Failed direct publish request: ${X}`),{success:!1}}}async function SDw(A,Q){let{entityType:w,entityId:B}=Q;try{return await A.queueManager.remove(w,B),A.logger.debug(`Entity removed from queue: ${B}`,{entityType:w}),{success:!0}}catch($){let f=SA($);return A.logger.error(`Failed to remove entity: ${f}`),{success:!1}}}async function mDw(A,Q){let{entityType:w,entityId:B,position:$}=Q;try{return await A.queueManager.reorder(w,B,$),A.logger.debug(`Entity reordered: ${B}`,{entityType:w,newPosition:$}),{success:!0}}catch(f){let Y=SA(f);return A.logger.error(`Failed to reorder entity: ${Y}`),{success:!1}}}async function uDw(A,Q,w){let{entityType:B}=w;try{let $=await Q.queueManager.list(B);return await A.messaging.send({type:sf.LIST_RESPONSE,payload:{entityType:B,queue:$.map((f)=>({entityId:f.entityId,position:f.position,queuedAt:f.queuedAt}))}}),{success:!0}}catch($){let f=SA($);return Q.logger.error(`Failed to list queue: ${f}`),{success:!1}}}async function cDw(A,Q){let{entityType:w,entityId:B,result:$}=Q;return A.scheduler.completePublish(w,B,$),A.logger.info(`Publish reported success: ${B}`,{entityType:w}),{success:!0}}async function lDw(A,Q){let{entityType:w,entityId:B,error:$}=Q;A.scheduler.failPublish(w,B,$);let f=A.retryTracker.getRetryInfo(B);return A.logger.info(`Publish reported failure: ${B}`,{entityType:w,error:$,retryCount:f?.retryCount}),{success:!0}}async function pDw(A,Q){let{entityType:w,entityId:B}=Q;return A.scheduler.completeGeneration(w,B),A.logger.info("Generation completed",{entityType:w,entityId:B}),{success:!0}}async function iDw(A,Q){let{entityType:w,error:B}=Q;return A.scheduler.failGeneration(w,B),A.logger.warn("Generation failed",{entityType:w,error:B}),{success:!0}}async function lA2(A,Q,w,B){try{if(B.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(B.maxUnpublishedDrafts!==void 0){let $=await A.listEntities({entityType:w,options:{filter:{metadata:{status:"draft"}},limit:B.maxUnpublishedDrafts+1}});if($.length>=B.maxUnpublishedDrafts)return{shouldGenerate:!1,reason:`Max unpublished drafts reached (${$.length}/${B.maxUnpublishedDrafts})`}}if(B.minSourceEntities!==void 0&&B.sourceEntityType){let $=await A.listEntities({entityType:B.sourceEntityType,options:{publishedOnly:!0,limit:B.minSourceEntities}});if($.length<B.minSourceEntities)return{shouldGenerate:!1,reason:`Not enough source entities (${$.length}/${B.minSourceEntities} ${B.sourceEntityType})`}}return{shouldGenerate:!0}}catch($){return Q.error("Failed to check generation conditions",{entityType:w,error:SA($)}),{shouldGenerate:!1,reason:`Condition check failed: ${SA($)}`}}}function pA2(A){let{context:Q,config:w,queueManager:B,providerRegistry:$,retryTracker:f,publishExecutor:Y,logger:X}=A,H=dDw(Q);return xU.createFresh({queueManager:B,providerRegistry:$,retryTracker:f,logger:X,backend:new $X0,...w.entitySchedules&&{entitySchedules:w.entitySchedules},...w.generationSchedules&&{generationSchedules:w.generationSchedules},...w.generationConditions&&{generationConditions:w.generationConditions},messageBus:H,publishExecutor:Y,onCheckGenerationConditions:(W,K)=>lA2(Q.entityService,X,W,K)})}function dDw(A){return{send:async($)=>{return A.messaging.send({type:$.type,payload:$.payload,...$.target!==void 0?{target:$.target}:{},...$.metadata!==void 0?{metadata:$.metadata}:{},...$.broadcast!==void 0?{broadcast:$.broadcast}:{}})},subscribe:()=>()=>{},unsubscribe:()=>{}}}async function iA2(A,Q,w){let B=A.getEntityTypes();for(let f of B){let Y=await A.listEntities({entityType:f,options:{filter:{metadata:{status:"queued"}}}});for(let X of Y)await Q.add(X.entityType,X.id)}let $=0;for(let f of B){let Y=await Q.list(f);$+=Y.length}if($>0)w.info(`Rebuilt queue with ${$} queued entities`)}_0();var nDw=["draft","queued","published","failed"];async function dA2(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:()=>tDw(A),digestProvider:oDw}})}var rDw=Z.object({summary:Z.object({draft:Z.number(),queued:Z.number(),published:Z.number(),failed:Z.number()}),generating:Z.array(Z.unknown())});function oDw(A){let{summary:Q,generating:w}=rDw.parse(A),B=Q.queued+w.length,$=B===0?"idle":`${Q.queued} queued \xB7 ${w.length} generating`,f=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:f,...Y>0?{tone:"warn"}:{}},{label:"Published",value:String(Q.published),tone:"good"}],needsOperator:Y}}var sDw=Z.object({sourceEntityType:Z.string(),sourceEntityId:Z.string(),attachmentType:Z.string().optional()});async function aDw(A){let Q=await A.jobs.getActiveJobs(),w=[];for(let B of Q){if(B.source!=="content-pipeline")continue;if(B.status!=="pending"&&B.status!=="processing")continue;let $;try{$=JSON.parse(B.data)}catch{continue}let f=sDw.safeParse($);if(!f.success)continue;w.push({id:B.id,label:f.data.attachmentType??B.type,target:`${f.data.sourceEntityType}/${f.data.sourceEntityId}`,status:B.status})}return w}async function tDw(A){let Q=A.entityService.getEntityTypes(),w=[],B={draft:0,queued:0,published:0,failed:0};for(let $ of Q){let f=await A.entityService.listEntities({entityType:$});for(let Y of f){let X=eDw(Y.metadata.status);if(!X)continue;B[X]++,w.push({id:Y.id,title:A3w(Y.id,Y.metadata.title),type:$,status:X})}}return{summary:B,items:w,generating:await aDw(A)}}function eDw(A){return nDw.find((Q)=>Q===A)}function A3w(A,Q){return typeof Q==="string"?Q:A}var nA2={name:"@brains/content-pipeline",version:"0.2.0-alpha.150",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:"^6.0.3"},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 os0 extends tQ{pluginContext;queueManager;providerRegistry;retryTracker;publishExecutor;publishAssetRegistry;publishAssetPreflight;scheduler;constructor(A={}){super("content-pipeline",nA2,A,NA2)}async onRegister(A){this.pluginContext=A,this.queueManager=A3.createFresh(),this.providerRegistry=Q3.createFresh(),this.retryTracker=w3.createFresh(),this.publishAssetRegistry=B3.createFresh(),this.publishAssetPreflight=new YX0({context:A,registry:this.publishAssetRegistry}),this.publishExecutor=new _y({context:A,providerRegistry:this.providerRegistry,publishAssetPreflight:this.publishAssetPreflight}),this.scheduler=pA2({context:A,config:this.config,queueManager:this.queueManager,providerRegistry:this.providerRegistry,retryTracker:this.retryTracker,publishExecutor:this.publishExecutor,logger:this.logger}),cA2(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 iA2(A.entityService,this.queueManager,this.logger),await dA2(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[XX0(this.pluginContext,this.id,this.queueManager),ZX0(this.pluginContext,this.id,this.providerRegistry,this.publishExecutor),HX0(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(),A3.resetInstance(),Q3.resetInstance(),w3.resetInstance(),B3.resetInstance()}}function ss0(A={}){return new os0(A)}wA();_0();var rA2=Z.object({accountId:Z.string().describe("Cloudflare account ID"),apiToken:Z.string().describe("Cloudflare API token with Analytics:Read permission"),siteTag:Z.string().describe("Cloudflare Web Analytics site tag")}),as0=Z.object({cloudflare:rA2.optional()});wA();_0();var w3w=Z.object({date:Z.string().describe("Single date in YYYY-MM-DD format").optional(),days:Z.number().min(1).max(365).describe("Number of days back from yesterday (e.g., 7 for last week)").optional(),startDate:Z.string().describe("Start date in YYYY-MM-DD format (use with endDate)").optional(),endDate:Z.string().describe("End date in YYYY-MM-DD format (use with startDate)").optional(),limit:Z.number().min(1).max(100).default(20).describe("Maximum items for breakdowns (pages, referrers, countries)")});function B3w(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 oA2(A,Q,w){let B=[];if(!w)return B;return B.push(M6(A,"query",`Query website analytics from Cloudflare.
|
|
7483
|
+
${w.content}`:w.prompt??"Write an engaging LinkedIn post";return A.ai.generate({prompt:B,templateName:`social-media:${w.platform}`})}),A.eval.registerHandler("create",async(Q)=>{let w=pGw.parse(Q),B=[],$=Zf.from(async(W)=>{let K={progress:W.progress};if(W.message!==void 0)K.message=W.message;B.push(K)});if(!$)throw Error("Failed to create progress reporter");let Y=await new WP(A.logger,A).process(w,`eval-${Date.now()}`,$),X=!1,H;if(Y.success&&Y.entityId){let W=await A.entityService.getEntity({entityType:"social-post",id:Y.entityId});X=!!W,H=W?.content.slice(0,300)}return{...Y,entityExists:X,entityPreview:H,progressSteps:B}})}wA();class jo{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 B=await this.entityService.getEntity({entityType:"social-post",id:w});if(!B){await this.reportFailure(Q,w,`Post not found: ${w}`);return}let $=B;if($.metadata.status==="published"){this.logger.debug("Post already published, skipping",{entityId:w});return}let f=$.metadata.platform,Y=this.providers.get(f);if(!Y){await this.reportFailure(Q,w,`No provider configured for platform: ${f}`);return}let X=n2($.content,OU),H;if(X.metadata.coverImageId)H=await this.fetchImageData(X.metadata.coverImageId);let W=X.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(X.metadata):[],G=K.length>0?K:U,q=G.length?await Y.publish(X.content,$.metadata,H,G):await Y.publish(X.content,$.metadata,H),V=new Date().toISOString(),J=q.id||void 0,b={...X.metadata,status:"published",publishedAt:V,...J&&{platformPostId:J}},L=i7.createPostContent(b,X.content);await this.entityService.updateEntity({entity:{...$,content:L,metadata:{...$.metadata,status:"published",publishedAt:V,platformPostId:J}}}),await this.reportSuccess(Q,w,q.id),this.logger.info(`Post published successfully: ${w}`,{platform:f,platformPostId:J})}catch(U){let G=U instanceof Error?U.message:String(U),q={...X.metadata,status:"failed"},V=i7.createPostContent(q,X.content);await this.entityService.updateEntity({entity:{...$,content:V,metadata:{...$.metadata,status:"failed"}}}),await this.reportFailure(Q,w,G),this.logger.error(`Post publish failed: ${w}`,{platform:f,error:G})}}catch(B){let $=SA(B);this.logger.error("Unexpected error in publish handler",{entityId:w,error:$}),await this.reportFailure(Q,w,$)}}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 B=await this.fetchSingleDocumentData(w.id);if(B)Q.push(B)}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 B=typeof Q.metadata.filename==="string"?Q.metadata.filename:`${A}.pdf`;return{type:"document",data:Buffer.from(w[1],"base64"),mimeType:"application/pdf",filename:B}}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 B=Q.content.match(/^data:([^;]+);base64,(.+)$/);if(!B?.[1]||!B[2]){this.logger.warn("Invalid image data URL format",{imageId:A});return}let $=B[1],f=B[2];return{data:Buffer.from(f,"base64"),mimeType:$}}catch(Q){this.logger.warn("Failed to fetch cover image",{imageId:A,error:Q});return}}}function zA2(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 B=Q.values().next().value;return await A.messaging.send({type:"publish:register",payload:{entityType:"social-post",provider:B,config:{publishResultIdField:"platformPostId"}}}),w.info("Registered social-post with publish-pipeline"),{success:!0}})}function qA2(A,Q,w){let B=new jo({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($)=>{return await B.handle($.payload),{success:!0}}),w.debug("Subscribed to publish:execute messages")}function VA2(A,Q){A.messaging.subscribe("entity:updated",async(w)=>{let{entityType:B,entityId:$,entity:f}=w.payload;if(B!=="post")return{success:!0};if(f.metadata?.status!=="queued")return{success:!0};try{if((await A.entityService.listEntities({entityType:"social-post",options:{filter:{metadata:{sourceEntityType:"post",sourceEntityId:$}},limit:1}})).length>0)return Q.debug(`Social post already exists for ${$}, skipping auto-generate`),{success:!0};return await A.messaging.send({type:"social:auto-generate",payload:{sourceEntityType:B,sourceEntityId:$,platform:"linkedin"}}),Q.info(`Auto-generate social post triggered for queued post ${$}`),{success:!0}}catch(X){let H=SA(X);return Q.error(`Failed to trigger auto-generate for ${$}:`,{error:H}),{success:!0}}}),Q.debug("Subscribed to entity:updated for auto-generation")}function bA2(A,Q){A.messaging.subscribe("social:auto-generate",async(w)=>{let{sourceEntityType:B,sourceEntityId:$,platform:f}=w.payload;try{let Y=await A.jobs.enqueue({type:`${i7.entityType}:generation`,data:{sourceEntityType:B,sourceEntityId:$,platform:f,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 X=SA(Y);return Q.error(`Failed to enqueue social post generation for ${$}:`,{error:X}),{success:!1}}}),Q.debug("Subscribed to social:auto-generate messages")}function JA2(A,Q){A.messaging.subscribe("generate:execute",async(w)=>{let{entityType:B}=w.payload;if(B!=="social-post")return{success:!0};Q.info("Received generate:execute for social-post");try{let $=await A.entityService.listEntities({entityType:"post",options:{filter:{metadata:{status:"published"}},limit:5}});if($.length===0)return Q.info("No published posts found for social post generation"),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:"No published posts available for social post generation"}}),{success:!0};let f=null;for(let X of $)if((await A.entityService.listEntities({entityType:"social-post",options:{filter:{metadata:{sourceEntityType:"post",sourceEntityId:X.id}},limit:1}})).length===0){f=X;break}if(!f)return Q.info("All recent posts already have social posts"),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:"All recent posts already have social posts generated"}}),{success:!0};let Y=await A.jobs.enqueue({type:`${i7.entityType}:generation`,data:{sourceEntityType:"post",sourceEntityId:f.id,platform:"linkedin",addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}});return Q.info("Social post generation job queued",{jobId:Y,sourcePostId:f.id}),{success:!0}}catch($){let f=SA($);return Q.error("Failed to handle generate:execute:",{error:f}),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:f}}),{success:!0}}}),Q.debug("Subscribed to generate:execute messages")}async function IA2({entity:A,config:Q}){let w=OF.parse(A),B=i7.parsePostFrontmatter(w),$=i7.getPostContent(w);return{$type:"ai.rizom.brain.socialPost",title:B.title,platform:B.platform,body:$,format:"text/markdown",status:B.status,...B.publishedAt&&{publishedAt:B.publishedAt},...B.platformPostId&&{platformPostId:B.platformPostId},...B.sourceEntityType&&{sourceLocalEntityType:B.sourceEntityType},...B.sourceEntityId&&{sourceLocalEntityId:B.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 Ms0(){return{entityType:"social-post",collection:"ai.rizom.brain.socialPost",lexicon:k6["ai.rizom.brain.socialPost"],validate:!1,buildRecord:IA2}}var FA2={name:"@brains/social-media",version:"0.2.0-alpha.151",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 Os0 extends rQ{entityType=i7.entityType;schema=OF;adapter=i7;providers=new Map;unregisterAtprotoProjection;constructor(A={}){super("social-media",FA2,A,Ls0)}createGenerationHandler(A){return new WP(this.logger.child("GenerationJobHandler"),A)}getTemplates(){return GA2()}getDataSources(){return[new eY0(this.logger.child("SocialPostDataSource"))]}getEntityTypeConfig(){return{publish:{publishStatuses:["queued","published","failed"]}}}async onRegister(A){if(this.initializeProviders(),zA2(A,this.providers,this.logger),qA2(A,this.providers,this.logger),this.config.autoGenerateOnBlogPublish)VA2(A,this.logger),bA2(A,this.logger),this.logger.info("Auto-generate on blog publish enabled");JA2(A,this.logger),DA2(A),this.unregisterAtprotoProjection=Q5.getInstance().register(Ms0()),this.logger.info("Social media plugin registered successfully")}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}initializeProviders(){if(this.config.linkedin?.accessToken){let A=Ps0(this.config.linkedin,this.logger.child("LinkedInClient"));this.providers.set("linkedin",A),this.logger.info("LinkedIn provider initialized")}}}function Po(A={}){return new Os0(A)}_0();var dGw=Z.enum(["draft","queued","published","failed"]),LA2=Z.object({status:dGw.default("draft"),queueOrder:Z.number().optional().describe("Position in publish queue (lower = sooner)"),publishedAt:Z.string().datetime().optional()});class xs0{name="internal";async publish(A,Q){return{id:"internal"}}}var Mo={interfaceType:"system",userId:"system",userPermissionLevel:"anchor",authorization:"system"},sf={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"},xF={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"},kA2={REGISTER:"publish-assets:register"};_0();var nGw=Z.enum(["provider"]),_A2=Z.object({executionMode:nGw.optional(),publishResultIdField:Z.string().min(1).optional(),publishTimestampField:Z.string().min(1).optional(),enabled:Z.boolean().optional()}).strict();var rGw=Z.object({skipIfDraftExists:Z.boolean().optional(),minSourceEntities:Z.number().optional(),maxUnpublishedDrafts:Z.number().optional(),sourceEntityType:Z.string().optional()}),NA2=Z.object({entitySchedules:Z.record(Z.string(),Z.string()).optional(),generationSchedules:Z.record(Z.string(),Z.string()).optional(),generationConditions:Z.record(Z.string(),rGw).optional()});class A3{static instance=null;queues=new Map;static getInstance(){return A3.instance??=new A3,A3.instance}static resetInstance(){A3.instance=null}static createFresh(){return new A3}constructor(){}async add(A,Q,w=Mo){let B=this.getOrCreateQueue(A),$=B.find((X)=>X.entityId===Q);if($)return{position:$.position};let f=B.length+1,Y={entityId:Q,entityType:A,position:f,queuedAt:new Date().toISOString(),authContext:{...w}};return B.push(Y),{position:f}}async remove(A,Q){let w=this.queues.get(A);if(!w)return;let B=w.findIndex(($)=>$.entityId===Q);if(B===-1)return;w.splice(B,1),this.recalculatePositions(w)}async reorder(A,Q,w){let B=this.queues.get(A);if(!B)return;let $=B.findIndex((X)=>X.entityId===Q);if($===-1)return;let[f]=B.splice($,1);if(!f)return;let Y=Math.max(0,Math.min(w-1,B.length));B.splice(Y,0,f),this.recalculatePositions(B)}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 Q3{static instance=null;providers=new Map;executionModes=new Map;publishResultIdFields=new Map;publishTimestampFields=new Map;defaultProvider=new xs0;static getInstance(){return Q3.instance??=new Q3,Q3.instance}static resetInstance(){Q3.instance=null}static createFresh(){return new Q3}constructor(){}register(A,Q,w){let B=this.providers.get(A);if(B&&B.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 jA2(A,Q){if(!Q.publishExecutor){Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:"Publish executor not configured",retryCount:0,willRetry:!1});return}await oGw(A,Q)}async function oGw(A,Q){if(!Q.publishExecutor)return;try{let w=await Q.publishExecutor.publish({entityType:A.entityType,id:A.entityId});if("error"in w){let B={entityType:A.entityType,entityId:A.entityId,error:w.error,retryCount:0,willRetry:!1};if(Q.messageBus)await Q.messageBus.send({type:sf.FAILED,payload:B,sender:"publish-service",broadcast:!0});Q.onFailed?.(B);return}vs0(A.entityType,A.entityId,w.result,Q)}catch(w){let B=SA(w);Q.retryTracker.recordFailure(A.entityId,B);let $=Q.retryTracker.getRetryInfo(A.entityId);Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:B,retryCount:$?.retryCount??1,willRetry:!1})}}function vs0(A,Q,w,B){if(B.retryTracker.clearRetries(Q),B.messageBus)B.messageBus.send({type:sf.COMPLETED,payload:{entityType:A,entityId:Q,result:w},sender:"publish-service",broadcast:!0});B.onPublish?.({entityType:A,entityId:Q,result:w})}function PA2(A,Q,w,B){B.retryTracker.recordFailure(Q,w);let $=B.retryTracker.getRetryInfo(Q),f={entityType:A,entityId:Q,error:w,retryCount:$?.retryCount??1,willRetry:!1};if(B.messageBus)B.messageBus.send({type:sf.FAILED,payload:f,sender:"publish-service",broadcast:!0});B.onFailed?.(f)}async function MA2(A,Q){let w=Q.generationConditions[A];if(w&&Q.onCheckGenerationConditions){let $=await Q.onCheckGenerationConditions(A,w);if(!$.shouldGenerate){if(Q.messageBus)Q.messageBus.send({type:xF.SKIPPED,payload:{entityType:A,reason:$.reason??"Conditions not met"},sender:"content-pipeline"});return}}let B={entityType:A};if(Q.messageBus)await Q.messageBus.send({type:xF.EXECUTE,payload:B,sender:"content-pipeline"});Q.onGenerate?.(B)}function OA2(A,Q,w){if(w)w.send({type:xF.COMPLETED,payload:{entityType:A,entityId:Q},sender:"content-pipeline"})}function xA2(A,Q,w){if(w)w.send({type:xF.FAILED,payload:{entityType:A,error:Q},sender:"content-pipeline"})}var sGw=1000;class Rs0{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(sGw,()=>this.processUnscheduledTypes())}stop(){if(aGw(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 jA2(A,Q)}get entitySchedules(){return this.deps.config.entitySchedules}}function aGw(A){for(let Q of A.values())Q.stop();A.clear()}class hs0{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(){tGw(this.generationJobs)}async handleTriggerGeneration(A){if(!this.deps.isRunning())return;try{await MA2(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 tGw(A){for(let Q of A.values())Q.stop();A.clear()}class xU{static instance=null;config;publishRunner;generationRunner;running=!1;static getInstance(A){return xU.instance??=new xU(A),xU.instance}static resetInstance(){if(xU.instance)xU.instance.stop();xU.instance=null}static createFresh(A){return new xU(A)}constructor(A){this.config={...A,entitySchedules:A.entitySchedules??{},generationSchedules:A.generationSchedules??{},generationConditions:A.generationConditions??{}},this.validateCronExpressions(),this.publishRunner=new Rs0({config:this.config,getPublishDeps:()=>this.publishDeps,isRunning:()=>this.running}),this.generationRunner=new hs0({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){vs0(A,Q,w,this.publishDeps)}failPublish(A,Q,w){PA2(A,Q,w,this.publishDeps)}completeGeneration(A,Q){OA2(A,Q,this.config.messageBus)}failGeneration(A,Q){xA2(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(B){throw Error(`Invalid ${w} cron expression for ${A}: "${Q}" - ${SA(B)}`,{cause:B})}}}class w3{static instance=null;retries=new Map;static getInstance(){return w3.instance??=new w3,w3.instance}static resetInstance(){w3.instance=null}static createFresh(){return new w3}constructor(){}recordFailure(A,Q){let B=(this.retries.get(A)?.retryCount??0)+1;this.retries.set(A,{entityId:A,retryCount:B,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 Oo(A){return Date.UTC(A.y,A.m-1,A.d,A.h,A.i,A.s)}function Cs0(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 eGw(A,Q){let w=new Date(Date.parse(A));if(isNaN(w))throw Error("Invalid ISO8601 passed to timezone parser.");let B=A.substring(9);return B.includes("Z")||B.includes("+")||B.includes("-")?ys0(w.getUTCFullYear(),w.getUTCMonth()+1,w.getUTCDate(),w.getUTCHours(),w.getUTCMinutes(),w.getUTCSeconds(),"Etc/UTC"):ys0(w.getFullYear(),w.getMonth()+1,w.getDate(),w.getHours(),w.getMinutes(),w.getSeconds(),Q)}function vA2(A,Q,w){return CA2(eGw(A,Q),w)}function CA2(A,Q){let w=new Date(Oo(A)),B=xo(w,A.tz),$=Oo(A),f=Oo(B),Y=$-f,X=new Date(w.getTime()+Y),H=xo(X,A.tz);if(Cs0(H,A)){let U=new Date(X.getTime()-3600000),G=xo(U,A.tz);return Cs0(G,A)?U:X}let W=new Date(X.getTime()+Oo(A)-Oo(H)),K=xo(W,A.tz);if(Cs0(K,A))return W;if(Q)throw Error("Invalid date passed to fromTZ()");return X.getTime()>W.getTime()?X:W}function xo(A,Q){let w,B;try{w=new Intl.DateTimeFormat("en-US",{timeZone:Q,year:"numeric",month:"numeric",day:"numeric",hour:"numeric",minute:"numeric",second:"numeric",hour12:!1}),B=w.formatToParts(A)}catch(f){let Y=f instanceof Error?f.message:String(f);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 $={year:0,month:0,day:0,hour:0,minute:0,second:0};for(let f of B)(f.type==="year"||f.type==="month"||f.type==="day"||f.type==="hour"||f.type==="minute"||f.type==="second")&&($[f.type]=parseInt(f.value,10));if(isNaN($.year)||isNaN($.month)||isNaN($.day)||isNaN($.hour)||isNaN($.minute)||isNaN($.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($)}`);return $.hour===24&&($.hour=0),{y:$.year,m:$.month,d:$.day,h:$.hour,i:$.minute,s:$.second,tz:Q}}function ys0(A,Q,w,B,$,f,Y){return{y:A,m:Q,d:w,h:B,i:$,s:f,tz:Y}}var gA2=[1,2,4,8,16],RA2=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 B;switch(this.mode){case"5-part":B=5;break;case"6-part":B=6;break;case"7-part":B=7;break;case"5-or-6-parts":B=[5,6];break;case"6-or-7-parts":B=[6,7];break;default:B=0}if(!(Array.isArray(B)?B.includes(Q):Q===B)){let $=Array.isArray(B)?B.join(" or "):B.toString();throw TypeError(`CronPattern: mode '${this.mode}' requires exactly ${$} 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,B){let $=this[A],f=A==="day"&&this.lastDayOfMonth,Y=A==="day"&&this.lastWeekday;if(Q===""&&!f&&!Y)throw TypeError("CronPattern: configuration entry "+A+" ("+Q+") is empty, check for trailing spaces.");if(Q==="*")return $.fill(B);let X=Q.split(",");if(X.length>1)for(let H=0;H<X.length;H++)this.partToArray(A,X[H],w,B);else Q.indexOf("-")!==-1&&Q.indexOf("/")!==-1?this.handleRangeWithStepping(Q,A,w,B):Q.indexOf("-")!==-1?this.handleRange(Q,A,w,B):Q.indexOf("/")!==-1?this.handleStepping(Q,A,w,B):Q!==""&&this.handleNumber(Q,A,w,B)}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,B){let $=this.extractNth(A,Q),f=A.toUpperCase().includes("W");if(Q!=="day"&&f)throw TypeError("CronPattern: Nearest weekday modifier (W) only allowed in day-of-month.");f&&(Q="nearestWeekdays");let Y=parseInt($[0],10)+w;if(isNaN(Y))throw TypeError("CronPattern: "+Q+" is not a number: '"+A+"'");this.setPart(Q,Y,$[1]||B)}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: '"+$+"'");if(w!==void 0){if(w===0)throw TypeError("CronPattern: Syntax error, illegal stepping: 0");if(w>this[B].length)throw TypeError("CronPattern: Syntax error, steps cannot be greater than maximum value of part ("+this[B].length+")")}}handleRangeWithStepping(A,Q,w,B){if(A.toUpperCase().includes("W"))throw TypeError("CronPattern: Syntax error, W is not allowed in ranges with stepping.");let $=this.extractNth(A,Q),f=$[0].match(/^(\d+)-(\d+)\/(\d+)$/);if(f===null)throw TypeError("CronPattern: Syntax error, illegal range with stepping: '"+A+"'");let[,Y,X,H]=f,W=parseInt(Y,10)+w,K=parseInt(X,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,$[1]||B)}extractNth(A,Q){let w=A,B;if(w.includes("#")){if(Q!=="dayOfWeek")throw Error("CronPattern: nth (#) only allowed in day-of-week field");B=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)");B="L",w=w.slice(0,-1)}return[w,B]}handleRange(A,Q,w,B){if(A.toUpperCase().includes("W"))throw TypeError("CronPattern: Syntax error, W is not allowed in a range.");let $=this.extractNth(A,Q),f=$[0].split("-");if(f.length!==2)throw TypeError("CronPattern: Syntax error, illegal range: '"+A+"'");let Y=parseInt(f[0],10)+w,X=parseInt(f[1],10)+w;this.validateNotNaN(Y,"CronPattern: Syntax error, illegal lower range (NaN)"),this.validateNotNaN(X,"CronPattern: Syntax error, illegal upper range (NaN)"),this.validateRange(Y,X,void 0,Q,A);for(let H=Y;H<=X;H++)this.setPart(Q,H,$[1]||B)}handleStepping(A,Q,w,B){if(A.toUpperCase().includes("W"))throw TypeError("CronPattern: Syntax error, W is not allowed in parts with stepping.");let $=this.extractNth(A,Q),f=$[0].split("/");if(f.length!==2)throw TypeError("CronPattern: Syntax error, illegal stepping: '"+A+"'");if(this.sloppyRanges)f[0]===""&&(f[0]="*");else{if(f[0]==="")throw TypeError("CronPattern: Syntax error, stepping with missing prefix ('"+A+"') is not allowed. Use wildcard (*/step) or range (min-max/step) instead.");if(f[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;f[0]!=="*"&&(Y=parseInt(f[0],10)+w);let X=parseInt(f[1],10);this.validateNotNaN(X,"CronPattern: Syntax error, illegal stepping: (NaN)"),this.validateRange(0,this[Q].length-1,X,Q,A);for(let H=Y;H<this[Q].length;H+=X)this.setPart(Q,H,$[1]||B)}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]|gA2[Q-1];else throw TypeError(`CronPattern: nth weekday out of range, should be 1-5 or L. Value: ${Q}, Type: ${typeof Q}`)}},gs0=[31,28,31,30,31,30,31,31,30,31,30,31],U$=[["month","year",0],["day","month",-1],["hour","day",0],["minute","hour",0],["second","minute",0]],d7=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?gs0[w]:new Date(Date.UTC(Q,w+1,0)).getUTCDate()}getLastWeekday(Q,w){let B=this.getLastDayOfMonth(Q,w),$=new Date(Date.UTC(Q,w,B)).getUTCDay();return $===0?B-2:$===6?B-1:B}getNearestWeekday(Q,w,B){let $=this.getLastDayOfMonth(Q,w);if(B>$)return-1;let f=new Date(Date.UTC(Q,w,B)).getUTCDay();return f===0?B===$?B-2:B+1:f===6?B===1?B+2:B-1:B}isNthWeekdayOfMonth(Q,w,B,$){let f=new Date(Date.UTC(Q,w,B)).getUTCDay(),Y=0;for(let X=1;X<=B;X++)new Date(Date.UTC(Q,w,X)).getUTCDay()===f&&Y++;if($&63&&gA2[Y-1]&$)return!0;if($&32){let X=this.getLastDayOfMonth(Q,w);for(let H=B+1;H<=X;H++)if(new Date(Date.UTC(Q,w,H)).getUTCDay()===f)return!1;return!0}return!1}fromDate(Q){if(this.tz!==void 0)if(typeof this.tz=="number")this.ms=Q.getUTCMilliseconds(),this.second=Q.getUTCSeconds(),this.minute=Q.getUTCMinutes()+this.tz,this.hour=Q.getUTCHours(),this.day=Q.getUTCDate(),this.month=Q.getUTCMonth(),this.year=Q.getUTCFullYear(),this.apply();else try{let w=xo(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 B=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: ${B}`)}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>gs0[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=vA2(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(vA2(Q,this.tz))}findNext(Q,w,B,$){return this._findMatch(Q,w,B,$,1)}_findMatch(Q,w,B,$,f){let Y=this[w],X;B.lastDayOfMonth&&(X=this.getLastDayOfMonth(this.year,this.month));let H=!B.starDOW&&w=="day"?new Date(Date.UTC(this.year,this.month,1,0,0,0,0)).getUTCDay():void 0,W=this[w]+$,K=f===1?(U)=>U<B[w].length:(U)=>U>=0;for(let U=W;K(U);U+=f){let G=B[w][U];if(w==="day"&&!G){for(let q=0;q<B.nearestWeekdays.length;q++)if(B.nearestWeekdays[q]){let V=this.getNearestWeekday(this.year,this.month,q-$);if(V===-1)continue;if(V===U-$){G=1;break}}}if(w==="day"&&B.lastWeekday){let q=this.getLastWeekday(this.year,this.month);U-$===q&&(G=1)}if(w==="day"&&B.lastDayOfMonth&&U-$==X&&(G=1),w==="day"&&!B.starDOW){let q=B.dayOfWeek[(H+(U-$-1))%7];if(q&&q&63)q=this.isNthWeekdayOfMonth(this.year,this.month,U-$,q)?1:0;else if(q)throw Error(`CronDate: Invalid value for dayOfWeek encountered. ${q}`);B.useAndLogic?G=G&&q:!Q.domAndDow&&!B.starDOM?G=G||q:G=G&&q}if(G)return this[w]=U-$,Y!==this[w]?2:1}return 3}recurse(Q,w,B){if(B===0&&!Q.starYear){if(this.year>=0&&this.year<Q.year.length&&Q.year[this.year]===0){let f=-1;for(let Y=this.year+1;Y<Q.year.length&&Y<1e4;Y++)if(Q.year[Y]===1){f=Y;break}if(f===-1)return null;this.year=f,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 $=this.findNext(w,U$[B][0],Q,U$[B][2]);if($>1){let f=B+1;for(;f<U$.length;)this[U$[f][0]]=-U$[f][2],f++;if($===3){if(this[U$[B][1]]++,this[U$[B][0]]=-U$[B][2],this.apply(),B===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,B-1)}return B+=1,B>=U$.length?this:(Q.starYear?this.year>=3000:this.year>=1e4)?null:this.recurse(Q,w,B)}increment(Q,w,B){return this.second+=w.interval!==void 0&&w.interval>1&&B?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($>1e4)return null;if(B===0&&!Q.starYear){if(this.year>=0&&this.year<Q.year.length&&Q.year[this.year]===0){let Y=-1;for(let X=this.year-1;X>=0;X--)if(Q.year[X]===1){Y=X;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 f=this.findPrevious(w,U$[B][0],Q,U$[B][2]);if(f>1){let Y=B+1;for(;Y<U$.length;){let X=U$[Y][0],H=U$[Y][2],W=this.getMaxPatternValue(X,Q,H);this[X]=W,Y++}if(f===3){if(this[U$[B][1]]--,B===0){let K=this.getLastDayOfMonth(this.year,this.month);this.day>K&&(this.day=K)}if(B===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?gs0[U]:new Date(Date.UTC(K,U+1,0)).getUTCDate();this.day>G&&(this.day=G)}this.apply();let X=U$[B][0],H=U$[B][2],W=this.getMaxPatternValue(X,Q,H);if(X==="day"){let K=this.getLastDayOfMonth(this.year,this.month);this[X]=Math.min(W,K)}else this[X]=W;if(this.apply(),B===0){let K=U$[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,U$[2][2]),this.minute=this.getMaxPatternValue("minute",Q,U$[3][2]),this.second=this.getMaxPatternValue("second",Q,U$[4][2]))}if(B===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,$+1)}else if(this.apply())return this.recurseBackward(Q,w,B-1,$+1)}return B+=1,B>=U$.length?this:this.year<0?null:this.recurseBackward(Q,w,B,$+1)}getMaxPatternValue(Q,w,B){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 $=w[Q].length-1;$>=0;$--)if(w[Q][$])return $-B;return w[Q].length-1-B}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)):CA2(ys0(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 B=0;B<U$.length;B++){let $=U$[B][0],f=U$[B][2],Y=this[$];if(Y+f<0||Y+f>=Q[$].length)return!1;let X=Q[$][Y+f];if($==="day"){if(!X){for(let H=0;H<Q.nearestWeekdays.length;H++)if(Q.nearestWeekdays[H]){let W=this.getNearestWeekday(this.year,this.month,H-f);if(W!==-1&&W===Y){X=1;break}}}if(Q.lastWeekday){let H=this.getLastWeekday(this.year,this.month);Y===H&&(X=1)}if(Q.lastDayOfMonth){let H=this.getLastDayOfMonth(this.year,this.month);Y===H&&(X=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?X=X&&W:!w.domAndDow&&!Q.starDOM?X=X||W:X=X&&W}}if(!X)return!1}return!0}};function ADw(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 d7(A.startAt,A.timezone)),A.stopAt&&(A.stopAt=new d7(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 vo(A){return Object.prototype.toString.call(A)==="[object Function]"||typeof A=="function"||A instanceof Function}function QDw(A){return vo(A)}function wDw(A){typeof Deno<"u"&&typeof Deno.unrefTimer<"u"?Deno.unrefTimer(A):A&&typeof A.unref<"u"&&A.unref()}var hA2=30000,BX0=[],Es0=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(vo(Q))$=Q;else if(typeof Q=="object")B=Q;else if(Q!==void 0)throw Error("Cron: Invalid argument passed for optionsIn. Should be one of function, or object (options).");if(vo(w))$=w;else if(typeof w=="object")B=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=B?.name,this.options=ADw(B),this._states={kill:!1,blocking:!1,previousRun:void 0,currentRun:void 0,once:void 0,currentTimeout:void 0,maxRuns:B?B.maxRuns:void 0,paused:B?B.paused:!1,pattern:new RA2("* * * * *",void 0,{mode:"auto"})},A&&(A instanceof Date||typeof A=="string"&&A.indexOf(":")>0)?this._states.once=new d7(A,this.getTz()):this._states.pattern=new RA2(A,this.options.timezone,{mode:this.options.mode,alternativeWeekdays:this.options.alternativeWeekdays,sloppyRanges:this.options.sloppyRanges}),this.name){if(BX0.find((f)=>f.name===this.name))throw Error("Cron: Tried to initialize new named job '"+this.name+"', but name already taken.");BX0.push(this)}return $!==void 0&&QDw($)&&(this.fn=$,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 d7(Q,this.getTz()):null,f=w==="next"?this._next:this._previous;for(;A--;){let Y=f.call(this,$);if(!Y)break;let X=Y.getDate(!1);B.push(this.applyDayOffset(X)),$=Y}return B}match(A){if(this._states.once){let w=new d7(A,this.getTz());w.ms=0;let B=new d7(this._states.once,this.getTz());return B.ms=0,w.getTime()===B.getTime()}let Q=new d7(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,B=!this._states.kill;return Q&&w&&B&&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 d7||A instanceof Date?Q.getTime()-A.getTime():Q.getTime()-new d7(A).getTime():null}stop(){this._states.kill=!0,this._states.currentTimeout&&clearTimeout(this._states.currentTimeout);let A=BX0.indexOf(this);A>=0&&BX0.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>hA2&&(Q=hA2),this._states.currentTimeout=setTimeout(()=>this._checkTrigger(w),Q),this._states.currentTimeout&&this.options.unref&&wDw(this._states.currentTimeout),this)}async _trigger(A){this._states.blocking=!0,this._states.currentRun=new d7(void 0,this.getTz());try{if(this.options.catch)try{this.fn!==void 0&&await this.fn(this,this.options.context)}catch(Q){if(vo(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 d7(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(),B=this._states.blocking&&this.options.protect;w&&!B?(this._states.maxRuns!==void 0&&this._states.maxRuns--,this._trigger()):w&&B&&vo(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 d7(A,this.getTz()),this.options.startAt&&A&&A.getTime()<this.options.startAt.getTime()&&(A=this.options.startAt);let B=this._states.once||new d7(A,this.getTz());return!w&&B!==this._states.once&&(B=B.increment(this._states.pattern,this.options,Q)),this._states.once&&this._states.once.getTime()<=A.getTime()||B===null||this._states.maxRuns!==void 0&&this._states.maxRuns<=0||this._states.kill||this.options.stopAt&&B.getTime()>=this.options.stopAt.getTime()?null:B}_previous(A){let Q=new d7(A,this.getTz());this.options.stopAt&&Q.getTime()>this.options.stopAt.getTime()&&(Q=this.options.stopAt);let w=new d7(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 d7(void 0,this.getTz()),B=A;if(this.options.startAt.getTime()<=w.getTime()){B=this.options.startAt;let $=B.getTime()+this.options.interval*1000;for(;$<=w.getTime();)B=new d7(B,this.getTz()).increment(this._states.pattern,this.options,!0),$=B.getTime()+this.options.interval*1000;Q=!0}return B===null&&(B=void 0),[B,Q]}};class $X0{scheduleCron(A,Q){let w=new Es0(A,()=>{Q()});return{stop:()=>w.stop()}}scheduleInterval(A,Q){let w=setInterval(()=>{Q()},A);return{stop:()=>clearInterval(w)}}validateCron(A){new Es0(A).stop()}}_0();var yA2=Z.union([Z.string().min(1),Z.object({location:Z.enum(["metadata","frontmatter"]),field:Z.string().min(1)})]),fX0=Z.object({entityType:Z.string().min(1),attachmentType:Z.string().min(1),mediaEntityType:Z.enum(["image","document"]),targetEntityField:yA2.optional(),requiredWhen:Z.object({status:Z.string().min(1).optional(),visibility:Z.string().min(1).optional()}).optional(),autoGenerate:Z.boolean().optional(),requiredForPublish:Z.boolean().optional(),jobType:Z.string().min(1).optional()});function Ts0(A){return`${A.entityType}:${A.attachmentType}`}class B3{static instance=null;definitions=new Map;static getInstance(){return B3.instance??=new B3,B3.instance}static resetInstance(){B3.instance=null}static createFresh(){return new B3}constructor(){}register(A){let Q=fX0.parse(A),w=Ts0(Q);return this.definitions.set(w,Q),()=>this.unregister(Q.entityType,Q.attachmentType)}get(A,Q){return this.definitions.get(Ts0({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(Ts0({entityType:A,attachmentType:Q}))}clear(){this.definitions.clear()}}u9();U2();class YX0{deps;constructor(A){this.deps=A}async ensureForEntity(A,Q={}){let w=this.deps.registry.list(A.entityType).filter(($)=>$.autoGenerate===!0).filter(($)=>!Q.attachmentType||$.attachmentType===Q.attachmentType),B={checked:w.length,enqueued:0,skipped:0};for(let $ of w)if(await this.ensureDefinition(A,$))B.enqueued+=1;else B.skipped+=1;return B}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 B=this.getPredictedMediaId(A,Q),$=this.getDeduplicationKey(A,Q);return await this.deps.context.jobs.enqueue({type:w,data:{sourceEntityType:A.entityType,sourceEntityId:A.id,attachmentType:Q.attachmentType,imageId:B,dedupKey:$,targetEntityType:A.entityType,targetEntityId:A.id,...this.getTargetImageFieldData(Q.targetEntityField)},options:{source:"content-pipeline",metadata:{operationType:"content_operations"},deduplication:"skip",deduplicationKey:$}}),this.deps.context.logger.debug("Queued publish asset generation",{entityType:A.entityType,entityId:A.id,attachmentType:Q.attachmentType,jobType: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 Ss0(A.metadata[Q]);if(Q.location==="metadata")return Ss0(A.metadata[Q.field]);let{frontmatter:w}=P6(A.content);return Ss0(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 H1(`${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 Ss0(A){return typeof A==="string"?A.length>0:A!==void 0}wA();_0();var BDw=Z.object({id:Z.string().min(1)});async function TA2(A,Q){let{bodyContent:w,coverImageId:B,documents:$,sourceEntityType:f,sourceEntityId:Y}=$Dw(Q.content),X=B?await XDw(A,B):void 0,H;if($&&$.length>0){let K=await ZDw(A,$);if(K.length>0)H=K}H??=await YDw(A,f,Y);let W={bodyContent:w};if(X)W.imageData=X;if(H&&H.length>0)W.documentData=H;return W}function $Dw(A){try{let Q=n2(A,Z.record(Z.string(),Z.unknown())),w=Q.metadata.coverImageId,B=typeof w==="string"?w:void 0,$=fDw(Q.metadata.documents),f=EA2(Q.metadata.sourceEntityType),Y=EA2(Q.metadata.sourceEntityId);return{bodyContent:Q.content,...B&&{coverImageId:B},...$.length>0&&{documents:$},...f&&{sourceEntityType:f},...Y&&{sourceEntityId:Y}}}catch{return{bodyContent:A}}}function fDw(A){if(!Array.isArray(A))return[];return A.flatMap((Q)=>{let w=BDw.safeParse(Q);return w.success?[w.data]:[]})}function EA2(A){return typeof A==="string"&&A.length>0?A:void 0}async function YDw(A,Q,w){if(!Q||!w)return;let B=await A.attachments.resolve({sourceEntityType:Q,sourceEntityId:w,attachmentType:"carousel"});return B?[B]:void 0}async function XDw(A,Q){let w=await A.entityService.getEntity({entityType:"image",id:Q});if(!w?.content)return;let B=SA2(w.content);if(!B?.mimeType.startsWith("image/"))return;return{data:B.data,mimeType:B.mimeType}}async function ZDw(A,Q){return(await Promise.all(Q.map((B)=>HDw(A,B)))).filter((B)=>B!==void 0)}async function HDw(A,Q){let w=await A.entityService.getEntity({entityType:"document",id:Q.id});if(!w?.content)return;let B=SA2(w.content);if(B?.mimeType!=="application/pdf")return;return{type:"document",data:B.data,mimeType:"application/pdf",filename:WDw(w,Q.id)}}function SA2(A){let Q=A.match(/^data:([^;]+);base64,(.+)$/);if(!Q?.[1]||!Q[2])return;return{mimeType:Q[1],data:Buffer.from(Q[2],"base64")}}function WDw(A,Q){let w=A.metadata.filename;return typeof w==="string"&&w.length>0?w:`${Q}.pdf`}u9();var KDw=/^---\r?\n[\s\S]*?\r?\n---(?:\r?\n|$)/;async function ms0(A,Q,w,B={}){let $=B.publishTimestampField??"publishedAt",f=Q.metadata[$],Y=B.publishedAt??(typeof f==="string"?f:void 0)??new Date().toISOString(),X={...Q.metadata,status:"published",[$]:Y,platformId:w.id,...UDw(w.id,B.publishResultIdField)},H={...Q,content:mA2(Q.content,Y,w.id,B.publishResultIdField,$),metadata:X};return await A.entityService.updateEntity({entity:H}),H}function mA2(A,Q,w,B,$="publishedAt"){if(!KDw.test(A))return A;let f=D4(D4(A,"status","published"),$,Q);if(!w||!B)return f;return D4(f,B,w)}function UDw(A,Q){if(!Q||Q==="platformId")return{};return{[Q]:A}}class _y{deps;constructor(A){this.deps=A}async resolveCandidate(A){let{entityType:Q,id:w,slug:B}=A;if(!w&&!B)return{error:"Either 'id' or 'slug' must be provided"};let $=await this.findPublishableEntity(Q,w,B);if(!$)return{error:`Entity not found: ${Q}:${w??B}`};if($.visibility!=="public")return{error:`Cannot publish ${Q}:${$.id} to a public provider because visibility is ${$.visibility}`};if($.metadata.status==="published")return{error:"Entity is already published"};if(!this.deps.providerRegistry.has(Q))return{error:`No publish provider registered for ${Q}. Check that the required credentials are configured.`};return{entity:$}}async publish(A){let Q=await this.resolveCandidate(A);if("error"in Q)return Q;let{entity:w}=Q,{entityType:B}=A,$=this.deps.providerRegistry.get(B),{bodyContent:f,imageData:Y,documentData:X}=await TA2(this.deps.context,w),H=await $.publish(f,w.metadata,Y,X),W=this.deps.providerRegistry.getPublishResultIdField(B),K=this.deps.providerRegistry.getPublishTimestampField(B),U=await ms0(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}}wA();_0();var us0=Z.object({action:Z.enum(["list","add","remove","reorder"]).describe("Queue action to perform"),entityType:Z.string().optional().describe("Entity type (required for add/remove/reorder, optional for list)"),entityId:Z.string().optional().describe("Entity ID (required for add/remove/reorder)"),position:Z.number().optional().describe("New position for reorder action (1-based)")}),cs0=Z.object({position:Z.number(),entityType:Z.string(),entityId:Z.string(),queuedAt:Z.string()}),GDw=Z.object({success:Z.literal(!0),message:Z.string().optional(),data:Z.object({queue:Z.array(cs0).optional(),entityType:Z.string().optional(),entityId:Z.string().optional(),position:Z.number().optional()}).optional()}),DDw=Z.object({success:Z.literal(!1),error:Z.string(),code:Z.string().optional()}),ls0=Z.union([GDw,DDw]);function XX0(A,Q,w){return{...M6(Q,"queue","Manage the publish queue for all entity types (list, add, remove, reorder)",us0,async($,f)=>{let{action:Y,entityType:X,entityId:H,position:W}=$;switch(Y){case"list":return zDw(w,X);case"add":return qDw(A,w,X,H,f);case"remove":return VDw(A,w,X,H,f);case"reorder":return bDw(A,w,X,H,W,f);default:return{success:!1,error:`Unknown action: ${Y}`}}},{sideEffects:"writes"}),outputSchema:ls0}}async function zDw(A,Q){let w=[];if(Q)w=await A.list(Q);else{let $=A.getRegisteredTypes();for(let f of $){let Y=await A.list(f);w.push(...Y)}w.sort((f,Y)=>new Date(f.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(($,f)=>({position:f+1,entityType:$.entityType,entityId:$.entityId,queuedAt:$.queuedAt}))},message:`${w.length} items in queue`}}async function qDw(A,Q,w,B,$){let f=ps0("add",w,B);if(!f.success)return f.error;A.permissions.assertEntityActionAllowed(f.entityType,"publish",$??{});let Y=await Q.add(f.entityType,f.entityId,{...$,authorization:"user"});return{success:!0,data:{entityType:f.entityType,entityId:f.entityId,position:Y.position},message:`Added to queue at position ${Y.position}`}}async function VDw(A,Q,w,B,$){let f=ps0("remove",w,B);if(!f.success)return f.error;return A.permissions.assertEntityActionAllowed(f.entityType,"update",$??{}),await Q.remove(f.entityType,f.entityId),{success:!0,data:{entityType:f.entityType,entityId:f.entityId},message:"Removed from queue"}}async function bDw(A,Q,w,B,$,f){let Y=ps0("reorder",w,B);if(!Y.success)return Y.error;let X=JDw($);if(!X.success)return X.error;return A.permissions.assertEntityActionAllowed(Y.entityType,"update",f??{}),await Q.reorder(Y.entityType,Y.entityId,X.position),{success:!0,data:{entityType:Y.entityType,entityId:Y.entityId,position:X.position},message:`Moved to position ${X.position}`}}function ps0(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 JDw(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}}_0();import{createHash as IDw}from"crypto";var is0=Z.object({entityType:Z.string().describe("Entity type to publish (e.g., social-post, post, deck)"),id:Z.string().optional().describe("Entity ID to publish"),slug:Z.string().optional().describe("Entity slug to publish"),confirmed:Z.boolean().optional(),confirmationToken:Z.string().optional(),contentHash:Z.string().optional(),expiresAt:Z.string().datetime().optional()}),FDw=Z.object({entityType:Z.string(),id:Z.string().optional(),slug:Z.string().optional(),confirmed:Z.boolean().optional(),confirmationToken:Z.string().optional(),contentHash:Z.string().optional(),expiresAt:Z.string().datetime().optional()}),LDw=Z.object({success:Z.literal(!0),message:Z.string().optional(),data:Z.object({entityType:Z.string().optional(),entityId:Z.string().optional(),platformId:Z.string().optional(),url:Z.string().optional()}).optional()}),kDw=Z.object({success:Z.literal(!1),error:Z.string(),code:Z.string().optional()}),_Dw=Z.object({success:Z.literal(!1).optional(),error:Z.string().optional(),needsConfirmation:Z.literal(!0),toolName:Z.string(),summary:Z.string(),preview:Z.string().optional(),args:Z.unknown()}),ds0=Z.union([LDw,kDw,_Dw]),NDw=900000;function ZX0(A,Q,w,B){let $=B??new _y({context:A,providerRegistry:w}),f=`${Q}_publish`;return{name:f,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:is0.shape,outputSchema:ds0,visibility:"anchor",sideEffects:"external",handler:async(Y,X)=>{let H=FDw.safeParse(Y);if(!H.success)return{success:!1,error:`Invalid input: ${H.error.issues.map((J)=>`${J.path.join(".")}: ${J.message}`).join(", ")}`};let W=H.data,{entityType:K,id:U,slug:G}=W;try{A.permissions.assertEntityActionAllowed(K,"publish",X)}catch(J){return{success:!1,error:J instanceof Error?J.message:String(J)}}let q=await $.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 J=PDw(f,W,V);if(J!==null)return J;let b;try{b=await $.publish({entityType:K,id:V.id})}catch(k){return{success:!1,error:k instanceof Error?k.message:String(k)}}if("error"in b)return{success:!1,error:b.error};let{entity:L,result:N}=b;return{success:!0,data:{entityType:K,entityId:L.id,platformId:N.id,url:N.url},message:`Published ${K}:${L.id}`}}return jDw(f,W,V)}}}function jDw(A,Q,w){let B=new Date(Date.now()+NDw).toISOString(),$=uA2(A,w,B),f=MDw(w);return{needsConfirmation:!0,toolName:A,summary:`Publish "${f}"?`,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:$,contentHash:w.contentHash,expiresAt:B}}}function PDw(A,Q,w){let{confirmationToken:B,contentHash:$,expiresAt:f}=Q;if(!B||!f)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(f);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($&&$!==w.contentHash)return{success:!1,error:`Cannot publish ${w.entityType}:${w.id} because it changed after confirmation. Review it and try again.`};if(B!==uA2(A,w,f))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 uA2(A,Q,w){return IDw("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 MDw(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 B=A.metadata.slug;if(typeof B==="string"&&B.length>0)return B;return A.id}wA();_0();var ns0=Z.object({entityType:Z.string().min(1).describe("Entity type to reconcile"),status:Z.string().min(1).optional().describe("Optional metadata status filter, e.g. published"),assetType:Z.string().min(1).optional().describe("Optional attachment type filter, e.g. og-image")}),rs0=Z.object({success:Z.literal(!0),data:Z.object({entityType:Z.string(),assetType:Z.string().optional(),checkedEntities:Z.number(),checkedAssets:Z.number(),enqueued:Z.number(),skipped:Z.number()}),message:Z.string().optional()});function HX0(A,Q,w,B){return{...M6(Q,"ensure-assets","Reconcile configured publish assets for existing entities, queueing missing generated assets such as OG images.",ns0,async(f,Y)=>{if(A.permissions.assertEntityActionAllowed(f.entityType,"publish",Y),w.list(f.entityType).filter((G)=>G.autoGenerate===!0).filter((G)=>!f.assetType||G.attachmentType===f.assetType).length===0)return{success:!0,data:{entityType:f.entityType,...f.assetType&&{assetType:f.assetType},checkedEntities:0,checkedAssets:0,enqueued:0,skipped:0},message:`No publish assets configured for ${f.entityType}`};let H=await A.entityService.listEntities({entityType:f.entityType,options:{...f.status&&{filter:{metadata:{status:f.status}}}}}),W=0,K=0,U=0;for(let G of H){let q=await B.ensureForEntity(G,{...f.assetType&&{attachmentType:f.assetType}});W+=q.checked,K+=q.enqueued,U+=q.skipped}return{success:!0,data:{entityType:f.entityType,...f.assetType&&{assetType:f.assetType},checkedEntities:H.length,checkedAssets:W,enqueued:K,skipped:U},message:`Queued ${K} publish asset job(s)`}},{sideEffects:"writes"}),outputSchema:rs0}}wA();function cA2(A,Q){ODw(A,Q),xDw(A,Q),vDw(A,Q),RDw(A,Q)}function ODw(A,Q){A.messaging.subscribe(sf.REGISTER,async(w)=>hDw(Q,w.payload)),A.messaging.subscribe(sf.QUEUE,async(w)=>EDw(A,Q,w.payload)),A.messaging.subscribe(sf.DIRECT,async(w)=>TDw(A,Q,w.payload)),A.messaging.subscribe(sf.REMOVE,async(w)=>SDw(Q,w.payload)),A.messaging.subscribe(sf.REORDER,async(w)=>mDw(Q,w.payload)),A.messaging.subscribe(sf.LIST,async(w)=>uDw(A,Q,w.payload)),A.messaging.subscribe(sf.REPORT_SUCCESS,async(w)=>cDw(Q,w.payload)),A.messaging.subscribe(sf.REPORT_FAILURE,async(w)=>lDw(Q,w.payload)),Q.logger.debug("Subscribed to publish messages")}function xDw(A,Q){A.messaging.subscribe(xF.REPORT_SUCCESS,async(w)=>pDw(Q,w.payload)),A.messaging.subscribe(xF.REPORT_FAILURE,async(w)=>iDw(Q,w.payload)),Q.logger.debug("Subscribed to generation messages")}function vDw(A,Q){A.messaging.subscribe(kA2.REGISTER,async(w)=>CDw(Q,w.payload)),Q.logger.debug("Subscribed to publish asset messages")}function RDw(A,Q){let w=async(B)=>gDw(A,Q,B.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 hDw(A,Q){let{entityType:w,provider:B,config:$}=Q;try{let f=$?_A2.safeParse($):void 0;if(f&&!f.success)return A.logger.warn("Invalid publish provider config",{entityType:w,error:f.error.message}),{success:!1};if(B)A.providerRegistry.register(w,B,f?.data),A.logger.info(`Registered provider for entity type: ${w}`,{providerName:B.name,executionMode:A.providerRegistry.getExecutionMode(w)});return{success:!0}}catch(f){let Y=SA(f);return A.logger.error(`Failed to register provider: ${Y}`),{success:!1}}}async function CDw(A,Q){let w=fX0.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 gDw(A,Q,w){try{if(Q.publishAssetRegistry.list(w.entityType).length===0)return{success:!0};let B=w.entity??await A.entityService.getEntity({entityType:w.entityType,id:w.entityId});if(!yDw(B))return{success:!0};return await Q.publishAssetPreflight.ensureForEntity(B),{success:!0}}catch(B){return Q.logger.warn("Failed to run publish asset preflight for entity event",{entityType:w.entityType,entityId:w.entityId,error:SA(B)}),{success:!1}}}function yDw(A){if(!A)return!1;let Q=LA2.safeParse(A.metadata);return Q.success&&Q.data.status==="published"}async function EDw(A,Q,w){let{entityType:B,entityId:$}=w;try{let f=w.authContext??Mo;A.permissions.assertEntityActionAllowed(B,"publish",f);let Y=await Q.queueManager.add(B,$,f);return await A.messaging.send({type:sf.QUEUED,payload:{entityType:B,entityId:$,position:Y.position}}),Q.logger.debug(`Entity queued: ${$}`,{entityType:B,position:Y.position}),{success:!0}}catch(f){let Y=SA(f);return Q.logger.error(`Failed to queue entity: ${Y}`),{success:!1}}}async function TDw(A,Q,w){let{entityType:B,entityId:$}=w,f=w.authContext??Mo;try{if(A.permissions.assertEntityActionAllowed(B,"publish",f),!Q.providerRegistry.has(B))return Q.scheduler.failPublish(B,$,`No publish provider registered for ${B}`),{success:!1};let Y=await Q.publishExecutor.publish({entityType:B,id:$});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: ${$}`,{entityType:B}),{success:!0}}catch(Y){let X=SA(Y);return Q.logger.error(`Failed direct publish request: ${X}`),{success:!1}}}async function SDw(A,Q){let{entityType:w,entityId:B}=Q;try{return await A.queueManager.remove(w,B),A.logger.debug(`Entity removed from queue: ${B}`,{entityType:w}),{success:!0}}catch($){let f=SA($);return A.logger.error(`Failed to remove entity: ${f}`),{success:!1}}}async function mDw(A,Q){let{entityType:w,entityId:B,position:$}=Q;try{return await A.queueManager.reorder(w,B,$),A.logger.debug(`Entity reordered: ${B}`,{entityType:w,newPosition:$}),{success:!0}}catch(f){let Y=SA(f);return A.logger.error(`Failed to reorder entity: ${Y}`),{success:!1}}}async function uDw(A,Q,w){let{entityType:B}=w;try{let $=await Q.queueManager.list(B);return await A.messaging.send({type:sf.LIST_RESPONSE,payload:{entityType:B,queue:$.map((f)=>({entityId:f.entityId,position:f.position,queuedAt:f.queuedAt}))}}),{success:!0}}catch($){let f=SA($);return Q.logger.error(`Failed to list queue: ${f}`),{success:!1}}}async function cDw(A,Q){let{entityType:w,entityId:B,result:$}=Q;return A.scheduler.completePublish(w,B,$),A.logger.info(`Publish reported success: ${B}`,{entityType:w}),{success:!0}}async function lDw(A,Q){let{entityType:w,entityId:B,error:$}=Q;A.scheduler.failPublish(w,B,$);let f=A.retryTracker.getRetryInfo(B);return A.logger.info(`Publish reported failure: ${B}`,{entityType:w,error:$,retryCount:f?.retryCount}),{success:!0}}async function pDw(A,Q){let{entityType:w,entityId:B}=Q;return A.scheduler.completeGeneration(w,B),A.logger.info("Generation completed",{entityType:w,entityId:B}),{success:!0}}async function iDw(A,Q){let{entityType:w,error:B}=Q;return A.scheduler.failGeneration(w,B),A.logger.warn("Generation failed",{entityType:w,error:B}),{success:!0}}async function lA2(A,Q,w,B){try{if(B.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(B.maxUnpublishedDrafts!==void 0){let $=await A.listEntities({entityType:w,options:{filter:{metadata:{status:"draft"}},limit:B.maxUnpublishedDrafts+1}});if($.length>=B.maxUnpublishedDrafts)return{shouldGenerate:!1,reason:`Max unpublished drafts reached (${$.length}/${B.maxUnpublishedDrafts})`}}if(B.minSourceEntities!==void 0&&B.sourceEntityType){let $=await A.listEntities({entityType:B.sourceEntityType,options:{publishedOnly:!0,limit:B.minSourceEntities}});if($.length<B.minSourceEntities)return{shouldGenerate:!1,reason:`Not enough source entities (${$.length}/${B.minSourceEntities} ${B.sourceEntityType})`}}return{shouldGenerate:!0}}catch($){return Q.error("Failed to check generation conditions",{entityType:w,error:SA($)}),{shouldGenerate:!1,reason:`Condition check failed: ${SA($)}`}}}function pA2(A){let{context:Q,config:w,queueManager:B,providerRegistry:$,retryTracker:f,publishExecutor:Y,logger:X}=A,H=dDw(Q);return xU.createFresh({queueManager:B,providerRegistry:$,retryTracker:f,logger:X,backend:new $X0,...w.entitySchedules&&{entitySchedules:w.entitySchedules},...w.generationSchedules&&{generationSchedules:w.generationSchedules},...w.generationConditions&&{generationConditions:w.generationConditions},messageBus:H,publishExecutor:Y,onCheckGenerationConditions:(W,K)=>lA2(Q.entityService,X,W,K)})}function dDw(A){return{send:async($)=>{return A.messaging.send({type:$.type,payload:$.payload,...$.target!==void 0?{target:$.target}:{},...$.metadata!==void 0?{metadata:$.metadata}:{},...$.broadcast!==void 0?{broadcast:$.broadcast}:{}})},subscribe:()=>()=>{},unsubscribe:()=>{}}}async function iA2(A,Q,w){let B=A.getEntityTypes();for(let f of B){let Y=await A.listEntities({entityType:f,options:{filter:{metadata:{status:"queued"}}}});for(let X of Y)await Q.add(X.entityType,X.id)}let $=0;for(let f of B){let Y=await Q.list(f);$+=Y.length}if($>0)w.info(`Rebuilt queue with ${$} queued entities`)}_0();var nDw=["draft","queued","published","failed"];async function dA2(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:()=>tDw(A),digestProvider:oDw}})}var rDw=Z.object({summary:Z.object({draft:Z.number(),queued:Z.number(),published:Z.number(),failed:Z.number()}),generating:Z.array(Z.unknown())});function oDw(A){let{summary:Q,generating:w}=rDw.parse(A),B=Q.queued+w.length,$=B===0?"idle":`${Q.queued} queued \xB7 ${w.length} generating`,f=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:f,...Y>0?{tone:"warn"}:{}},{label:"Published",value:String(Q.published),tone:"good"}],needsOperator:Y}}var sDw=Z.object({sourceEntityType:Z.string(),sourceEntityId:Z.string(),attachmentType:Z.string().optional()});async function aDw(A){let Q=await A.jobs.getActiveJobs(),w=[];for(let B of Q){if(B.source!=="content-pipeline")continue;if(B.status!=="pending"&&B.status!=="processing")continue;let $;try{$=JSON.parse(B.data)}catch{continue}let f=sDw.safeParse($);if(!f.success)continue;w.push({id:B.id,label:f.data.attachmentType??B.type,target:`${f.data.sourceEntityType}/${f.data.sourceEntityId}`,status:B.status})}return w}async function tDw(A){let Q=A.entityService.getEntityTypes(),w=[],B={draft:0,queued:0,published:0,failed:0};for(let $ of Q){let f=await A.entityService.listEntities({entityType:$});for(let Y of f){let X=eDw(Y.metadata.status);if(!X)continue;B[X]++,w.push({id:Y.id,title:A3w(Y.id,Y.metadata.title),type:$,status:X})}}return{summary:B,items:w,generating:await aDw(A)}}function eDw(A){return nDw.find((Q)=>Q===A)}function A3w(A,Q){return typeof Q==="string"?Q:A}var nA2={name:"@brains/content-pipeline",version:"0.2.0-alpha.151",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 os0 extends tQ{pluginContext;queueManager;providerRegistry;retryTracker;publishExecutor;publishAssetRegistry;publishAssetPreflight;scheduler;constructor(A={}){super("content-pipeline",nA2,A,NA2)}async onRegister(A){this.pluginContext=A,this.queueManager=A3.createFresh(),this.providerRegistry=Q3.createFresh(),this.retryTracker=w3.createFresh(),this.publishAssetRegistry=B3.createFresh(),this.publishAssetPreflight=new YX0({context:A,registry:this.publishAssetRegistry}),this.publishExecutor=new _y({context:A,providerRegistry:this.providerRegistry,publishAssetPreflight:this.publishAssetPreflight}),this.scheduler=pA2({context:A,config:this.config,queueManager:this.queueManager,providerRegistry:this.providerRegistry,retryTracker:this.retryTracker,publishExecutor:this.publishExecutor,logger:this.logger}),cA2(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 iA2(A.entityService,this.queueManager,this.logger),await dA2(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[XX0(this.pluginContext,this.id,this.queueManager),ZX0(this.pluginContext,this.id,this.providerRegistry,this.publishExecutor),HX0(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(),A3.resetInstance(),Q3.resetInstance(),w3.resetInstance(),B3.resetInstance()}}function ss0(A={}){return new os0(A)}wA();_0();var rA2=Z.object({accountId:Z.string().describe("Cloudflare account ID"),apiToken:Z.string().describe("Cloudflare API token with Analytics:Read permission"),siteTag:Z.string().describe("Cloudflare Web Analytics site tag")}),as0=Z.object({cloudflare:rA2.optional()});wA();_0();var w3w=Z.object({date:Z.string().describe("Single date in YYYY-MM-DD format").optional(),days:Z.number().min(1).max(365).describe("Number of days back from yesterday (e.g., 7 for last week)").optional(),startDate:Z.string().describe("Start date in YYYY-MM-DD format (use with endDate)").optional(),endDate:Z.string().describe("End date in YYYY-MM-DD format (use with startDate)").optional(),limit:Z.number().min(1).max(100).default(20).describe("Maximum items for breakdowns (pages, referrers, countries)")});function B3w(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 oA2(A,Q,w){let B=[];if(!w)return B;return B.push(M6(A,"query",`Query website analytics from Cloudflare.
|
|
7484
7484
|
|
|
7485
7485
|
Date range options (use only one):
|
|
7486
7486
|
- No params: yesterday only
|
|
@@ -7618,7 +7618,7 @@ Returns pageviews, visitors, top pages, referrers, devices, and countries.`,w3w,
|
|
|
7618
7618
|
}
|
|
7619
7619
|
}
|
|
7620
7620
|
}
|
|
7621
|
-
`,{...this.baseVariables(A),limit:A.limit??20})).map((B)=>({country:B.dimensions.countryName,visits:B.sum.visits}))}}var es0=7,$3w=10;function aA2(A){return async()=>{if(!A)return{unavailable:!0,reason:"Cloudflare analytics not configured"};let Q=eQ0(),w=SOA(es0),B=cv(w),$=cv(Q);try{let[f,Y]=await Promise.all([A.getWebsiteStats({startDate:B,endDate:$}),A.getTopPages({startDate:B,endDate:$,limit:$3w})]);return{days:es0,startDate:B,endDate:$,pageviews:f.pageviews,visitors:f.visitors,topPages:Y}}catch(f){return{error:f instanceof Error?f.message:"Failed to fetch analytics",days:es0}}}}var tA2={name:"@brains/analytics",version:"0.2.0-alpha.
|
|
7621
|
+
`,{...this.baseVariables(A),limit:A.limit??20})).map((B)=>({country:B.dimensions.countryName,visits:B.sum.visits}))}}var es0=7,$3w=10;function aA2(A){return async()=>{if(!A)return{unavailable:!0,reason:"Cloudflare analytics not configured"};let Q=eQ0(),w=SOA(es0),B=cv(w),$=cv(Q);try{let[f,Y]=await Promise.all([A.getWebsiteStats({startDate:B,endDate:$}),A.getTopPages({startDate:B,endDate:$,limit:$3w})]);return{days:es0,startDate:B,endDate:$,pageviews:f.pageviews,visitors:f.visitors,topPages:Y}}catch(f){return{error:f instanceof Error?f.message:"Failed to fetch analytics",days:es0}}}}var tA2={name:"@brains/analytics",version:"0.2.0-alpha.151",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 eA2 extends tQ{cloudflareClient;constructor(A={}){super("analytics",tA2,A,as0)}async onRegister(A){this.cloudflareClient=this.config.cloudflare?new ts0(this.config.cloudflare):void 0,A.insights.register("traffic-overview",aA2(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:sA2(Q)}})}async getTools(){return oA2(this.id,this.getContext(),this.cloudflareClient)}}function Y3w(A={}){return new eA2(A)}var WX0=Y3w;wA();_0();wA();_0();import{join as z3w}from"path";U2();var A12="note",X3w=new Set(["description","excerpt","summary","tagline","story"]);function Z3w(A){if(A.endsWith("s"))return A;return eW(A)}function ho(A){return A===A12}function Q12(A,Q){let w=A===A12?"Note":qb(A),B=Q?.label??w;return{label:B,pluralLabel:Q?.pluralName??Z3w(B)}}function Ro(A){return typeof A==="object"&&A!==null}function KP(A){if(!Ro(A))return;let Q=A.def;return Ro(Q)?Q:void 0}function w12(A){let Q=KP(A)?.type;return typeof Q==="string"?Q:void 0}function H3w(A){return typeof A==="function"?A():A}function Aa0(A,Q=!1,w){let B=w12(A),$=KP(A);if(B==="optional"||B==="nullable")return Aa0($?.innerType,!0,w);if(B==="default")return Aa0($?.innerType,!0,H3w($?.defaultValue));let f={inner:A,isOptional:Q};if(w!==void 0)f.defaultValue=w;return f}function W3w(A){let Q=KP(A)?.entries;if(!Ro(Q))return;let w=Object.values(Q);return w.every((B)=>typeof B==="string")?w:void 0}function K3w(A){let Q=KP(A)?.values;return Array.isArray(Q)?Q[0]:void 0}function U3w(A){let Q=KP(A)?.checks;if(!Array.isArray(Q))return!1;return Q.some((w)=>{return KP(w)?.format==="datetime"})}function G3w(A){return A==="imageId"||A.endsWith("ImageId")}function D3w(A){if(!Ro(A))return;let Q=A.shape;return Ro(Q)?Q:void 0}function KX0(A,Q){let{inner:w,isOptional:B,defaultValue:$}=Aa0(Q),f=w12(w),Y=$??K3w(w),X={name:A,label:qb(A),widget:"string",...B&&{required:!1},...Y!==void 0&&{default:Y}};switch(f){case"string":{if(G3w(A))return{...X,widget:"image"};if(U3w(w))return{...X,widget:"datetime"};if(X3w.has(A))return{...X,widget:"text"};return{...X,widget:"string"}}case"number":return{...X,widget:"number"};case"boolean":return{...X,widget:"boolean"};case"enum":{let H=W3w(w);return{...X,widget:"select",...H?{options:H}:{}}}case"array":{let H=KP(w)?.element,W=KX0("item",H);if(W.widget==="object"&&W.fields)return{...X,widget:"list",fields:W.fields};return{...X,widget:"list",field:{name:A,label:qb(A),widget:W.widget}}}case"object":{let H=Object.entries(D3w(w)??{}).map(([W,K])=>KX0(W,K));return{...X,widget:"object",fields:H}}case"literal":return{...X,widget:"string"};default:return{...X,widget:"string"}}}function B12(A){return`<!doctype html>
|
|
7622
7622
|
<html lang="en" data-climate="paper">
|
|
7623
7623
|
<head>
|
|
7624
7624
|
<meta charset="utf-8" />
|
|
@@ -7674,7 +7674,7 @@ ${RC}
|
|
|
7674
7674
|
<script type="module" src="${A.assetPath}"></script>
|
|
7675
7675
|
</body>
|
|
7676
7676
|
</html>`}var q3w=z3w(import.meta.dir,"..","dist","ui","cms-app.js"),V3w=Z.object({entityType:Z.string(),id:Z.string(),frontmatter:Z.record(Z.string(),Z.unknown()),body:Z.string().optional(),baseContentHash:Z.string().optional()}),b3w=Z.object({entityType:Z.string(),frontmatter:Z.record(Z.string(),Z.unknown()),body:Z.string().optional()}),J3w=Z.object({entityType:Z.string(),instruction:Z.string().trim().min(1),selection:Z.string().min(1).max(8000),body:Z.string(),frontmatter:Z.record(Z.string(),Z.unknown())}),I3w=Z.object({suggestion:Z.string()}),F3w="file",$12=10485760,L3w=Z.object({watchEnabled:Z.boolean(),lastSync:Z.string().nullable(),git:Z.object({branch:Z.string(),hasChanges:Z.boolean(),ahead:Z.number(),behind:Z.number(),lastCommit:Z.string().nullable(),remote:Z.string().nullable()}).nullable()});function f12(A){let{routePath:Q,getContext:w,resolveOperatorSession:B,getEntityDisplay:$}=A,f=`${Q}/assets/app.js`,Y=(H)=>`${Q}/api/${H}`,X=async(H)=>await B(H)?null:Tw({error:"Operator session required"},401);return[{path:Q,method:"GET",public:!0,handler:async(H)=>{if(!await B(H))return new Response(null,{status:302,headers:{Location:`/login?return_to=${encodeURIComponent(Q)}`,"Cache-Control":"no-store"}});return new Response(B12({assetPath:f,surfaces:SI(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:f,method:"GET",public:!0,handler:async()=>{let H=Bun.file(q3w);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 X(H);if(W)return W;return _3w(w(),$())}},{path:Y("schema"),method:"GET",public:!0,handler:async(H)=>{let W=await X(H);if(W)return W;return N3w(w(),H)}},{path:Y("entities"),method:"GET",public:!0,handler:async(H)=>{let W=await X(H);if(W)return W;return j3w(w(),H)}},{path:Y("entities"),method:"PUT",public:!0,handler:async(H)=>{let W=await X(H);if(W)return W;return P3w(w(),H)}},{path:Y("entities"),method:"POST",public:!0,handler:async(H)=>{let W=await X(H);if(W)return W;return M3w(w(),H)}},{path:Y("entities"),method:"DELETE",public:!0,handler:async(H)=>{let W=await X(H);if(W)return W;return O3w(w(),H)}},{path:Y("upload"),method:"POST",public:!0,handler:async(H)=>{let W=await X(H);if(W)return W;return v3w(w(),H,Y("upload"))}},{path:Y("assist"),method:"POST",public:!0,handler:async(H)=>{let W=await X(H);if(W)return W;return x3w(w(),H)}},{path:Y("sync-status"),method:"GET",public:!0,handler:async(H)=>{let W=await X(H);if(W)return W;return k3w(w())}}]}async function k3w(A){let Q={directorySync:null,git:null},w=await A.messaging.send({type:"sync:status:request",payload:{}});if(!("success"in w)||!w.success)return Tw(Q);let B=L3w.safeParse(w.data);if(!B.success)return Tw(Q);return Tw({directorySync:{lastSync:B.data.lastSync,watching:B.data.watchEnabled},git:B.data.git})}async function _3w(A,Q){let w=new Map((await A.entityService.getEntityCounts()).map(($)=>[$.entityType,$.count])),B=A.entityService.getEntityTypes().flatMap(($)=>{if(!A.entities.getEffectiveFrontmatterSchema($))return[];let Y=A.entities.getAdapter($);return[{entityType:$,label:Q12($,Q?.[$]).pluralLabel,isSingleton:Y?.isSingleton===!0,hasBody:Y?.hasBody!==!1,count:w.get($)??0}]});return Tw({types:B})}function N3w(A,Q){let w=new URL(Q.url).searchParams.get("type");if(!w)return Tw({error:"type query parameter is required"},400);let B=A.entities.getEffectiveFrontmatterSchema(w);if(!B)return Tw({error:`Unknown entity type: ${w}`},404);let $=A.entities.getAdapter(w),f=ho(w),Y=f?[]:Object.entries(B.shape).map(([X,H])=>KX0(X,H));return Tw({entityType:w,format:f?"raw":"frontmatter",isSingleton:$?.isSingleton===!0,hasBody:f||$?.hasBody!==!1,fields:Y})}async function j3w(A,Q){let w=new URL(Q.url).searchParams,B=w.get("type");if(!B)return Tw({error:"type query parameter is required"},400);if(!A.entities.getEffectiveFrontmatterSchema(B))return Tw({error:`Unknown entity type: ${B}`},404);let $=w.get("id");if($){let Y=await A.entityService.getEntity({entityType:B,id:$});if(!Y)return Tw({error:`Entity not found: ${$}`},404);let{frontmatter:X,body:H}=Qa0(B,Y.content);return Tw({entity:{id:Y.id,entityType:Y.entityType,frontmatter:X,body:H,contentHash:Y.contentHash,created:Y.created,updated:Y.updated}})}let f=await A.entityService.listEntities({entityType:B});return Tw({entities:f.map((Y)=>({id:Y.id,entityType:Y.entityType,frontmatter:Qa0(B,Y.content).frontmatter,updated:Y.updated}))})}async function P3w(A,Q){let w;try{w=V3w.parse(await Q.json())}catch{return Tw({error:"Invalid update payload"},400)}let{entityType:B,id:$}=w,f=A.entities.getEffectiveFrontmatterSchema(B);if(!f)return Tw({error:`Unknown entity type: ${B}`},404);let Y=Y12(A,B,w.body);if(Y)return Y;let X=ho(B);if(X&&Object.keys(w.frontmatter).length>0)return Tw({error:`Entity type ${B} is raw markdown without frontmatter`},400);let H=X?{success:!0,data:{}}:f.safeParse(w.frontmatter);if(!H.success)return Tw({error:"Invalid frontmatter",issues:H.error.issues},400);let W=await A.entityService.getEntity({entityType:B,id:$});if(!W)return Tw({error:`Entity not found: ${$}`},404);if(w.baseContentHash!==void 0&&w.baseContentHash!==W.contentHash)return Tw({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??Qa0(B,W.content).body,U=X?K:V8(K,H.data),G=A.entities.getAdapter(B)?.fromMarkdown(U),q={...W,...G,id:W.id,entityType:W.entityType,content:U},V=await A.entityService.updateEntity({entity:q});return Tw({entityId:V.entityId,jobId:V.jobId,skipped:V.skipped})}async function M3w(A,Q){let w;try{w=b3w.parse(await Q.json())}catch{return Tw({error:"Invalid create payload"},400)}let{entityType:B}=w,$=A.entities.getEffectiveFrontmatterSchema(B);if(!$)return Tw({error:`Unknown entity type: ${B}`},404);let f=Y12(A,B,w.body);if(f)return f;let Y=ho(B);if(Y&&Object.keys(w.frontmatter).length>0)return Tw({error:`Entity type ${B} is raw markdown without frontmatter`},400);let X=Y?{success:!0,data:{}}:$.safeParse(w.frontmatter);if(!X.success)return Tw({error:"Invalid frontmatter",issues:X.error.issues},400);let H=Y?w.body??"":V8(w.body??"",X.data),W=A.entities.getAdapter(B)?.fromMarkdown(H),K=await A.entityService.createEntity({entity:{...W,entityType:B,content:H,metadata:W?.metadata??{}}});return Tw({entityId:K.entityId,jobId:K.jobId},201)}async function O3w(A,Q){let w=new URL(Q.url).searchParams,B=w.get("type"),$=w.get("id");if(!B||!$)return Tw({error:"type and id query parameters are required"},400);if(!await A.entityService.getEntity({entityType:B,id:$}))return Tw({error:`Entity not found: ${$}`},404);let Y=await A.entityService.deleteEntity({entityType:B,id:$});return Tw({deleted:Y})}async function x3w(A,Q){let w;try{w=J3w.parse(await Q.json())}catch{return Tw({error:"Invalid assist payload or selection length"},400)}if(!A.entities.getEffectiveFrontmatterSchema(w.entityType))return Tw({error:`Unknown entity type: ${w.entityType}`},404);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(`
|
|
7677
|
-
`),{object:$}=await A.ai.generateObject(B,I3w);return Tw({suggestion:$.suggestion})}async function v3w(A,Q,w){let B=Number(Q.headers.get("content-length"));if(Number.isFinite(B)&&B>$12)return Tw({error:"Upload too large"},400);let $;try{$=await Q.formData()}catch{return Tw({error:"Invalid multipart upload"},400)}let f=$.get(F3w);if(!(f instanceof File))return Tw({error:"Missing upload file"},400);if(f.size>$12)return Tw({error:"Upload too large"},400);let Y=A.entities.getUploadSaveHandler(f.type);if(!Y)return Tw({error:`No handler accepts uploads of type ${f.type}`},415);let H=await A.uploads.scoped({namespace:"upload",refKind:"upload",routePath:w}).save({filename:f.name,mediaType:f.type,content:Buffer.from(await f.arrayBuffer())}),W=await Y.handler({upload:{kind:"upload",id:H.id}},{interfaceType:"cms",userId:"operator"});if(!W.success)return Tw({error:W.error},502);return Tw({entityId:W.data.entityId,jobId:W.data.jobId},201)}function Y12(A,Q,w){if(w===void 0)return null;if(A.entities.getAdapter(Q)?.hasBody===!1)return Tw({error:`Entity type ${Q} does not have a body`},400);return null}function Qa0(A,Q){if(ho(A))return{frontmatter:{},body:Q};try{let w=n2(Q,Z.record(Z.string(),Z.unknown()));return{frontmatter:w.metadata,body:w.content}}catch{return{frontmatter:{},body:Q}}}function Tw(A,Q=200){return new Response(JSON.stringify(A),{status:Q,headers:{"Content-Type":"application/json; charset=utf-8","Cache-Control":"no-store"}})}var X12={name:"@brains/cms",version:"0.2.0-alpha.
|
|
7677
|
+
`),{object:$}=await A.ai.generateObject(B,I3w);return Tw({suggestion:$.suggestion})}async function v3w(A,Q,w){let B=Number(Q.headers.get("content-length"));if(Number.isFinite(B)&&B>$12)return Tw({error:"Upload too large"},400);let $;try{$=await Q.formData()}catch{return Tw({error:"Invalid multipart upload"},400)}let f=$.get(F3w);if(!(f instanceof File))return Tw({error:"Missing upload file"},400);if(f.size>$12)return Tw({error:"Upload too large"},400);let Y=A.entities.getUploadSaveHandler(f.type);if(!Y)return Tw({error:`No handler accepts uploads of type ${f.type}`},415);let H=await A.uploads.scoped({namespace:"upload",refKind:"upload",routePath:w}).save({filename:f.name,mediaType:f.type,content:Buffer.from(await f.arrayBuffer())}),W=await Y.handler({upload:{kind:"upload",id:H.id}},{interfaceType:"cms",userId:"operator"});if(!W.success)return Tw({error:W.error},502);return Tw({entityId:W.data.entityId,jobId:W.data.jobId},201)}function Y12(A,Q,w){if(w===void 0)return null;if(A.entities.getAdapter(Q)?.hasBody===!1)return Tw({error:`Entity type ${Q} does not have a body`},400);return null}function Qa0(A,Q){if(ho(A))return{frontmatter:{},body:Q};try{let w=n2(Q,Z.record(Z.string(),Z.unknown()));return{frontmatter:w.metadata,body:w.content}}catch{return{frontmatter:{},body:Q}}}function Tw(A,Q=200){return new Response(JSON.stringify(A),{status:Q,headers:{"Content-Type":"application/json; charset=utf-8","Cache-Control":"no-store"}})}var X12={name:"@brains/cms",version:"0.2.0-alpha.151",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/state":"^6.7.1","@codemirror/view":"^6.43.6",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 h3w=Z.looseObject({label:Z.string().optional(),pluralName:Z.string().optional()}),C3w=Z.object({entityDisplay:Z.record(Z.string(),h3w).optional(),routePath:Z.string().default("/cms")});class wa0 extends tQ{constructor(A={}){super("cms",X12,A,C3w)}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 f12({routePath:this.config.routePath,getContext:()=>this.getContext(),resolveOperatorSession:g3w,getEntityDisplay:()=>this.config.entityDisplay??this.getContext().entityDisplay})}}function UP(A={}){return new wa0(A)}async function g3w(A){return Boolean(await M7()?.getOperatorSession(A))}wA();_0();wA();_0();var UX0=["StatsWidget","ListWidget","CustomWidget","PipelineWidget","IdentityWidget","ProfileWidget","SystemWidget"],y3w=new Set(UX0),E3w=Z.enum(["public","trusted","anchor"]);function Ba0(A){return y3w.has(A)}var Z12=Z.object({label:Z.string(),value:Z.string(),tone:Z.enum(["plain","good","warn"]).optional()}),H12=Z.object({id:Z.string(),pluginId:Z.string(),title:Z.string(),description:Z.string().optional(),group:Z.string().min(1),priority:Z.number().default(50),section:Z.enum(["primary","secondary","sidebar"]).default("primary"),rendererName:Z.string(),visibility:E3w.default("public"),needsOperator:Z.number().int().nonnegative().optional(),digest:Z.array(Z12).max(4).optional()});class GX0{widgets=new Map;logger;constructor(A){this.logger=A.child("DashboardWidgetRegistry")}register(A){let w={...H12.parse(A),dataProvider:A.dataProvider,...A.digestProvider?{digestProvider:A.digestProvider}:{},...A.component?{component:A.component}:{},...A.clientScript?{clientScript:A.clientScript}:{}},B=`${w.pluginId}:${w.id}`;this.widgets.set(B,w),this.logger.debug("Dashboard widget registered",{key:B,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((B)=>!Q.section||B.section===Q.section).filter((B)=>B9.hasPermission(w,B.visibility)).sort((B,$)=>B.priority-$.priority)}get size(){return this.widgets.size}}class DX0{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}}),B=await Promise.allSettled(w.map(async($)=>{let f=await $.dataProvider(),{dataProvider:Y,digestProvider:X,component:H,clientScript:W,visibility:K="public",...U}=$;return{key:`${$.pluginId}:${$.id}`,widget:{...U,visibility:K,...this.deriveLiveDigest($,f)},data:f}}));for(let $=0;$<B.length;$++){let f=B[$],Y=w[$];if(!f||!Y)continue;if(f.status==="fulfilled")Q[f.value.key]={widget:f.value.widget,data:f.value.data};else this.logger.error("Widget data provider failed",{widgetId:Y.id,pluginId:Y.pluginId,error:SA(f.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:SA(w)}),{}}}async fetch(A,Q,w){return await this.getDashboardData()}}import{render as Vzw}from"preact-render-to-string";var W12=`* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
7678
7678
|
html, body { min-height: 100%; max-width: 100%; }
|
|
7679
7679
|
body {
|
|
7680
7680
|
font-family: var(--console-ui);
|
|
@@ -9332,7 +9332,7 @@ ${K12}`;import{jsxDEV as vF,Fragment as G12}from"preact/jsx-dev-runtime";functio
|
|
|
9332
9332
|
activate(resolveId(window.location.hash), false);
|
|
9333
9333
|
});
|
|
9334
9334
|
})();`;function _zw({hiddenWidgetCount:A,loginUrl:Q}){return VA("section",{class:"card operator-gate",children:[VA("div",{children:[VA("div",{class:"card-title",children:"Operator access"},void 0,!1,void 0,this),VA("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),VA("a",{class:"operator-gate-link",href:Q,children:"Sign in"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function Nzw({dashboardPath:A,surfaces:Q,operatorAccess:w}){let B=w?.isOperator?w.logoutUrl:w?.loginUrl??"/login",$=w?.isOperator?"Operator":"Visitor",f=w?.isOperator?"Sign out":"Sign in";return VA("header",{class:"console-strip","aria-label":"Operator surfaces",children:[VA("a",{class:"console-mark",href:A,"aria-label":"Dashboard home",children:[VA("span",{class:"pulse"},void 0,!1,void 0,this),VA("span",{children:["Brain"," ",VA("span",{class:"console-mark-long",children:["\xB7 ",VA("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),VA("nav",{class:"surface-nav","aria-label":"Console surfaces",children:Q.map((Y)=>VA("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),VA("button",{class:"command-chip",type:"button","aria-label":"Search or jump",children:[VA("span",{class:"command-chip-hint",children:"Search or jump\u2026"},void 0,!1,void 0,this),VA("kbd",{children:"\u2318K"},void 0,!1,void 0,this),VA("span",{class:"command-chip-icon","aria-hidden":"true",children:"\u2315"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),VA("a",{class:"session-chip",href:B,"aria-label":`${$} \xB7 ${f}`,children:[VA("span",{children:$},void 0,!1,void 0,this),VA("strong",{children:f},void 0,!1,void 0,this),VA("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 jzw({tabs:A}){return VA("nav",{class:"dashboard-tabs","aria-label":"Dashboard sections",role:"tablist",children:[VA("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)=>VA("a",{class:"dashboard-tab",href:`#${Q.id}`,role:"tab","aria-selected":"false","data-dashboard-tab-link":Q.id,children:[VA("span",{children:Q.label},void 0,!1,void 0,this),Q.needsOperator>0?VA("span",{class:"tab-badge tab-badge--needs",children:Q.needsOperator},void 0,!1,void 0,this):Q.widgetCount>0?VA("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 Za0(A){return A.indexStatus?.ready??A.indexReady??A.appInfo.embeddings>0}function Pzw({input:A}){let Q=Za0(A),w=A.activityLog?.[0],B=A.appInfo.entityCounts.length,$=A.appInfo.interactions.map((U)=>U.id).slice(0,3).join(" / "),f=A.indexStatus?.embeddedEntities??A.appInfo.embeddings,Y=A.indexStatus?.embeddableEntities,X=A.indexStatus?(A.indexStatus.activeEmbeddingJobs??0)+(A.indexStatus.missingEmbeddings??0)+(A.indexStatus.staleEmbeddings??0):0,H=Y===void 0?`${f}`:`${f}/${Y}`,W=X>0?`${H} embedded \xB7 ${X} queued`:`${H} embedded`,K=(A.jobProgress??[]).some((U)=>U.status==="processing"||U.status==="pending");return VA("section",{class:"overview-vitals","aria-label":"Runtime vitals",children:[VA("article",{class:"vital-card",children:[VA("span",{class:"vital-label",children:"Entities"},void 0,!1,void 0,this),VA("strong",{class:"vital-num",children:A.appInfo.entities},void 0,!1,void 0,this),VA("span",{class:"vital-sub",children:B===1?"1 type":`${B} types`},void 0,!1,void 0,this)]},void 0,!0,void 0,this),VA("article",{class:"vital-card",children:[VA("span",{class:"vital-label",children:"Interactions"},void 0,!1,void 0,this),VA("strong",{class:"vital-num",children:A.appInfo.interactions.length},void 0,!1,void 0,this),VA("span",{class:"vital-sub",children:$||"no channels"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),VA("article",{class:`vital-card ${Q?"vital-card--ok":"vital-card--warm"}`,children:[VA("span",{class:"vital-label",children:"Semantic index"},void 0,!1,void 0,this),VA("strong",{class:"vital-num vital-num--text",children:Q?"Ready":"Pending"},void 0,!1,void 0,this),VA("span",{class:"vital-sub",children:W},void 0,!1,void 0,this)]},void 0,!0,void 0,this),VA("article",{class:`vital-card${K?" vital-card--warm":""}`,children:[VA("span",{class:"vital-label",children:"Last write"},void 0,!1,void 0,this),VA("strong",{class:"vital-num vital-num--text",children:w?Ha0(w.timestamp):"\u2014"},void 0,!1,void 0,this),VA("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 Mzw({input:A}){let{role:Q,purpose:w,values:B}=A.character;if(!Q&&!w&&B.length===0)return null;return VA("aside",{class:"card identity-capsule",children:[VA("div",{class:"card-head",children:[VA("span",{class:"card-title",children:"Identity"},void 0,!1,void 0,this),VA("span",{class:"card-from",children:"identity"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),VA("div",{class:"identity-capsule-body",children:[Q&&VA("span",{class:"identity-role",children:["\u201C",Q,"\u201D"]},void 0,!0,void 0,this),B.length>0&&VA("span",{class:"values",children:B.map(($)=>VA("span",{class:"value",children:$},$,!1,void 0,this))},void 0,!1,void 0,this),w&&VA("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 Ozw({cards:A}){if(A.length===0)return VA("section",{class:"card overview-empty-digest",children:[VA("div",{class:"card-head",children:VA("span",{class:"card-title",children:"Group digests"},void 0,!1,void 0,this)},void 0,!1,void 0,this),VA("p",{class:"muted",children:"No plugin groups are visible yet."},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return VA("section",{class:"digests","aria-label":"Group digests",children:A.map((Q)=>VA("a",{class:"card digest-card",href:Q.href,children:[VA("div",{class:"digest-head",children:[VA("h4",{children:Q.label},void 0,!1,void 0,this),VA("span",{class:"digest-go",children:"open \u2192"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),VA("dl",{class:"digest-lines",children:Q.lines.map((w)=>VA("div",{class:`digest-line digest-line--${w.tone??"plain"}`,children:[VA("dt",{children:w.label},void 0,!1,void 0,this),VA("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 xzw(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 Ha0(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 L12={created:{glyph:"\uFF0B",tone:""},updated:{glyph:"\u2713",tone:" ledger-glyph--ok"},deleted:{glyph:"\u2212",tone:" ledger-glyph--warn"}};function vzw({events:A}){return VA("section",{class:"card activity-ledger",children:[VA("div",{class:"card-head",children:[VA("span",{class:"card-title",children:"Activity"},void 0,!1,void 0,this),VA("span",{class:"card-from",children:"entity events"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.length===0?VA("p",{class:"muted",children:"No entity activity has been observed this session."},void 0,!1,void 0,this):VA("ol",{class:"ledger",children:A.map((Q)=>VA("li",{class:"ledger-entry",children:[VA("time",{class:"ledger-time",dateTime:Q.timestamp,children:Ha0(Q.timestamp)},void 0,!1,void 0,this),VA("span",{class:`ledger-glyph${L12[Q.action].tone}`,"aria-hidden":"true",children:L12[Q.action].glyph},void 0,!1,void 0,this),VA("span",{class:"ledger-what",children:[VA("b",{children:Q.entityType},void 0,!1,void 0,this)," ",Q.action," \u2014"," ",VA("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 Rzw(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 hzw(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 Czw({status:A}){let Q=Rzw(A),w=A.ready?A.degraded?"Degraded":"Ready":"Indexing";return VA("div",{class:"index-gauge",style:`--index-percent: ${Q}%`,children:[VA("div",{class:"index-gauge-ring","aria-hidden":"true",children:VA("span",{children:[Q,"%"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),VA("div",{class:"index-gauge-copy",children:[VA("strong",{children:w},void 0,!1,void 0,this),VA("span",{children:hzw(A)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}function gzw({input:A}){let Q=Za0(A);return VA("section",{class:"card semantic-index-card",children:[VA("div",{class:"card-head",children:[VA("span",{class:"card-title",children:"Semantic index"},void 0,!1,void 0,this),VA("span",{class:"card-from",children:"entity-service"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.indexStatus?VA(Czw,{status:A.indexStatus},void 0,!1,void 0,this):VA("dl",{class:"kv",children:VA("div",{class:"kv-row",children:[VA("dt",{children:"Semantic index"},void 0,!1,void 0,this),VA("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 yzw({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 VA("section",{class:"card content-sync-card",children:[VA("div",{class:"card-head",children:[VA("span",{class:"card-title",children:"Content sync"},void 0,!1,void 0,this),VA("span",{class:"card-from",children:"directory-sync"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),VA("dl",{class:"kv",children:[VA("div",{class:"kv-row",children:[VA("dt",{children:"Path"},void 0,!1,void 0,this),VA("dd",{children:A.syncPath},void 0,!1,void 0,this)]},void 0,!0,void 0,this),VA("div",{class:"kv-row",children:[VA("dt",{children:"Files"},void 0,!1,void 0,this),VA("dd",{children:w?`${Q} \xB7 ${w}`:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this),VA("div",{class:"kv-row",children:[VA("dt",{children:"Watch"},void 0,!1,void 0,this),VA("dd",{children:A.watchEnabled?"Watching":A.isInitialized?"Manual":"Not initialized"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),VA("div",{class:"kv-row",children:[VA("dt",{children:"Last sync"},void 0,!1,void 0,this),VA("dd",{children:A.lastSync?`last sync ${xzw(A.lastSync)}`:"\u2014"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),VA("div",{class:"pipeline-mini","aria-label":"Write pipeline",children:[VA("span",{class:`pipeline-step${A.isInitialized?" is-done":""}`,children:"entity db"},void 0,!1,void 0,this),VA("span",{class:"pipeline-track"},void 0,!1,void 0,this),VA("span",{class:`pipeline-step${(A.totalFiles??0)>0?" is-done":""}`,children:"exported"},void 0,!1,void 0,this),VA("span",{class:"pipeline-track"},void 0,!1,void 0,this),VA("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 Ezw={pending:"run",processing:"run",completed:"done",failed:"fail"},Tzw={pending:"pending",processing:"running",completed:"done",failed:"failed"};function Szw({jobs:A}){return VA("section",{class:"card widget-card--wide job-queue-card",children:[VA("div",{class:"card-head",children:[VA("span",{class:"card-title",children:"Job queue"},void 0,!1,void 0,this),VA("span",{class:"card-from",children:"job-queue"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.length===0?VA("p",{class:"muted",children:"No recent job progress observed."},void 0,!1,void 0,this):VA("table",{class:"jobs",children:[VA("thead",{children:VA("tr",{children:[VA("th",{children:"Job"},void 0,!1,void 0,this),VA("th",{children:"Type"},void 0,!1,void 0,this),VA("th",{children:"Updated"},void 0,!1,void 0,this),VA("th",{children:"Status"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),VA("tbody",{children:A.map((Q)=>VA("tr",{children:[VA("td",{class:"mono",children:Q.id.slice(0,8)},void 0,!1,void 0,this),VA("td",{children:Q.jobType??Q.kind},void 0,!1,void 0,this),VA("td",{class:"mono",children:Ha0(Q.updatedAt)},void 0,!1,void 0,this),VA("td",{children:VA("span",{class:`status-pill status-pill--${Ezw[Q.status]}`,children:[Tzw[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 mzw({input:A,tabs:Q,showOperatorGate:w}){let B=Izw(Q,A),$=A.activityLog??[];return VA("section",{id:"overview",class:"dashboard-tab-panel is-active","data-dashboard-tab-panel":!0,"aria-labelledby":"dashboard-tab-overview",children:[VA(Pzw,{input:A},void 0,!1,void 0,this),VA(Mzw,{input:A},void 0,!1,void 0,this),w&&A.operatorAccess&&VA(_zw,{hiddenWidgetCount:A.operatorAccess.hiddenWidgetCount,loginUrl:A.operatorAccess.loginUrl},void 0,!1,void 0,this),VA("div",{class:"overview-grid",children:[VA(Ozw,{cards:B},void 0,!1,void 0,this),VA(vzw,{events:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}function uzw({tab:A,input:Q,now:w}){let B=[...A.widgets.primary,...A.widgets.secondary],$=A.group==="system",f=A.group==="knowledge",Y=A.widgets.sidebar.length>0||$;return VA("section",{id:A.id,class:"dashboard-tab-panel","data-dashboard-tab-panel":!0,"data-dashboard-group":A.group,children:[VA("header",{class:"tab-section-head",children:VA("h2",{children:A.label},void 0,!1,void 0,this)},void 0,!1,void 0,this),VA("div",{class:`layout tab-layout${Y?"":" tab-layout--main-only"}`,children:[VA("div",{class:"main-column",children:[f&&VA(z12,{total:Q.appInfo.entities,entityCounts:Q.appInfo.entityCounts},void 0,!1,void 0,this),$&&VA(k12,{children:[VA(gzw,{input:Q},void 0,!1,void 0,this),Q.directorySyncStatus&&VA(yzw,{status:Q.directorySyncStatus},void 0,!1,void 0,this),VA(Szw,{jobs:Q.jobProgress??[]},void 0,!1,void 0,this)]},void 0,!0,void 0,this),B.map((X)=>VA(fa0,{widget:X},`${X.widget.pluginId}:${X.widget.id}`,!1,void 0,this))]},void 0,!0,void 0,this),Y&&VA("div",{class:"sidebar-column",children:[$&&VA(k12,{children:[VA(q12,{endpoints:Q.appInfo.endpoints,baseUrl:Q.baseUrl},void 0,!1,void 0,this),VA(I12,{appInfo:Q.appInfo,now:w},void 0,!1,void 0,this),VA(V12,{interactions:Q.appInfo.interactions,baseUrl:Q.baseUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.widgets.sidebar.map((X)=>VA(fa0,{widget:X},`${X.widget.pluginId}:${X.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 czw({input:A}){let Q=Lzw(A.widgets),w=A.operatorAccess&&!A.operatorAccess.isOperator&&A.operatorAccess.hiddenWidgetCount>0,B=A.dashboardPath??"/dashboard",$=new Date;return VA("html",{lang:"en","data-climate":"instrument",children:[VA("head",{children:[VA("meta",{charSet:"utf-8"},void 0,!1,void 0,this),VA("meta",{name:"viewport",content:"width=device-width, initial-scale=1.0, viewport-fit=cover"},void 0,!1,void 0,this),VA("title",{children:A.title},void 0,!1,void 0,this),VA("link",{rel:"preconnect",href:"https://fonts.googleapis.com"},void 0,!1,void 0,this),VA("link",{rel:"preconnect",href:"https://fonts.gstatic.com",crossOrigin:"anonymous"},void 0,!1,void 0,this),VA("link",{href:Rd,rel:"stylesheet"},void 0,!1,void 0,this),A.themeCSS!==void 0&&VA("style",{"data-dashboard-theme":!0,dangerouslySetInnerHTML:{__html:A.themeCSS}},void 0,!1,void 0,this),VA("style",{"data-dashboard-styles":!0,dangerouslySetInnerHTML:{__html:U12}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),VA("body",{children:[VA(Nzw,{dashboardPath:B,surfaces:A.surfaces??[{id:"dashboard",label:"Dashboard",href:B,isActive:!0}],operatorAccess:A.operatorAccess},void 0,!1,void 0,this),VA("main",{class:"console","data-component":"dashboard:dashboard",children:[VA("div",{class:"frame",children:[VA(D12,{title:A.title,tagline:A.profile.description},void 0,!1,void 0,this),VA(jzw,{tabs:Q},void 0,!1,void 0,this),VA("div",{class:"canvas",children:VA("div",{class:"dashboard-tab-panels",children:[VA(mzw,{input:A,tabs:Q,showOperatorGate:Boolean(w)},void 0,!1,void 0,this),Q.map((f)=>VA(uzw,{tab:f,input:A,now:$},f.id,!1,void 0,this))]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),VA(F12,{title:A.title,appInfo:A.appInfo,baseUrl:A.baseUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this),VA("script",{dangerouslySetInnerHTML:{__html:tN}},void 0,!1,void 0,this),VA("script",{dangerouslySetInnerHTML:{__html:eN}},void 0,!1,void 0,this),VA("script",{dangerouslySetInnerHTML:{__html:kzw}},void 0,!1,void 0,this),A.widgetScripts.map((f,Y)=>VA("script",{dangerouslySetInnerHTML:{__html:f}},`widget-script:${Y}`,!1,void 0,this))]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}function N12(A){return`<!doctype html>
|
|
9335
|
-
${Vzw(VA(czw,{input:A},void 0,!1,void 0,this))}`}function lzw(A){return A.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"group"}function j12(A){let Q=A.query.trim().toLowerCase(),w=[];if(A.cmsPath!==void 0&&A.entities.length>0){let $=A.cmsPath;w.push({id:"entities",label:"Entities",items:A.entities.map((f)=>({id:`${f.entityType}/${f.id}`,title:f.title,sub:f.entityType,href:`${$}#/${encodeURIComponent(f.entityType)}/${encodeURIComponent(f.id)}`,tag:"edit in cms"}))})}let B=qX0([...new Set(A.groups)]).map(($)=>({group:$,label:Ny($)})).filter(({group:$,label:f})=>Q===""||f.toLowerCase().includes(Q)||$.toLowerCase().includes(Q)).map(({group:$,label:f})=>({id:`tab/${$}`,title:f,sub:"tab",href:`${A.dashboardPath}#${lzw($)}`,tag:"dashboard"}));if(B.length>0)w.push({id:"tabs",label:"Dashboard",items:B});return w}function P12(A,Q){let w={},B=new Set;for(let[$,f]of Object.entries(A)){let Y=Q?.get(f.widget.pluginId,f.widget.id);if(w[$]={...f,...Y?.component?{component:Y.component}:{}},Y?.clientScript)B.add(Y.clientScript)}return{widgets:w,widgetScripts:Array.from(B)}}var M12={name:"@brains/dashboard",version:"0.2.0-alpha.150",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:"^6.0.3"},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 izw=Z.object({version:Z.string().default("1.0.0"),routePath:Z.string().default("/dashboard"),themeCSS:Z.string().optional()}),dzw=Z.object({id:Z.string(),pluginId:Z.string(),title:Z.string(),description:Z.string().optional(),group:Z.string().min(1),priority:Z.number().default(50),section:Z.enum(["primary","secondary","sidebar"]).default("primary"),rendererName:Z.string(),visibility:Z.enum(["public","trusted","anchor"]).default("public"),needsOperator:Z.number().int().nonnegative().optional(),digest:Z.array(Z.object({label:Z.string(),value:Z.string(),tone:Z.enum(["plain","good","warn"]).optional()})).max(4).optional(),component:Z.custom().optional(),clientScript:Z.string().optional(),dataProvider:Z.custom((A)=>typeof A==="function",{message:"Expected dashboard widget data provider function"}),digestProvider:Z.custom((A)=>typeof A==="function",{message:"Expected dashboard widget digest provider function"}).optional()}).superRefine((A,Q)=>{if(!Ba0(A.rendererName)&&!A.component)Q.addIssue({code:"custom",message:"Custom dashboard widgets must register a Preact component.",path:["component"]})}),nzw=Z.object({pluginId:Z.string(),widgetId:Z.string().optional()}),rzw=Z.object({entityType:Z.string(),entityId:Z.string(),conversationId:Z.string().optional()}),ozw=Z.object({id:Z.string(),type:Z.enum(["job","batch"]),status:Z.enum(["pending","processing","completed","failed"]),message:Z.string().optional(),progress:Z.object({current:Z.number(),total:Z.number(),percentage:Z.number()}).optional(),jobDetails:Z.object({jobType:Z.string(),priority:Z.number(),retryCount:Z.number()}).optional()}),szw=Z.object({success:Z.literal(!0),data:Z.object({syncPath:Z.string(),isInitialized:Z.boolean(),watchEnabled:Z.boolean(),lastSync:Z.string().datetime().optional(),totalFiles:Z.number().int().nonnegative().optional(),byEntityType:Z.record(Z.string(),Z.number().int().nonnegative()).optional()})});function azw(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 Wa0 extends tQ{widgetRegistry=null;datasource=null;siteUrl;ctx;activityLog=[];jobProgress=[];constructor(A={}){super("dashboard",M12,A,izw)}recordActivity(A,Q){let w=rzw.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=ozw.safeParse(A);if(!Q.success)return;let w=Q.data.progress?`${Q.data.progress.current}/${Q.data.progress.total}`:void 0,B={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=[B,...this.jobProgress.filter(($)=>$.id!==B.id||$.kind!==B.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:SA(Q)})}return}async getDirectorySyncStatus(){if(!this.ctx)return;try{let A=await this.ctx.messaging.send({type:"sync:status:request",payload:{}}),Q=szw.safeParse(A);return Q.success?Q.data.data:void 0}catch(A){this.logger.debug("Directory sync status unavailable",{error:SA(A)});return}}async onRegister(A){this.siteUrl=A.siteUrl,this.ctx=A,this.widgetRegistry=new GX0(this.logger),this.datasource=new DX0(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=dzw.parse(Q.payload),B=azw(w);return this.widgetRegistry?.register(B),this.logger.debug("Widget registered via messaging",{widgetId:w.id,pluginId:w.pluginId,rendererName:w.rendererName,builtIn:UX0.includes(w.rendererName)}),{success:!0}}catch(w){return this.logger.error("Failed to register widget",{error:SA(w),payload:Q.payload}),{success:!1,error:"Widget registration failed"}}}),A.messaging.subscribe("dashboard:unregister-widget",async(Q)=>{try{let w=nzw.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:SA(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 M7()?.getOperatorSession(A),B=Boolean(w),$=B?"anchor":"public",f=this.widgetRegistry?.list({permissionLevel:"anchor"})??[],Y=f.filter((h)=>B9.hasPermission($,h.visibility)),X=f.length-Y.length,[H,W,K,U]=await Promise.all([this.datasource.getDashboardData({permissionLevel:$,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}})(),J={...W,endpoints:W.endpoints.filter((h)=>B9.hasPermission($,h.visibility)),interactions:W.interactions.filter((h)=>B9.hasPermission($,h.visibility))},b=q.name||W.model||"Brain Dashboard",L=new URL(A.url),N=`${L.pathname}${L.search}`,k=encodeURIComponent(N),x=P12(H.widgets,this.widgetRegistry),v={title:b,baseUrl:V,widgets:x.widgets,widgetScripts:x.widgetScripts,dashboardPath:this.config.routePath,surfaces:SI(Q.webRoutes.getRoutes(),{activeId:"dashboard",self:{id:"dashboard",href:this.config.routePath}}),character:G,profile:q,appInfo:J,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:B,hiddenWidgetCount:X,loginUrl:`/login?return_to=${k}`,logoutUrl:`/logout?return_to=${k}`}};return new Response(N12(v),{headers:{"Content-Type":"text/html; charset=utf-8"}})}},{path:"/api/console/jump",method:"GET",public:!0,handler:async(A)=>{if(!await M7()?.getOperatorSession(A))return Response.json({error:"Operator session required"},{status:401});let w=this.ctx;if(!w)return Response.json({groups:[]});let B=new URL(A.url).searchParams.get("q")?.trim()??"",$=[];if(B.length>=2)try{$=(await w.entityService.search({query:B,options:{limit:6}})).map((H)=>({entityType:H.entity.entityType,id:H.entity.id,title:H.entity.title??H.entity.id}))}catch{}let f=(this.widgetRegistry?.list({permissionLevel:"anchor"})??[]).map((X)=>X.group),Y=SI(w.webRoutes.getRoutes(),{activeId:"dashboard"}).find((X)=>X.id==="cms")?.href;return Response.json({groups:j12({query:B,groups:[...f,"knowledge","system"],dashboardPath:this.config.routePath,cmsPath:Y,entities:$})})}}]}async getTools(){return[]}getWidgetRegistry(){return this.widgetRegistry}}function hF(A={}){return new Wa0(A)}_0();var tzw=Z.enum(["public","trusted","anchor"]),ezw=Z.object({label:Z.string(),value:Z.string(),tone:Z.enum(["plain","good","warn"]).optional()}),Aqw=Z.object({id:Z.string(),pluginId:Z.string(),title:Z.string(),description:Z.string().optional(),group:Z.string().min(1),priority:Z.number(),section:Z.enum(["primary","secondary","sidebar"]),rendererName:Z.string(),visibility:tzw,needsOperator:Z.number().int().nonnegative().optional(),digest:Z.array(ezw).max(4).optional(),component:Z.custom().optional()}),Qqw=Z.object({widget:Aqw,data:Z.unknown()}),wqw=Z.object({widgets:Z.record(Z.string(),Qqw)});wA();_0();wA();_0();import{h as Iqw}from"preact";wA();xX();U2();_0();var VX0=Z.enum(["generating","draft","queued","published","failed"]),Bqw=Z.enum(["generating","draft","queued","published","failed"]),bX0=Z.object({subject:Z.string(),status:VX0,entityIds:Z.array(Z.string()).optional(),scheduledFor:Z.string().datetime().optional(),sentAt:Z.string().datetime().optional(),buttondownId:Z.string().optional(),sourceEntityType:Z.string().optional()}),O12=Z.object({subject:Z.string(),status:VX0,entityIds:Z.array(Z.string()).optional(),scheduledFor:Z.string().datetime().optional(),sentAt:Z.string().datetime().optional(),buttondownId:Z.string().optional(),sourceEntityType:Z.string().optional(),error:Z.string().optional()}),$qw=Z.object({subject:Z.string(),status:Bqw,entityIds:Z.array(Z.string()).optional(),scheduledFor:Z.string().datetime().optional(),sentAt:Z.string().datetime().optional(),buttondownId:Z.string().optional(),sourceEntityType:Z.string().optional(),error:Z.string().optional()}),jy=_Q.extend({entityType:Z.literal("newsletter"),metadata:$qw});wA();class x12 extends g2{constructor(){super({entityType:"newsletter",purpose:"An email newsletter issue composed for subscribers.",schema:jy,frontmatterSchema:bX0})}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 v12=new x12;wA();wA();U2();_0();var fqw=Z.looseObject({id:Z.string().optional(),limit:Z.number().optional(),page:Z.number().optional(),pageSize:Z.number().optional(),baseUrl:Z.string().optional(),status:Z.enum(["generating","draft","queued","published","failed"]).optional()}),Yqw=Z.looseObject({entityType:Z.string().optional(),query:fqw.optional()});function R12(A){try{let{content:Q}=n2(A.content,bX0);return Q}catch{return A.content}}class Ka0 extends J8{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=Yqw.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}transformEntity(A){let Q=R12(A),w={id:A.id,subject:A.metadata.subject,status:A.metadata.status,excerpt:zf(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:B}=this.parseQuery(A),$=w.entityService;if(B.id)return this.fetchSingleNewsletter(B.id,Q,$);let f=B.status,Y=f?{filter:{metadata:{status:f}}}:void 0,{items:X,pagination:H}=await this.fetchList(B,$,Y);return Q.parse(this.buildListResult(X,H,B))}async fetchSingleNewsletter(A,Q,w){let B=await w.getEntity({entityType:this.config.entityType,id:A});if(!B)throw Error(`Newsletter not found: ${A}`);let $=await this.resolveNavigation(B,w),f=[];if(B.metadata.entityIds?.length){let H=B.metadata.sourceEntityType??"post";f=(await Promise.all(B.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=R12(B),X={id:B.id,subject:B.metadata.subject,status:B.metadata.status,content:Y,created:B.created,updated:B.updated,sentAt:B.metadata.sentAt,scheduledFor:B.metadata.scheduledFor,newsletter:B,prevNewsletter:$.prev?{id:$.prev.id,subject:$.prev.subject,url:$.prev.url}:null,nextNewsletter:$.next?{id:$.next.id,subject:$.next.subject,url:$.next.url}:null,sourceEntities:f.length>0?f:void 0};return Q.parse(X)}}wA();U2();_0();var Xqw=Z.object({prompt:Z.string().optional().describe("AI generation prompt"),sourceEntityIds:Z.array(Z.string()).optional().describe("Entity IDs to include in newsletter (e.g., blog posts)"),sourceEntityType:Z.enum(["post"]).optional().describe("Type of source entities"),content:Z.string().optional().describe("Direct content (skip AI)"),subject:Z.string().optional().describe("Newsletter subject (AI-generated if not provided)"),addToQueue:Z.boolean().optional().describe("Create as queued (true) or draft (false)")});class Ua0 extends q4{constructor(A,Q){super(A,Q,{schema:Xqw,jobTypeName:"newsletter:generation",entityType:"newsletter"})}async generate(A,Q){let w=A.addToQueue??!1,{prompt:B,sourceEntityIds:$,sourceEntityType:f}=A,{content:Y,subject:X}=A;if(Y){if(!X)this.failEarly("Subject is required when providing content directly");await this.reportProgress(Q,{progress:50,message:"Using provided content"})}else if($&&$.length>0){let G=f??"post";await this.reportProgress(Q,{progress:10,message:`Fetching ${$.length} source entities`});let V=(await Promise.all($.map((k)=>this.context.entityService.getEntity({entityType:G,id:k})))).filter((k)=>k!=null);if(V.length===0)this.failEarly(`No source entities found for IDs: ${$.join(", ")}`);await this.reportProgress(Q,{progress:30,message:`Generating newsletter from ${V.length} posts`});let b=`Create an engaging newsletter that highlights these blog posts:
|
|
9335
|
+
${Vzw(VA(czw,{input:A},void 0,!1,void 0,this))}`}function lzw(A){return A.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"group"}function j12(A){let Q=A.query.trim().toLowerCase(),w=[];if(A.cmsPath!==void 0&&A.entities.length>0){let $=A.cmsPath;w.push({id:"entities",label:"Entities",items:A.entities.map((f)=>({id:`${f.entityType}/${f.id}`,title:f.title,sub:f.entityType,href:`${$}#/${encodeURIComponent(f.entityType)}/${encodeURIComponent(f.id)}`,tag:"edit in cms"}))})}let B=qX0([...new Set(A.groups)]).map(($)=>({group:$,label:Ny($)})).filter(({group:$,label:f})=>Q===""||f.toLowerCase().includes(Q)||$.toLowerCase().includes(Q)).map(({group:$,label:f})=>({id:`tab/${$}`,title:f,sub:"tab",href:`${A.dashboardPath}#${lzw($)}`,tag:"dashboard"}));if(B.length>0)w.push({id:"tabs",label:"Dashboard",items:B});return w}function P12(A,Q){let w={},B=new Set;for(let[$,f]of Object.entries(A)){let Y=Q?.get(f.widget.pluginId,f.widget.id);if(w[$]={...f,...Y?.component?{component:Y.component}:{}},Y?.clientScript)B.add(Y.clientScript)}return{widgets:w,widgetScripts:Array.from(B)}}var M12={name:"@brains/dashboard",version:"0.2.0-alpha.151",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 izw=Z.object({version:Z.string().default("1.0.0"),routePath:Z.string().default("/dashboard"),themeCSS:Z.string().optional()}),dzw=Z.object({id:Z.string(),pluginId:Z.string(),title:Z.string(),description:Z.string().optional(),group:Z.string().min(1),priority:Z.number().default(50),section:Z.enum(["primary","secondary","sidebar"]).default("primary"),rendererName:Z.string(),visibility:Z.enum(["public","trusted","anchor"]).default("public"),needsOperator:Z.number().int().nonnegative().optional(),digest:Z.array(Z.object({label:Z.string(),value:Z.string(),tone:Z.enum(["plain","good","warn"]).optional()})).max(4).optional(),component:Z.custom().optional(),clientScript:Z.string().optional(),dataProvider:Z.custom((A)=>typeof A==="function",{message:"Expected dashboard widget data provider function"}),digestProvider:Z.custom((A)=>typeof A==="function",{message:"Expected dashboard widget digest provider function"}).optional()}).superRefine((A,Q)=>{if(!Ba0(A.rendererName)&&!A.component)Q.addIssue({code:"custom",message:"Custom dashboard widgets must register a Preact component.",path:["component"]})}),nzw=Z.object({pluginId:Z.string(),widgetId:Z.string().optional()}),rzw=Z.object({entityType:Z.string(),entityId:Z.string(),conversationId:Z.string().optional()}),ozw=Z.object({id:Z.string(),type:Z.enum(["job","batch"]),status:Z.enum(["pending","processing","completed","failed"]),message:Z.string().optional(),progress:Z.object({current:Z.number(),total:Z.number(),percentage:Z.number()}).optional(),jobDetails:Z.object({jobType:Z.string(),priority:Z.number(),retryCount:Z.number()}).optional()}),szw=Z.object({success:Z.literal(!0),data:Z.object({syncPath:Z.string(),isInitialized:Z.boolean(),watchEnabled:Z.boolean(),lastSync:Z.string().datetime().optional(),totalFiles:Z.number().int().nonnegative().optional(),byEntityType:Z.record(Z.string(),Z.number().int().nonnegative()).optional()})});function azw(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 Wa0 extends tQ{widgetRegistry=null;datasource=null;siteUrl;ctx;activityLog=[];jobProgress=[];constructor(A={}){super("dashboard",M12,A,izw)}recordActivity(A,Q){let w=rzw.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=ozw.safeParse(A);if(!Q.success)return;let w=Q.data.progress?`${Q.data.progress.current}/${Q.data.progress.total}`:void 0,B={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=[B,...this.jobProgress.filter(($)=>$.id!==B.id||$.kind!==B.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:SA(Q)})}return}async getDirectorySyncStatus(){if(!this.ctx)return;try{let A=await this.ctx.messaging.send({type:"sync:status:request",payload:{}}),Q=szw.safeParse(A);return Q.success?Q.data.data:void 0}catch(A){this.logger.debug("Directory sync status unavailable",{error:SA(A)});return}}async onRegister(A){this.siteUrl=A.siteUrl,this.ctx=A,this.widgetRegistry=new GX0(this.logger),this.datasource=new DX0(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=dzw.parse(Q.payload),B=azw(w);return this.widgetRegistry?.register(B),this.logger.debug("Widget registered via messaging",{widgetId:w.id,pluginId:w.pluginId,rendererName:w.rendererName,builtIn:UX0.includes(w.rendererName)}),{success:!0}}catch(w){return this.logger.error("Failed to register widget",{error:SA(w),payload:Q.payload}),{success:!1,error:"Widget registration failed"}}}),A.messaging.subscribe("dashboard:unregister-widget",async(Q)=>{try{let w=nzw.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:SA(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 M7()?.getOperatorSession(A),B=Boolean(w),$=B?"anchor":"public",f=this.widgetRegistry?.list({permissionLevel:"anchor"})??[],Y=f.filter((h)=>B9.hasPermission($,h.visibility)),X=f.length-Y.length,[H,W,K,U]=await Promise.all([this.datasource.getDashboardData({permissionLevel:$,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}})(),J={...W,endpoints:W.endpoints.filter((h)=>B9.hasPermission($,h.visibility)),interactions:W.interactions.filter((h)=>B9.hasPermission($,h.visibility))},b=q.name||W.model||"Brain Dashboard",L=new URL(A.url),N=`${L.pathname}${L.search}`,k=encodeURIComponent(N),x=P12(H.widgets,this.widgetRegistry),v={title:b,baseUrl:V,widgets:x.widgets,widgetScripts:x.widgetScripts,dashboardPath:this.config.routePath,surfaces:SI(Q.webRoutes.getRoutes(),{activeId:"dashboard",self:{id:"dashboard",href:this.config.routePath}}),character:G,profile:q,appInfo:J,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:B,hiddenWidgetCount:X,loginUrl:`/login?return_to=${k}`,logoutUrl:`/logout?return_to=${k}`}};return new Response(N12(v),{headers:{"Content-Type":"text/html; charset=utf-8"}})}},{path:"/api/console/jump",method:"GET",public:!0,handler:async(A)=>{if(!await M7()?.getOperatorSession(A))return Response.json({error:"Operator session required"},{status:401});let w=this.ctx;if(!w)return Response.json({groups:[]});let B=new URL(A.url).searchParams.get("q")?.trim()??"",$=[];if(B.length>=2)try{$=(await w.entityService.search({query:B,options:{limit:6}})).map((H)=>({entityType:H.entity.entityType,id:H.entity.id,title:H.entity.title??H.entity.id}))}catch{}let f=(this.widgetRegistry?.list({permissionLevel:"anchor"})??[]).map((X)=>X.group),Y=SI(w.webRoutes.getRoutes(),{activeId:"dashboard"}).find((X)=>X.id==="cms")?.href;return Response.json({groups:j12({query:B,groups:[...f,"knowledge","system"],dashboardPath:this.config.routePath,cmsPath:Y,entities:$})})}}]}async getTools(){return[]}getWidgetRegistry(){return this.widgetRegistry}}function hF(A={}){return new Wa0(A)}_0();var tzw=Z.enum(["public","trusted","anchor"]),ezw=Z.object({label:Z.string(),value:Z.string(),tone:Z.enum(["plain","good","warn"]).optional()}),Aqw=Z.object({id:Z.string(),pluginId:Z.string(),title:Z.string(),description:Z.string().optional(),group:Z.string().min(1),priority:Z.number(),section:Z.enum(["primary","secondary","sidebar"]),rendererName:Z.string(),visibility:tzw,needsOperator:Z.number().int().nonnegative().optional(),digest:Z.array(ezw).max(4).optional(),component:Z.custom().optional()}),Qqw=Z.object({widget:Aqw,data:Z.unknown()}),wqw=Z.object({widgets:Z.record(Z.string(),Qqw)});wA();_0();wA();_0();import{h as Iqw}from"preact";wA();xX();U2();_0();var VX0=Z.enum(["generating","draft","queued","published","failed"]),Bqw=Z.enum(["generating","draft","queued","published","failed"]),bX0=Z.object({subject:Z.string(),status:VX0,entityIds:Z.array(Z.string()).optional(),scheduledFor:Z.string().datetime().optional(),sentAt:Z.string().datetime().optional(),buttondownId:Z.string().optional(),sourceEntityType:Z.string().optional()}),O12=Z.object({subject:Z.string(),status:VX0,entityIds:Z.array(Z.string()).optional(),scheduledFor:Z.string().datetime().optional(),sentAt:Z.string().datetime().optional(),buttondownId:Z.string().optional(),sourceEntityType:Z.string().optional(),error:Z.string().optional()}),$qw=Z.object({subject:Z.string(),status:Bqw,entityIds:Z.array(Z.string()).optional(),scheduledFor:Z.string().datetime().optional(),sentAt:Z.string().datetime().optional(),buttondownId:Z.string().optional(),sourceEntityType:Z.string().optional(),error:Z.string().optional()}),jy=_Q.extend({entityType:Z.literal("newsletter"),metadata:$qw});wA();class x12 extends g2{constructor(){super({entityType:"newsletter",purpose:"An email newsletter issue composed for subscribers.",schema:jy,frontmatterSchema:bX0})}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 v12=new x12;wA();wA();U2();_0();var fqw=Z.looseObject({id:Z.string().optional(),limit:Z.number().optional(),page:Z.number().optional(),pageSize:Z.number().optional(),baseUrl:Z.string().optional(),status:Z.enum(["generating","draft","queued","published","failed"]).optional()}),Yqw=Z.looseObject({entityType:Z.string().optional(),query:fqw.optional()});function R12(A){try{let{content:Q}=n2(A.content,bX0);return Q}catch{return A.content}}class Ka0 extends J8{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=Yqw.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}transformEntity(A){let Q=R12(A),w={id:A.id,subject:A.metadata.subject,status:A.metadata.status,excerpt:zf(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:B}=this.parseQuery(A),$=w.entityService;if(B.id)return this.fetchSingleNewsletter(B.id,Q,$);let f=B.status,Y=f?{filter:{metadata:{status:f}}}:void 0,{items:X,pagination:H}=await this.fetchList(B,$,Y);return Q.parse(this.buildListResult(X,H,B))}async fetchSingleNewsletter(A,Q,w){let B=await w.getEntity({entityType:this.config.entityType,id:A});if(!B)throw Error(`Newsletter not found: ${A}`);let $=await this.resolveNavigation(B,w),f=[];if(B.metadata.entityIds?.length){let H=B.metadata.sourceEntityType??"post";f=(await Promise.all(B.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=R12(B),X={id:B.id,subject:B.metadata.subject,status:B.metadata.status,content:Y,created:B.created,updated:B.updated,sentAt:B.metadata.sentAt,scheduledFor:B.metadata.scheduledFor,newsletter:B,prevNewsletter:$.prev?{id:$.prev.id,subject:$.prev.subject,url:$.prev.url}:null,nextNewsletter:$.next?{id:$.next.id,subject:$.next.subject,url:$.next.url}:null,sourceEntities:f.length>0?f:void 0};return Q.parse(X)}}wA();U2();_0();var Xqw=Z.object({prompt:Z.string().optional().describe("AI generation prompt"),sourceEntityIds:Z.array(Z.string()).optional().describe("Entity IDs to include in newsletter (e.g., blog posts)"),sourceEntityType:Z.enum(["post"]).optional().describe("Type of source entities"),content:Z.string().optional().describe("Direct content (skip AI)"),subject:Z.string().optional().describe("Newsletter subject (AI-generated if not provided)"),addToQueue:Z.boolean().optional().describe("Create as queued (true) or draft (false)")});class Ua0 extends q4{constructor(A,Q){super(A,Q,{schema:Xqw,jobTypeName:"newsletter:generation",entityType:"newsletter"})}async generate(A,Q){let w=A.addToQueue??!1,{prompt:B,sourceEntityIds:$,sourceEntityType:f}=A,{content:Y,subject:X}=A;if(Y){if(!X)this.failEarly("Subject is required when providing content directly");await this.reportProgress(Q,{progress:50,message:"Using provided content"})}else if($&&$.length>0){let G=f??"post";await this.reportProgress(Q,{progress:10,message:`Fetching ${$.length} source entities`});let V=(await Promise.all($.map((k)=>this.context.entityService.getEntity({entityType:G,id:k})))).filter((k)=>k!=null);if(V.length===0)this.failEarly(`No source entities found for IDs: ${$.join(", ")}`);await this.reportProgress(Q,{progress:30,message:`Generating newsletter from ${V.length} posts`});let b=`Create an engaging newsletter that highlights these blog posts:
|
|
9336
9336
|
|
|
9337
9337
|
${V.map((k)=>`## ${k.metadata.title}
|
|
9338
9338
|
|
|
@@ -9401,17 +9401,17 @@ Newsletter-specific guidelines:
|
|
|
9401
9401
|
- "Reply and let me know..."
|
|
9402
9402
|
- "Until next time..."
|
|
9403
9403
|
|
|
9404
|
-
The goal is to build a relationship with readers through valuable, authentic content.`});_0();wA();import{jsxDEV as af,Fragment as Gqw}from"preact/jsx-dev-runtime";var Hqw=Z.enum(["generating","draft","queued","published","failed"]),Wqw=Z.object({id:Z.string(),subject:Z.string(),status:Hqw,excerpt:Z.string(),created:Z.string(),sentAt:Z.string().optional(),url:Z.string()}),Kqw=Z.object({newsletters:Z.array(Wqw),totalCount:Z.number(),pagination:zA0.nullable()}),Uqw=({newsletters:A,totalCount:Q,pageTitle:w,pagination:B,baseUrl:$="/newsletters"})=>{let f=w??"Newsletters",Y=`Browse all ${Q} ${Q===1?"newsletter":"newsletters"}`;return af(Gqw,{children:[af(pQ,{title:f,description:Y},void 0,!1,void 0,this),af("div",{className:"newsletter-list bg-theme",children:af("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[af("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:f},void 0,!1,void 0,this),A.length===0?af("p",{className:"text-theme-muted italic",children:"No newsletters yet."},void 0,!1,void 0,this):af("div",{className:"space-y-4",children:A.map((X)=>af(G6,{href:X.url,children:[af(Y7,{className:"text-lg",children:X.subject},void 0,!1,void 0,this),af(g7,{children:af("div",{className:"flex items-center gap-3",children:[af(iY,{status:X.status},void 0,!1,void 0,this),af("span",{className:"text-sm text-theme-muted",children:_5(X.sentAt??X.created,{style:"long"})},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),X.excerpt&&af("p",{className:"text-theme-muted line-clamp-2",children:X.excerpt},void 0,!1,void 0,this)]},X.id,!0,void 0,this))},void 0,!1,void 0,this),B&&B.totalPages>1&&af(pq,{currentPage:B.currentPage,totalPages:B.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)},C12=d1({name:"newsletter-list",description:"Newsletter list page template",schema:Kqw,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:Uqw}});_0();wA();import{jsxDEV as sB,Fragment as bqw}from"preact/jsx-dev-runtime";var Dqw=Z.enum(["generating","draft","queued","published","failed"]),zqw=Z.object({id:Z.string(),title:Z.string(),url:Z.string()}),g12=Z.object({id:Z.string(),subject:Z.string(),url:Z.string()}),qqw=Z.object({id:Z.string(),subject:Z.string(),status:Dqw,content:Z.string(),created:Z.string(),updated:Z.string(),sentAt:Z.string().optional(),scheduledFor:Z.string().optional(),sourceEntities:Z.array(zqw).optional(),prevNewsletter:g12.nullable().optional(),nextNewsletter:g12.nullable().optional()}),Vqw=({subject:A,status:Q,content:w,created:B,sentAt:$,scheduledFor:f,sourceEntities:Y,prevNewsletter:X,nextNewsletter:H})=>{let W=[{label:"Home",href:"/"},{label:"Newsletters",href:"/newsletters"},{label:A}],K=$??B,U=$?"Sent":"Created";return sB(bqw,{children:[sB(pQ,{title:A,description:`Newsletter: ${A}`},void 0,!1,void 0,this),sB("section",{className:"newsletter-detail-section",children:sB("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:sB("div",{className:"max-w-3xl mx-auto",children:[sB(vD,{items:W},void 0,!1,void 0,this),sB("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),sB("div",{className:"flex flex-wrap items-center gap-3 mb-8 text-sm text-theme-muted",children:[sB(iY,{status:Q},void 0,!1,void 0,this),sB("span",{children:[U,": ",_5(K,{style:"long"})]},void 0,!0,void 0,this),f&&Q==="queued"&&sB("span",{children:["Scheduled for: ",_5(f,{style:"long"})]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Y&&Y.length>0&&sB(G6,{variant:"compact",className:"mb-8",children:[sB("h3",{className:"text-sm font-medium text-heading mb-2",children:"Related Content"},void 0,!1,void 0,this),sB("ul",{className:"space-y-1",children:Y.map((G)=>sB("li",{children:sB("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),sB(F9,{markdown:w},void 0,!1,void 0,this),(X??H)&&sB("nav",{className:"mt-12 pt-8 border-t border-theme",children:sB("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[X?sB(G6,{href:X.url,variant:"compact",children:[sB("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Newer"},void 0,!1,void 0,this),sB("span",{className:"block mt-1 font-medium text-heading group-hover:text-brand transition-colors truncate",children:X.subject},void 0,!1,void 0,this)]},void 0,!0,void 0,this):sB("div",{},void 0,!1,void 0,this),H&&sB(G6,{href:H.url,variant:"compact",className:"md:text-right",children:[sB("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Older"},void 0,!1,void 0,this),sB("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)},y12=d1({name:"newsletter-detail",description:"Individual newsletter detail template",schema:qqw,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:Vqw}});var JX0={name:"@brains/newsletter",version:"0.2.0-alpha.
|
|
9404
|
+
The goal is to build a relationship with readers through valuable, authentic content.`});_0();wA();import{jsxDEV as af,Fragment as Gqw}from"preact/jsx-dev-runtime";var Hqw=Z.enum(["generating","draft","queued","published","failed"]),Wqw=Z.object({id:Z.string(),subject:Z.string(),status:Hqw,excerpt:Z.string(),created:Z.string(),sentAt:Z.string().optional(),url:Z.string()}),Kqw=Z.object({newsletters:Z.array(Wqw),totalCount:Z.number(),pagination:zA0.nullable()}),Uqw=({newsletters:A,totalCount:Q,pageTitle:w,pagination:B,baseUrl:$="/newsletters"})=>{let f=w??"Newsletters",Y=`Browse all ${Q} ${Q===1?"newsletter":"newsletters"}`;return af(Gqw,{children:[af(pQ,{title:f,description:Y},void 0,!1,void 0,this),af("div",{className:"newsletter-list bg-theme",children:af("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[af("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:f},void 0,!1,void 0,this),A.length===0?af("p",{className:"text-theme-muted italic",children:"No newsletters yet."},void 0,!1,void 0,this):af("div",{className:"space-y-4",children:A.map((X)=>af(G6,{href:X.url,children:[af(Y7,{className:"text-lg",children:X.subject},void 0,!1,void 0,this),af(g7,{children:af("div",{className:"flex items-center gap-3",children:[af(iY,{status:X.status},void 0,!1,void 0,this),af("span",{className:"text-sm text-theme-muted",children:_5(X.sentAt??X.created,{style:"long"})},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),X.excerpt&&af("p",{className:"text-theme-muted line-clamp-2",children:X.excerpt},void 0,!1,void 0,this)]},X.id,!0,void 0,this))},void 0,!1,void 0,this),B&&B.totalPages>1&&af(pq,{currentPage:B.currentPage,totalPages:B.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)},C12=d1({name:"newsletter-list",description:"Newsletter list page template",schema:Kqw,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:Uqw}});_0();wA();import{jsxDEV as sB,Fragment as bqw}from"preact/jsx-dev-runtime";var Dqw=Z.enum(["generating","draft","queued","published","failed"]),zqw=Z.object({id:Z.string(),title:Z.string(),url:Z.string()}),g12=Z.object({id:Z.string(),subject:Z.string(),url:Z.string()}),qqw=Z.object({id:Z.string(),subject:Z.string(),status:Dqw,content:Z.string(),created:Z.string(),updated:Z.string(),sentAt:Z.string().optional(),scheduledFor:Z.string().optional(),sourceEntities:Z.array(zqw).optional(),prevNewsletter:g12.nullable().optional(),nextNewsletter:g12.nullable().optional()}),Vqw=({subject:A,status:Q,content:w,created:B,sentAt:$,scheduledFor:f,sourceEntities:Y,prevNewsletter:X,nextNewsletter:H})=>{let W=[{label:"Home",href:"/"},{label:"Newsletters",href:"/newsletters"},{label:A}],K=$??B,U=$?"Sent":"Created";return sB(bqw,{children:[sB(pQ,{title:A,description:`Newsletter: ${A}`},void 0,!1,void 0,this),sB("section",{className:"newsletter-detail-section",children:sB("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:sB("div",{className:"max-w-3xl mx-auto",children:[sB(vD,{items:W},void 0,!1,void 0,this),sB("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),sB("div",{className:"flex flex-wrap items-center gap-3 mb-8 text-sm text-theme-muted",children:[sB(iY,{status:Q},void 0,!1,void 0,this),sB("span",{children:[U,": ",_5(K,{style:"long"})]},void 0,!0,void 0,this),f&&Q==="queued"&&sB("span",{children:["Scheduled for: ",_5(f,{style:"long"})]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Y&&Y.length>0&&sB(G6,{variant:"compact",className:"mb-8",children:[sB("h3",{className:"text-sm font-medium text-heading mb-2",children:"Related Content"},void 0,!1,void 0,this),sB("ul",{className:"space-y-1",children:Y.map((G)=>sB("li",{children:sB("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),sB(F9,{markdown:w},void 0,!1,void 0,this),(X??H)&&sB("nav",{className:"mt-12 pt-8 border-t border-theme",children:sB("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[X?sB(G6,{href:X.url,variant:"compact",children:[sB("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Newer"},void 0,!1,void 0,this),sB("span",{className:"block mt-1 font-medium text-heading group-hover:text-brand transition-colors truncate",children:X.subject},void 0,!1,void 0,this)]},void 0,!0,void 0,this):sB("div",{},void 0,!1,void 0,this),H&&sB(G6,{href:H.url,variant:"compact",className:"md:text-right",children:[sB("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Older"},void 0,!1,void 0,this),sB("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)},y12=d1({name:"newsletter-detail",description:"Individual newsletter detail template",schema:qqw,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:Vqw}});var JX0={name:"@brains/newsletter",version:"0.2.0-alpha.151",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 Fqw=Z.looseObject({}),Lqw=Z.object({prompt:Z.string().optional(),content:Z.string().optional()});class IX0 extends rQ{entityType="newsletter";schema=jy;adapter=v12;constructor(A={}){super("newsletter",JX0,A,Fqw)}getEntityTypeConfig(){return{publish:{publishStatuses:["queued","published","failed"]}}}createGenerationHandler(A){return new Ua0(this.logger,A)}getTemplates(){return{generation:h12,"newsletter-list":C12,"newsletter-detail":y12}}getDataSources(){return[new Ka0(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:()=>Iqw(Hi0,{variant:"inline"})}});return{success:!0}}),this.logger.debug("Newsletter plugin registered")}deferPublishRegistration(A){let Q={name:"internal",publish:async(w,B)=>{let $=typeof B.subject==="string"?B.subject:"",f=await A.messaging.send({type:"buttondown:send",payload:{entityId:"",subject:$,content:w}});return{id:!("noop"in f)&&f.data?.emailId?f.data.emailId:"internal"}}};A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"publish:register",payload:{entityType:"newsletter",provider:Q,config:{publishResultIdField:"buttondownId",publishTimestampField:"sentAt"}}}),{success:!0}})}subscribeToGenerateExecute(A){A.messaging.subscribe("generate:execute",async(Q)=>{if(Q.payload.entityType!=="newsletter")return{success:!0};try{let 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((B)=>B.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:SA(w)}}),{success:!0}}})}registerEvalHandlers(A){A.eval.registerHandler("generation",async(Q)=>{let w=Lqw.parse(Q),B=w.content?`Create an engaging newsletter based on this content:
|
|
9405
9405
|
|
|
9406
9406
|
${w.content}`:w.prompt??"Write an engaging newsletter";return A.ai.generate({prompt:B,templateName:"newsletter:generation"})})}}function FX0(A={}){return new IX0(A)}wA();_0();_0();var _qw="https://api.buttondown.email/v1",Nqw=Z.enum(["unactivated","regular","unsubscribed","already_subscribed"]),jqw=Z.enum(["draft","about_to_send","scheduled","sent"]),Ga0=Z.looseObject({id:Z.string(),email:Z.string(),subscriber_type:Nqw,metadata:Z.record(Z.string(),Z.string()).optional()}),E12=Z.looseObject({id:Z.string(),subject:Z.string(),body:Z.string().optional(),status:jqw,publish_date:Z.string().optional()}),Pqw=Z.looseObject({results:Z.array(Ga0),count:Z.number()}),Mqw=Z.looseObject({detail:Z.string().optional(),message:Z.string().optional(),code:Z.string().optional()});class Da0 extends Error{status;code;constructor(A,Q,w){super(A);this.name="ButtondownApiError",this.status=Q,this.code=w}}class GP{config;logger;constructor(A,Q){this.config=A,this.logger=Q}async request(A,Q={}){let w=`${_qw}${A}`;this.logger.debug("Buttondown API request",{endpoint:A,method:Q.method??"GET"});let B=await fetch(w,{...Q,headers:{Authorization:`Token ${this.config.apiKey}`,"Content-Type":"application/json",...Q.headers}});if(!B.ok){let $=await B.json().catch(()=>({})),f=Mqw.safeParse($),Y=f.success?f.data.detail??f.data.message??`HTTP ${B.status}`:`HTTP ${B.status}`,X=f.success?f.data.code:void 0;throw this.logger.error("Buttondown API error",{endpoint:A,status:B.status,code:X,error:Y}),new Da0(`Buttondown API error: ${Y}`,B.status,X)}return B.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 Ga0.parse(await this.request("/subscribers",{method:"POST",body:JSON.stringify(Q)}))}catch(w){if(w instanceof Da0&&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 Ga0.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(),B=w?`/subscribers?${w}`:"/subscribers";return Pqw.parse(await this.request(B))}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"}),E12.parse(await this.request("/emails",{method:"POST",body:JSON.stringify(Q)}))}async getEmail(A){return E12.parse(await this.request(`/emails/${A}`))}async validateCredentials(){try{return await this.request("/subscribers?page_size=1"),!0}catch{return!1}}}wA();_0();var Oqw=Z.object({email:Z.string().email().describe("Email address to subscribe"),name:Z.string().optional().describe("Subscriber name (optional)"),tags:Z.array(Z.string()).optional().describe("Tags to apply to subscriber (optional)")}),xqw=Z.object({email:Z.string().email().describe("Email address to unsubscribe")}),vqw=Z.object({type:Z.enum(["unactivated","regular","unsubscribed"]).optional().describe("Filter by subscriber status"),limit:Z.number().optional().describe("Maximum number of results")});function T12(A,Q,w){let B=new GP(Q,w);return[M6(A,"subscribe","Subscribe an email address to the newsletter. Uses double opt-in by default.",Oqw,async($)=>{try{let f=await B.createSubscriber({email:$.email,...$.name&&{name:$.name},...$.tags&&{tags:$.tags}}),Y=f.subscriber_type==="already_subscribed";return b8({subscriberId:f.id,email:f.email,status:f.subscriber_type,message:Y?"already_subscribed":"subscribed"},Y?`${$.email} is already subscribed`:`Subscribed ${$.email} successfully`)}catch(f){return _7(SA(f))}}),M6(A,"unsubscribe","Unsubscribe an email address from the newsletter.",xqw,async($)=>{try{return await B.unsubscribe($.email),b8({email:$.email},`Unsubscribed ${$.email} successfully`)}catch(f){return _7(SA(f))}}),M6(A,"list_subscribers","List newsletter subscribers with optional filtering by status.",vqw,async($)=>{try{let f=await B.listSubscribers({...$.type&&{type:$.type},...$.limit&&{limit:$.limit}});return b8({subscribers:f.results.map((Y)=>({id:Y.id,email:Y.email,status:Y.subscriber_type})),count:f.count},`Found ${f.count} subscribers`)}catch(f){return _7(SA(f))}})]}async function S12(A,Q,w,B){if(A.entityType!=="post")return{success:!0,skipped:!0,reason:"Only post entity types trigger auto-send"};let $=await w.getEntity({entityType:"post",id:A.entityId});if(!$)return{success:!1,error:`Post ${A.entityId} not found`};B.info("Auto-sending newsletter for published post",{postId:$.id,title:$.metadata.title});try{let f=await Q.createEmail({subject:$.metadata.title,body:$.content,status:"about_to_send"});return B.info("Newsletter sent for post",{postId:$.id,emailId:f.id}),{success:!0,emailId:f.id}}catch(f){let Y=SA(f);return B.error("Failed to send newsletter for post",{postId:$.id,error:Y}),{success:!1,error:Y}}}var Rqw=Z.object({apiKey:Z.string().optional().describe("Buttondown API key"),doubleOptIn:Z.boolean().default(!0).describe("Require email confirmation for new subscribers"),autoSendOnPublish:Z.boolean().default(!1).describe("Automatically send newsletter when a blog post is published")});class LX0 extends tQ{constructor(A={}){super("buttondown",JX0,A,Rqw)}async onRegister(A){if(A.messaging.subscribe("buttondown:is-configured",async()=>{return{success:!!this.config.apiKey}}),this.config.apiKey){let Q=new GP({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(B){return this.logger.error("Buttondown send failed",{error:SA(B)}),{success:!1}}}),this.config.autoSendOnPublish)A.messaging.subscribe("publish:completed",async(w)=>{let B=await S12(w.payload,Q,A.entityService,this.logger);if(!B.success)return this.logger.error("Buttondown auto-send failed",{entityId:w.payload.entityId,error:B.error}),{success:!1,error:B.error};return{success:!0}}),this.logger.info("Buttondown auto-send on publish enabled")}}async getTools(){if(!this.config.apiKey)return[];return T12(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 kX0(A={}){return new LX0(A)}var hqw=Z.object({apiKey:Z.string().optional().describe("Buttondown API key"),doubleOptIn:Z.boolean().optional().describe("Require email confirmation for new subscribers"),autoSendOnPublish:Z.boolean().optional().describe("Automatically send newsletter when a blog post is published")});function m12(A={}){let Q=hqw.safeParse(A);if(!Q.success)throw new o3("newsletter",Q.error.issues.map((B)=>({path:B.path.map(String).join("."),code:B.code,message:B.message})));let w=Q.data;return[FX0({}),kX0({...w.apiKey!==void 0&&{apiKey:w.apiKey},...w.doubleOptIn!==void 0&&{doubleOptIn:w.doubleOptIn},...w.autoSendOnPublish!==void 0&&{autoSendOnPublish:w.autoSendOnPublish}})]}wA();_0();import{existsSync as nqw,mkdirSync as rqw,writeFileSync as oqw}from"fs";import{join as WV}from"path";_0();var za0=Z.object({baseFolder:Z.string().default("_obsidian")});function qa0(A){return typeof A==="object"&&A!==null}function Co(A){if(!qa0(A))return;let Q=A.def;return qa0(Q)?Q:void 0}function u12(A){let Q=Co(A)?.type;return typeof Q==="string"?Q:void 0}function Cqw(A){return typeof A==="function"?A():A}function gqw(A){let Q=A,w=!0,B=void 0,$=!1,f=!0;while(f){f=!1;let X=Co(Q),H=u12(Q);if(H==="optional"||H==="nullable"){w=!1,Q=X?.innerType,f=!0;continue}if(H==="default")w=!1,$=!0,B=Cqw(X?.defaultValue),Q=X?.innerType,f=!0}let Y={inner:Q,required:w};if($)Y.defaultValue=B;return Y}function yqw(A){let w=Co(A)?.entries;if(!qa0(w))return;let B=Object.values(w);if(!B.every(($)=>typeof $==="string"))return;return B}function Eqw(A){let Q=Co(A),w=Q?.values;if(Array.isArray(w))return w[0];return Q?.value}function c12(A){let Q=u12(A);if(Q==="enum"){let w=yqw(A);return w?{type:"enum",enumValues:w}:{type:"enum"}}if(Q==="literal")return{type:"string",defaultValue:Eqw(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=Co(A);return c12(w?.out)}return{type:"unknown"}}function l12(A){let Q=[];for(let[w,B]of Object.entries(A.shape)){let{inner:$,required:f,defaultValue:Y}=gqw(B),X=c12($),H={name:w,type:X.type,required:f},W=Y!==void 0?Y:X.defaultValue;if(W!==void 0)H.defaultValue=W;if(X.enumValues)H.enumValues=X.enumValues;Q.push(H)}return Q}function Tqw(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 p12(A,Q,w=""){let B=["---"];for(let $ of Q){let f=Tqw($,A);if(f==="")B.push(`${$.name}:`);else B.push(`${$.name}: ${f}`)}if(B.push("---"),B.push(""),w)B.push(w);else B.push("<!-- Write your content here -->"),B.push("");return B.join(`
|
|
9407
9407
|
`)}fv();var Sqw={string:"Input",number:"Number",boolean:"Boolean",date:"Date",enum:"Select",array:"Multi",unknown:"Input"};function mqw(A){let Q={name:A.name,id:A.name,type:Sqw[A.type]};if(A.type==="enum"&&A.enumValues){let w={};A.enumValues.forEach((B,$)=>{w[String($)]=B}),Q.options=w}return Q}function i12(A,Q){let w={filesPaths:A,fields:Q.map(mqw)};return`---
|
|
9408
9408
|
${$v(w)}---
|
|
9409
|
-
`}U2();fv();var uqw=new Set(["entityType"]),cqw={base:"Notes"},lqw=new Set(["note"]);function pqw(A){let Q=["file.name"];for(let w of A)if(!uqw.has(w.name))Q.push(w.name);return Q}function iqw(A){return A.some((Q)=>Q.name==="status"&&Q.type==="enum")}function d12(A,Q){let w=cqw[A]??$9A(A),B=iqw(Q),$=pqw(Q),f=[{type:"table",name:`All ${w}`,order:$}];if(B)f.push({type:"table",name:"By Status",groupBy:{property:"status",direction:"ASC"},order:$});let X={filters:{and:[lqw.has(A)?'file.folder == "/"':`file.inFolder("${A}")`]},views:f};return{filename:`${w}.base`,content:$v(X),hasStatus:B}}function n12(A){if(A.length===0)return null;let Q=A.map((B)=>`file.inFolder("${B}")`),w={filters:{and:[Q.length===1?Q[0]:{or:Q}]},views:[{type:"table",name:"Settings",order:["file.name","file.folder"]}]};return $v(w)}function r12(A){if(A.length===0)return null;let Q=A.map((B)=>`file.inFolder("${B.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 $v(w)}var o12={name:"@brains/obsidian-vault",version:"0.2.0-alpha.
|
|
9409
|
+
`}U2();fv();var uqw=new Set(["entityType"]),cqw={base:"Notes"},lqw=new Set(["note"]);function pqw(A){let Q=["file.name"];for(let w of A)if(!uqw.has(w.name))Q.push(w.name);return Q}function iqw(A){return A.some((Q)=>Q.name==="status"&&Q.type==="enum")}function d12(A,Q){let w=cqw[A]??$9A(A),B=iqw(Q),$=pqw(Q),f=[{type:"table",name:`All ${w}`,order:$}];if(B)f.push({type:"table",name:"By Status",groupBy:{property:"status",direction:"ASC"},order:$});let X={filters:{and:[lqw.has(A)?'file.folder == "/"':`file.inFolder("${A}")`]},views:f};return{filename:`${w}.base`,content:$v(X),hasStatus:B}}function n12(A){if(A.length===0)return null;let Q=A.map((B)=>`file.inFolder("${B}")`),w={filters:{and:[Q.length===1?Q[0]:{or:Q}]},views:[{type:"table",name:"Settings",order:["file.name","file.folder"]}]};return $v(w)}function r12(A){if(A.length===0)return null;let Q=A.map((B)=>`file.inFolder("${B.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 $v(w)}var o12={name:"@brains/obsidian-vault",version:"0.2.0-alpha.151",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 sqw={mkdir:rqw,writeFile:oqw,existsFile:nqw},aqw=Z.object({entityTypes:Z.array(Z.string()).optional().describe("Entity types to generate templates for (default: all)")});class Va0 extends tQ{deps;constructor(A={},Q={}){super("obsidian-vault",o12,A,za0);this.deps={...sqw,...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[M6(this.id,"sync-templates","Generate Obsidian templates, Metadata Menu fileClass definitions, and Bases views for all registered entity types.",aqw,async(Q)=>{return this.sync(A,Q.entityTypes)},{sideEffects:"external"})]}async sync(A,Q){try{let w=A.entityService.getEntityTypes(),B=Q?w.filter((b)=>Q.includes(b)):w,$=WV(A.dataDir,this.config.baseFolder),f=WV($,"templates"),Y=WV($,"fileClasses"),X=WV($,"bases");this.deps.mkdir(f,{recursive:!0}),this.deps.mkdir(Y,{recursive:!0}),this.deps.mkdir(X,{recursive:!0});let H=[],W=[],K=[],U=[],G=[],q=[];for(let b of B){let L=A.entities.getEffectiveFrontmatterSchema(b);if(!L){this.logger.debug(`Skipping ${b}: no frontmatter schema`),W.push(b);continue}let N=l12(L),k=A.entities.getAdapter(b),x=k?.isSingleton===!0,v=i12(b,N);if(this.deps.writeFile(WV(Y,`${b}.md`),v),K.push(b),x){G.push(b),this.logger.debug(`Generated fileClass (singleton): ${b}`);continue}let h=k?.getBodyTemplate()??"",P=p12(b,N,h);this.deps.writeFile(WV(f,`${b}.md`),P),H.push(b);let E=d12(b,N),S=WV(X,E.filename);if(!this.deps.existsFile(S))this.deps.writeFile(S,E.content),U.push(b),this.logger.debug(`Generated base: ${E.filename}`);if(E.hasStatus)q.push({entityType:b,fields:N});this.logger.debug(`Generated template + fileClass: ${b}`)}let V=n12(G);if(V){let b=WV(X,"Settings.base");if(!this.deps.existsFile(b))this.deps.writeFile(b,V),U.push("Settings"),this.logger.debug("Generated Settings.base")}let J=r12(q);if(J){let b=WV(X,"Pipeline.base");if(!this.deps.existsFile(b))this.deps.writeFile(b,J),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)`),b8({generated:H,skipped:W,fileClasses:K,bases:U})}catch(w){return this.logger.error("Failed to sync",{error:w}),_7(w instanceof Error?w.message:"Unknown error")}}}function ba0(A={},Q){return new Va0(A,Q)}y6();wA();wA();U2();t8();wA();_0();var _X0=Z.enum(["draft","active","archived"]),NX0=Z.enum(["anchor","trusted","public"]),jX0=Z.enum(["agent-confirmed","manual"]),tqw=Z.enum(["draft","active","archived"]),eqw=Z.enum(["anchor","trusted","public"]),AVw=Z.enum(["agent-confirmed","manual"]),$3=Z.preprocess((A)=>typeof A==="string"&&A.trim().length===0?void 0:A,Z.string().min(1).optional()),KV=Z.preprocess((A)=>typeof A==="string"&&A.trim().length===0?void 0:A,Z.string().min(1).optional()),Ja0=Z.object({event:Z.string().min(1),target:Z.string().min(1),operatorAction:Z.boolean().optional(),label:KV,description:KV,operatorDescription:KV}),Ia0=Z.object({id:Z.string().min(1),title:Z.string().min(1),prompt:KV,requiredDetails:Z.array(Z.string().min(1)).default([]),instructions:Z.array(Z.string().min(1)).default([]),doneWhen:Z.array(Z.string().min(1)).default([]),transitions:Z.array(Ja0).default([])}),PX0=Z.object({purpose:Z.string().min(1),operatingRules:Z.array(Z.string().min(1)).default([]),initialState:Z.string().min(1),states:Z.array(Ia0).min(1),finalStates:Z.array(Z.string().min(1)).min(1),nextPrompts:Z.array(Z.string().min(1)).default([])}),Py=Z.object({title:Z.string(),status:_X0.default("active"),audience:NX0.default("anchor"),trigger:$3.optional(),lifecycle:$3.optional(),once:Z.boolean().optional(),starterText:$3.optional(),description:$3.optional(),starterPrompt:$3.optional(),completionMode:jX0.default("agent-confirmed")}),s12=Z.object({title:Z.string(),status:_X0,audience:NX0,trigger:$3.optional(),lifecycle:$3.optional(),once:Z.boolean().optional(),starterText:$3.optional(),description:$3.optional(),starterPrompt:$3.optional(),completionMode:jX0}),QVw=Z.object({title:Z.string(),status:tqw,audience:eqw,trigger:KV.optional(),lifecycle:KV.optional(),once:Z.boolean().optional(),starterText:KV.optional(),description:KV.optional(),starterPrompt:KV.optional(),completionMode:AVw}),My=_Q.extend({entityType:Z.literal("playbook"),metadata:QVw});class MX0 extends z6{constructor(){super(PX0,{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:Fa0,parser:La0},{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:wVw,parser:BVw},{key:"label",label:"Label",type:"custom",formatter:Fa0,parser:La0},{key:"description",label:"Description",type:"string"},{key:"operatorDescription",label:"Operator Description",type:"custom",formatter:Fa0,parser:La0}]}]},{key:"finalStates",label:"Final States",type:"array",itemType:"string"},{key:"nextPrompts",label:"Next Prompts",type:"array",itemType:"string"}]})}}var go=new MX0;function Fa0(A){return typeof A==="string"?A:""}function La0(A){let Q=A.trim();return Q.length>0?Q:void 0}function wVw(A){return typeof A==="boolean"?String(A):""}function BVw(A){let Q=A.trim().toLowerCase();if(Q==="true")return!0;if(Q==="false")return!1;return}function ka0(A){let Q=[],w=new Set,B=new Set;for(let $ of A.states){if(w.has($.id))B.add($.id);w.add($.id)}if(!w.has(A.initialState))Q.push(`Playbook initial state '${A.initialState}' is not defined.`);for(let $ of B)Q.push(`Duplicate playbook state id '${$}'.`);for(let $ of A.finalStates)if(!w.has($))Q.push(`Playbook final state '${$}' is not defined.`);for(let $ of A.states)for(let f of $.transitions)if(!w.has(f.target))Q.push(`Playbook transition '${$.id}' -> '${f.target}' targets an undefined state.`);for(let $ of $Vw(A,w))Q.push(`Playbook state '${$}' is unreachable.`);return{valid:Q.length===0,errors:Q}}function Oy(A){let Q=ka0(A);if(!Q.valid)throw Error(Q.errors.join(`
|
|
9410
9410
|
`))}function $Vw(A,Q){if(!Q.has(A.initialState))return[];let w=new Set,B=[A.initialState];while(B.length>0){let $=B.shift();if(!$||w.has($))continue;w.add($);let f=A.states.find((Y)=>Y.id===$);if(!f)continue;for(let Y of f.transitions)if(Q.has(Y.target)&&!w.has(Y.target))B.push(Y.target)}return A.states.map(($)=>$.id).filter(($)=>!w.has($))}class xX0 extends g2{constructor(){super({entityType:"playbook",purpose:"A guided multi-step workflow the assistant runs together with the user.",schema:My,frontmatterSchema:Py})}createPlaybookContent(A,Q){return this.buildMarkdown(go.format(Q),A)}parsePlaybookContent(A){let Q=this.parseFrontMatter(A,Py),w=this.extractBody(A).trim(),B=fVw(w)?YVw(w):go.parse(w);return Oy(B),{frontmatter:Py.parse(Q),body:B,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 DP=new xX0;function fVw(A){return/^##\s+Steps\s*$/im.test(A)}function YVw(A){let Q=XVw(_a0(A,"Steps"));if(Q.length===0)throw Error("Playbook must declare at least one step.");let w=Q.map((B,$)=>{let f=$===Q.length-1;if(!f&&B.doneWhen.length===0&&B.choices.length===0&&!B.skip)throw Error(`Playbook step '${B.title}' must declare Done when, Choices, or Skip.`);return{id:B.id,title:B.title,...B.prompt?{prompt:B.prompt}:{},requiredDetails:B.requiredDetails,instructions:B.instructions,doneWhen:B.doneWhen,transitions:[...B.doneWhen.length>0&&!f?[{event:"NEXT",target:Q[$+1]?.id??B.id}]:[],...B.choices.map((Y,X)=>({event:`CHOICE_${X+1}`,target:H1(Y.target),operatorAction:!0,label:Y.label})),...B.skip?[{event:"SKIP",target:H1(B.skip.target),operatorAction:!0,label:B.skip.label}]:[]]}});return{purpose:ZVw(A,"Purpose"),operatingRules:a12(A,"Operating Rules"),initialState:Q[0]?.id??"",states:w,finalStates:[Q.at(-1)?.id??""],nextPrompts:a12(A,"Next Prompts")}}function XVw(A){let Q=[],w;for(let B of A.split(/\r?\n/)){let $=/^###\s+(.+?)\s*$/.exec(B);if($){w={title:$[1]??"",content:[]},Q.push(w);continue}w?.content.push(B)}return Q.map((B)=>{let $=B.content.join(`
|
|
9411
9411
|
`);return{title:B.title,id:H1(B.title),...t12($,"Say")?{prompt:t12($,"Say")}:{},requiredDetails:OX0($,"Required details"),instructions:OX0($,"To do"),doneWhen:OX0($,"Done when"),choices:HVw($,"Choices"),...e12($)?{skip:e12($)}:{}}})}function _a0(A,Q){let w=A.split(/\r?\n/),B=w.findIndex((f)=>f.trim().toLowerCase()===`## ${Q.toLowerCase()}`);if(B===-1)return"";let $=[];for(let f of w.slice(B+1)){if(/^##\s+/.test(f))break;$.push(f)}return $.join(`
|
|
9412
9412
|
`).trim()}function ZVw(A,Q){return _a0(A,Q).split(/\r?\n/).map((w)=>w.trim()).filter((w)=>w.length>0&&!w.startsWith("#")).join(`
|
|
9413
9413
|
`).trim()}function a12(A,Q){return A22(_a0(A,Q))}function t12(A,Q){return new RegExp(`^${KVw(Q)}:\\s*(.+?)\\s*$`,"im").exec(A)?.[1]?.trim()}function OX0(A,Q){let w=A.split(/\r?\n/),B=w.findIndex((f)=>f.trim().toLowerCase()===`${Q.toLowerCase()}:`);if(B===-1)return[];let $=[];for(let f of w.slice(B+1)){let Y=f.trim();if(Y.length===0)continue;if(/^[A-Za-z][A-Za-z ]+:/.test(Y)||/^#{1,6}\s+/.test(Y))break;$.push(f)}return A22($.join(`
|
|
9414
|
-
`))}function HVw(A,Q){return OX0(A,Q).map(WVw)}function WVw(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 e12(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 A22(A){return A.split(/\r?\n/).map((Q)=>/^-\s+(.+?)\s*$/.exec(Q)?.[1]?.trim()).filter((Q)=>Boolean(Q))}function KVw(A){return A.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}_0();var vX0=Z.object({}).catchall(Z.unknown()).transform(()=>({}));var RX0={name:"@brains/playbooks",version:"0.2.0-alpha.
|
|
9414
|
+
`))}function HVw(A,Q){return OX0(A,Q).map(WVw)}function WVw(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 e12(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 A22(A){return A.split(/\r?\n/).map((Q)=>/^-\s+(.+?)\s*$/.exec(Q)?.[1]?.trim()).filter((Q)=>Boolean(Q))}function KVw(A){return A.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}_0();var vX0=Z.object({}).catchall(Z.unknown()).transform(()=>({}));var RX0={name:"@brains/playbooks",version:"0.2.0-alpha.151",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 GVw="playbook";class Na0 extends rQ{entityType=GVw;schema=My;adapter=DP;constructor(A={}){super("playbook",RX0,A,vX0)}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 ja0(A={}){return new Na0(A)}y6();wA();_0();xX();ku();function hX0(A,Q){return A.length===Q.length&&A.every((w,B)=>w===Q[B])}function Pa0(A,Q){return Q==="NEXT"&&A.doneWhen.length>0}function CX0(A,Q){return Q.gateVerdicts.some((w)=>w.stateId===A.id&&hX0(w.goal,A.doneWhen)&&w.met)}function DVw(A,Q,w){return n1.createMachine({id:A,initial:Q.initialState,states:Object.fromEntries(Q.states.map((B)=>{let $=Q.finalStates.includes(B.id);return[B.id,{...$?{type:"final"}:{},...$?{}:{on:Object.fromEntries(B.transitions.map((f)=>[f.event,{target:f.target,...Pa0(B,f.event)?{guard:()=>CX0(B,w)}:{}}]))}}]}))})}function Ma0(A,Q){let w=DVw(Q.playbookId,A,Q);return n1.createActor(w,{snapshot:w.resolveState({value:Q.currentState})})}function zVw(A,Q,w){let B=Ma0(Q,A);B.start();let $=B.getSnapshot().can({type:w});return B.stop(),$}function xy(A,Q,w){return w.transitions.filter((B)=>zVw(A,Q,B.event))}function yo(A,Q,w){let B=new Set(xy(A,Q,w).map(($)=>`${$.event}\x00${$.target}`));return w.transitions.filter(($)=>!B.has(`${$.event}\x00${$.target}`))}function Q22(A,Q){return A.evidence.filter((w)=>!w.stateId||w.stateId===Q)}function zP(A,Q){return A.states.find((w)=>w.id===Q)}function qP(A){let Q=A.operatorDescription??A.description??A.label;return Q?`- ${A.event} -> ${A.target}: ${Q}`:`- ${A.event} -> ${A.target}`}function w22(A,Q){if(Q.doneWhen.length===0)return"- no gated Done When conditions";let w=A.gateVerdicts.find((B)=>B.stateId===Q.id&&hX0(B.goal,Q.doneWhen));if(!w)return`- Not yet met: ${Q.doneWhen.join("; ")}`;return w.met?`- Met: ${w.reason}`:`- Not yet met: ${w.reason}`}function B22(A,Q,w){let B=xy(A,Q,w),$=B.filter((H)=>H.operatorAction!==!0),f=B.filter((H)=>H.operatorAction===!0),Y=yo(A,Q,w),X=A.gateVerdicts.find((H)=>H.stateId===w.id&&hX0(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:",X?`- ${X.met?"Met":"Not yet met"}: ${X.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:",...$.length>0?$.map((H)=>qP(H)):["- none"],"Available operator actions:",...f.length>0?f.map((H)=>qP(H)):["- none"],"Blocked events:",...Y.length>0?Y.map((H)=>qP(H)):["- none"]].join(`
|
|
9415
9415
|
`)}function $22(A){let{run:Q,body:w,state:B,playbookTitle:$}=A,f=xy(Q,w,B),Y=f.filter((b)=>b.operatorAction!==!0),X=f.filter((b)=>b.operatorAction===!0),H=yo(Q,w,B),W=Y.map((b)=>qP(b)).join(`
|
|
9416
9416
|
`),K=X.map((b)=>qP(b)).join(`
|
|
9417
9417
|
`),U=H.map((b)=>qP(b)).join(`
|
|
@@ -9485,9 +9485,9 @@ ${Object.entries(A).map(([w,B])=>`- ${w}: playbookId=${B.playbookId}, trigger=${
|
|
|
9485
9485
|
${A.guidance}`:$}}function q22(A){return{...A,evidence:A.evidence.map((Q)=>({...Q,data:xVw(Q.data)}))}}function xVw(A){return Object.fromEntries(["entityType","entityId","operation"].flatMap((Q)=>A[Q]!==void 0?[[Q,A[Q]]]:[]))}function vVw(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 RVw(A){if(!A)return"Continuing.";return A.prompt??`Continuing to ${A.title}.`}function V22(){return{promptTokens:0,completionTokens:0,totalTokens:0}}function b22(A,Q){let w=A.filter(Q),B=w.filter(($)=>$.status==="active"||$.status==="offered");return Ca0(B)??Ca0(w)}function Ca0(A){return[...A].sort((Q,w)=>(w.completedAt??w.updatedAt).localeCompare(Q.completedAt??Q.updatedAt))[0]}function hVw(A){return{async evaluate(Q){let w=Q.goal.join(`
|
|
9486
9486
|
`),B=await A.entityService.search({query:w,options:{limit:8,excludeTypes:["playbook"],visibilityScope:B$("anchor")}}),$=CVw(Q,B),{verdict:f}=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:$,schema:NVw});return f}}}function CVw(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,B)=>gVw(B+1,w)):["No runtime evidence collected for this state."],"","## KB excerpts",...Q.length>0?Q.map((w,B)=>yVw(B+1,w)):["No relevant KB excerpts found."]].join(`
|
|
9487
9487
|
`)}function gVw(A,Q){return`${A}. ${Q.kind} at ${Q.observedAt}: ${I22(Q.data)}`}function yVw(A,Q){return[`${A}. ${Q.entity.entityType}/${Q.entity.id} (score ${Q.score})`,`Excerpt: ${Q.excerpt}`,`Content: ${F22(Q.entity.content,1200)}`,`Metadata: ${I22(Q.entity.metadata)}`].join(`
|
|
9488
|
-
`)}function I22(A){try{return F22(JSON.stringify(A),1200)}catch{return"[unserializable]"}}function F22(A,Q){return A.length>Q?`${A.slice(0,Q)}\u2026`:A}var EVw={async evaluate(){return{met:!1,reason:"No playbook goal check is configured."}}};function ya0(A={},Q={}){return new ga0(A,Q)}y6();wA();_0();import{readFile as SVw}from"fs/promises";import{join as mVw}from"path";var L22={name:"@brains/rover-onboarding",version:"0.2.0-alpha.150",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:"^6.0.3"},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 uVw=Z.object({enabled:Z.boolean().default(!1)}).strict(),k22=[{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 _22 extends tQ{dependencies=["playbook","playbooks"];constructor(A={}){super("rover-onboarding",L22,A,uVw)}async onReady(A){if(!this.config.enabled)return;for(let Q of k22)await this.seedPlaybookIfMissing(A,Q);for(let Q of k22){if(!Q.starter)continue;await A.messaging.send({type:wO,payload:Q.starter})}}async seedPlaybookIfMissing(A,Q){if(await A.entityService.getEntity({entityType:"playbook",id:Q.id,visibilityScope:"restricted"}))return;let B=await SVw(mVw(import.meta.dir,"..","content","playbook",Q.fileName),"utf8");await A.entityService.createEntityFromMarkdown({input:{entityType:"playbook",id:Q.id,markdown:B}})}}function N22(A={}){return new _22(A)}wA();_0();_0();wA();var Ea0=Z.enum(["new","planned","in-progress","done","declined"]),Ta0=Z.enum(["low","medium","high","critical"]),cVw=Z.enum(["new","planned","in-progress","done","declined"]),lVw=Z.enum(["low","medium","high","critical"]),Eo=Z.object({title:Z.string(),status:Ea0,priority:Ta0.default("medium"),requested:Z.number().int().default(1),declinedReason:Z.string().optional()}),pVw=Z.object({title:Z.string(),status:Ea0,priority:Ta0,requested:Z.number().int(),slug:Z.string()}),iVw=Z.object({title:Z.string(),status:cVw,priority:lVw,requested:Z.number().int(),slug:Z.string()}),To=_Q.extend({entityType:Z.literal("wish"),metadata:iVw});_0();var Sa0=Z.object({}).catchall(Z.unknown()).transform(()=>({}));wA();U2();class So extends g2{constructor(){super({entityType:"wish",purpose:"An explicitly recorded capability or outcome the assistant cannot currently fulfill, kept for future planning.",schema:To,frontmatterSchema:Eo})}createWishContent(A,Q){return this.buildMarkdown(Q,A)}parseWishContent(A){let Q=this.parseFrontMatter(A,Eo);return{frontmatter:Eo.parse(Q),description:this.extractBody(A).trim()}}fromMarkdown(A){let{frontmatter:Q}=this.parseWishContent(A),w=H1(Q.title);return{content:A,entityType:"wish",metadata:{title:Q.title,status:Q.status,priority:Q.priority,requested:Q.requested,slug:w}}}}var j22=new So;U2();U2();async function P22(A,Q){let w=`${Q.title}: ${Q.description}`,$=(await A.search({query:w,options:{types:["wish"],limit:1}}))[0];if($&&$.score>=A.similarityThreshold)return $.entity;let f=H1(Q.title);return A.getEntity({entityType:"wish",id:f})}class TX0{logger;context;adapter=new So;constructor(A,Q){this.logger=A,this.context=Q}async process(A,Q,w){let B=A.title??A.prompt??"Untitled wish",$=A.content??A.prompt??"",f=await P22({search:(W)=>this.context.entityService.search(W),getEntity:(W)=>this.context.entityService.getEntity(W),similarityThreshold:0.85},{title:B,description:$});if(f){let{frontmatter:W,description:K}=this.adapter.parseWishContent(f.content),U=W.requested+1,G=this.adapter.createWishContent({...W,requested:U},K);return await this.context.entityService.updateEntity({entity:{...f,content:G,metadata:{...f.metadata,requested:U}}}),this.logger.info("Incremented wish request count",{id:f.id,requested:U}),{success:!0,entityId:f.id,existed:!0,requested:U}}let Y=H1(B),X=A.options?.priority??"medium",H=this.adapter.createWishContent({title:B,status:"new",priority:X,requested:1},$);return await this.context.entityService.createEntity({entity:{id:Y,entityType:"wish",content:H,metadata:{title:B,status:"new",priority:X,requested:1,slug:Y}}}),this.logger.info("Created new wish",{id:Y,title:B}),{success:!0,entityId:Y,existed:!1,requested:1}}}var M22={critical:0,high:1,medium:2,low:3};function O22(A){A.sort((Q,w)=>{let B=w.metadata.requested-Q.metadata.requested;if(B!==0)return B;return M22[Q.metadata.priority]-M22[w.metadata.priority]})}var x22={name:"@brains/wishlist",version:"0.2.0-alpha.150",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:"^6.0.3"},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 nVw=Z.object({items:Z.array(Z.object({name:Z.string(),count:Z.number()}))}),rVw="wish";class v22 extends rQ{entityType=rVw;schema=To;adapter=j22;constructor(A={}){super("wishlist",x22,A,Sa0)}async interceptCreate(A,Q,w){let B=await new TX0(this.logger,w).process({...A.title?{title:A.title}:{},...A.prompt?{prompt:A.prompt}:{},...A.content?{content:A.content}:{}},`wish-create-${Date.now()}`,{});if(!B.success)return{kind:"handled",result:{success:!1,error:B.error??"Failed to create wish"}};return{kind:"handled",result:{success:!0,data:{...B.entityId?{entityId:B.entityId}:{},status:B.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:B}=nVw.parse(w),$=B[0];return{digest:$?[{label:"Top wish",value:`${$.name} \xB7 \xD7${$.count}`}]:[{label:"Wishes",value:"none yet"}]}},dataProvider:async()=>{let w=await A.entityService.listEntities({entityType:"wish",options:{limit:10}});return O22(w),{items:w.map((B)=>({id:B.id,name:B.metadata.title,count:B.metadata.requested,priority:B.metadata.priority,status:B.metadata.status}))}}}}),{success:!0}});let Q=new TX0(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 oVw(A={}){return new v22(A)}var SX0=oVw;wA();wA();_0();var mo=Z.object({title:Z.string(),target:Z.string()}),R22=Z.object({title:Z.string(),target:Z.string(),slug:Z.string().optional()}),uo=_Q.extend({entityType:Z.literal("prompt"),metadata:R22});wA();U2();class ma0 extends g2{constructor(){super({entityType:"prompt",purpose:"A reusable prompt or instruction template.",schema:uo,frontmatterSchema:mo})}toMarkdown(A){let Q=this.extractBody(A.content),w=this.parseFrontMatter(A.content,mo);return this.buildMarkdown(Q,w)}fromMarkdown(A){let Q=this.parseFrontMatter(A,mo),w=H1(Q.target.replace(/:/g,"-"));return{content:A,entityType:"prompt",metadata:{title:Q.title,target:Q.target,slug:w}}}}var ua0=new ma0;var h22={name:"@brains/prompt",version:"0.2.0-alpha.150",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:"^6.0.3"},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 aVw="prompt";class ca0 extends rQ{entityType=aVw;schema=uo;adapter=ua0;constructor(){super("prompt",h22,{},k7)}getEntityTypeConfig(){return{embeddable:!1}}}function bP(){return new ca0}wA();_0();_0();class mX0{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 B=await this.fetchFn(w.toString(),{headers:{Authorization:`Client-ID ${this.apiKey}`}});if(!B.ok)throw Error(`Unsplash API error: ${B.status} ${B.statusText}`);let $=eVw.parse(await B.json());return{photos:$.results.map(Abw),total:$.total,totalPages:$.total_pages,page:Q.page}}async triggerDownload(A){try{await this.fetchFn(A,{headers:{Authorization:`Client-ID ${this.apiKey}`}})}catch{}}}var tVw=Z.looseObject({id:Z.string(),description:Z.string().nullable(),alt_description:Z.string().nullable(),urls:Z.looseObject({raw:Z.url(),full:Z.url(),regular:Z.url(),small:Z.url(),thumb:Z.url()}),links:Z.looseObject({html:Z.url(),download_location:Z.url()}),user:Z.looseObject({name:Z.string(),links:Z.looseObject({html:Z.url()})}),width:Z.number().int().nonnegative(),height:Z.number().int().nonnegative()}),eVw=Z.looseObject({total:Z.number().int().nonnegative(),total_pages:Z.number().int().nonnegative(),results:Z.array(tVw)});function Abw(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}}_0();async function uX0(A,Q,w,B){let $=await A.getEntity({entityType:Q,id:w});if(!$)return!1;return await A.updateEntity({entity:{...$,metadata:{...$.metadata,coverImageId:B}}}),!0}var Qbw={query:Z.string().describe("Search terms for stock photos"),perPage:Z.number().min(1).max(30).default(10).describe("Results per page (1-30)"),page:Z.number().min(1).default(1).describe("Page number")},wbw={photoId:Z.string().describe("Photo ID from search results"),downloadLocation:Z.url().describe("Download tracking URL (required by provider ToS)"),photographerName:Z.string().describe("Photographer name for attribution"),photographerUrl:Z.url().describe("Photographer profile URL for attribution"),sourceUrl:Z.url().describe("Photo page URL on provider"),imageUrl:Z.url().describe("Image URL to download"),title:Z.string().optional().describe("Image entity title"),alt:Z.string().optional().describe("Alt text for the image"),targetEntityType:Z.string().optional().describe("Entity type to set cover image on"),targetEntityId:Z.string().optional().describe("Entity ID to set cover image on")},Bbw=Z.object({query:Z.string(),perPage:Z.number().min(1).max(30).default(10),page:Z.number().min(1).default(1)}),$bw=Z.object({photoId:Z.string(),downloadLocation:Z.url(),photographerName:Z.string(),photographerUrl:Z.url(),sourceUrl:Z.url(),imageUrl:Z.url(),title:Z.string().optional(),alt:Z.string().optional(),targetEntityType:Z.string().optional(),targetEntityId:Z.string().optional()});function C22(A,Q){return[fbw(A,Q),Ybw(A,Q)]}function fbw(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:Qbw,visibility:"anchor",sideEffects:"none",handler:async(w)=>{let B=Bbw.safeParse(w);if(!B.success)return{success:!1,error:`Invalid input: ${B.error.message}`};try{return{success:!0,data:await Q.provider.searchPhotos(B.data.query,{page:B.data.page,perPage:B.data.perPage})}}catch($){return{success:!1,error:$ instanceof Error?$.message:"Search failed"}}}}}function Ybw(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:wbw,visibility:"anchor",sideEffects:"external",handler:async(w)=>{let B=$bw.safeParse(w);if(!B.success)return{success:!1,error:`Invalid input: ${B.error.message}`};let{photoId:$,downloadLocation:f,photographerName:Y,photographerUrl:X,sourceUrl:H,imageUrl:W,title:K,alt:U,targetEntityType:G,targetEntityId:q}=B.data,V={photographerName:Y,photographerUrl:X,sourceUrl:H},J=await Q.entityService.listEntities({entityType:"image",options:{limit:1,filter:{metadata:{sourceUrl:W}}}});if(J[0]){let N={imageEntityId:J[0].id,alreadyExisted:!0,attribution:V};if(G&&q)N.coverSet=await uX0(Q.entityService,G,q,J[0].id);return{success:!0,data:N}}let b=await Q.jobs.enqueue({type:"select-photo",data:{photoId:$,downloadLocation:f,photographerName:Y,photographerUrl:X,sourceUrl:H,imageUrl:W,...K!==void 0?{title:K}:{},...U!==void 0?{alt:U}:{},...G!==void 0?{targetEntityType:G}:{},...q!==void 0?{targetEntityId:q}:{}}}),L={imageEntityId:$,alreadyExisted:!1,attribution:V,jobId:b,status:"generating"};if(G&&q)L.coverSet=!1;return{success:!0,data:L}}}}wA();_0();F4();var Xbw=Z.object({photoId:Z.string(),downloadLocation:Z.url(),photographerName:Z.string(),photographerUrl:Z.url(),sourceUrl:Z.url(),imageUrl:Z.url(),title:Z.string().optional(),alt:Z.string().optional(),targetEntityType:Z.string().optional(),targetEntityId:Z.string().optional()});class la0 extends tw{deps;constructor(A,Q){super(A,{schema:Xbw,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 B=await this.deps.fetchImage(A.imageUrl),$=A.title??`Stock photo ${A.photoId}`,f=mX.createImageEntity({dataUrl:B,title:$,alt:A.alt??$});await this.reportProgress(w,{progress:75,message:"Saving stock photo"});let{entityId:Y}=await this.deps.entityService.createEntity({entity:{id:A.photoId,...f,metadata:{...f.metadata,sourceUrl:A.imageUrl}}}),X={imageEntityId:Y,alreadyExisted:!1};if(A.targetEntityType&&A.targetEntityId){if(X.coverSet=await uX0(this.deps.entityService,A.targetEntityType,A.targetEntityId,Y),!X.coverSet)X.warning=`Target entity ${A.targetEntityType}:${A.targetEntityId} not found; cover image not set`}return await this.reportProgress(w,{progress:100,message:"Stock photo selected"}),X}summarizeDataForLog(A){return{photoId:A.photoId,hasTarget:A.targetEntityType!==void 0}}}F4();var g22={name:"@brains/stock-photo",version:"0.2.0-alpha.150",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:"^6.0.3"},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 Hbw=Z.object({provider:Z.enum(["unsplash"]).default("unsplash"),apiKey:Z.string().optional().describe("Stock photo provider API key")});class pa0 extends tQ{deps;cachedTools=null;constructor(A={},Q={}){super("stock-photo",g22,A,Hbw);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=C22(this.id,{provider:Q,entityService:A.entityService,fetchImage:this.deps.fetchImage??TH,jobs:A.jobs}),this.cachedTools}async registerJobHandlers(){if(!this.config.apiKey)return;let A=this.getContext();A.jobs.registerHandler("select-photo",new la0(this.logger.child("SelectPhotoJobHandler"),{provider:this.createProvider(),entityService:A.entityService,fetchImage:this.deps.fetchImage??TH}))}createProvider(){return new mX0(this.config.apiKey??"",this.deps.fetch??globalThis.fetch)}}function ia0(A={},Q={}){return new pa0(A,Q)}wA();_0();wA();wA();_0();var y22=Z.enum(["ai","foundation","work"]),E22=Z.object({suffix:y22,title:Z.string(),body:Z.string(),linkLabel:Z.string(),linkHref:Z.string()}),co=Z.object({eyebrow:Z.string(),headline:Z.string(),cards:Z.array(E22).min(1)}),da0=Z.object({title:Z.string(),slug:Z.string(),status:Z.enum(["draft","published"])}),Wbw=Z.object({title:Z.string(),slug:Z.string(),status:Z.enum(["draft","published"])}),lo=_Q.extend({entityType:Z.literal("ecosystem-section"),metadata:Wbw});class T22 extends g2{constructor(){super({entityType:"ecosystem-section",purpose:"A section of the Rizom ecosystem overview.",schema:lo,frontmatterSchema:da0})}fromMarkdown(A){return{content:A,entityType:"ecosystem-section",metadata:this.parseFrontmatter(A)}}}var na0=new T22;_0();function Kbw(A){return A.replace(/^---\n[\s\S]*?\n---\n?/,"")}function ra0(A,Q){return new RegExp(`(?:^|\\n)## ${Q}\\s*\\n([\\s\\S]*?)(?=\\n## |$)`).exec(A)?.[1]?.trim()??""}function po(A,Q){return new RegExp(`(?:^|\\n)#### ${Q}\\s*\\n([\\s\\S]*?)(?=\\n#### |\\n### |$)`).exec(A)?.[1]?.trim()??""}function cX0(A){let Q=Kbw(A),B=ra0(Q,"Cards").split(/^### Card \d+\s*$/m).map(($)=>$.trim()).filter(Boolean);return co.parse({eyebrow:ra0(Q,"Eyebrow"),headline:ra0(Q,"Headline"),cards:B.map(($)=>({suffix:po($,"Suffix"),title:po($,"Title"),body:po($,"Body"),linkLabel:po($,"Link Label"),linkHref:po($,"Link Href")}))})}function S22(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(`
|
|
9488
|
+
`)}function I22(A){try{return F22(JSON.stringify(A),1200)}catch{return"[unserializable]"}}function F22(A,Q){return A.length>Q?`${A.slice(0,Q)}\u2026`:A}var EVw={async evaluate(){return{met:!1,reason:"No playbook goal check is configured."}}};function ya0(A={},Q={}){return new ga0(A,Q)}y6();wA();_0();import{readFile as SVw}from"fs/promises";import{join as mVw}from"path";var L22={name:"@brains/rover-onboarding",version:"0.2.0-alpha.151",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 uVw=Z.object({enabled:Z.boolean().default(!1)}).strict(),k22=[{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 _22 extends tQ{dependencies=["playbook","playbooks"];constructor(A={}){super("rover-onboarding",L22,A,uVw)}async onReady(A){if(!this.config.enabled)return;for(let Q of k22)await this.seedPlaybookIfMissing(A,Q);for(let Q of k22){if(!Q.starter)continue;await A.messaging.send({type:wO,payload:Q.starter})}}async seedPlaybookIfMissing(A,Q){if(await A.entityService.getEntity({entityType:"playbook",id:Q.id,visibilityScope:"restricted"}))return;let B=await SVw(mVw(import.meta.dir,"..","content","playbook",Q.fileName),"utf8");await A.entityService.createEntityFromMarkdown({input:{entityType:"playbook",id:Q.id,markdown:B}})}}function N22(A={}){return new _22(A)}wA();_0();_0();wA();var Ea0=Z.enum(["new","planned","in-progress","done","declined"]),Ta0=Z.enum(["low","medium","high","critical"]),cVw=Z.enum(["new","planned","in-progress","done","declined"]),lVw=Z.enum(["low","medium","high","critical"]),Eo=Z.object({title:Z.string(),status:Ea0,priority:Ta0.default("medium"),requested:Z.number().int().default(1),declinedReason:Z.string().optional()}),pVw=Z.object({title:Z.string(),status:Ea0,priority:Ta0,requested:Z.number().int(),slug:Z.string()}),iVw=Z.object({title:Z.string(),status:cVw,priority:lVw,requested:Z.number().int(),slug:Z.string()}),To=_Q.extend({entityType:Z.literal("wish"),metadata:iVw});_0();var Sa0=Z.object({}).catchall(Z.unknown()).transform(()=>({}));wA();U2();class So extends g2{constructor(){super({entityType:"wish",purpose:"An explicitly recorded capability or outcome the assistant cannot currently fulfill, kept for future planning.",schema:To,frontmatterSchema:Eo})}createWishContent(A,Q){return this.buildMarkdown(Q,A)}parseWishContent(A){let Q=this.parseFrontMatter(A,Eo);return{frontmatter:Eo.parse(Q),description:this.extractBody(A).trim()}}fromMarkdown(A){let{frontmatter:Q}=this.parseWishContent(A),w=H1(Q.title);return{content:A,entityType:"wish",metadata:{title:Q.title,status:Q.status,priority:Q.priority,requested:Q.requested,slug:w}}}}var j22=new So;U2();U2();async function P22(A,Q){let w=`${Q.title}: ${Q.description}`,$=(await A.search({query:w,options:{types:["wish"],limit:1}}))[0];if($&&$.score>=A.similarityThreshold)return $.entity;let f=H1(Q.title);return A.getEntity({entityType:"wish",id:f})}class TX0{logger;context;adapter=new So;constructor(A,Q){this.logger=A,this.context=Q}async process(A,Q,w){let B=A.title??A.prompt??"Untitled wish",$=A.content??A.prompt??"",f=await P22({search:(W)=>this.context.entityService.search(W),getEntity:(W)=>this.context.entityService.getEntity(W),similarityThreshold:0.85},{title:B,description:$});if(f){let{frontmatter:W,description:K}=this.adapter.parseWishContent(f.content),U=W.requested+1,G=this.adapter.createWishContent({...W,requested:U},K);return await this.context.entityService.updateEntity({entity:{...f,content:G,metadata:{...f.metadata,requested:U}}}),this.logger.info("Incremented wish request count",{id:f.id,requested:U}),{success:!0,entityId:f.id,existed:!0,requested:U}}let Y=H1(B),X=A.options?.priority??"medium",H=this.adapter.createWishContent({title:B,status:"new",priority:X,requested:1},$);return await this.context.entityService.createEntity({entity:{id:Y,entityType:"wish",content:H,metadata:{title:B,status:"new",priority:X,requested:1,slug:Y}}}),this.logger.info("Created new wish",{id:Y,title:B}),{success:!0,entityId:Y,existed:!1,requested:1}}}var M22={critical:0,high:1,medium:2,low:3};function O22(A){A.sort((Q,w)=>{let B=w.metadata.requested-Q.metadata.requested;if(B!==0)return B;return M22[Q.metadata.priority]-M22[w.metadata.priority]})}var x22={name:"@brains/wishlist",version:"0.2.0-alpha.151",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 nVw=Z.object({items:Z.array(Z.object({name:Z.string(),count:Z.number()}))}),rVw="wish";class v22 extends rQ{entityType=rVw;schema=To;adapter=j22;constructor(A={}){super("wishlist",x22,A,Sa0)}async interceptCreate(A,Q,w){let B=await new TX0(this.logger,w).process({...A.title?{title:A.title}:{},...A.prompt?{prompt:A.prompt}:{},...A.content?{content:A.content}:{}},`wish-create-${Date.now()}`,{});if(!B.success)return{kind:"handled",result:{success:!1,error:B.error??"Failed to create wish"}};return{kind:"handled",result:{success:!0,data:{...B.entityId?{entityId:B.entityId}:{},status:B.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:B}=nVw.parse(w),$=B[0];return{digest:$?[{label:"Top wish",value:`${$.name} \xB7 \xD7${$.count}`}]:[{label:"Wishes",value:"none yet"}]}},dataProvider:async()=>{let w=await A.entityService.listEntities({entityType:"wish",options:{limit:10}});return O22(w),{items:w.map((B)=>({id:B.id,name:B.metadata.title,count:B.metadata.requested,priority:B.metadata.priority,status:B.metadata.status}))}}}}),{success:!0}});let Q=new TX0(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 oVw(A={}){return new v22(A)}var SX0=oVw;wA();wA();_0();var mo=Z.object({title:Z.string(),target:Z.string()}),R22=Z.object({title:Z.string(),target:Z.string(),slug:Z.string().optional()}),uo=_Q.extend({entityType:Z.literal("prompt"),metadata:R22});wA();U2();class ma0 extends g2{constructor(){super({entityType:"prompt",purpose:"A reusable prompt or instruction template.",schema:uo,frontmatterSchema:mo})}toMarkdown(A){let Q=this.extractBody(A.content),w=this.parseFrontMatter(A.content,mo);return this.buildMarkdown(Q,w)}fromMarkdown(A){let Q=this.parseFrontMatter(A,mo),w=H1(Q.target.replace(/:/g,"-"));return{content:A,entityType:"prompt",metadata:{title:Q.title,target:Q.target,slug:w}}}}var ua0=new ma0;var h22={name:"@brains/prompt",version:"0.2.0-alpha.151",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 aVw="prompt";class ca0 extends rQ{entityType=aVw;schema=uo;adapter=ua0;constructor(){super("prompt",h22,{},k7)}getEntityTypeConfig(){return{embeddable:!1}}}function bP(){return new ca0}wA();_0();_0();class mX0{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 B=await this.fetchFn(w.toString(),{headers:{Authorization:`Client-ID ${this.apiKey}`}});if(!B.ok)throw Error(`Unsplash API error: ${B.status} ${B.statusText}`);let $=eVw.parse(await B.json());return{photos:$.results.map(Abw),total:$.total,totalPages:$.total_pages,page:Q.page}}async triggerDownload(A){try{await this.fetchFn(A,{headers:{Authorization:`Client-ID ${this.apiKey}`}})}catch{}}}var tVw=Z.looseObject({id:Z.string(),description:Z.string().nullable(),alt_description:Z.string().nullable(),urls:Z.looseObject({raw:Z.url(),full:Z.url(),regular:Z.url(),small:Z.url(),thumb:Z.url()}),links:Z.looseObject({html:Z.url(),download_location:Z.url()}),user:Z.looseObject({name:Z.string(),links:Z.looseObject({html:Z.url()})}),width:Z.number().int().nonnegative(),height:Z.number().int().nonnegative()}),eVw=Z.looseObject({total:Z.number().int().nonnegative(),total_pages:Z.number().int().nonnegative(),results:Z.array(tVw)});function Abw(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}}_0();async function uX0(A,Q,w,B){let $=await A.getEntity({entityType:Q,id:w});if(!$)return!1;return await A.updateEntity({entity:{...$,metadata:{...$.metadata,coverImageId:B}}}),!0}var Qbw={query:Z.string().describe("Search terms for stock photos"),perPage:Z.number().min(1).max(30).default(10).describe("Results per page (1-30)"),page:Z.number().min(1).default(1).describe("Page number")},wbw={photoId:Z.string().describe("Photo ID from search results"),downloadLocation:Z.url().describe("Download tracking URL (required by provider ToS)"),photographerName:Z.string().describe("Photographer name for attribution"),photographerUrl:Z.url().describe("Photographer profile URL for attribution"),sourceUrl:Z.url().describe("Photo page URL on provider"),imageUrl:Z.url().describe("Image URL to download"),title:Z.string().optional().describe("Image entity title"),alt:Z.string().optional().describe("Alt text for the image"),targetEntityType:Z.string().optional().describe("Entity type to set cover image on"),targetEntityId:Z.string().optional().describe("Entity ID to set cover image on")},Bbw=Z.object({query:Z.string(),perPage:Z.number().min(1).max(30).default(10),page:Z.number().min(1).default(1)}),$bw=Z.object({photoId:Z.string(),downloadLocation:Z.url(),photographerName:Z.string(),photographerUrl:Z.url(),sourceUrl:Z.url(),imageUrl:Z.url(),title:Z.string().optional(),alt:Z.string().optional(),targetEntityType:Z.string().optional(),targetEntityId:Z.string().optional()});function C22(A,Q){return[fbw(A,Q),Ybw(A,Q)]}function fbw(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:Qbw,visibility:"anchor",sideEffects:"none",handler:async(w)=>{let B=Bbw.safeParse(w);if(!B.success)return{success:!1,error:`Invalid input: ${B.error.message}`};try{return{success:!0,data:await Q.provider.searchPhotos(B.data.query,{page:B.data.page,perPage:B.data.perPage})}}catch($){return{success:!1,error:$ instanceof Error?$.message:"Search failed"}}}}}function Ybw(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:wbw,visibility:"anchor",sideEffects:"external",handler:async(w)=>{let B=$bw.safeParse(w);if(!B.success)return{success:!1,error:`Invalid input: ${B.error.message}`};let{photoId:$,downloadLocation:f,photographerName:Y,photographerUrl:X,sourceUrl:H,imageUrl:W,title:K,alt:U,targetEntityType:G,targetEntityId:q}=B.data,V={photographerName:Y,photographerUrl:X,sourceUrl:H},J=await Q.entityService.listEntities({entityType:"image",options:{limit:1,filter:{metadata:{sourceUrl:W}}}});if(J[0]){let N={imageEntityId:J[0].id,alreadyExisted:!0,attribution:V};if(G&&q)N.coverSet=await uX0(Q.entityService,G,q,J[0].id);return{success:!0,data:N}}let b=await Q.jobs.enqueue({type:"select-photo",data:{photoId:$,downloadLocation:f,photographerName:Y,photographerUrl:X,sourceUrl:H,imageUrl:W,...K!==void 0?{title:K}:{},...U!==void 0?{alt:U}:{},...G!==void 0?{targetEntityType:G}:{},...q!==void 0?{targetEntityId:q}:{}}}),L={imageEntityId:$,alreadyExisted:!1,attribution:V,jobId:b,status:"generating"};if(G&&q)L.coverSet=!1;return{success:!0,data:L}}}}wA();_0();F4();var Xbw=Z.object({photoId:Z.string(),downloadLocation:Z.url(),photographerName:Z.string(),photographerUrl:Z.url(),sourceUrl:Z.url(),imageUrl:Z.url(),title:Z.string().optional(),alt:Z.string().optional(),targetEntityType:Z.string().optional(),targetEntityId:Z.string().optional()});class la0 extends tw{deps;constructor(A,Q){super(A,{schema:Xbw,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 B=await this.deps.fetchImage(A.imageUrl),$=A.title??`Stock photo ${A.photoId}`,f=mX.createImageEntity({dataUrl:B,title:$,alt:A.alt??$});await this.reportProgress(w,{progress:75,message:"Saving stock photo"});let{entityId:Y}=await this.deps.entityService.createEntity({entity:{id:A.photoId,...f,metadata:{...f.metadata,sourceUrl:A.imageUrl}}}),X={imageEntityId:Y,alreadyExisted:!1};if(A.targetEntityType&&A.targetEntityId){if(X.coverSet=await uX0(this.deps.entityService,A.targetEntityType,A.targetEntityId,Y),!X.coverSet)X.warning=`Target entity ${A.targetEntityType}:${A.targetEntityId} not found; cover image not set`}return await this.reportProgress(w,{progress:100,message:"Stock photo selected"}),X}summarizeDataForLog(A){return{photoId:A.photoId,hasTarget:A.targetEntityType!==void 0}}}F4();var g22={name:"@brains/stock-photo",version:"0.2.0-alpha.151",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 Hbw=Z.object({provider:Z.enum(["unsplash"]).default("unsplash"),apiKey:Z.string().optional().describe("Stock photo provider API key")});class pa0 extends tQ{deps;cachedTools=null;constructor(A={},Q={}){super("stock-photo",g22,A,Hbw);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=C22(this.id,{provider:Q,entityService:A.entityService,fetchImage:this.deps.fetchImage??TH,jobs:A.jobs}),this.cachedTools}async registerJobHandlers(){if(!this.config.apiKey)return;let A=this.getContext();A.jobs.registerHandler("select-photo",new la0(this.logger.child("SelectPhotoJobHandler"),{provider:this.createProvider(),entityService:A.entityService,fetchImage:this.deps.fetchImage??TH}))}createProvider(){return new mX0(this.config.apiKey??"",this.deps.fetch??globalThis.fetch)}}function ia0(A={},Q={}){return new pa0(A,Q)}wA();_0();wA();wA();_0();var y22=Z.enum(["ai","foundation","work"]),E22=Z.object({suffix:y22,title:Z.string(),body:Z.string(),linkLabel:Z.string(),linkHref:Z.string()}),co=Z.object({eyebrow:Z.string(),headline:Z.string(),cards:Z.array(E22).min(1)}),da0=Z.object({title:Z.string(),slug:Z.string(),status:Z.enum(["draft","published"])}),Wbw=Z.object({title:Z.string(),slug:Z.string(),status:Z.enum(["draft","published"])}),lo=_Q.extend({entityType:Z.literal("ecosystem-section"),metadata:Wbw});class T22 extends g2{constructor(){super({entityType:"ecosystem-section",purpose:"A section of the Rizom ecosystem overview.",schema:lo,frontmatterSchema:da0})}fromMarkdown(A){return{content:A,entityType:"ecosystem-section",metadata:this.parseFrontmatter(A)}}}var na0=new T22;_0();function Kbw(A){return A.replace(/^---\n[\s\S]*?\n---\n?/,"")}function ra0(A,Q){return new RegExp(`(?:^|\\n)## ${Q}\\s*\\n([\\s\\S]*?)(?=\\n## |$)`).exec(A)?.[1]?.trim()??""}function po(A,Q){return new RegExp(`(?:^|\\n)#### ${Q}\\s*\\n([\\s\\S]*?)(?=\\n#### |\\n### |$)`).exec(A)?.[1]?.trim()??""}function cX0(A){let Q=Kbw(A),B=ra0(Q,"Cards").split(/^### Card \d+\s*$/m).map(($)=>$.trim()).filter(Boolean);return co.parse({eyebrow:ra0(Q,"Eyebrow"),headline:ra0(Q,"Headline"),cards:B.map(($)=>({suffix:po($,"Suffix"),title:po($,"Title"),body:po($,"Body"),linkLabel:po($,"Link Label"),linkHref:po($,"Link Href")}))})}function S22(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(`
|
|
9489
9489
|
`)}var Ubw=Z.looseObject({query:Z.object({id:Z.string().optional()}).optional()});class lX0{id="rizom-ecosystem:entities";name="Rizom Ecosystem";description="Fetches an ecosystem-section entity for rendering";async fetch(A,Q,w){let $=Ubw.parse(A??{}).query?.id??"rizom-ecosystem",f=await w.entityService.getEntity({entityType:"ecosystem-section",id:$});if(!f)throw Error(`Ecosystem section not found: ${$}`);return Q.parse(cX0(f.content))}}import{jsxDEV as zbw}from"preact/jsx-dev-runtime";var Gbw="px-6 md:px-10 xl:px-20",Dbw=`${Gbw} relative z-[1]`,m22=({id:A,className:Q,children:w})=>zbw("section",{id:A,className:N2(Dbw,Q),children:w},void 0,!1,void 0,this);import{jsxDEV as pX0}from"preact/jsx-dev-runtime";var qbw=new Map([["work","text-accent"],["foundation","text-secondary"],["ai","text-accent-bright"]]),u22=({name:A="rizom",brandSuffix:Q,className:w,dotClassName:B,suffixClassName:$})=>{let f=qbw.get(Q);return pX0("span",{className:N2("inline-flex items-baseline gap-0 font-display font-medium tracking-[-0.015em] [font-variation-settings:'opsz'_24]",w),children:[pX0("span",{className:"text-theme",children:A},void 0,!1,void 0,this),pX0("span",{className:N2(f??"text-accent",B),children:"."},void 0,!1,void 0,this),pX0("span",{className:N2("italic font-normal text-theme-muted",$),children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{Fragment as oa0}from"preact";import{jsxDEV as io}from"preact/jsx-dev-runtime";var Vbw=/(\*[^*]+\*)/;function c22(A,Q){let w=A.split(`
|
|
9490
|
-
`);return io(oa0,{children:w.map((B,$)=>io(oa0,{children:[$>0&&io("br",{},void 0,!1,void 0,this),B.split(Vbw).map((f,Y)=>{if(f.length>=3&&f.startsWith("*")&&f.endsWith("*"))return io("span",{className:Q,children:f.slice(1,-1)},Y,!1,void 0,this);return io(oa0,{children:f},Y,!1,void 0,this)})]},$,!0,void 0,this))},void 0,!1,void 0,this)}import{jsxDEV as aY,Fragment as Mbw}from"preact/jsx-dev-runtime";var bbw="italic text-accent font-normal",Jbw="You are here",Ibw={work:"text-accent",foundation:"text-secondary",ai:"text-accent-bright"},Fbw={work:"border-t-accent/60",foundation:"border-t-secondary/60",ai:"border-t-accent-bright/60"},Lbw={work:"hover:border-t-accent",foundation:"hover:border-t-secondary",ai:"hover:border-t-accent-bright"},kbw="font-label text-[10.5px] uppercase tracking-[0.26em] mt-1",_bw="font-body text-[15px] leading-[1.6] text-theme-muted mt-2",Nbw="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",jbw="font-label text-[10.5px] uppercase tracking-[0.22em] text-accent self-start mt-[18px] pb-1",Pbw=({card:A})=>{let Q=A.linkLabel===Jbw,w=A.linkHref.trim().length===0,B=aY(Mbw,{children:[aY(u22,{brandSuffix:A.suffix,className:"text-[clamp(28px,3vw,40px)] [font-variation-settings:'opsz'_96]"},void 0,!1,void 0,this),aY("span",{className:`${kbw} ${Ibw[A.suffix]}`,children:A.title},void 0,!1,void 0,this),aY("p",{className:_bw,children:A.body},void 0,!1,void 0,this),Q?aY("span",{className:jbw,children:A.linkLabel},void 0,!1,void 0,this):aY("span",{className:Nbw,children:A.linkLabel},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$=`flex flex-col gap-[14px] border-t pt-7 ${Q?Fbw[A.suffix]:"border-white/10"}`;return Q||w?aY("div",{className:$,children:B},void 0,!1,void 0,this):aY("a",{href:A.linkHref,className:`${$} text-inherit no-underline transition-colors ${Lbw[A.suffix]}`,children:B},void 0,!1,void 0,this)},l22=({eyebrow:A,headline:Q,cards:w})=>aY(m22,{id:"ecosystem",className:"pt-[112px] pb-[144px] border-t border-white/5",children:[aY("div",{className:"mx-auto mb-[88px] max-w-[1180px] text-center",children:[aY("span",{className:"font-label text-[11px] font-semibold uppercase tracking-[0.24em] text-accent",children:A},void 0,!1,void 0,this),aY("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:c22(Q,bbw)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),aY("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((B)=>aY(Pbw,{card:B},B.suffix,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this);wA();var sa0=d1({name:"ecosystem",description:"Rizom ecosystem sibling-site section",schema:co,formatter:{parse:cX0,format:S22},dataSourceId:"rizom-ecosystem:entities",requiredPermission:"public",layout:{component:l22}});var p22={name:"@brains/rizom-ecosystem",version:"0.2.0-alpha.
|
|
9490
|
+
`);return io(oa0,{children:w.map((B,$)=>io(oa0,{children:[$>0&&io("br",{},void 0,!1,void 0,this),B.split(Vbw).map((f,Y)=>{if(f.length>=3&&f.startsWith("*")&&f.endsWith("*"))return io("span",{className:Q,children:f.slice(1,-1)},Y,!1,void 0,this);return io(oa0,{children:f},Y,!1,void 0,this)})]},$,!0,void 0,this))},void 0,!1,void 0,this)}import{jsxDEV as aY,Fragment as Mbw}from"preact/jsx-dev-runtime";var bbw="italic text-accent font-normal",Jbw="You are here",Ibw={work:"text-accent",foundation:"text-secondary",ai:"text-accent-bright"},Fbw={work:"border-t-accent/60",foundation:"border-t-secondary/60",ai:"border-t-accent-bright/60"},Lbw={work:"hover:border-t-accent",foundation:"hover:border-t-secondary",ai:"hover:border-t-accent-bright"},kbw="font-label text-[10.5px] uppercase tracking-[0.26em] mt-1",_bw="font-body text-[15px] leading-[1.6] text-theme-muted mt-2",Nbw="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",jbw="font-label text-[10.5px] uppercase tracking-[0.22em] text-accent self-start mt-[18px] pb-1",Pbw=({card:A})=>{let Q=A.linkLabel===Jbw,w=A.linkHref.trim().length===0,B=aY(Mbw,{children:[aY(u22,{brandSuffix:A.suffix,className:"text-[clamp(28px,3vw,40px)] [font-variation-settings:'opsz'_96]"},void 0,!1,void 0,this),aY("span",{className:`${kbw} ${Ibw[A.suffix]}`,children:A.title},void 0,!1,void 0,this),aY("p",{className:_bw,children:A.body},void 0,!1,void 0,this),Q?aY("span",{className:jbw,children:A.linkLabel},void 0,!1,void 0,this):aY("span",{className:Nbw,children:A.linkLabel},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$=`flex flex-col gap-[14px] border-t pt-7 ${Q?Fbw[A.suffix]:"border-white/10"}`;return Q||w?aY("div",{className:$,children:B},void 0,!1,void 0,this):aY("a",{href:A.linkHref,className:`${$} text-inherit no-underline transition-colors ${Lbw[A.suffix]}`,children:B},void 0,!1,void 0,this)},l22=({eyebrow:A,headline:Q,cards:w})=>aY(m22,{id:"ecosystem",className:"pt-[112px] pb-[144px] border-t border-white/5",children:[aY("div",{className:"mx-auto mb-[88px] max-w-[1180px] text-center",children:[aY("span",{className:"font-label text-[11px] font-semibold uppercase tracking-[0.24em] text-accent",children:A},void 0,!1,void 0,this),aY("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:c22(Q,bbw)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),aY("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((B)=>aY(Pbw,{card:B},B.suffix,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this);wA();var sa0=d1({name:"ecosystem",description:"Rizom ecosystem sibling-site section",schema:co,formatter:{parse:cX0,format:S22},dataSourceId:"rizom-ecosystem:entities",requiredPermission:"public",layout:{component:l22}});var p22={name:"@brains/rizom-ecosystem",version:"0.2.0-alpha.151",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 xbw=Z.object({}).catchall(Z.unknown()).transform(()=>({})),vbw="ecosystem-section";class aa0 extends rQ{entityType=vbw;schema=lo;adapter=na0;constructor(A={}){super("rizom-ecosystem",p22,A,xbw)}getTemplates(){return{ecosystem:sa0}}getDataSources(){return[new lX0]}}function JP(A={}){return new aa0(A)}_0();wA();wA();U2();_0();t8();_0();wA();var E$="agent",i22="agent-discovery";var d22="agent-network",n22="AgentNetworkWidget",no="agent-discovery:entities",ta0="agent-list",ea0="agent-detail",j5="skill",r22="skill",iX0="skill-derivation",o22="skill:project",s22="skill-derivation",a22="skill:skill-derivation",t22="skills";var dX0=Z.object({name:Z.string(),description:Z.string(),tags:Z.array(Z.string())}),Ry=Z.enum(["discovered","approved"]).describe("Discovered for review or approved for calling"),e22=Z.enum(["discovered","approved"]).describe("Discovered for review or approved for calling"),Rbw=Z.enum(["professional","team","collective"]),UV=Z.object({name:Z.string(),kind:Rbw,organization:Z.string().optional(),brainName:Z.string().describe("Name of the brain instance"),url:Z.string().url().describe("Brain endpoint URL"),did:Z.string().optional().describe("Decentralized identifier (public)"),repoDid:Z.string().optional().describe("ATProto repo DID"),brainDid:Z.string().optional().describe("ATProto brain DID"),anchorDid:Z.string().optional().describe("ATProto anchor DID"),cardUri:Z.string().optional().describe("ATProto brain card URI"),cardCid:Z.string().optional().describe("ATProto brain card CID"),a2aEndpoint:Z.string().url().optional().describe("A2A endpoint URL"),status:Ry,discoveredAt:Z.string().datetime().describe("When this agent was first discovered")}),AQ2=Z.object({name:Z.string(),url:Z.string().url(),status:Ry,discoveredAt:Z.string().datetime().optional(),slug:Z.string(),repoDid:Z.string().optional(),brainDid:Z.string().optional(),anchorDid:Z.string().optional(),cardUri:Z.string().optional(),cardCid:Z.string().optional(),a2aEndpoint:Z.string().url().optional()}),hbw=Z.object({name:Z.string(),kind:Z.enum(["professional","team","collective"]),organization:Z.string().optional(),brainName:Z.string(),url:Z.string().url(),did:Z.string().optional(),repoDid:Z.string().optional(),brainDid:Z.string().optional(),anchorDid:Z.string().optional(),cardUri:Z.string().optional(),cardCid:Z.string().optional(),a2aEndpoint:Z.string().url().optional(),status:e22,discoveredAt:Z.string().datetime()}),Cbw=Z.object({name:Z.string(),url:Z.string().url(),status:e22,discoveredAt:Z.string().datetime().optional(),slug:Z.string(),repoDid:Z.string().optional(),brainDid:Z.string().optional(),anchorDid:Z.string().optional(),cardUri:Z.string().optional(),cardCid:Z.string().optional(),a2aEndpoint:Z.string().url().optional()}),ro=L$.extend({entityType:Z.literal(E$),metadata:AQ2}),gbw=_Q.extend({entityType:Z.literal(E$),metadata:Cbw}),oo=gbw.extend({frontmatter:hbw,about:Z.string(),skills:Z.array(dX0),notes:Z.string()}),ybw=oo.extend({url:Z.string().optional(),typeLabel:Z.string().optional()}),Ebw=oo.extend({url:Z.string(),typeLabel:Z.string()});_0();var Tbw=Z.array(dX0);function QQ2(A){let Q=Tbw.safeParse(A);if(!Q.success||Q.data.length===0)return"";return Q.data.map((w)=>{let B=w.tags.length>0?` [${w.tags.join(", ")}]`:"";return`- ${w.name}: ${w.description}${B}`}).join(`
|
|
9491
9491
|
`)}function wQ2(A){if(!A.trim())return[];let Q=[];for(let w of A.split(`
|
|
9492
9492
|
`)){let B=w.match(/^- (.+?): (.+?)(?:\s+\[(.+?)\])?$/);if(!B)continue;let $=B[1]??"",f=B[2]??"",Y=B[3],X=Y?Y.split(",").map((H)=>H.trim()).filter(Boolean):[];Q.push({name:$,description:f,tags:X})}return Q}var Sbw=Z.object({name:Z.string(),description:Z.string(),tags:Z.array(Z.string())}),mbw=Z.object({about:Z.string(),skills:Z.array(Sbw),notes:Z.string()}),BQ2=new z6(mbw,{title:"Agent",mappings:[{key:"about",label:"About",type:"string"},{key:"skills",label:"Skills",type:"custom",formatter:QQ2,parser:wQ2},{key:"notes",label:"Notes",type:"string"}]});class i4 extends g2{constructor(){super({entityType:E$,purpose:"A saved remote peer-brain contact in the local agent directory.",schema:ro,frontmatterSchema:UV})}fromMarkdown(A){let Q=this.parseFrontMatter(A,UV),w=qO(Q.url);return{content:A,entityType:E$,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:Ry.parse(A.status),discoveredAt:A.discoveredAt},w=BQ2.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=BQ2.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,UV),body:this.parseAgentContent(A.content)}}}wA();_0();var ubw=new i4,$Q2=Z.enum(["discovered","approved"]),cbw=Z.looseObject({id:Z.string().optional(),limit:Z.number().optional(),page:Z.number().optional(),pageSize:Z.number().optional(),baseUrl:Z.string().optional(),status:$Q2.optional()}),lbw=Z.looseObject({entityType:Z.string().optional(),query:cbw.optional()});function pbw(A){let Q=n2(A.content,UV),w=ubw.parseAgentContent(A.content);return oo.parse({...A,frontmatter:Q.metadata,about:w.about,skills:w.skills,notes:w.notes})}class nX0 extends J8{id=no;name="Agent Directory DataSource";description="Fetches and transforms agent entities for rendering";config={entityType:E$,defaultSort:[{field:"discoveredAt",direction:"desc"}],defaultLimit:50,lookupField:"slug",enableNavigation:!0};constructor(A){super(A)}transformEntity(A){return pbw(A)}buildDetailResult(A,Q){return{agent:A,prevAgent:Q?.prev??null,nextAgent:Q?.next??null}}parseQuery(A){let Q=lbw.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}buildListResult(A,Q,w){let B=$Q2.safeParse(w.status);return{agents:A,pagination:Q,baseUrl:w.baseUrl,selectedStatus:B.success?B.data:"all"}}async fetch(A,Q,w){let{query:B}=this.parseQuery(A);if(B.id)return super.fetch(A,Q,w);let{items:$,pagination:f}=await this.fetchList(B,w.entityService,B.status?{filter:{metadata:{status:B.status}}}:void 0);return Q.parse(this.buildListResult($,f,B))}}wA();_0();y6();wA();async function rX0(A,Q){let B=`${(A.startsWith("http")?A:`https://${A}`).replace(/\/$/,"")}/.well-known/agent-card.json`;try{let $=await Q(B);if(!$.ok)return null;let f=await $.json();return bm(f)}catch{return null}}function IP(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""}U2();var ibw=new i4;function fQ2(A){return A.trim().toLowerCase().replace(/[_\s]+/g,"-")}function CF(A){let Q=new Set,w=[];for(let B of A){let $=fQ2(B);if(!$||Q.has($))continue;Q.add($),w.push($)}return w}function dbw(A,Q){if(Q.count!==A.count)return Q.count-A.count;return A.tag.localeCompare(Q.tag)}async function YQ2(A,Q={}){let w=Q.minCount??1,B=Q.topN??12,$=Q.visibilityScope??"public",f=new Map,[Y,X]=await Promise.all([A.entityService.listEntities({entityType:j5,options:{filter:{visibilityScope:$}}}),A.entityService.listEntities({entityType:E$,options:{filter:{visibilityScope:$}}})]),H=(W)=>{for(let K of CF(W))f.set(K,(f.get(K)??0)+1)};for(let W of Y)H(W.metadata.tags);for(let W of X){let K=ibw.parseAgentContent(W.content);H(K.skills.flatMap((U)=>U.tags))}return Array.from(f.entries()).map(([W,K])=>({tag:W,count:K})).filter((W)=>W.count>=w).sort(dbw).slice(0,B)}function XQ2(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(`
|
|
9493
9493
|
`)}var nbw=new i4;function oX0(A,Q={}){let w=A.anchor?.name??A.brainName,B=A.anchor?.kind??"professional",$=[];if(A.anchor?.description)$.push(A.anchor.description);if(A.description)$.push(A.description);let f=Q.status??"discovered",Y=new Date().toISOString();return{content:nbw.createAgentContent({name:w,kind:B,...A.anchor?.organization&&{organization:A.anchor.organization},brainName:A.brainName,url:A.url,status:f,discoveredAt:Y,about:$.join(`
|
|
@@ -9588,7 +9588,7 @@ ${A.guidance}`:$}}function q22(A){return{...A,evidence:A.evidence.map((Q)=>({...
|
|
|
9588
9588
|
setTagFilter("all");
|
|
9589
9589
|
});
|
|
9590
9590
|
})();`;import{jsxDEV as Fw}from"preact/jsx-dev-runtime";function wJw({item:A}){return Fw("li",{class:"list-item",children:[Fw("div",{class:"list-main",children:[Fw("span",{class:"list-name",children:A.name},void 0,!1,void 0,this),Fw("span",{class:"list-desc",children:A.description},void 0,!1,void 0,this),A.tags.length>0&&Fw("div",{class:"list-tags",children:A.tags.map((Q)=>Fw("span",{class:"tag",children:Q},`${A.id}:${Q}`,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Fw("div",{class:"list-meta",children:A.status==="discovered"&&Fw("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 BJw({item:A}){return Fw("li",{class:"list-item agent-network-skill-row","data-agent-network-skill-row":!0,"data-agent-network-tags":JSON.stringify(A.tags),children:[Fw("div",{class:"list-main",children:Fw("span",{class:"list-name",children:A.name},void 0,!1,void 0,this)},void 0,!1,void 0,this),Fw("div",{class:"list-meta",children:Fw("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 $Jw({kind:A,items:Q,active:w}){return Fw("div",{class:`agent-network-panel${w?" is-active":""}`,"data-agent-network-panel":A,children:Q.length>0?Fw("ul",{class:"list agent-network-list",children:Q.map((B)=>Fw(wJw,{item:B},B.id,!1,void 0,this))},void 0,!1,void 0,this):Fw("p",{class:"agent-network-empty",children:"Nothing to show yet."},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function fJw({skills:A,count:Q,filters:w}){return Fw("div",{class:"agent-network-panel","data-agent-network-panel":"skills",children:[Fw("div",{class:"agent-network-filter-row",role:"tablist","aria-label":"Filter skills by tag",children:[Fw("button",{class:"agent-network-filter is-active",type:"button","data-agent-network-tag-filter":"all","aria-pressed":"true",children:[Fw("span",{class:"count",children:Q},void 0,!1,void 0,this),Fw("span",{class:"label",children:"all"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),w.map((B)=>Fw("button",{class:`agent-network-filter${B.variant==="gap"?" is-gap":""}`,type:"button","data-agent-network-tag-filter":B.tag,"aria-pressed":"false",children:[Fw("span",{class:"count",children:B.count},void 0,!1,void 0,this),Fw("span",{class:"label",children:B.tag},void 0,!1,void 0,this)]},B.tag,!0,void 0,this))]},void 0,!0,void 0,this),A.length>0?Fw("ul",{class:"list agent-network-list agent-network-skills-list",children:A.map((B)=>Fw(BJw,{item:B},B.id,!1,void 0,this))},void 0,!1,void 0,this):Fw("p",{class:"agent-network-empty",children:"Nothing to show yet."},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function wt0({data:A}){let Q=Qt0.safeParse(A);if(!Q.success)return Fw("p",{class:"muted",children:"Nothing to show yet."},void 0,!1,void 0,this);let w=Q.data;return Fw("div",{"data-agent-network-widget":!0,"data-agent-network-view":"agents",children:[Fw("div",{class:"agent-network-view-tabs",role:"tablist","aria-label":"Browse the agent network",children:[Fw("button",{class:"agent-network-view-tab is-active",type:"button","data-agent-network-view-tab":"agents","aria-pressed":"true",children:["Agents",Fw("span",{class:"agent-network-view-count",children:w.counts.agents},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Fw("button",{class:"agent-network-view-tab",type:"button","data-agent-network-view-tab":"skills","aria-pressed":"false",children:["Skills",Fw("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),Fw("div",{class:"agent-network-kind-tabs",role:"tablist","aria-label":"Filter agents by kind",children:sX0.map((B)=>{let $=B==="all";return Fw("button",{class:`agent-network-kind-tab${$?" is-active":""}`,type:"button","data-agent-network-kind-tab":B,"aria-pressed":$?"true":"false",children:[Fw("span",{class:"agent-network-kind-count",children:w.agents[B].length},void 0,!1,void 0,this),Fw("span",{class:"agent-network-kind-label",children:B},void 0,!1,void 0,this)]},B,!0,void 0,this)})},void 0,!1,void 0,this),sX0.map((B)=>Fw($Jw,{kind:B,items:w.agents[B],active:B==="all"},B,!1,void 0,this)),Fw(fJw,{skills:w.skills,count:w.counts.skills,filters:w.skillFilters},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}var YJw=Z.object({counts:Z.object({agents:Z.number(),skills:Z.number()})});function DQ2(A,Q){A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"dashboard:register-widget",payload:{id:d22,pluginId:Q,title:"Agent Network",group:"network",section:"secondary",priority:15,rendererName:n22,component:wt0,clientScript:aX0,dataProvider:async()=>GQ2(A),digestProvider:(w)=>{let{counts:B}=YJw.parse(w);return{digest:[{label:"Agents",value:String(B.agents)},{label:"Skills",value:String(B.skills)}]}}}}),{success:!0}})}U2();var zQ2=new i4;function XJw(A){return A.skills.map((Q)=>({name:Q.name,description:Q.description,tags:Q.tags??[]}))}function ZJw(A){return new URL(A).hostname}function HJw(A){return[`ATProto card: ${A.uri}`,`ATProto card CID: ${A.cid}`,`ATProto repo DID: ${A.repoDid}`].join(`
|
|
9591
|
-
`)}function WJw(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 KJw(A,Q,w){await A.messaging.send({type:Q,payload:w,broadcast:!0})}async function UJw(A,Q,w=new Date().toISOString()){let{record:B}=Q,$=ZJw(B.siteUrl),f=await A.entityService.getEntity({entityType:"agent",id:$}),Y=f?zQ2.parseEntity(f):void 0,X=B.brain.did,H=B.anchor.did,W=XJw(B),K=f?.metadata.status??"discovered",U=f?.metadata.url??B.siteUrl,G=f?.metadata.slug??qO(U),q=f?.metadata.name??B.anchor.name,V=Y?.frontmatter.kind??B.anchor.kind,J=f?.metadata.discoveredAt??w,b=B.brain.purpose.length>0?B.brain.purpose:Y?.body.about??"",L=W.length>0?W:Y?.body.skills??[],N={...f?.metadata??{},name:q,url:U,status:K,discoveredAt:J,slug:G,repoDid:Q.repoDid,...X&&{brainDid:X},...H&&{anchorDid:H},cardUri:Q.uri,cardCid:Q.cid},k=zQ2.createAgentContent({name:q,kind:V,...Y?.frontmatter.organization&&{organization:Y.frontmatter.organization},brainName:B.brain.name,url:U,...X&&{did:X,brainDid:X},...H&&{anchorDid:H},repoDid:Q.repoDid,cardUri:Q.uri,cardCid:Q.cid,...Y?.frontmatter.a2aEndpoint&&{a2aEndpoint:Y.frontmatter.a2aEndpoint},status:K,discoveredAt:J,about:b,skills:L,notes:HJw({repoDid:Q.repoDid,uri:Q.uri,cid:Q.cid})});if(f){let v={...f,content:k,metadata:N,updated:w};return await A.entityService.updateEntity({entity:v}),{agent:v,created:!1}}let x={id:$,entityType:"agent",content:k,metadata:N,contentHash:"",visibility:"public",created:w,updated:w};return await A.entityService.createEntity({entity:x}),{agent:x,created:!0}}function qQ2(A){A.messaging.subscribe(yd,async(Q)=>{let w=ju0.parse(Q.payload),B=await UJw(A,w),$=WJw({agent:B.agent,repoDid:w.repoDid,uri:w.uri,cid:w.cid,record:w.record});return await KJw(A,B.created?_u0:Nu0,$),{success:!0,data:$}})}function VQ2(){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(" ")}jB();_0();import{jsxDEV as bQ2}from"preact/jsx-dev-runtime";function tX0(A){try{return new URL(A).hostname}catch{return A}}var eX0=({name:A,className:Q=""})=>{let w=A.charAt(0).toUpperCase(),B=0;for(let f=0;f<A.length;f++)B=A.charCodeAt(f)+((B<<5)-B);let $=Math.abs(B)%360;return bQ2("div",{className:`flex items-center justify-center rounded-full text-white font-bold flex-shrink-0 ${Q}`,style:{backgroundColor:`hsl(${$}, 55%, 45%)`},children:w},void 0,!1,void 0,this)},AZ0=({kind:A,size:Q="md"})=>{let B={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 bQ2("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]"} ${B}`,children:A},void 0,!1,void 0,this)};import{jsxDEV as l2,Fragment as zJw}from"preact/jsx-dev-runtime";var GJw=({skills:A})=>{if(A.length===0)return null;return l2("div",{className:"flex gap-1.5 flex-wrap mt-2",children:A.map((Q)=>l2("span",{className:"text-[11px] px-2 py-0.5 bg-theme-subtle rounded-md text-theme-muted",children:Q.name},Q.name,!1,void 0,this))},void 0,!1,void 0,this)};function DJw(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric"})}function JQ2(A,Q,w){let B=new URLSearchParams({status:Q});if(w>1)B.set("page",String(w));return`${A}?${B.toString()}`}var Bt0=({agent:A})=>{let{frontmatter:Q,about:w,skills:B,url:$}=A,f=Q.status==="approved";return l2("a",{href:$,className:`flex items-start gap-5 p-6 rounded-xl border border-theme bg-theme-subtle hover:shadow-lg transition-shadow ${f?"":"opacity-70"}`,children:[l2(eX0,{name:Q.name,className:"w-12 h-12 text-lg"},void 0,!1,void 0,this),l2("div",{className:"flex-1 min-w-0",children:[l2("div",{className:"flex items-center gap-2 mb-1 flex-wrap",children:[l2("span",{className:"text-lg font-semibold text-heading",children:Q.name},void 0,!1,void 0,this),l2(AZ0,{kind:Q.kind,size:"sm"},void 0,!1,void 0,this),Q.organization&&l2("span",{className:"text-xs text-theme-muted",children:["\xB7 ",Q.organization]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),l2("div",{className:"text-sm text-theme-muted mb-1",children:Q.brainName},void 0,!1,void 0,this),w&&l2("p",{className:"text-sm text-theme-muted line-clamp-2 mb-0",children:w},void 0,!1,void 0,this),f&&l2(GJw,{skills:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this),l2("div",{className:"flex flex-col items-end gap-1 flex-shrink-0 text-right",children:[l2("span",{className:"text-xs text-theme-muted",children:tX0(Q.url)},void 0,!1,void 0,this),l2("span",{className:"text-[11px] text-theme-muted opacity-60",children:f?`Discovered ${DJw(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)},IQ2=({agents:A,pageTitle:Q,pagination:w,baseUrl:B="/agents",selectedStatus:$})=>{let f=Q??"Agent Directory",Y=w?.totalItems??A.length,X=A.filter((G)=>G.frontmatter.status==="approved"),H=A.filter((G)=>G.frontmatter.status==="discovered"),W=X.length,K=H.length,U=`Your network of ${Y} ${Y===1?"brain":"brains"} and their anchors`;return l2(zJw,{children:[l2(pQ,{title:f,description:U},void 0,!1,void 0,this),l2("div",{className:"agent-list bg-theme",children:l2("div",{className:"container mx-auto px-6 md:px-12 max-w-5xl py-16 md:py-24",children:[l2("div",{className:"mb-8 pb-6 border-b border-theme",children:[l2("h1",{className:"text-4xl font-bold text-heading mb-2",children:f},void 0,!1,void 0,this),l2("p",{className:"text-theme-muted mb-4",children:U},void 0,!1,void 0,this),l2("div",{className:"flex flex-wrap gap-2 text-sm mb-4",children:[l2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-heading",children:[Y," total"]},void 0,!0,void 0,this),l2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-status-success",children:[W," approved"]},void 0,!0,void 0,this),l2("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),l2("div",{className:"flex flex-wrap gap-2 text-sm",children:[l2("a",{href:B,className:`px-3 py-1 rounded-full border transition-colors ${$==="all"?"border-theme text-heading bg-theme-subtle":"border-theme text-theme-muted hover:text-heading"}`,children:"All"},void 0,!1,void 0,this),l2("a",{href:`${B}?status=approved`,className:`px-3 py-1 rounded-full border transition-colors ${$==="approved"?"border-theme text-heading bg-theme-subtle":"border-theme text-theme-muted hover:text-heading"}`,children:"Approved"},void 0,!1,void 0,this),l2("a",{href:`${B}?status=discovered`,className:`px-3 py-1 rounded-full border transition-colors ${$==="discovered"?"border-theme text-heading bg-theme-subtle":"border-theme text-theme-muted hover:text-heading"}`,children:"Discovered"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),$==="all"&&X.length>0&&l2("section",{className:"mb-10",children:[l2("div",{className:"flex items-center justify-between mb-4",children:[l2("h2",{className:"text-lg font-semibold text-heading",children:"Approved brains"},void 0,!1,void 0,this),l2("span",{className:"text-sm text-theme-muted",children:X.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),l2("div",{className:"flex flex-col gap-4",children:X.map((G)=>l2(Bt0,{agent:G},G.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$==="all"&&H.length>0&&l2("section",{children:[l2("div",{className:"flex items-center justify-between mb-4",children:[l2("div",{children:[l2("h2",{className:"text-lg font-semibold text-heading",children:"Discovered brains"},void 0,!1,void 0,this),l2("p",{className:"text-sm text-theme-muted",children:"Review and approve these before calling them."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),l2("span",{className:"text-sm text-theme-muted",children:H.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),l2("div",{className:"flex flex-col gap-4",children:H.map((G)=>l2(Bt0,{agent:G},G.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$!=="all"&&A.length>0&&l2("section",{children:[l2("div",{className:"flex items-center justify-between mb-4",children:[l2("h2",{className:"text-lg font-semibold text-heading",children:$==="approved"?"Approved brains":"Discovered brains"},void 0,!1,void 0,this),l2("span",{className:"text-sm text-theme-muted",children:A.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),l2("div",{className:"flex flex-col gap-4",children:A.map((G)=>l2(Bt0,{agent:G},G.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.length===0&&l2("p",{className:"text-center text-theme-muted py-16",children:"No agents in your directory yet."},void 0,!1,void 0,this),w&&w.totalPages>1&&$==="all"&&l2("div",{className:"mt-12",children:l2(pq,{currentPage:w.currentPage,totalPages:w.totalPages,baseUrl:B},void 0,!1,void 0,this)},void 0,!1,void 0,this),w&&w.totalPages>1&&$!=="all"&&l2("nav",{"aria-label":"Pagination",className:"flex items-center justify-center gap-3 mt-12",children:[w.hasPrevPage?l2("a",{href:JQ2(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):l2("span",{className:"px-3 py-2 rounded-md border border-theme text-sm text-theme-muted opacity-50",children:"\u2190 Prev"},void 0,!1,void 0,this),l2("span",{className:"text-sm text-theme-muted",children:["Page ",w.currentPage," of ",w.totalPages]},void 0,!0,void 0,this),w.hasNextPage?l2("a",{href:JQ2(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):l2("span",{className:"px-3 py-2 rounded-md border border-theme text-sm text-theme-muted opacity-50",children:"Next \u2192"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as P2,Fragment as JJw}from"preact/jsx-dev-runtime";function qJw(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"})}var ao=({children:A})=>P2("h2",{className:"text-sm font-semibold text-theme-muted uppercase tracking-wide mb-3",children:A},void 0,!1,void 0,this),VJw=({skill:A})=>P2("div",{className:"flex items-start gap-3 px-4 py-3 bg-theme-subtle rounded-lg",children:[P2("div",{className:"flex-1",children:[P2("div",{className:"text-sm font-semibold text-heading",children:A.name},void 0,!1,void 0,this),P2("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&&P2("div",{className:"flex gap-1 flex-shrink-0",children:A.tags.map((Q)=>P2("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),bJw=({label:A,value:Q,valueClassName:w})=>P2("div",{className:"flex justify-between text-[13px]",children:[P2("span",{className:"text-theme-muted",children:A},void 0,!1,void 0,this),P2("span",{className:w??"text-heading",children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this),FQ2=({agent:A,prevAgent:Q,nextAgent:w})=>{let{frontmatter:B,about:$,skills:f,notes:Y}=A,X=tX0(B.url),H=B.status==="approved";return P2(JJw,{children:[P2(pQ,{title:B.name,description:$||`Agent profile for ${B.name}`},void 0,!1,void 0,this),P2("article",{className:"agent-detail",children:P2("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:[P2("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),P2("div",{className:"flex items-start gap-6 mb-8",children:[P2(eX0,{name:B.name,className:"w-[72px] h-[72px] text-3xl"},void 0,!1,void 0,this),P2("div",{children:[P2("div",{className:"flex items-center gap-3 mb-1",children:[P2("h1",{className:"text-3xl md:text-4xl font-bold text-heading",children:B.name},void 0,!1,void 0,this),P2(AZ0,{kind:B.kind},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P2("div",{className:"text-base text-theme-muted mb-2",children:B.brainName},void 0,!1,void 0,this),P2("div",{className:"flex items-center gap-3 text-theme-muted",children:[B.organization&&P2("span",{className:"text-[15px]",children:B.organization},void 0,!1,void 0,this),B.organization&&P2("span",{className:"text-theme-muted opacity-40",children:"\xB7"},void 0,!1,void 0,this),P2("span",{className:"text-sm",children:["Discovered ",qJw(B.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),P2("div",{className:"border-b border-theme mb-8"},void 0,!1,void 0,this),!H&&P2("div",{className:"mb-8 rounded-xl border border-theme bg-theme-subtle px-5 py-4",children:[P2("div",{className:"text-sm font-semibold text-heading mb-1",children:"Saved for review"},void 0,!1,void 0,this),P2("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),P2("div",{className:"flex flex-col md:flex-row gap-12",children:[P2("div",{className:"flex-[2] min-w-0",children:[$&&P2("section",{className:"mb-8",children:[P2(ao,{children:"About"},void 0,!1,void 0,this),P2("p",{className:"text-[15px] text-theme leading-relaxed",children:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this),f.length>0&&P2("section",{className:"mb-8",children:[P2(ao,{children:"Skills"},void 0,!1,void 0,this),P2("div",{className:"flex flex-col gap-2.5",children:f.map((W)=>P2(VJw,{skill:W},W.name,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Y&&P2("section",{className:"mb-8",children:[P2(ao,{children:"Notes"},void 0,!1,void 0,this),P2("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),P2("aside",{className:"flex-1 md:pl-8 md:border-l border-theme-muted/20",children:[P2("section",{className:"mb-8",children:[P2(ao,{children:"Brain"},void 0,!1,void 0,this),P2("div",{className:"p-4 bg-theme-subtle rounded-xl",children:[P2("div",{className:"text-[15px] font-semibold text-heading mb-1",children:B.brainName},void 0,!1,void 0,this),B.did&&P2("div",{className:"text-xs text-theme-muted font-mono",children:B.did},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),P2("section",{className:"mb-8",children:[P2(ao,{children:"Connection"},void 0,!1,void 0,this),P2("div",{className:"flex flex-col gap-3",children:[P2("div",{children:[P2("div",{className:"text-[13px] text-theme-muted mb-0.5",children:"Endpoint"},void 0,!1,void 0,this),P2("div",{className:"text-xs text-heading font-mono",children:B.url},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P2(bJw,{label:"Status",value:B.status==="approved"?"Approved":"Discovered",valueClassName:B.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),P2("a",{href:B.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 ",X," \u2197"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),(Q??w)&&P2("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:[P2("div",{className:"min-h-[1px]",children:Q&&P2("a",{href:Q.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[P2("span",{children:"\u2190 Previous"},void 0,!1,void 0,this),P2("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),P2("div",{className:"min-h-[1px] md:text-right",children:w&&P2("a",{href:w.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[P2("span",{children:"Next \u2192"},void 0,!1,void 0,this),P2("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 IJw=Z.union([Z.enum(["public","shared","restricted"]),Z.literal("private")]).optional().transform((A)=>{if(A===void 0)return"public";if(A==="private")return"restricted";return A}),FJw=Z.object({currentPage:Z.number(),totalPages:Z.number(),totalItems:Z.number(),pageSize:Z.number(),hasNextPage:Z.boolean(),hasPrevPage:Z.boolean()}),LJw=Z.object({name:Z.string(),description:Z.string(),tags:Z.array(Z.string())}),$t0=Z.enum(["discovered","approved"]),kJw=Z.enum(["professional","team","collective"]),_Jw=Z.object({name:Z.string(),kind:kJw,organization:Z.string().optional(),brainName:Z.string(),url:Z.url(),did:Z.string().optional(),repoDid:Z.string().optional(),brainDid:Z.string().optional(),anchorDid:Z.string().optional(),cardUri:Z.string().optional(),cardCid:Z.string().optional(),a2aEndpoint:Z.url().optional(),status:$t0,discoveredAt:Z.string()}),NJw=Z.object({name:Z.string(),url:Z.url(),status:$t0,discoveredAt:Z.string().optional(),slug:Z.string(),repoDid:Z.string().optional(),brainDid:Z.string().optional(),anchorDid:Z.string().optional(),cardUri:Z.string().optional(),cardCid:Z.string().optional(),a2aEndpoint:Z.url().optional()}),QZ0=Z.object({id:Z.string(),entityType:Z.literal(E$),content:Z.string(),created:Z.string(),updated:Z.string(),visibility:IJw,metadata:NJw,contentHash:Z.string(),frontmatter:_Jw,about:Z.string(),skills:Z.array(LJw),notes:Z.string(),url:Z.string(),typeLabel:Z.string()}),jJw=Z.object({agents:Z.array(QZ0),pageTitle:Z.string().optional(),pagination:FJw.nullable(),baseUrl:Z.string().optional(),selectedStatus:Z.union([Z.literal("all"),$t0])});function LQ2(){return{[ta0]:d1({name:ta0,description:"Agent directory list page template",schema:jJw,dataSourceId:no,requiredPermission:"public",layout:{component:IQ2}}),[ea0]:d1({name:ea0,description:"Individual agent profile template",schema:Z.object({agent:QZ0,prevAgent:QZ0.nullable(),nextAgent:QZ0.nullable()}),dataSourceId:no,requiredPermission:"public",layout:{component:FQ2}})}}var hy={name:"@brains/agent-discovery",version:"0.2.0-alpha.150",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:"^6.0.3"},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 MJw=new i4;class ft0 extends rQ{entityType=E$;schema=ro;adapter=MJw;constructor(){super(i22,hy,{},k7)}createGenerationHandler(A){return new At0(this.logger.child("AgentGenerationJobHandler"),A)}getTemplates(){return LQ2()}getDataSources(){return[new nX0(this.logger.child("AgentDataSource"))]}async onRegister(A){qQ2(A),DQ2(A,this.id)}async getInstructions(){return VQ2()}}function Yt0(){return new ft0}wA();_0();$9();_0();var kQ2=Z.object({source:Z.object({kind:Z.literal("url"),url:Z.string().min(1).describe("Remote agent domain or URL to verify and connect. Preserve bare domains as bare domains.")}),confirmed:Z.boolean().optional(),confirmationToken:Z.string().optional()}),OJw=new i4;function xJw(A){let Q=IP(A);if(!Q)return null;return{domain:Q,fetchTarget:A.trim().startsWith("http")?A.trim():Q}}function vJw(A,Q){return(IP(Q)||A).toLowerCase()}async function RJw(A){let{context:Q,entityId:w,card:B}=A,$=new Date().toISOString(),f=await Q.entityService.getEntity({entityType:E$,id:w}),Y=oX0(B,{status:"approved"}),H={...OJw.fromMarkdown(Y.content).metadata,...Y.metadata,a2aEndpoint:B.url};if(f){let K={...f,content:Y.content,metadata:H,updated:$};return await Q.entityService.updateEntity({entity:K}),{entity:K,created:!1}}let W={id:w,entityType:E$,content:Y.content,metadata:H,contentHash:"",visibility:"public",created:$,updated:$};return await Q.entityService.createEntity({entity:W}),{entity:W,created:!0}}function _Q2(A,Q=globalThis.fetch){let B=new RX;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:kQ2.shape,visibility:"trusted",sideEffects:"external",handler:async($,f)=>{let Y=kQ2.safeParse($);if(!Y.success)return{success:!1,error:`Invalid input: ${Y.error.issues.map((K)=>`${K.path.join(".")}: ${K.message}`).join(", ")}`};let X=Y.data,H=xJw(X.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(E$,"create",f)}catch(K){return{success:!1,error:K instanceof Error?K.message:String(K)}}if(X.confirmed){let K=X.confirmationToken,U=B.validate(K,X);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 rX0(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=vJw(H.domain,G.url),{entity:V,created:J}=await RJw({context:A,entityId:q,sourceUrl:X.source.url,card:G});return{success:!0,data:{status:V.metadata.status,entityId:V.id,connected:!0,created:J,a2aEndpoint:G.url,skills:G.skills.map((b)=>({name:b.name,description:b.description,tags:b.tags}))}}}let W=B.create((K)=>({source:X.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}}}}$9();_0();var hJw=Z.enum(["public","trusted"]),NQ2=Z.object({agent:Z.string().min(1).describe("Saved agent id, domain, or URL whose inbound A2A trust to set."),level:hJw.describe("Inbound A2A trust level. Use trusted to grant trusted inbound access, public to revoke it."),confirmed:Z.boolean().optional(),confirmationToken:Z.string().optional(),keyFingerprint:Z.string().optional()}),CJw=Z.object({keys:Z.array(Z.unknown())}),gJw=Z.object({kty:Z.literal("OKP"),crv:Z.literal("Ed25519"),x:Z.string(),kid:Z.string().optional(),alg:Z.literal("EdDSA").optional()}).passthrough();function jQ2(A){return(IP(A)||A.trim()).toLowerCase()}async function yJw(A,Q){let w=jQ2(Q),B=await A.entityService.getEntity({entityType:E$,id:w});if(!B)return null;let $=jQ2(B.metadata.a2aEndpoint??B.metadata.url);if(!$)return null;return{domain:$}}async function EJw(A,Q){try{let w=await Q(`https://${A}/.well-known/jwks.json`);if(!w.ok)return null;let B=CJw.safeParse(await w.json());if(!B.success)return null;let $=B.data.keys.map((f)=>gJw.safeParse(f)).find((f)=>f.success);if(!$?.success)return null;return bu0($.data)}catch{return null}}function PQ2(A,Q=globalThis.fetch){let B=new RX;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:NQ2.shape,visibility:"anchor",sideEffects:"external",handler:async($)=>{let f=NQ2.safeParse($);if(!f.success)return{success:!1,error:`Invalid input: ${f.error.issues.map((G)=>`${G.path.join(".")}: ${G.message}`).join(", ")}`};let Y=M7();if(!Y)return{success:!1,error:"Auth service is required to set inbound A2A trust.",code:"auth_service_unavailable"};let X=await yJw(A,f.data.agent);if(!X)return{success:!1,error:`No saved agent contact found for ${f.data.agent}. Connect the agent before setting inbound trust.`,code:"agent_not_found"};let H=f.data;if(H.confirmed){let G=B.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:X.domain,keyFingerprint:H.keyFingerprint,grantedLevel:"trusted"});return{success:!0,data:{agent:X.domain,level:q.grantedLevel,keyFingerprint:q.keyFingerprint}}}return await Y.revokeA2APeerTrust(X.domain),{success:!0,data:{agent:X.domain,level:"public"}}}let W=H.level==="trusted"?await EJw(X.domain,Q):void 0;if(H.level==="trusted"&&!W)return{success:!1,error:`Could not fetch an A2A signing key from ${X.domain}.`,code:"jwks_unavailable"};let K=B.create((G)=>({agent:X.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 ${X.domain}?`:`Revoke inbound trusted A2A access from ${X.domain}?`,preview:U?`This will grant inbound trusted A2A access to ${X.domain} and pin key fingerprint ${W}. It will not add or remove the directory contact.`:`This will revoke inbound trusted A2A access from ${X.domain}. The directory contact remains saved for outbound calls.`,args:K}}}}var TJw=Z.object({}).strict();class Xt0 extends tQ{fetchFn;constructor(A){super("agent",hy,{},TJw);this.fetchFn=A}async getTools(){return[_Q2(this.getContext(),this.fetchFn),PQ2(this.getContext(),this.fetchFn)]}}function Zt0(){return new Xt0}wA();wA();_0();var FP=Z.object({name:Z.string(),description:Z.string(),tags:Z.array(Z.string()),examples:Z.array(Z.string())}),MQ2=FP,to=L$.extend({entityType:Z.literal(j5),metadata:MQ2});wA();class Cy extends g2{constructor(){super({entityType:j5,purpose:"A capability advertised by a remote agent.",schema:to,frontmatterSchema:FP})}fromMarkdown(A){let Q=this.parseFrontMatter(A,FP);return{content:A,entityType:j5,metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}wA();_0();var SJw=Z.object({skills:Z.array(FP).max(8)}),OQ2=d1({name:"skill:skill-derivation",description:"Derive skills from topic titles and brain capabilities",dataSourceId:"shell:ai-content",schema:SJw,useKnowledgeContext:!0,basePrompt:`You are analyzing a brain's content to identify its high-level capabilities.
|
|
9591
|
+
`)}function WJw(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 KJw(A,Q,w){await A.messaging.send({type:Q,payload:w,broadcast:!0})}async function UJw(A,Q,w=new Date().toISOString()){let{record:B}=Q,$=ZJw(B.siteUrl),f=await A.entityService.getEntity({entityType:"agent",id:$}),Y=f?zQ2.parseEntity(f):void 0,X=B.brain.did,H=B.anchor.did,W=XJw(B),K=f?.metadata.status??"discovered",U=f?.metadata.url??B.siteUrl,G=f?.metadata.slug??qO(U),q=f?.metadata.name??B.anchor.name,V=Y?.frontmatter.kind??B.anchor.kind,J=f?.metadata.discoveredAt??w,b=B.brain.purpose.length>0?B.brain.purpose:Y?.body.about??"",L=W.length>0?W:Y?.body.skills??[],N={...f?.metadata??{},name:q,url:U,status:K,discoveredAt:J,slug:G,repoDid:Q.repoDid,...X&&{brainDid:X},...H&&{anchorDid:H},cardUri:Q.uri,cardCid:Q.cid},k=zQ2.createAgentContent({name:q,kind:V,...Y?.frontmatter.organization&&{organization:Y.frontmatter.organization},brainName:B.brain.name,url:U,...X&&{did:X,brainDid:X},...H&&{anchorDid:H},repoDid:Q.repoDid,cardUri:Q.uri,cardCid:Q.cid,...Y?.frontmatter.a2aEndpoint&&{a2aEndpoint:Y.frontmatter.a2aEndpoint},status:K,discoveredAt:J,about:b,skills:L,notes:HJw({repoDid:Q.repoDid,uri:Q.uri,cid:Q.cid})});if(f){let v={...f,content:k,metadata:N,updated:w};return await A.entityService.updateEntity({entity:v}),{agent:v,created:!1}}let x={id:$,entityType:"agent",content:k,metadata:N,contentHash:"",visibility:"public",created:w,updated:w};return await A.entityService.createEntity({entity:x}),{agent:x,created:!0}}function qQ2(A){A.messaging.subscribe(yd,async(Q)=>{let w=ju0.parse(Q.payload),B=await UJw(A,w),$=WJw({agent:B.agent,repoDid:w.repoDid,uri:w.uri,cid:w.cid,record:w.record});return await KJw(A,B.created?_u0:Nu0,$),{success:!0,data:$}})}function VQ2(){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(" ")}jB();_0();import{jsxDEV as bQ2}from"preact/jsx-dev-runtime";function tX0(A){try{return new URL(A).hostname}catch{return A}}var eX0=({name:A,className:Q=""})=>{let w=A.charAt(0).toUpperCase(),B=0;for(let f=0;f<A.length;f++)B=A.charCodeAt(f)+((B<<5)-B);let $=Math.abs(B)%360;return bQ2("div",{className:`flex items-center justify-center rounded-full text-white font-bold flex-shrink-0 ${Q}`,style:{backgroundColor:`hsl(${$}, 55%, 45%)`},children:w},void 0,!1,void 0,this)},AZ0=({kind:A,size:Q="md"})=>{let B={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 bQ2("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]"} ${B}`,children:A},void 0,!1,void 0,this)};import{jsxDEV as l2,Fragment as zJw}from"preact/jsx-dev-runtime";var GJw=({skills:A})=>{if(A.length===0)return null;return l2("div",{className:"flex gap-1.5 flex-wrap mt-2",children:A.map((Q)=>l2("span",{className:"text-[11px] px-2 py-0.5 bg-theme-subtle rounded-md text-theme-muted",children:Q.name},Q.name,!1,void 0,this))},void 0,!1,void 0,this)};function DJw(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric"})}function JQ2(A,Q,w){let B=new URLSearchParams({status:Q});if(w>1)B.set("page",String(w));return`${A}?${B.toString()}`}var Bt0=({agent:A})=>{let{frontmatter:Q,about:w,skills:B,url:$}=A,f=Q.status==="approved";return l2("a",{href:$,className:`flex items-start gap-5 p-6 rounded-xl border border-theme bg-theme-subtle hover:shadow-lg transition-shadow ${f?"":"opacity-70"}`,children:[l2(eX0,{name:Q.name,className:"w-12 h-12 text-lg"},void 0,!1,void 0,this),l2("div",{className:"flex-1 min-w-0",children:[l2("div",{className:"flex items-center gap-2 mb-1 flex-wrap",children:[l2("span",{className:"text-lg font-semibold text-heading",children:Q.name},void 0,!1,void 0,this),l2(AZ0,{kind:Q.kind,size:"sm"},void 0,!1,void 0,this),Q.organization&&l2("span",{className:"text-xs text-theme-muted",children:["\xB7 ",Q.organization]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),l2("div",{className:"text-sm text-theme-muted mb-1",children:Q.brainName},void 0,!1,void 0,this),w&&l2("p",{className:"text-sm text-theme-muted line-clamp-2 mb-0",children:w},void 0,!1,void 0,this),f&&l2(GJw,{skills:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this),l2("div",{className:"flex flex-col items-end gap-1 flex-shrink-0 text-right",children:[l2("span",{className:"text-xs text-theme-muted",children:tX0(Q.url)},void 0,!1,void 0,this),l2("span",{className:"text-[11px] text-theme-muted opacity-60",children:f?`Discovered ${DJw(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)},IQ2=({agents:A,pageTitle:Q,pagination:w,baseUrl:B="/agents",selectedStatus:$})=>{let f=Q??"Agent Directory",Y=w?.totalItems??A.length,X=A.filter((G)=>G.frontmatter.status==="approved"),H=A.filter((G)=>G.frontmatter.status==="discovered"),W=X.length,K=H.length,U=`Your network of ${Y} ${Y===1?"brain":"brains"} and their anchors`;return l2(zJw,{children:[l2(pQ,{title:f,description:U},void 0,!1,void 0,this),l2("div",{className:"agent-list bg-theme",children:l2("div",{className:"container mx-auto px-6 md:px-12 max-w-5xl py-16 md:py-24",children:[l2("div",{className:"mb-8 pb-6 border-b border-theme",children:[l2("h1",{className:"text-4xl font-bold text-heading mb-2",children:f},void 0,!1,void 0,this),l2("p",{className:"text-theme-muted mb-4",children:U},void 0,!1,void 0,this),l2("div",{className:"flex flex-wrap gap-2 text-sm mb-4",children:[l2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-heading",children:[Y," total"]},void 0,!0,void 0,this),l2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-status-success",children:[W," approved"]},void 0,!0,void 0,this),l2("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),l2("div",{className:"flex flex-wrap gap-2 text-sm",children:[l2("a",{href:B,className:`px-3 py-1 rounded-full border transition-colors ${$==="all"?"border-theme text-heading bg-theme-subtle":"border-theme text-theme-muted hover:text-heading"}`,children:"All"},void 0,!1,void 0,this),l2("a",{href:`${B}?status=approved`,className:`px-3 py-1 rounded-full border transition-colors ${$==="approved"?"border-theme text-heading bg-theme-subtle":"border-theme text-theme-muted hover:text-heading"}`,children:"Approved"},void 0,!1,void 0,this),l2("a",{href:`${B}?status=discovered`,className:`px-3 py-1 rounded-full border transition-colors ${$==="discovered"?"border-theme text-heading bg-theme-subtle":"border-theme text-theme-muted hover:text-heading"}`,children:"Discovered"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),$==="all"&&X.length>0&&l2("section",{className:"mb-10",children:[l2("div",{className:"flex items-center justify-between mb-4",children:[l2("h2",{className:"text-lg font-semibold text-heading",children:"Approved brains"},void 0,!1,void 0,this),l2("span",{className:"text-sm text-theme-muted",children:X.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),l2("div",{className:"flex flex-col gap-4",children:X.map((G)=>l2(Bt0,{agent:G},G.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$==="all"&&H.length>0&&l2("section",{children:[l2("div",{className:"flex items-center justify-between mb-4",children:[l2("div",{children:[l2("h2",{className:"text-lg font-semibold text-heading",children:"Discovered brains"},void 0,!1,void 0,this),l2("p",{className:"text-sm text-theme-muted",children:"Review and approve these before calling them."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),l2("span",{className:"text-sm text-theme-muted",children:H.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),l2("div",{className:"flex flex-col gap-4",children:H.map((G)=>l2(Bt0,{agent:G},G.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$!=="all"&&A.length>0&&l2("section",{children:[l2("div",{className:"flex items-center justify-between mb-4",children:[l2("h2",{className:"text-lg font-semibold text-heading",children:$==="approved"?"Approved brains":"Discovered brains"},void 0,!1,void 0,this),l2("span",{className:"text-sm text-theme-muted",children:A.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),l2("div",{className:"flex flex-col gap-4",children:A.map((G)=>l2(Bt0,{agent:G},G.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.length===0&&l2("p",{className:"text-center text-theme-muted py-16",children:"No agents in your directory yet."},void 0,!1,void 0,this),w&&w.totalPages>1&&$==="all"&&l2("div",{className:"mt-12",children:l2(pq,{currentPage:w.currentPage,totalPages:w.totalPages,baseUrl:B},void 0,!1,void 0,this)},void 0,!1,void 0,this),w&&w.totalPages>1&&$!=="all"&&l2("nav",{"aria-label":"Pagination",className:"flex items-center justify-center gap-3 mt-12",children:[w.hasPrevPage?l2("a",{href:JQ2(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):l2("span",{className:"px-3 py-2 rounded-md border border-theme text-sm text-theme-muted opacity-50",children:"\u2190 Prev"},void 0,!1,void 0,this),l2("span",{className:"text-sm text-theme-muted",children:["Page ",w.currentPage," of ",w.totalPages]},void 0,!0,void 0,this),w.hasNextPage?l2("a",{href:JQ2(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):l2("span",{className:"px-3 py-2 rounded-md border border-theme text-sm text-theme-muted opacity-50",children:"Next \u2192"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as P2,Fragment as JJw}from"preact/jsx-dev-runtime";function qJw(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"})}var ao=({children:A})=>P2("h2",{className:"text-sm font-semibold text-theme-muted uppercase tracking-wide mb-3",children:A},void 0,!1,void 0,this),VJw=({skill:A})=>P2("div",{className:"flex items-start gap-3 px-4 py-3 bg-theme-subtle rounded-lg",children:[P2("div",{className:"flex-1",children:[P2("div",{className:"text-sm font-semibold text-heading",children:A.name},void 0,!1,void 0,this),P2("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&&P2("div",{className:"flex gap-1 flex-shrink-0",children:A.tags.map((Q)=>P2("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),bJw=({label:A,value:Q,valueClassName:w})=>P2("div",{className:"flex justify-between text-[13px]",children:[P2("span",{className:"text-theme-muted",children:A},void 0,!1,void 0,this),P2("span",{className:w??"text-heading",children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this),FQ2=({agent:A,prevAgent:Q,nextAgent:w})=>{let{frontmatter:B,about:$,skills:f,notes:Y}=A,X=tX0(B.url),H=B.status==="approved";return P2(JJw,{children:[P2(pQ,{title:B.name,description:$||`Agent profile for ${B.name}`},void 0,!1,void 0,this),P2("article",{className:"agent-detail",children:P2("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:[P2("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),P2("div",{className:"flex items-start gap-6 mb-8",children:[P2(eX0,{name:B.name,className:"w-[72px] h-[72px] text-3xl"},void 0,!1,void 0,this),P2("div",{children:[P2("div",{className:"flex items-center gap-3 mb-1",children:[P2("h1",{className:"text-3xl md:text-4xl font-bold text-heading",children:B.name},void 0,!1,void 0,this),P2(AZ0,{kind:B.kind},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P2("div",{className:"text-base text-theme-muted mb-2",children:B.brainName},void 0,!1,void 0,this),P2("div",{className:"flex items-center gap-3 text-theme-muted",children:[B.organization&&P2("span",{className:"text-[15px]",children:B.organization},void 0,!1,void 0,this),B.organization&&P2("span",{className:"text-theme-muted opacity-40",children:"\xB7"},void 0,!1,void 0,this),P2("span",{className:"text-sm",children:["Discovered ",qJw(B.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),P2("div",{className:"border-b border-theme mb-8"},void 0,!1,void 0,this),!H&&P2("div",{className:"mb-8 rounded-xl border border-theme bg-theme-subtle px-5 py-4",children:[P2("div",{className:"text-sm font-semibold text-heading mb-1",children:"Saved for review"},void 0,!1,void 0,this),P2("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),P2("div",{className:"flex flex-col md:flex-row gap-12",children:[P2("div",{className:"flex-[2] min-w-0",children:[$&&P2("section",{className:"mb-8",children:[P2(ao,{children:"About"},void 0,!1,void 0,this),P2("p",{className:"text-[15px] text-theme leading-relaxed",children:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this),f.length>0&&P2("section",{className:"mb-8",children:[P2(ao,{children:"Skills"},void 0,!1,void 0,this),P2("div",{className:"flex flex-col gap-2.5",children:f.map((W)=>P2(VJw,{skill:W},W.name,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Y&&P2("section",{className:"mb-8",children:[P2(ao,{children:"Notes"},void 0,!1,void 0,this),P2("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),P2("aside",{className:"flex-1 md:pl-8 md:border-l border-theme-muted/20",children:[P2("section",{className:"mb-8",children:[P2(ao,{children:"Brain"},void 0,!1,void 0,this),P2("div",{className:"p-4 bg-theme-subtle rounded-xl",children:[P2("div",{className:"text-[15px] font-semibold text-heading mb-1",children:B.brainName},void 0,!1,void 0,this),B.did&&P2("div",{className:"text-xs text-theme-muted font-mono",children:B.did},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),P2("section",{className:"mb-8",children:[P2(ao,{children:"Connection"},void 0,!1,void 0,this),P2("div",{className:"flex flex-col gap-3",children:[P2("div",{children:[P2("div",{className:"text-[13px] text-theme-muted mb-0.5",children:"Endpoint"},void 0,!1,void 0,this),P2("div",{className:"text-xs text-heading font-mono",children:B.url},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P2(bJw,{label:"Status",value:B.status==="approved"?"Approved":"Discovered",valueClassName:B.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),P2("a",{href:B.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 ",X," \u2197"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),(Q??w)&&P2("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:[P2("div",{className:"min-h-[1px]",children:Q&&P2("a",{href:Q.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[P2("span",{children:"\u2190 Previous"},void 0,!1,void 0,this),P2("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),P2("div",{className:"min-h-[1px] md:text-right",children:w&&P2("a",{href:w.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[P2("span",{children:"Next \u2192"},void 0,!1,void 0,this),P2("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 IJw=Z.union([Z.enum(["public","shared","restricted"]),Z.literal("private")]).optional().transform((A)=>{if(A===void 0)return"public";if(A==="private")return"restricted";return A}),FJw=Z.object({currentPage:Z.number(),totalPages:Z.number(),totalItems:Z.number(),pageSize:Z.number(),hasNextPage:Z.boolean(),hasPrevPage:Z.boolean()}),LJw=Z.object({name:Z.string(),description:Z.string(),tags:Z.array(Z.string())}),$t0=Z.enum(["discovered","approved"]),kJw=Z.enum(["professional","team","collective"]),_Jw=Z.object({name:Z.string(),kind:kJw,organization:Z.string().optional(),brainName:Z.string(),url:Z.url(),did:Z.string().optional(),repoDid:Z.string().optional(),brainDid:Z.string().optional(),anchorDid:Z.string().optional(),cardUri:Z.string().optional(),cardCid:Z.string().optional(),a2aEndpoint:Z.url().optional(),status:$t0,discoveredAt:Z.string()}),NJw=Z.object({name:Z.string(),url:Z.url(),status:$t0,discoveredAt:Z.string().optional(),slug:Z.string(),repoDid:Z.string().optional(),brainDid:Z.string().optional(),anchorDid:Z.string().optional(),cardUri:Z.string().optional(),cardCid:Z.string().optional(),a2aEndpoint:Z.url().optional()}),QZ0=Z.object({id:Z.string(),entityType:Z.literal(E$),content:Z.string(),created:Z.string(),updated:Z.string(),visibility:IJw,metadata:NJw,contentHash:Z.string(),frontmatter:_Jw,about:Z.string(),skills:Z.array(LJw),notes:Z.string(),url:Z.string(),typeLabel:Z.string()}),jJw=Z.object({agents:Z.array(QZ0),pageTitle:Z.string().optional(),pagination:FJw.nullable(),baseUrl:Z.string().optional(),selectedStatus:Z.union([Z.literal("all"),$t0])});function LQ2(){return{[ta0]:d1({name:ta0,description:"Agent directory list page template",schema:jJw,dataSourceId:no,requiredPermission:"public",layout:{component:IQ2}}),[ea0]:d1({name:ea0,description:"Individual agent profile template",schema:Z.object({agent:QZ0,prevAgent:QZ0.nullable(),nextAgent:QZ0.nullable()}),dataSourceId:no,requiredPermission:"public",layout:{component:FQ2}})}}var hy={name:"@brains/agent-discovery",version:"0.2.0-alpha.151",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 MJw=new i4;class ft0 extends rQ{entityType=E$;schema=ro;adapter=MJw;constructor(){super(i22,hy,{},k7)}createGenerationHandler(A){return new At0(this.logger.child("AgentGenerationJobHandler"),A)}getTemplates(){return LQ2()}getDataSources(){return[new nX0(this.logger.child("AgentDataSource"))]}async onRegister(A){qQ2(A),DQ2(A,this.id)}async getInstructions(){return VQ2()}}function Yt0(){return new ft0}wA();_0();$9();_0();var kQ2=Z.object({source:Z.object({kind:Z.literal("url"),url:Z.string().min(1).describe("Remote agent domain or URL to verify and connect. Preserve bare domains as bare domains.")}),confirmed:Z.boolean().optional(),confirmationToken:Z.string().optional()}),OJw=new i4;function xJw(A){let Q=IP(A);if(!Q)return null;return{domain:Q,fetchTarget:A.trim().startsWith("http")?A.trim():Q}}function vJw(A,Q){return(IP(Q)||A).toLowerCase()}async function RJw(A){let{context:Q,entityId:w,card:B}=A,$=new Date().toISOString(),f=await Q.entityService.getEntity({entityType:E$,id:w}),Y=oX0(B,{status:"approved"}),H={...OJw.fromMarkdown(Y.content).metadata,...Y.metadata,a2aEndpoint:B.url};if(f){let K={...f,content:Y.content,metadata:H,updated:$};return await Q.entityService.updateEntity({entity:K}),{entity:K,created:!1}}let W={id:w,entityType:E$,content:Y.content,metadata:H,contentHash:"",visibility:"public",created:$,updated:$};return await Q.entityService.createEntity({entity:W}),{entity:W,created:!0}}function _Q2(A,Q=globalThis.fetch){let B=new RX;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:kQ2.shape,visibility:"trusted",sideEffects:"external",handler:async($,f)=>{let Y=kQ2.safeParse($);if(!Y.success)return{success:!1,error:`Invalid input: ${Y.error.issues.map((K)=>`${K.path.join(".")}: ${K.message}`).join(", ")}`};let X=Y.data,H=xJw(X.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(E$,"create",f)}catch(K){return{success:!1,error:K instanceof Error?K.message:String(K)}}if(X.confirmed){let K=X.confirmationToken,U=B.validate(K,X);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 rX0(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=vJw(H.domain,G.url),{entity:V,created:J}=await RJw({context:A,entityId:q,sourceUrl:X.source.url,card:G});return{success:!0,data:{status:V.metadata.status,entityId:V.id,connected:!0,created:J,a2aEndpoint:G.url,skills:G.skills.map((b)=>({name:b.name,description:b.description,tags:b.tags}))}}}let W=B.create((K)=>({source:X.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}}}}$9();_0();var hJw=Z.enum(["public","trusted"]),NQ2=Z.object({agent:Z.string().min(1).describe("Saved agent id, domain, or URL whose inbound A2A trust to set."),level:hJw.describe("Inbound A2A trust level. Use trusted to grant trusted inbound access, public to revoke it."),confirmed:Z.boolean().optional(),confirmationToken:Z.string().optional(),keyFingerprint:Z.string().optional()}),CJw=Z.object({keys:Z.array(Z.unknown())}),gJw=Z.object({kty:Z.literal("OKP"),crv:Z.literal("Ed25519"),x:Z.string(),kid:Z.string().optional(),alg:Z.literal("EdDSA").optional()}).passthrough();function jQ2(A){return(IP(A)||A.trim()).toLowerCase()}async function yJw(A,Q){let w=jQ2(Q),B=await A.entityService.getEntity({entityType:E$,id:w});if(!B)return null;let $=jQ2(B.metadata.a2aEndpoint??B.metadata.url);if(!$)return null;return{domain:$}}async function EJw(A,Q){try{let w=await Q(`https://${A}/.well-known/jwks.json`);if(!w.ok)return null;let B=CJw.safeParse(await w.json());if(!B.success)return null;let $=B.data.keys.map((f)=>gJw.safeParse(f)).find((f)=>f.success);if(!$?.success)return null;return bu0($.data)}catch{return null}}function PQ2(A,Q=globalThis.fetch){let B=new RX;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:NQ2.shape,visibility:"anchor",sideEffects:"external",handler:async($)=>{let f=NQ2.safeParse($);if(!f.success)return{success:!1,error:`Invalid input: ${f.error.issues.map((G)=>`${G.path.join(".")}: ${G.message}`).join(", ")}`};let Y=M7();if(!Y)return{success:!1,error:"Auth service is required to set inbound A2A trust.",code:"auth_service_unavailable"};let X=await yJw(A,f.data.agent);if(!X)return{success:!1,error:`No saved agent contact found for ${f.data.agent}. Connect the agent before setting inbound trust.`,code:"agent_not_found"};let H=f.data;if(H.confirmed){let G=B.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:X.domain,keyFingerprint:H.keyFingerprint,grantedLevel:"trusted"});return{success:!0,data:{agent:X.domain,level:q.grantedLevel,keyFingerprint:q.keyFingerprint}}}return await Y.revokeA2APeerTrust(X.domain),{success:!0,data:{agent:X.domain,level:"public"}}}let W=H.level==="trusted"?await EJw(X.domain,Q):void 0;if(H.level==="trusted"&&!W)return{success:!1,error:`Could not fetch an A2A signing key from ${X.domain}.`,code:"jwks_unavailable"};let K=B.create((G)=>({agent:X.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 ${X.domain}?`:`Revoke inbound trusted A2A access from ${X.domain}?`,preview:U?`This will grant inbound trusted A2A access to ${X.domain} and pin key fingerprint ${W}. It will not add or remove the directory contact.`:`This will revoke inbound trusted A2A access from ${X.domain}. The directory contact remains saved for outbound calls.`,args:K}}}}var TJw=Z.object({}).strict();class Xt0 extends tQ{fetchFn;constructor(A){super("agent",hy,{},TJw);this.fetchFn=A}async getTools(){return[_Q2(this.getContext(),this.fetchFn),PQ2(this.getContext(),this.fetchFn)]}}function Zt0(){return new Xt0}wA();wA();_0();var FP=Z.object({name:Z.string(),description:Z.string(),tags:Z.array(Z.string()),examples:Z.array(Z.string())}),MQ2=FP,to=L$.extend({entityType:Z.literal(j5),metadata:MQ2});wA();class Cy extends g2{constructor(){super({entityType:j5,purpose:"A capability advertised by a remote agent.",schema:to,frontmatterSchema:FP})}fromMarkdown(A){let Q=this.parseFrontMatter(A,FP);return{content:A,entityType:j5,metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}wA();_0();var SJw=Z.object({skills:Z.array(FP).max(8)}),OQ2=d1({name:"skill:skill-derivation",description:"Derive skills from topic titles and brain capabilities",dataSourceId:"shell:ai-content",schema:SJw,useKnowledgeContext:!0,basePrompt:`You are analyzing a brain's content to identify its high-level capabilities.
|
|
9592
9592
|
|
|
9593
9593
|
Given knowledge domains, CONSOLIDATE related topics into broader skills.
|
|
9594
9594
|
There should be FEWER skills than topics \u2014 combine related domains.
|
|
@@ -9738,9 +9738,9 @@ Context:
|
|
|
9738
9738
|
${JSON.stringify(B,null,2)}
|
|
9739
9739
|
|
|
9740
9740
|
Draft SWOT:
|
|
9741
|
-
${JSON.stringify(w,null,2)}`}function HZ0(A){return A.map((Q)=>Q.detail===null?{title:Q.title}:{title:Q.title,detail:Q.detail})}function HIw(A,Q){let w=["strengths","weaknesses","opportunities","threats"];for(let B of w){let $=new Set(A[B].map((f)=>f.theme.trim().toLowerCase()));for(let f of Q[B]){let Y=f.sourceTheme.trim().toLowerCase();if(!$.has(Y))throw Error(`SWOT refinement invented theme "${f.sourceTheme}" in ${B}`)}}}class WZ0{logger;context;adapter=new GV;constructor(A,Q){this.logger=A,this.context=Q}validateAndParse(A){let Q=Kt0.safeParse(A??{});return Q.success?Q.data:null}async process(A,Q,w){await w.report({progress:0.2,message:"Building SWOT context"});let B=await qt0(this.context),$;if(B.summary.brainSkillCount+B.summary.approvedAgentCount+B.summary.discoveredAgentCount===0)$={strengths:[],weaknesses:[],opportunities:[],threats:[]};else{await w.report({progress:0.6,message:"Synthesizing SWOT analysis"});let{object:W}=await this.context.ai.generateObject(await YIw(this.context,B),Ut0),K=Ut0.parse(W);await w.report({progress:0.75,message:"Refining SWOT language"});let U=await this.context.ai.generateObject(await ZIw(this.context,B,K),YZ0);$=YZ0.parse(U.object),HIw(K,$)}let Y=new Date().toISOString(),X=this.adapter.createSwotContent({strengths:HZ0($.strengths),weaknesses:HZ0($.weaknesses),opportunities:HZ0($.opportunities),threats:HZ0($.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:X,metadata:{derivedAt:Y}}});else await this.context.entityService.createEntity({entity:{id:"swot",entityType:"swot",content:X,metadata:{derivedAt:Y}}});return this.logger.info("SWOT derivation complete",{derivedAt:Y,brainSkillCount:B.summary.brainSkillCount,approvedAgentCount:B.summary.approvedAgentCount,discoveredAgentCount:B.summary.discoveredAgentCount}),{entityId:"swot"}}}_0();import{jsxDEV as d4}from"preact/jsx-dev-runtime";var KZ0=Z.object({title:Z.string(),detail:Z.string().optional()}),WIw=Z.discriminatedUnion("status",[Z.object({status:Z.literal("generating")}),Z.object({status:Z.literal("ready"),strengths:Z.array(KZ0).default([]),weaknesses:Z.array(KZ0).default([]),opportunities:Z.array(KZ0).default([]),threats:Z.array(KZ0).default([]),derivedAt:Z.string()})]);function KIw({items:A}){if(A.length===0)return d4("p",{class:"swot-empty",children:"\u2014"},void 0,!1,void 0,this);return d4("ul",{class:"swot-list",children:A.map((Q)=>d4("li",{class:"swot-item",children:[d4("b",{children:Q.title},void 0,!1,void 0,this),Q.detail?d4("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 UZ0({title:A,tone:Q,items:w}){return d4("section",{class:`swot-cell is-${Q}`,children:[d4("div",{class:"swot-head",children:A},void 0,!1,void 0,this),d4(KIw,{items:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function Jt0({data:A}){let Q=WIw.safeParse(A);if(!Q.success||Q.data.status==="generating")return d4("div",{"data-swot-widget":!0,children:d4("p",{class:"muted",children:"generating assessment\u2026"},void 0,!1,void 0,this)},void 0,!1,void 0,this);let w=Q.data;return d4("div",{"data-swot-widget":!0,children:d4("div",{class:"swot",role:"grid","aria-label":"SWOT analysis of agent network",children:[d4(UZ0,{title:"Strengths",tone:"s",items:w.strengths},void 0,!1,void 0,this),d4(UZ0,{title:"Weaknesses",tone:"w",items:w.weaknesses},void 0,!1,void 0,this),d4(UZ0,{title:"Opportunities",tone:"o",items:w.opportunities},void 0,!1,void 0,this),d4(UZ0,{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 It0={name:"@brains/assessment",version:"0.2.0-alpha.
|
|
9741
|
+
${JSON.stringify(w,null,2)}`}function HZ0(A){return A.map((Q)=>Q.detail===null?{title:Q.title}:{title:Q.title,detail:Q.detail})}function HIw(A,Q){let w=["strengths","weaknesses","opportunities","threats"];for(let B of w){let $=new Set(A[B].map((f)=>f.theme.trim().toLowerCase()));for(let f of Q[B]){let Y=f.sourceTheme.trim().toLowerCase();if(!$.has(Y))throw Error(`SWOT refinement invented theme "${f.sourceTheme}" in ${B}`)}}}class WZ0{logger;context;adapter=new GV;constructor(A,Q){this.logger=A,this.context=Q}validateAndParse(A){let Q=Kt0.safeParse(A??{});return Q.success?Q.data:null}async process(A,Q,w){await w.report({progress:0.2,message:"Building SWOT context"});let B=await qt0(this.context),$;if(B.summary.brainSkillCount+B.summary.approvedAgentCount+B.summary.discoveredAgentCount===0)$={strengths:[],weaknesses:[],opportunities:[],threats:[]};else{await w.report({progress:0.6,message:"Synthesizing SWOT analysis"});let{object:W}=await this.context.ai.generateObject(await YIw(this.context,B),Ut0),K=Ut0.parse(W);await w.report({progress:0.75,message:"Refining SWOT language"});let U=await this.context.ai.generateObject(await ZIw(this.context,B,K),YZ0);$=YZ0.parse(U.object),HIw(K,$)}let Y=new Date().toISOString(),X=this.adapter.createSwotContent({strengths:HZ0($.strengths),weaknesses:HZ0($.weaknesses),opportunities:HZ0($.opportunities),threats:HZ0($.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:X,metadata:{derivedAt:Y}}});else await this.context.entityService.createEntity({entity:{id:"swot",entityType:"swot",content:X,metadata:{derivedAt:Y}}});return this.logger.info("SWOT derivation complete",{derivedAt:Y,brainSkillCount:B.summary.brainSkillCount,approvedAgentCount:B.summary.approvedAgentCount,discoveredAgentCount:B.summary.discoveredAgentCount}),{entityId:"swot"}}}_0();import{jsxDEV as d4}from"preact/jsx-dev-runtime";var KZ0=Z.object({title:Z.string(),detail:Z.string().optional()}),WIw=Z.discriminatedUnion("status",[Z.object({status:Z.literal("generating")}),Z.object({status:Z.literal("ready"),strengths:Z.array(KZ0).default([]),weaknesses:Z.array(KZ0).default([]),opportunities:Z.array(KZ0).default([]),threats:Z.array(KZ0).default([]),derivedAt:Z.string()})]);function KIw({items:A}){if(A.length===0)return d4("p",{class:"swot-empty",children:"\u2014"},void 0,!1,void 0,this);return d4("ul",{class:"swot-list",children:A.map((Q)=>d4("li",{class:"swot-item",children:[d4("b",{children:Q.title},void 0,!1,void 0,this),Q.detail?d4("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 UZ0({title:A,tone:Q,items:w}){return d4("section",{class:`swot-cell is-${Q}`,children:[d4("div",{class:"swot-head",children:A},void 0,!1,void 0,this),d4(KIw,{items:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function Jt0({data:A}){let Q=WIw.safeParse(A);if(!Q.success||Q.data.status==="generating")return d4("div",{"data-swot-widget":!0,children:d4("p",{class:"muted",children:"generating assessment\u2026"},void 0,!1,void 0,this)},void 0,!1,void 0,this);let w=Q.data;return d4("div",{"data-swot-widget":!0,children:d4("div",{class:"swot",role:"grid","aria-label":"SWOT analysis of agent network",children:[d4(UZ0,{title:"Strengths",tone:"s",items:w.strengths},void 0,!1,void 0,this),d4(UZ0,{title:"Weaknesses",tone:"w",items:w.weaknesses},void 0,!1,void 0,this),d4(UZ0,{title:"Opportunities",tone:"o",items:w.opportunities},void 0,!1,void 0,this),d4(UZ0,{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 It0={name:"@brains/assessment",version:"0.2.0-alpha.151",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 GIw=Z.object({status:Z.enum(["ready","generating"])}),Ft0=new GV;class Lt0 extends rQ{entityType="swot";schema=gy;adapter=Ft0;initialSyncComplete=!1;constructor(){super("swot",It0,{},k7)}async onRegister(A){let Q=new WZ0(this.logger.child("SwotDerivationHandler"),A);A.jobs.registerHandler("derive",Q),A.eval.registerHandler("deriveSwot",async()=>{let f=Zf.from(async()=>{});if(!f)throw Error("Expected progress reporter to be created");await Q.process({reason:"eval"},"eval-swot-derive",f);let Y=await A.entityService.getEntity({entityType:"swot",id:"swot"});if(!Y)throw Error("Expected SWOT entity to be created during eval");return Ft0.parseSwotContent(Y.content).frontmatter});let w=async(f)=>{try{return await A.jobs.enqueue({type:"derive",data:{reason:f},options:{source:this.id,priority:10,deduplication:"coalesce",deduplicationKey:"swot",metadata:{operationType:"data_processing",operationTarget:`swot:${f}`}}})}catch(Y){return this.logger.error("Failed to queue SWOT derivation",{error:Y,reason:f}),null}},B=async(f)=>{if(!await A.entityService.getEntity({entityType:"swot",id:"swot"}))await w(f)};A.messaging.subscribe("sync:initial:completed",async()=>{return this.initialSyncComplete=!0,await B("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:(f)=>{let{status:Y}=GIw.parse(f);return{digest:[{label:"SWOT",value:Y==="ready"?"Ready":"Generating",tone:Y==="ready"?"good":"warn"}]}},component:Jt0,dataProvider:async()=>{let f=await A.entityService.getEntity({entityType:"swot",id:"swot"});if(!f)return{status:"generating"};let{frontmatter:Y}=Ft0.parseSwotContent(f.content);return{status:"ready",...Y}}}}),{success:!0}});let $=async(f)=>{let{entityType:Y}=f.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",$),A.messaging.subscribe("entity:updated",$),A.messaging.subscribe("entity:deleted",$)}}function kt0(){return new Lt0}wA();t8();_0();var jq$=new GV,lQ2=Z.object({name:Z.string(),description:Z.string(),tags:Z.array(Z.string())}),pQ2=Z.enum(["discovered","approved"]),DIw=Z.object({name:Z.string(),kind:Z.enum(["professional","team","collective"]),organization:Z.string().optional(),brainName:Z.string(),url:Z.string().url(),did:Z.string().optional(),status:pQ2,discoveredAt:Z.string().datetime()}),zIw=L$.extend({entityType:Z.literal("agent"),metadata:Z.object({name:Z.string(),url:Z.string().url(),status:pQ2,slug:Z.string()})}),_t0=Z.object({name:Z.string(),description:Z.string(),tags:Z.array(Z.string()),examples:Z.array(Z.string())}),qIw=L$.extend({entityType:Z.literal("skill"),metadata:_t0}),VIw=Z.object({about:Z.string(),skills:Z.array(lQ2),notes:Z.string()});function bIw(A){if(!Array.isArray(A)||A.length===0)return"";return A.map((w)=>{let B=w.tags.length>0?` [${w.tags.join(", ")}]`:"";return`- ${w.name}: ${w.description}${B}`}).join(`
|
|
9742
9742
|
`)}function JIw(A){if(!A.trim())return[];return A.split(`
|
|
9743
|
-
`).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 IIw=new z6(VIw,{title:"Agent",mappings:[{key:"about",label:"About",type:"string"},{key:"skills",label:"Skills",type:"custom",formatter:bIw,parser:JIw},{key:"notes",label:"Notes",type:"string"}]});class iQ2 extends g2{constructor(){super({entityType:"agent",purpose:"An agent entity used for SWOT evaluation.",schema:zIw,frontmatterSchema:DIw})}fromMarkdown(A){return{content:A,entityType:"agent"}}createAgentContent(A){let Q=IIw.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 dQ2 extends g2{constructor(){super({entityType:"skill",purpose:"A skill entity used for SWOT evaluation.",schema:qIw,frontmatterSchema:_t0})}fromMarkdown(A){let Q=this.parseFrontMatter(A,_t0);return{content:A,entityType:"skill",metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}var Pq$=new iQ2,Mq$=new dQ2,FIw=Z.object({name:Z.string(),description:Z.string(),tags:Z.array(Z.string()),examples:Z.array(Z.string())}),Oq$=Z.object({skills:Z.array(FIw),agents:Z.array(Z.object({id:Z.string().optional(),name:Z.string(),kind:Z.enum(["professional","team","collective"]),organization:Z.string().optional(),brainName:Z.string(),url:Z.url(),did:Z.string().optional(),status:Z.enum(["discovered","approved"]),discoveredAt:Z.string().datetime().optional(),about:Z.string(),skills:Z.array(lQ2),notes:Z.string().default("")}))});var LIw=Z.object({}).strict();function GZ0(A={}){return LIw.parse(A),[kt0()]}wA();_0();_0();var Nt0=Z.object({enabled:Z.boolean().default(!0),pdsEndpoint:Z.url().default("https://bsky.social").describe("AT Protocol PDS service endpoint"),identifier:Z.string().optional().describe("PDS login identifier, usually a handle or account DID"),repoDid:Z.string().optional().describe("DID of the PDS repo that owns records"),appPassword:Z.string().optional().describe("App password for prototype authentication; supply via ${ENV_VAR} interpolation, never a committed literal"),anchorDid:Z.string().optional().describe("Optional human/operator DID referenced from records; defaults to did:web:<site-host>:anchor when omitted"),brainDid:Z.string().optional().describe("Optional public brain DID referenced from records; defaults to did:web:<site-host> when omitted")});_0();var kIw=Z.looseObject({message:Z.string()}),_Iw=Z.looseObject({did:Z.string(),handle:Z.string(),accessJwt:Z.string(),refreshJwt:Z.string()}),jt0=Z.looseObject({uri:Z.string(),cid:Z.string()}),NIw=jt0.extend({value:Z.record(Z.string(),Z.unknown())}),jIw=Z.looseObject({$type:Z.literal("blob").optional(),ref:Z.looseObject({$link:Z.string()}),mimeType:Z.string(),size:Z.number().int().nonnegative()}).transform((A)=>({...A.$type!==void 0?{$type:A.$type}:{},ref:{$link:A.ref.$link},mimeType:A.mimeType,size:A.size})),PIw=Z.looseObject({blob:jIw});function MIw(A){return A.replace(/\/+$/,"")}var OIw=(A,Q)=>fetch(A,Q);async function As(A,Q){let w=await A.text(),B;try{B=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 $=kIw.safeParse(B);throw Error($.success?$.data.message:`AT Protocol request failed with ${A.status}`)}return Q.parse(B)}class Qs{pdsEndpoint;identifier;appPassword;fetchFn;session;constructor(A){this.pdsEndpoint=MIw(A.pdsEndpoint),this.identifier=A.identifier,this.appPassword=A.appPassword,this.fetchFn=A.fetch??OIw}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 As(A,_Iw);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 As(w,jt0)}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 As(w,jt0)}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 As(w,NIw)}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 As(w,PIw)}async getSession(){return this.session??=await this.createSession(),this.session}}function kP(A){return A?.startsWith("did:web:")??!1}function DZ0(A){if(!kP(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 rQ2(A){if(!kP(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(($)=>{try{return decodeURIComponent($)}catch{return $}}).join("/")}/did.json`}function oQ2(A){return A.replace(/\/+$/,"")}function ws(A){return`did:web:${encodeURIComponent(A)}`}function zZ0(A){return`${ws(A)}:anchor`}function Pt0(A){return{"@context":["https://www.w3.org/ns/did/v1"],id:A}}function sQ2(A,Q){let w=A.identifier?.startsWith("did:")?void 0:A.identifier?[`at://${A.identifier}`]:void 0;return{...Pt0(Q),...w&&{alsoKnownAs:w},service:[{id:"#atproto_pds",type:"AtprotoPersonalDataServer",serviceEndpoint:oQ2(A.pdsEndpoint)}]}}function aQ2(A){if(!kP(A.brainDid))return null;return sQ2(A,A.brainDid)}function nQ2(A,Q){if(!A||!Q)return;let w=DZ0(A),B=rQ2(A);if(!w||!B)return;return{path:B,hostname:w,document:Q}}function qZ0(A){let Q=[],w=nQ2(A.brainDid,aQ2(A));if(w)Q.push(w);if(kP(A.anchorDid)&&A.anchorDid!==A.brainDid){let B=nQ2(A.anchorDid,Pt0(A.anchorDid));if(B)Q.push(B)}return Q}function Mt0(A,Q){let w=[];if(!A.brainDid){let B=ws(Q);w.push({path:"/.well-known/did.json",hostname:Q,document:sQ2(A,B)})}if(!A.anchorDid){let B=zZ0(Q);w.push({path:"/anchor/did.json",hostname:Q,document:Pt0(B)})}return w}function xIw(A,Q){if(!A)return;try{return new URL(A,Q).toString()}catch{return}}function vIw(A){let Q=A.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,200);return Q.length>0?Q:"skill"}function tQ2(A,Q){let w=A[Q];return typeof w==="string"&&w.length>0?w:void 0}function eQ2(A,Q){let w=A[Q];if(!Array.isArray(w))return;let B=w.filter(($)=>typeof $==="string"&&$.length>0);return B.length>0?B:void 0}function RIw(A){let Q=A.metadata,w=tQ2(Q,"name"),B=tQ2(Q,"description");if(!w||!B)return;let $=eQ2(Q,"tags"),f=eQ2(Q,"examples");return{id:vIw(w),name:w,description:B,...$&&{tags:$},...f&&{examples:f}}}async function hIw(A){if(!A.entityService.hasEntityType("skill"))return[];return(await A.entityService.listEntities({entityType:"skill",options:{filter:{visibilityScope:"public"}}})).map((w)=>RIw(w)).filter((w)=>w!==void 0).slice(0,100)}async function Ot0(A,Q,w=new Date){let B=A.identity.get(),$=A.identity.getProfile(),f=await A.identity.getAppInfo(),Y=xIw(A.siteUrl??$.website,void 0);if(!Y)throw Error("AT Protocol brain card publishing requires siteUrl");let X=new URL(Y).hostname,H=Q.brainDid??ws(X),W=Q.anchorDid??zZ0(X);if(kP(H)){if(DZ0(H)!==X)throw Error("AT Protocol brain card did:web host must match siteUrl host")}let K=await hIw(A);return{$type:"ai.rizom.brain.card",siteUrl:Y,brain:{did:H,name:B.name,role:B.role,purpose:B.purpose,values:B.values},anchor:{did:W,name:$.name,kind:$.kind},skills:K,model:f.model,version:f.version,createdAt:w.toISOString(),updatedAt:w.toISOString()}}var Aw2={name:"@brains/atproto",version:"0.2.0-alpha.150",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:"^6.0.3"},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 Qw2=k6["ai.rizom.brain.card"],gIw=Z.looseObject({did:Z.string()}),yIw=Z.looseObject({service:Z.array(Z.looseObject({id:Z.string().optional(),type:Z.string().optional(),serviceEndpoint:Z.string().optional()})).optional()}),EIw="ai.rizom.brain.card",TIw="self",ww2=50;class xt0 extends tQ{deps;projectionRegistry;constructor(A={},Q={}){super("atproto",Aw2,A,Nt0);this.deps=Q,this.projectionRegistry=Q.projectionRegistry??Q5.getInstance()}getWebRoutes(){if(!this.config.enabled)return[];let A=qZ0(this.config),Q=[...!this.config.brainDid?["/.well-known/did.json"]:[],...!this.config.anchorDid?["/anchor/did.json"]:[]];return[...new Set([...A.map((B)=>B.path),...Q])].map((B)=>({path:B,method:"GET",public:!0,handler:($)=>{let f=new URL($.url).hostname,Y=[...qZ0(this.config),...Mt0(this.config,f)].filter((H)=>H.path===B),X=Y.find((H)=>H.hostname===f)??Y[0];if(!X)return new Response("Not found",{status:404});return new Response(JSON.stringify(X.document),{headers:{"Content-Type":"application/did+json"}})}}))}async publishBrainCard(A,Q={}){let w=await Ot0(A,this.config);xq(Qw2,w);let B=this.config.repoDid;if(Q.dryRun)return{record:w,dryRun:!0,...B&&{repo:B}};let $=this.resolveAppPassword();if(!this.config.identifier||!$)throw Error("AT Protocol publishing requires identifier and app password configuration");let f=this.createPdsClient($),Y=await f.createSession(),X=B??Y.did;if(!f.putRecord)throw Error("AT Protocol PDS client does not support record upserts");let H=await f.putRecord({repo:X,collection:"ai.rizom.brain.card",rkey:"self",validate:!1,record:w});return{record:w,repo:X,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((f)=>f.trim()))].filter((f)=>f.length>0);if(w.length===0)throw Error("AT Protocol discovery requires at least one repo DID or handle");if(w.length>ww2)throw Error(`AT Protocol discovery accepts at most ${ww2} repos per batch`);let B=new Set,$=[];for(let f of w)try{let Y=await this.resolveRepoPdsEndpoint(f),X=this.createPublicPdsClient(Y.pdsEndpoint);if(!X.getRecord)throw Error("AT Protocol PDS client does not support record reads");let H=await X.getRecord({repo:Y.repoDid,collection:EIw,rkey:TIw});xq(Qw2,H.value);let W=mIw(H.uri)??Y.repoDid,K=`${W}:${H.uri}:${H.cid}`;if(B.has(K)){$.push({repo:f,status:"skipped",repoDid:W,uri:H.uri,cid:H.cid,error:"Duplicate brain card in discovery batch"});continue}B.add(K),await A.messaging.send({type:yd,payload:{repoDid:W,uri:H.uri,cid:H.cid,record:H.value},broadcast:!0}),$.push({repo:f,status:"discovered",repoDid:W,uri:H.uri,cid:H.cid})}catch(Y){$.push({repo:f,status:"skipped",error:SA(Y)})}return{discovered:$.filter((f)=>f.status==="discovered").length,skipped:$.filter((f)=>f.status==="skipped").length,results:$}}async validatePdsCredentials(){let A=this.resolveAppPassword();if(!this.config.identifier||!A)return!1;try{return await this.createPdsClient(A).createSession(),!0}catch(Q){return this.logger.warn("AT Protocol PDS authentication failed",{error:SA(Q)}),!1}}async getTools(){return[]}async publishProjectedEntity(A,Q,w){let B=await this.findPublishEntity(A,Q),$=Q.entityId??Q.slug;if(!$)throw Error(`${Q.entityType} publish requires entityId or slug`);if(!B)throw Error(`${Q.entityType} not found: ${$}`);if(B.visibility!=="public")throw Error(`Cannot publish non-public ${Q.entityType}: ${$}`);let f=this.config.repoDid;if(Q.dryRun){let G=await w.buildRecord({entity:B,context:A,config:this.config,...Q.topics&&{topics:Q.topics},dryRun:!0});return xq(w.lexicon,G),{record:G,dryRun:!0,...f&&{repo:f}}}let Y=this.resolveAppPassword();if(!this.config.identifier||!Y)throw Error("AT Protocol publishing requires identifier and app password configuration");let X=this.createPdsClient(Y),H=await X.createSession(),W=f??H.did,K=await w.buildRecord({entity:B,context:A,config:this.config,client:X,...Q.topics&&{topics:Q.topics}});if(xq(w.lexicon,K),!X.putRecord)throw Error("AT Protocol PDS client does not support record upserts");let U=await X.putRecord({repo:W,collection:w.collection,rkey:SIw(B.id),...w.validate!==void 0&&{validate:w.validate},record:K});return await w.onPublished?.({entity:B,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 Qs({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 B=gIw.safeParse(await w.json());return B.success?B.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(uIw(A)):void 0,w=yIw.safeParse(Q);if(!w.success)return;return w.data.service?.find(($)=>$.id==="#atproto_pds"||$.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 Qs({pdsEndpoint:this.config.pdsEndpoint,identifier:this.config.identifier??"",appPassword:A})}resolveAppPassword(){return this.config.appPassword}}function SIw(A){let Q=A.replace(/[^A-Za-z0-9._~:-]/g,"_").slice(0,512);return Q.length>0?Q:"self"}function mIw(A){return/^at:\/\/([^/]+)/.exec(A)?.[1]}function uIw(A){let Q=A.slice(8).split(":").map(decodeURIComponent),[w,...B]=Q;if(!w)throw Error(`Invalid did:web value: ${A}`);if(B.length===0)return`https://${w}/.well-known/did.json`;return`https://${w}/${B.join("/")}/did.json`}function VZ0(A,Q){return new xt0(A,Q)}wA();_0();var bZ0={name:"@brains/rover",version:"0.2.0-alpha.150",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:"^6.0.3"},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 lIw=Z.looseObject({});class Bw2 extends tQ{constructor(A={}){super("rover-profile",bZ0,A,lIw)}async onRegister(A){A.entities.extendFrontmatterSchema("anchor-profile",_k)}}function $w2(A={}){return new Bw2(A)}wA();_0();jB();wA();wA();var Bs=qz.extend(_k.shape);class JZ0{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 B=w.entityService,[$,f,Y,X]=await Promise.all([Kx(B,Bs),Of0(B,{entityType:"post",count:3,parse:hr}),Of0(B,{entityType:"deck",count:3,parse:mr}),vr(B)]),H={profile:$,posts:f,decks:Y,postsListUrl:this.postsListUrl,decksListUrl:this.decksListUrl,cta:an0(X.cta),sections:X.sections??{}};return Q.parse(H)}}wA();class IZ0{id="professional:about";name="About Page DataSource";description="Fetches full profile data for the about page";async fetch(A,Q,w){let $={profile:await Kx(w.entityService,Bs)};return Q.parse($)}}import{jsxDEV as vB,Fragment as dIw}from"preact/jsx-dev-runtime";var pIw="grid md:grid-cols-[14rem_1px_1fr] gap-y-2 gap-x-0 md:gap-16 items-start",iIw="border-t md:border-t-0 md:border-l border-rule-strong md:self-stretch",vt0=({number:A,title:Q,blurb:w,children:B})=>vB("section",{className:"py-20 border-b border-rule px-6 md:px-12",children:vB("div",{className:"max-w-6xl mx-auto",children:vB("div",{className:pIw,children:[vB($i0,{title:Q,number:A,blurb:w},void 0,!1,void 0,this),vB("div",{className:iIw,"aria-hidden":"true"},void 0,!1,void 0,this),vB("div",{className:"mt-6 md:mt-0",children:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this),Rt0=({profile:A,posts:Q,decks:w,postsListUrl:B,decksListUrl:$,cta:f,sections:Y})=>{let X=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,X].find((q)=>q)??"Professional site",G=Boolean(A.description)||A.expertise!==void 0&&A.expertise.length>0;return vB(dIw,{children:[vB(pQ,{title:K,description:U,ogType:"website"},void 0,!1,void 0,this),vB("div",{className:"homepage-list bg-theme",children:[vB("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:vB("div",{className:"relative z-10 max-w-6xl mx-auto w-full",children:[A.name&&vB("div",{className:"flex items-center gap-[0.6rem] mb-6 font-mono text-[0.7rem] font-medium uppercase tracking-[0.22em] text-accent",children:[vB("span",{className:"w-[18px] h-px bg-accent","aria-hidden":"true"},void 0,!1,void 0,this),vB("span",{children:A.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),X&&vB("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:c70(X,"italic font-normal text-accent [font-variation-settings:'opsz'_144,'SOFT'_80]")},void 0,!1,void 0,this),A.intro&&vB("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:c70(A.intro,"italic text-accent")},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),vB(vt0,{number:"01",title:"Essays",blurb:Y.essays?.blurb,children:vB(u70,{items:H,viewAllUrl:B,viewAllLabel:"View all essays"},void 0,!1,void 0,this)},void 0,!1,void 0,this),W.length>0&&vB(vt0,{number:"02",title:"Presentations",blurb:Y.presentations?.blurb,children:vB(u70,{items:W,viewAllUrl:$,viewAllLabel:"View all presentations"},void 0,!1,void 0,this)},void 0,!1,void 0,this),G&&vB(vt0,{number:"03",title:"About",blurb:Y.about?.blurb,children:vB("div",{className:"flex flex-col gap-8",children:[A.description&&vB("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&&vB(fi0,{subjects:A.expertise},void 0,!1,void 0,this),vB("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",vB("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),vB(lp0,{cta:f,variant:"editorial",socialLinks:A.socialLinks},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as a6,Fragment as nIw}from"preact/jsx-dev-runtime";var ht0=({profile:A})=>{let Q=`About ${A.name||"Me"}`,w=[A.description,A.intro].find(($)=>$)??"About page",B=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 a6(nIw,{children:[a6(pQ,{title:Q,description:w,ogType:"profile"},void 0,!1,void 0,this),a6("div",{className:"about-page bg-theme",children:[a6("header",{className:"hero-bg-pattern relative w-full py-16 md:py-24 px-6 md:px-12 bg-theme overflow-hidden",children:a6("div",{className:"relative z-10 max-w-4xl mx-auto",children:[a6("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&&a6("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),a6("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-12 md:py-16",children:[A.story&&a6("section",{className:"content-section-reveal mb-20 md:mb-28",children:a6(F9,{markdown:A.story},void 0,!1,void 0,this)},void 0,!1,void 0,this),B&&a6("div",{className:"content-section-reveal grid md:grid-cols-2 gap-x-16 gap-y-12",children:[A.expertise&&A.expertise.length>0&&a6("section",{children:[a6("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Expertise"},void 0,!1,void 0,this),a6("ul",{className:"flex flex-wrap gap-3",children:A.expertise.map(($,f)=>a6("li",{className:Pn({variant:"accent",size:"lg"}),children:$},f,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.currentFocus&&a6("section",{children:[a6("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Current Focus"},void 0,!1,void 0,this),a6("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&&a6("section",{children:[a6("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Availability"},void 0,!1,void 0,this),a6("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)&&a6("section",{children:[a6("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Contact"},void 0,!1,void 0,this),a6("div",{className:"space-y-4",children:[A.email&&a6("p",{className:"text-lg",children:a6("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&&a6("p",{className:"text-lg",children:a6("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&&a6("div",{className:"flex flex-wrap gap-4 mt-4",children:A.socialLinks.map(($,f)=>a6(I9,{href:$.url,external:!0,variant:"secondary",size:"md",children:$.label?.length?$.label:$.platform},f,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as n4,Fragment as fw2}from"preact/jsx-dev-runtime";var Ct0=()=>{return n4(fw2,{children:[n4(pQ,{title:"Thanks for subscribing!",description:"You've successfully subscribed to the newsletter."},void 0,!1,void 0,this),n4("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:n4("div",{className:"text-center max-w-md",children:[n4("div",{className:"text-6xl mb-6",children:"\uD83C\uDF89"},void 0,!1,void 0,this),n4("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Thanks for subscribing!"},void 0,!1,void 0,this),n4("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),n4(I9,{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)},gt0=()=>{return n4(fw2,{children:[n4(pQ,{title:"Subscription failed",description:"There was a problem with your subscription."},void 0,!1,void 0,this),n4("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:n4("div",{className:"text-center max-w-md",children:[n4("div",{className:"text-6xl mb-6",children:"\uD83D\uDE22"},void 0,!1,void 0,this),n4("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Something went wrong"},void 0,!1,void 0,this),n4("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),n4(I9,{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)};_0();var Yw2=Z.object({label:Z.string().describe("Display label for entity type (e.g., 'Essay')"),pluralName:Z.string().optional().describe("URL path segment (defaults to label.toLowerCase() + 's')")}),rIw={post:{label:"Post"},deck:{label:"Deck"}},Xw2=Z.object({entityDisplay:Z.object({post:Yw2,deck:Yw2}).default(rIw).describe("Display metadata for post and deck entity types used by the homepage")});var Zw2={name:"@brains/site-professional",version:"0.2.0-alpha.150",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:"^6.0.3"},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 sIw=Z.object({blurb:Z.string().optional().describe("Short italic subtitle under the section title")}),aIw=Z.object({heading:Z.string(),buttonText:Z.string(),buttonLink:Z.string()}),Hw2=Z.looseObject({name:Z.string(),kind:Z.enum(["professional","team","collective"]),organization:Z.string().optional(),description:Z.string().optional(),avatar:Z.string().optional(),website:Z.string().optional(),email:Z.string().optional(),socialLinks:Z.array(Z.object({platform:Z.enum(["github","instagram","linkedin","email","website"]),url:Z.string(),label:Z.string().optional()})).optional(),tagline:Z.string().optional(),intro:Z.string().optional(),story:Z.string().optional(),role:Z.string().optional(),audience:Z.string().optional(),expertise:Z.array(Z.string()).optional(),currentFocus:Z.string().optional(),availability:Z.string().optional(),desiredTone:Z.string().optional()}),tIw=Z.looseObject({id:Z.string(),entityType:Z.literal("post"),content:Z.string(),created:Z.string(),updated:Z.string(),contentHash:Z.string(),metadata:Z.looseObject({title:Z.string(),publishedAt:Z.string().optional()}),frontmatter:Z.looseObject({excerpt:Z.string(),seriesName:Z.string().optional(),seriesIndex:Z.number().optional()}),body:Z.string(),url:Z.string().optional(),typeLabel:Z.string().optional(),listUrl:Z.string().optional(),listLabel:Z.string().optional(),seriesUrl:Z.string().optional(),coverImageUrl:Z.string().optional(),ogImageUrl:Z.string().optional(),coverImageWidth:Z.number().optional(),coverImageHeight:Z.number().optional(),coverImageSrcset:Z.string().optional(),coverImageSizes:Z.string().optional()}),eIw=Z.looseObject({id:Z.string(),entityType:Z.literal("deck"),content:Z.string(),created:Z.string(),updated:Z.string(),contentHash:Z.string(),metadata:Z.looseObject({title:Z.string(),publishedAt:Z.string().optional()}),frontmatter:Z.looseObject({title:Z.string(),description:Z.string().optional(),publishedAt:Z.string().optional()}),body:Z.string(),url:Z.string().optional(),typeLabel:Z.string().optional(),listUrl:Z.string().optional(),listLabel:Z.string().optional(),coverImageUrl:Z.string().optional(),ogImageUrl:Z.string().optional(),coverImageWidth:Z.number().optional(),coverImageHeight:Z.number().optional()});class yt0 extends tQ{dependencies=["blog","decks"];constructor(A){super("professional-site",Zw2,A,Xw2)}async onRegister(A){let Q=this.config.entityDisplay.post,w=this.config.entityDisplay.deck,B=`/${Q.pluralName??Q.label.toLowerCase()+"s"}`,$=`/${w.pluralName??w.label.toLowerCase()+"s"}`,f=new JZ0(B,$);A.entities.registerDataSource(f);let Y=new IZ0;A.entities.registerDataSource(Y);let X=Z.object({profile:Hw2,posts:Z.array(tIw),decks:Z.array(eIw),postsListUrl:Z.string(),decksListUrl:Z.string(),cta:aIw,sections:Z.record(Z.string(),sIw)}),H=Z.object({profile:Hw2}),W=Z.object({});A.templates.register({"homepage-list":d1({name:"homepage-list",description:"Professional homepage with essays and presentations",schema:X,dataSourceId:"professional:homepage-list",requiredPermission:"public",layout:{component:Rt0}}),about:d1({name:"about",description:"About page with full profile information",schema:H,dataSourceId:"professional:about",requiredPermission:"public",layout:{component:ht0}}),"subscribe-thanks":d1({name:"subscribe-thanks",description:"Newsletter subscription success page",schema:W,requiredPermission:"public",layout:{component:Ct0}}),"subscribe-error":d1({name:"subscribe-error",description:"Newsletter subscription error page",schema:W,requiredPermission:"public",layout:{component:gt0}})}),this.logger.info("Professional site plugin registered successfully")}async getTools(){return[]}async getResources(){return[]}}function Ww2(A){return new yt0(A??{})}var Kw2=[{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 FZ0}from"preact/jsx-dev-runtime";function Uw2({sections:A,siteInfo:Q,slots:w,wordmark:B}){return FZ0("div",{className:"flex flex-col min-h-screen bg-theme overflow-x-clip",children:[FZ0(np0,{title:Q.title,navigation:Q.navigation.primary,showThemeToggle:!0,...Q.logo!==void 0?{logo:Q.logo}:{},...B!==void 0?{wordmark:B}:{}},void 0,!1,void 0,this),FZ0("main",{className:"flex-grow flex flex-col bg-theme",children:A},void 0,!1,void 0,this),FZ0(dp0,{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(($)=>$.render())},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}var AFw={layouts:{default:Uw2},routes:Kw2,plugin:Ww2,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"}}}},$s=AFw;var Gw2=`/*
|
|
9743
|
+
`).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 IIw=new z6(VIw,{title:"Agent",mappings:[{key:"about",label:"About",type:"string"},{key:"skills",label:"Skills",type:"custom",formatter:bIw,parser:JIw},{key:"notes",label:"Notes",type:"string"}]});class iQ2 extends g2{constructor(){super({entityType:"agent",purpose:"An agent entity used for SWOT evaluation.",schema:zIw,frontmatterSchema:DIw})}fromMarkdown(A){return{content:A,entityType:"agent"}}createAgentContent(A){let Q=IIw.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 dQ2 extends g2{constructor(){super({entityType:"skill",purpose:"A skill entity used for SWOT evaluation.",schema:qIw,frontmatterSchema:_t0})}fromMarkdown(A){let Q=this.parseFrontMatter(A,_t0);return{content:A,entityType:"skill",metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}var Pq$=new iQ2,Mq$=new dQ2,FIw=Z.object({name:Z.string(),description:Z.string(),tags:Z.array(Z.string()),examples:Z.array(Z.string())}),Oq$=Z.object({skills:Z.array(FIw),agents:Z.array(Z.object({id:Z.string().optional(),name:Z.string(),kind:Z.enum(["professional","team","collective"]),organization:Z.string().optional(),brainName:Z.string(),url:Z.url(),did:Z.string().optional(),status:Z.enum(["discovered","approved"]),discoveredAt:Z.string().datetime().optional(),about:Z.string(),skills:Z.array(lQ2),notes:Z.string().default("")}))});var LIw=Z.object({}).strict();function GZ0(A={}){return LIw.parse(A),[kt0()]}wA();_0();_0();var Nt0=Z.object({enabled:Z.boolean().default(!0),pdsEndpoint:Z.url().default("https://bsky.social").describe("AT Protocol PDS service endpoint"),identifier:Z.string().optional().describe("PDS login identifier, usually a handle or account DID"),repoDid:Z.string().optional().describe("DID of the PDS repo that owns records"),appPassword:Z.string().optional().describe("App password for prototype authentication; supply via ${ENV_VAR} interpolation, never a committed literal"),anchorDid:Z.string().optional().describe("Optional human/operator DID referenced from records; defaults to did:web:<site-host>:anchor when omitted"),brainDid:Z.string().optional().describe("Optional public brain DID referenced from records; defaults to did:web:<site-host> when omitted")});_0();var kIw=Z.looseObject({message:Z.string()}),_Iw=Z.looseObject({did:Z.string(),handle:Z.string(),accessJwt:Z.string(),refreshJwt:Z.string()}),jt0=Z.looseObject({uri:Z.string(),cid:Z.string()}),NIw=jt0.extend({value:Z.record(Z.string(),Z.unknown())}),jIw=Z.looseObject({$type:Z.literal("blob").optional(),ref:Z.looseObject({$link:Z.string()}),mimeType:Z.string(),size:Z.number().int().nonnegative()}).transform((A)=>({...A.$type!==void 0?{$type:A.$type}:{},ref:{$link:A.ref.$link},mimeType:A.mimeType,size:A.size})),PIw=Z.looseObject({blob:jIw});function MIw(A){return A.replace(/\/+$/,"")}var OIw=(A,Q)=>fetch(A,Q);async function As(A,Q){let w=await A.text(),B;try{B=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 $=kIw.safeParse(B);throw Error($.success?$.data.message:`AT Protocol request failed with ${A.status}`)}return Q.parse(B)}class Qs{pdsEndpoint;identifier;appPassword;fetchFn;session;constructor(A){this.pdsEndpoint=MIw(A.pdsEndpoint),this.identifier=A.identifier,this.appPassword=A.appPassword,this.fetchFn=A.fetch??OIw}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 As(A,_Iw);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 As(w,jt0)}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 As(w,jt0)}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 As(w,NIw)}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 As(w,PIw)}async getSession(){return this.session??=await this.createSession(),this.session}}function kP(A){return A?.startsWith("did:web:")??!1}function DZ0(A){if(!kP(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 rQ2(A){if(!kP(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(($)=>{try{return decodeURIComponent($)}catch{return $}}).join("/")}/did.json`}function oQ2(A){return A.replace(/\/+$/,"")}function ws(A){return`did:web:${encodeURIComponent(A)}`}function zZ0(A){return`${ws(A)}:anchor`}function Pt0(A){return{"@context":["https://www.w3.org/ns/did/v1"],id:A}}function sQ2(A,Q){let w=A.identifier?.startsWith("did:")?void 0:A.identifier?[`at://${A.identifier}`]:void 0;return{...Pt0(Q),...w&&{alsoKnownAs:w},service:[{id:"#atproto_pds",type:"AtprotoPersonalDataServer",serviceEndpoint:oQ2(A.pdsEndpoint)}]}}function aQ2(A){if(!kP(A.brainDid))return null;return sQ2(A,A.brainDid)}function nQ2(A,Q){if(!A||!Q)return;let w=DZ0(A),B=rQ2(A);if(!w||!B)return;return{path:B,hostname:w,document:Q}}function qZ0(A){let Q=[],w=nQ2(A.brainDid,aQ2(A));if(w)Q.push(w);if(kP(A.anchorDid)&&A.anchorDid!==A.brainDid){let B=nQ2(A.anchorDid,Pt0(A.anchorDid));if(B)Q.push(B)}return Q}function Mt0(A,Q){let w=[];if(!A.brainDid){let B=ws(Q);w.push({path:"/.well-known/did.json",hostname:Q,document:sQ2(A,B)})}if(!A.anchorDid){let B=zZ0(Q);w.push({path:"/anchor/did.json",hostname:Q,document:Pt0(B)})}return w}function xIw(A,Q){if(!A)return;try{return new URL(A,Q).toString()}catch{return}}function vIw(A){let Q=A.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,200);return Q.length>0?Q:"skill"}function tQ2(A,Q){let w=A[Q];return typeof w==="string"&&w.length>0?w:void 0}function eQ2(A,Q){let w=A[Q];if(!Array.isArray(w))return;let B=w.filter(($)=>typeof $==="string"&&$.length>0);return B.length>0?B:void 0}function RIw(A){let Q=A.metadata,w=tQ2(Q,"name"),B=tQ2(Q,"description");if(!w||!B)return;let $=eQ2(Q,"tags"),f=eQ2(Q,"examples");return{id:vIw(w),name:w,description:B,...$&&{tags:$},...f&&{examples:f}}}async function hIw(A){if(!A.entityService.hasEntityType("skill"))return[];return(await A.entityService.listEntities({entityType:"skill",options:{filter:{visibilityScope:"public"}}})).map((w)=>RIw(w)).filter((w)=>w!==void 0).slice(0,100)}async function Ot0(A,Q,w=new Date){let B=A.identity.get(),$=A.identity.getProfile(),f=await A.identity.getAppInfo(),Y=xIw(A.siteUrl??$.website,void 0);if(!Y)throw Error("AT Protocol brain card publishing requires siteUrl");let X=new URL(Y).hostname,H=Q.brainDid??ws(X),W=Q.anchorDid??zZ0(X);if(kP(H)){if(DZ0(H)!==X)throw Error("AT Protocol brain card did:web host must match siteUrl host")}let K=await hIw(A);return{$type:"ai.rizom.brain.card",siteUrl:Y,brain:{did:H,name:B.name,role:B.role,purpose:B.purpose,values:B.values},anchor:{did:W,name:$.name,kind:$.kind},skills:K,model:f.model,version:f.version,createdAt:w.toISOString(),updatedAt:w.toISOString()}}var Aw2={name:"@brains/atproto",version:"0.2.0-alpha.151",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 Qw2=k6["ai.rizom.brain.card"],gIw=Z.looseObject({did:Z.string()}),yIw=Z.looseObject({service:Z.array(Z.looseObject({id:Z.string().optional(),type:Z.string().optional(),serviceEndpoint:Z.string().optional()})).optional()}),EIw="ai.rizom.brain.card",TIw="self",ww2=50;class xt0 extends tQ{deps;projectionRegistry;constructor(A={},Q={}){super("atproto",Aw2,A,Nt0);this.deps=Q,this.projectionRegistry=Q.projectionRegistry??Q5.getInstance()}getWebRoutes(){if(!this.config.enabled)return[];let A=qZ0(this.config),Q=[...!this.config.brainDid?["/.well-known/did.json"]:[],...!this.config.anchorDid?["/anchor/did.json"]:[]];return[...new Set([...A.map((B)=>B.path),...Q])].map((B)=>({path:B,method:"GET",public:!0,handler:($)=>{let f=new URL($.url).hostname,Y=[...qZ0(this.config),...Mt0(this.config,f)].filter((H)=>H.path===B),X=Y.find((H)=>H.hostname===f)??Y[0];if(!X)return new Response("Not found",{status:404});return new Response(JSON.stringify(X.document),{headers:{"Content-Type":"application/did+json"}})}}))}async publishBrainCard(A,Q={}){let w=await Ot0(A,this.config);xq(Qw2,w);let B=this.config.repoDid;if(Q.dryRun)return{record:w,dryRun:!0,...B&&{repo:B}};let $=this.resolveAppPassword();if(!this.config.identifier||!$)throw Error("AT Protocol publishing requires identifier and app password configuration");let f=this.createPdsClient($),Y=await f.createSession(),X=B??Y.did;if(!f.putRecord)throw Error("AT Protocol PDS client does not support record upserts");let H=await f.putRecord({repo:X,collection:"ai.rizom.brain.card",rkey:"self",validate:!1,record:w});return{record:w,repo:X,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((f)=>f.trim()))].filter((f)=>f.length>0);if(w.length===0)throw Error("AT Protocol discovery requires at least one repo DID or handle");if(w.length>ww2)throw Error(`AT Protocol discovery accepts at most ${ww2} repos per batch`);let B=new Set,$=[];for(let f of w)try{let Y=await this.resolveRepoPdsEndpoint(f),X=this.createPublicPdsClient(Y.pdsEndpoint);if(!X.getRecord)throw Error("AT Protocol PDS client does not support record reads");let H=await X.getRecord({repo:Y.repoDid,collection:EIw,rkey:TIw});xq(Qw2,H.value);let W=mIw(H.uri)??Y.repoDid,K=`${W}:${H.uri}:${H.cid}`;if(B.has(K)){$.push({repo:f,status:"skipped",repoDid:W,uri:H.uri,cid:H.cid,error:"Duplicate brain card in discovery batch"});continue}B.add(K),await A.messaging.send({type:yd,payload:{repoDid:W,uri:H.uri,cid:H.cid,record:H.value},broadcast:!0}),$.push({repo:f,status:"discovered",repoDid:W,uri:H.uri,cid:H.cid})}catch(Y){$.push({repo:f,status:"skipped",error:SA(Y)})}return{discovered:$.filter((f)=>f.status==="discovered").length,skipped:$.filter((f)=>f.status==="skipped").length,results:$}}async validatePdsCredentials(){let A=this.resolveAppPassword();if(!this.config.identifier||!A)return!1;try{return await this.createPdsClient(A).createSession(),!0}catch(Q){return this.logger.warn("AT Protocol PDS authentication failed",{error:SA(Q)}),!1}}async getTools(){return[]}async publishProjectedEntity(A,Q,w){let B=await this.findPublishEntity(A,Q),$=Q.entityId??Q.slug;if(!$)throw Error(`${Q.entityType} publish requires entityId or slug`);if(!B)throw Error(`${Q.entityType} not found: ${$}`);if(B.visibility!=="public")throw Error(`Cannot publish non-public ${Q.entityType}: ${$}`);let f=this.config.repoDid;if(Q.dryRun){let G=await w.buildRecord({entity:B,context:A,config:this.config,...Q.topics&&{topics:Q.topics},dryRun:!0});return xq(w.lexicon,G),{record:G,dryRun:!0,...f&&{repo:f}}}let Y=this.resolveAppPassword();if(!this.config.identifier||!Y)throw Error("AT Protocol publishing requires identifier and app password configuration");let X=this.createPdsClient(Y),H=await X.createSession(),W=f??H.did,K=await w.buildRecord({entity:B,context:A,config:this.config,client:X,...Q.topics&&{topics:Q.topics}});if(xq(w.lexicon,K),!X.putRecord)throw Error("AT Protocol PDS client does not support record upserts");let U=await X.putRecord({repo:W,collection:w.collection,rkey:SIw(B.id),...w.validate!==void 0&&{validate:w.validate},record:K});return await w.onPublished?.({entity:B,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 Qs({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 B=gIw.safeParse(await w.json());return B.success?B.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(uIw(A)):void 0,w=yIw.safeParse(Q);if(!w.success)return;return w.data.service?.find(($)=>$.id==="#atproto_pds"||$.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 Qs({pdsEndpoint:this.config.pdsEndpoint,identifier:this.config.identifier??"",appPassword:A})}resolveAppPassword(){return this.config.appPassword}}function SIw(A){let Q=A.replace(/[^A-Za-z0-9._~:-]/g,"_").slice(0,512);return Q.length>0?Q:"self"}function mIw(A){return/^at:\/\/([^/]+)/.exec(A)?.[1]}function uIw(A){let Q=A.slice(8).split(":").map(decodeURIComponent),[w,...B]=Q;if(!w)throw Error(`Invalid did:web value: ${A}`);if(B.length===0)return`https://${w}/.well-known/did.json`;return`https://${w}/${B.join("/")}/did.json`}function VZ0(A,Q){return new xt0(A,Q)}wA();_0();var bZ0={name:"@brains/rover",version:"0.2.0-alpha.151",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 lIw=Z.looseObject({});class Bw2 extends tQ{constructor(A={}){super("rover-profile",bZ0,A,lIw)}async onRegister(A){A.entities.extendFrontmatterSchema("anchor-profile",_k)}}function $w2(A={}){return new Bw2(A)}wA();_0();jB();wA();wA();var Bs=qz.extend(_k.shape);class JZ0{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 B=w.entityService,[$,f,Y,X]=await Promise.all([Kx(B,Bs),Of0(B,{entityType:"post",count:3,parse:hr}),Of0(B,{entityType:"deck",count:3,parse:mr}),vr(B)]),H={profile:$,posts:f,decks:Y,postsListUrl:this.postsListUrl,decksListUrl:this.decksListUrl,cta:an0(X.cta),sections:X.sections??{}};return Q.parse(H)}}wA();class IZ0{id="professional:about";name="About Page DataSource";description="Fetches full profile data for the about page";async fetch(A,Q,w){let $={profile:await Kx(w.entityService,Bs)};return Q.parse($)}}import{jsxDEV as vB,Fragment as dIw}from"preact/jsx-dev-runtime";var pIw="grid md:grid-cols-[14rem_1px_1fr] gap-y-2 gap-x-0 md:gap-16 items-start",iIw="border-t md:border-t-0 md:border-l border-rule-strong md:self-stretch",vt0=({number:A,title:Q,blurb:w,children:B})=>vB("section",{className:"py-20 border-b border-rule px-6 md:px-12",children:vB("div",{className:"max-w-6xl mx-auto",children:vB("div",{className:pIw,children:[vB($i0,{title:Q,number:A,blurb:w},void 0,!1,void 0,this),vB("div",{className:iIw,"aria-hidden":"true"},void 0,!1,void 0,this),vB("div",{className:"mt-6 md:mt-0",children:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this),Rt0=({profile:A,posts:Q,decks:w,postsListUrl:B,decksListUrl:$,cta:f,sections:Y})=>{let X=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,X].find((q)=>q)??"Professional site",G=Boolean(A.description)||A.expertise!==void 0&&A.expertise.length>0;return vB(dIw,{children:[vB(pQ,{title:K,description:U,ogType:"website"},void 0,!1,void 0,this),vB("div",{className:"homepage-list bg-theme",children:[vB("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:vB("div",{className:"relative z-10 max-w-6xl mx-auto w-full",children:[A.name&&vB("div",{className:"flex items-center gap-[0.6rem] mb-6 font-mono text-[0.7rem] font-medium uppercase tracking-[0.22em] text-accent",children:[vB("span",{className:"w-[18px] h-px bg-accent","aria-hidden":"true"},void 0,!1,void 0,this),vB("span",{children:A.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),X&&vB("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:c70(X,"italic font-normal text-accent [font-variation-settings:'opsz'_144,'SOFT'_80]")},void 0,!1,void 0,this),A.intro&&vB("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:c70(A.intro,"italic text-accent")},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),vB(vt0,{number:"01",title:"Essays",blurb:Y.essays?.blurb,children:vB(u70,{items:H,viewAllUrl:B,viewAllLabel:"View all essays"},void 0,!1,void 0,this)},void 0,!1,void 0,this),W.length>0&&vB(vt0,{number:"02",title:"Presentations",blurb:Y.presentations?.blurb,children:vB(u70,{items:W,viewAllUrl:$,viewAllLabel:"View all presentations"},void 0,!1,void 0,this)},void 0,!1,void 0,this),G&&vB(vt0,{number:"03",title:"About",blurb:Y.about?.blurb,children:vB("div",{className:"flex flex-col gap-8",children:[A.description&&vB("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&&vB(fi0,{subjects:A.expertise},void 0,!1,void 0,this),vB("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",vB("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),vB(lp0,{cta:f,variant:"editorial",socialLinks:A.socialLinks},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as a6,Fragment as nIw}from"preact/jsx-dev-runtime";var ht0=({profile:A})=>{let Q=`About ${A.name||"Me"}`,w=[A.description,A.intro].find(($)=>$)??"About page",B=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 a6(nIw,{children:[a6(pQ,{title:Q,description:w,ogType:"profile"},void 0,!1,void 0,this),a6("div",{className:"about-page bg-theme",children:[a6("header",{className:"hero-bg-pattern relative w-full py-16 md:py-24 px-6 md:px-12 bg-theme overflow-hidden",children:a6("div",{className:"relative z-10 max-w-4xl mx-auto",children:[a6("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&&a6("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),a6("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-12 md:py-16",children:[A.story&&a6("section",{className:"content-section-reveal mb-20 md:mb-28",children:a6(F9,{markdown:A.story},void 0,!1,void 0,this)},void 0,!1,void 0,this),B&&a6("div",{className:"content-section-reveal grid md:grid-cols-2 gap-x-16 gap-y-12",children:[A.expertise&&A.expertise.length>0&&a6("section",{children:[a6("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Expertise"},void 0,!1,void 0,this),a6("ul",{className:"flex flex-wrap gap-3",children:A.expertise.map(($,f)=>a6("li",{className:Pn({variant:"accent",size:"lg"}),children:$},f,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.currentFocus&&a6("section",{children:[a6("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Current Focus"},void 0,!1,void 0,this),a6("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&&a6("section",{children:[a6("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Availability"},void 0,!1,void 0,this),a6("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)&&a6("section",{children:[a6("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Contact"},void 0,!1,void 0,this),a6("div",{className:"space-y-4",children:[A.email&&a6("p",{className:"text-lg",children:a6("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&&a6("p",{className:"text-lg",children:a6("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&&a6("div",{className:"flex flex-wrap gap-4 mt-4",children:A.socialLinks.map(($,f)=>a6(I9,{href:$.url,external:!0,variant:"secondary",size:"md",children:$.label?.length?$.label:$.platform},f,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as n4,Fragment as fw2}from"preact/jsx-dev-runtime";var Ct0=()=>{return n4(fw2,{children:[n4(pQ,{title:"Thanks for subscribing!",description:"You've successfully subscribed to the newsletter."},void 0,!1,void 0,this),n4("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:n4("div",{className:"text-center max-w-md",children:[n4("div",{className:"text-6xl mb-6",children:"\uD83C\uDF89"},void 0,!1,void 0,this),n4("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Thanks for subscribing!"},void 0,!1,void 0,this),n4("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),n4(I9,{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)},gt0=()=>{return n4(fw2,{children:[n4(pQ,{title:"Subscription failed",description:"There was a problem with your subscription."},void 0,!1,void 0,this),n4("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:n4("div",{className:"text-center max-w-md",children:[n4("div",{className:"text-6xl mb-6",children:"\uD83D\uDE22"},void 0,!1,void 0,this),n4("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Something went wrong"},void 0,!1,void 0,this),n4("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),n4(I9,{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)};_0();var Yw2=Z.object({label:Z.string().describe("Display label for entity type (e.g., 'Essay')"),pluralName:Z.string().optional().describe("URL path segment (defaults to label.toLowerCase() + 's')")}),rIw={post:{label:"Post"},deck:{label:"Deck"}},Xw2=Z.object({entityDisplay:Z.object({post:Yw2,deck:Yw2}).default(rIw).describe("Display metadata for post and deck entity types used by the homepage")});var Zw2={name:"@brains/site-professional",version:"0.2.0-alpha.151",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 sIw=Z.object({blurb:Z.string().optional().describe("Short italic subtitle under the section title")}),aIw=Z.object({heading:Z.string(),buttonText:Z.string(),buttonLink:Z.string()}),Hw2=Z.looseObject({name:Z.string(),kind:Z.enum(["professional","team","collective"]),organization:Z.string().optional(),description:Z.string().optional(),avatar:Z.string().optional(),website:Z.string().optional(),email:Z.string().optional(),socialLinks:Z.array(Z.object({platform:Z.enum(["github","instagram","linkedin","email","website"]),url:Z.string(),label:Z.string().optional()})).optional(),tagline:Z.string().optional(),intro:Z.string().optional(),story:Z.string().optional(),role:Z.string().optional(),audience:Z.string().optional(),expertise:Z.array(Z.string()).optional(),currentFocus:Z.string().optional(),availability:Z.string().optional(),desiredTone:Z.string().optional()}),tIw=Z.looseObject({id:Z.string(),entityType:Z.literal("post"),content:Z.string(),created:Z.string(),updated:Z.string(),contentHash:Z.string(),metadata:Z.looseObject({title:Z.string(),publishedAt:Z.string().optional()}),frontmatter:Z.looseObject({excerpt:Z.string(),seriesName:Z.string().optional(),seriesIndex:Z.number().optional()}),body:Z.string(),url:Z.string().optional(),typeLabel:Z.string().optional(),listUrl:Z.string().optional(),listLabel:Z.string().optional(),seriesUrl:Z.string().optional(),coverImageUrl:Z.string().optional(),ogImageUrl:Z.string().optional(),coverImageWidth:Z.number().optional(),coverImageHeight:Z.number().optional(),coverImageSrcset:Z.string().optional(),coverImageSizes:Z.string().optional()}),eIw=Z.looseObject({id:Z.string(),entityType:Z.literal("deck"),content:Z.string(),created:Z.string(),updated:Z.string(),contentHash:Z.string(),metadata:Z.looseObject({title:Z.string(),publishedAt:Z.string().optional()}),frontmatter:Z.looseObject({title:Z.string(),description:Z.string().optional(),publishedAt:Z.string().optional()}),body:Z.string(),url:Z.string().optional(),typeLabel:Z.string().optional(),listUrl:Z.string().optional(),listLabel:Z.string().optional(),coverImageUrl:Z.string().optional(),ogImageUrl:Z.string().optional(),coverImageWidth:Z.number().optional(),coverImageHeight:Z.number().optional()});class yt0 extends tQ{dependencies=["blog","decks"];constructor(A){super("professional-site",Zw2,A,Xw2)}async onRegister(A){let Q=this.config.entityDisplay.post,w=this.config.entityDisplay.deck,B=`/${Q.pluralName??Q.label.toLowerCase()+"s"}`,$=`/${w.pluralName??w.label.toLowerCase()+"s"}`,f=new JZ0(B,$);A.entities.registerDataSource(f);let Y=new IZ0;A.entities.registerDataSource(Y);let X=Z.object({profile:Hw2,posts:Z.array(tIw),decks:Z.array(eIw),postsListUrl:Z.string(),decksListUrl:Z.string(),cta:aIw,sections:Z.record(Z.string(),sIw)}),H=Z.object({profile:Hw2}),W=Z.object({});A.templates.register({"homepage-list":d1({name:"homepage-list",description:"Professional homepage with essays and presentations",schema:X,dataSourceId:"professional:homepage-list",requiredPermission:"public",layout:{component:Rt0}}),about:d1({name:"about",description:"About page with full profile information",schema:H,dataSourceId:"professional:about",requiredPermission:"public",layout:{component:ht0}}),"subscribe-thanks":d1({name:"subscribe-thanks",description:"Newsletter subscription success page",schema:W,requiredPermission:"public",layout:{component:Ct0}}),"subscribe-error":d1({name:"subscribe-error",description:"Newsletter subscription error page",schema:W,requiredPermission:"public",layout:{component:gt0}})}),this.logger.info("Professional site plugin registered successfully")}async getTools(){return[]}async getResources(){return[]}}function Ww2(A){return new yt0(A??{})}var Kw2=[{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 FZ0}from"preact/jsx-dev-runtime";function Uw2({sections:A,siteInfo:Q,slots:w,wordmark:B}){return FZ0("div",{className:"flex flex-col min-h-screen bg-theme overflow-x-clip",children:[FZ0(np0,{title:Q.title,navigation:Q.navigation.primary,showThemeToggle:!0,...Q.logo!==void 0?{logo:Q.logo}:{},...B!==void 0?{wordmark:B}:{}},void 0,!1,void 0,this),FZ0("main",{className:"flex-grow flex flex-col bg-theme",children:A},void 0,!1,void 0,this),FZ0(dp0,{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(($)=>$.render())},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}var AFw={layouts:{default:Uw2},routes:Kw2,plugin:Ww2,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"}}}},$s=AFw;var Gw2=`/*
|
|
9744
9744
|
* Default theme \u2014 simplified editorial base inspired by the Rizom family.
|
|
9745
9745
|
*
|
|
9746
9746
|
* This theme is intentionally less branded than @brains/theme-rizom. It
|
|
@@ -10323,7 +10323,7 @@ ${JSON.stringify(w,null,2)}`}function HZ0(A){return A.map((Q)=>Q.detail===null?{
|
|
|
10323
10323
|
font: 10px/1.45 var(--font-mono, "JetBrains Mono", ui-monospace, monospace);
|
|
10324
10324
|
}
|
|
10325
10325
|
`}},void 0,!1,void 0,this),lZ("section",{className:"product-shell",children:[lZ("header",{className:"product-hero",children:[Q.brandLabel&&lZ("p",{className:"printable-kicker",children:Q.brandLabel},void 0,!1,void 0,this),lZ("h1",{className:"printable-title",children:Q.name},void 0,!1,void 0,this),Q.availability&&lZ("div",{className:"printable-meta",children:lZ("span",{children:Q.availability},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),lZ("div",{className:"product-body-wrap",children:[lZ("aside",{className:"product-rail","aria-hidden":"true",children:lZ("p",{className:"product-rail-label",children:"Product brief / capabilities"},void 0,!1,void 0,this)},void 0,!1,void 0,this),lZ(F9,{markdown:Q.body,className:"printable-body"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.brandLabel&&lZ("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 NFw=26214400,jFw=60000;class ct0{metadata={outputEntityType:"document"};context;renderPdf;constructor(A,Q={}){this.context=A,this.renderPdf=Q.renderPdf??kU}async resolve(A){if(A.sourceEntityType!=="product"||A.attachmentType!==PZ0)return;let Q=await this.context.entityService.getEntity({entityType:"product",id:A.sourceEntityId});if(!Q)return;let w=PFw(Q,{brandLabel:this.resolveBrandLabel()}),B=await FFw(_Fw(kFw(),"brain-product-printable-"));try{let $=await RZ({outputDir:B,mediaPath:`/_media/printable/product/${Q.id}`,template:Mw2,format:"pdf",content:w,siteConfig:{title:w.name,themeMode:"light"},themeCSS:this.context.themeCSS}),f=await hZ({rootDir:B});try{return{type:"document",data:await this.renderPdf(f.urlFor($.urlPath),{maxBytes:NFw,timeoutMs:jFw,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${MFw(Q)}-printable.pdf`}}finally{await f.close()}}finally{await LFw(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.trim();return Q.length>0?Q:void 0}}function PFw(A,Q={}){let{frontmatter:w,content:B}=P6(A.content),$=PW.parse(w);return{name:$.name,body:B,availability:$.availability,...Q.brandLabel?{brandLabel:Q.brandLabel}:{}}}function MFw(A){let Q=A.metadata.slug;return Q.length>0?Q:H1(A.metadata.name)}u9();U2();_0();import{jsxDEV as vFw}from"preact/jsx-dev-runtime";var MZ0="og-image",OFw="products:og-image",Ow2=Z.object({name:Z.string().min(1),tagline:Z.string().optional(),availability:Z.string().optional(),brandLabel:Z.string().optional()}),xw2={name:OFw,pluginId:"products",schema:Ow2,renderers:{image:xFw}};function xFw(A){let Q=Ow2.parse(A);return vFw(uq,{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 lt0{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!==MZ0)return;let Q=await this.context.entityService.getEntity({entityType:"product",id:A.sourceEntityId});if(!Q)return;let{frontmatter:w,content:B}=P6(Q.content),$=PW.parse(w),f=RFw(B,"Tagline"),Y=this.resolveBrandLabel(),X={name:$.name,availability:$.availability,...f?{tagline:f}:{},...Y?{brandLabel:Y}:{}};return{type:"image",data:await nj({mediaPath:`/_media/og/product/${Q.id}`,template:xw2,content:X,title:X.name,themeMode:"light",themeCSS:this.context.themeCSS,tmpPrefix:"brain-product-og-image-",...this.deps.screenshotPng&&{screenshotPng:this.deps.screenshotPng}}),mimeType:"image/png",filename:`${hFw(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 RFw(A,Q){let w=A.split(/\r?\n/),B=w.findIndex((Y)=>Y.trim().toLowerCase()===`## ${Q.toLowerCase()}`);if(B===-1)return;let $=[];for(let Y of w.slice(B+1)){if(Y.trim().startsWith("## "))break;$.push(Y)}let f=$.join(`
|
|
10326
|
-
`).trim();return f.length>0?f:void 0}function hFw(A){let Q=A.metadata.slug;return Q.length>0?Q:H1(A.metadata.name)}var vw2={name:"@brains/products",version:"0.2.0-alpha.
|
|
10326
|
+
`).trim();return f.length>0?f:void 0}function hFw(A){let Q=A.metadata.slug;return Q.length>0?Q:H1(A.metadata.name)}var vw2={name:"@brains/products",version:"0.2.0-alpha.151",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 gFw=Z.union([Z.enum(["public","shared","restricted"]),Z.literal("private")]).optional().transform((A)=>{if(A===void 0)return"public";if(A==="private")return"restricted";return A}),Rw2=Z.object({id:Z.string(),entityType:Z.string(),content:Z.string(),created:Z.string(),updated:Z.string(),visibility:gFw,metadata:Z.record(Z.string(),Z.unknown()),contentHash:Z.string()}),hw2=Z.enum(["available","early access","coming soon","planned"]),yFw=Z.object({title:Z.string(),description:Z.string()}),EFw=Z.object({name:Z.string(),availability:hw2,order:Z.number(),ogImageId:Z.string().optional()}),TFw=Z.object({tagline:Z.string(),promise:Z.string(),role:Z.string(),purpose:Z.string(),audience:Z.string(),values:Z.array(Z.string()).min(1),features:Z.array(yFw).min(1).max(6),story:Z.string()}),SFw=Z.object({name:Z.string(),availability:hw2,order:Z.number(),slug:Z.string()}),Cw2=Rw2.extend({entityType:Z.literal("product"),metadata:SFw,frontmatter:EFw,body:TFw,labels:Z.record(Z.string(),Z.string()),url:Z.string().optional(),typeLabel:Z.string().optional(),listUrl:Z.string().optional(),listLabel:Z.string().optional(),ogImageUrl:Z.string().optional()}),OZ0=Z.object({title:Z.string(),description:Z.string()}),mFw=Z.object({heading:Z.string(),buttonText:Z.string(),link:Z.string()}),uFw=Z.object({headline:Z.string(),tagline:Z.string()}),cFw=Z.object({vision:Z.string(),pillars:Z.array(OZ0).min(1).max(6),approach:Z.array(OZ0).min(1).max(6),productsIntro:Z.string(),technologies:Z.array(OZ0).min(1).max(6),benefits:Z.array(OZ0).min(1).max(6),cta:mFw}),lFw=Z.object({headline:Z.string(),slug:Z.string()}),pFw=Rw2.extend({entityType:Z.literal("products-overview"),metadata:lFw,frontmatter:uFw,body:cFw,labels:Z.record(Z.string(),Z.string())}),iFw=Z.object({overview:pFw,products:Z.array(Cw2)}),dFw=Z.object({product:Cw2});class pt0 extends rQ{entityType=_Z0.entityType;schema=Ty;adapter=_Z0;unregisterPrintableAttachmentProvider;unregisterOgImageAttachmentProvider;constructor(A={}){super("products",vw2,A,ut0)}getTemplates(){return{"product-list":d1({name:"product-list",description:"Products page \u2014 overview + brain model cards",schema:iFw,dataSourceId:"products:entities",requiredPermission:"public",layout:{component:Nw2}}),"product-detail":d1({name:"product-detail",description:"Individual product detail page",schema:dFw,dataSourceId:"products:entities",requiredPermission:"public",layout:{component:jw2}})}}getDataSources(){return[new jZ0(this.logger.child("ProductsDataSource"))]}async onRegister(A){this.unregisterPrintableAttachmentProvider=A.attachments.register("product",PZ0,new ct0(A)),this.unregisterOgImageAttachmentProvider=A.attachments.register("product",MZ0,new lt0(A)),A.entities.register("products-overview",my,mt0)}async onShutdown(){this.unregisterPrintableAttachmentProvider?.(),this.unregisterPrintableAttachmentProvider=void 0,this.unregisterOgImageAttachmentProvider?.(),this.unregisterOgImageAttachmentProvider=void 0}}function it0(A={}){return new pt0(A)}import{join as vLw}from"path";import{jsxDEV as xZ0,Fragment as nFw}from"preact/jsx-dev-runtime";var cy=({children:A})=>xZ0(nFw,{children:[xZ0("div",{id:"bgCanvasWrap",className:"rizom-frame-canvas-wrap fixed top-0 left-0 w-full h-full pointer-events-none",children:xZ0("canvas",{id:"heroCanvas",className:"w-full h-full block"},void 0,!1,void 0,this)},void 0,!1,void 0,this),xZ0("div",{className:"max-w-[1440px] mx-auto relative overflow-x-clip",children:A},void 0,!1,void 0,this)]},void 0,!0,void 0,this);import{jsxDEV as AF$}from"preact/jsx-dev-runtime";var oFw=n90({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 tf(...A){return oFw(rC(A))}import{jsxDEV as XF$}from"preact/jsx-dev-runtime";import{jsxDEV as KF$}from"preact/jsx-dev-runtime";import{jsxDEV as zF$}from"preact/jsx-dev-runtime";import{jsxDEV as IF$}from"preact/jsx-dev-runtime";var dt0="px-6 md:px-10 xl:px-20",bF$=`${dt0} relative z-[1]`;import{jsxDEV as _F$}from"preact/jsx-dev-runtime";import{jsxDEV as xF$}from"preact/jsx-dev-runtime";import{jsxDEV as CF$}from"preact/jsx-dev-runtime";import{jsxDEV as TF$,Fragment as EF$}from"preact/jsx-dev-runtime";import{jsxDEV as uF$}from"preact/jsx-dev-runtime";import{Fragment as pF$}from"preact";import{jsxDEV as dF$}from"preact/jsx-dev-runtime";import{jsxDEV as eF$,Fragment as tF$}from"preact/jsx-dev-runtime";var tFw=[{suffix:"work",title:"The service",body:"Workshops and consulting that apply the methodology in live engagements.",linkLabel:"Visit rizom.work \u2192",linkHref:"https://rizom.work"},{suffix:"foundation",title:"The source",body:"The non-profit that holds the IP and stewards the methodology independently.",linkLabel:"Read the manifesto \u2192",linkHref:"https://rizom.foundation"},{suffix:"ai",title:"The tools",body:"Open-source AI agents built on the methodology, the technical layer underneath.",linkLabel:"See the platform \u2192",linkHref:"https://rizom.ai"}];function gw2(A){return{eyebrow:"The Ecosystem",headline:"One practice. *Three faces.*",cards:tFw.map((Q)=>Q.suffix===A?{...Q,linkLabel:"You are here",linkHref:""}:Q)}}var eFw=gw2();import{jsxDEV as wLw}from"preact/jsx-dev-runtime";var RZ0="px-6 md:px-10 xl:px-20",QLw=`${RZ0} relative z-[1]`,yF=({id:A,className:Q,children:w})=>wLw("section",{id:A,className:tf(QLw,Q),children:w},void 0,!1,void 0,this);import{jsxDEV as RL$}from"preact/jsx-dev-runtime";import{jsxDEV as gL$}from"preact/jsx-dev-runtime";import{jsxDEV as XLw}from"preact/jsx-dev-runtime";var BLw="inline-flex items-center justify-center cursor-pointer border border-solid transition-all [gap:var(--rizom-btn-gap)] [border-radius:var(--rizom-btn-radius)] [font-family:var(--rizom-btn-font-family)] [font-style:var(--rizom-btn-font-style)] [letter-spacing:var(--rizom-btn-letter-spacing)] [text-transform:var(--rizom-btn-text-transform)]",$Lw={primary:"[font-weight:var(--rizom-btn-primary-font-weight)] [color:var(--rizom-btn-primary-color)] [background:var(--rizom-btn-primary-bg)] [border-color:var(--rizom-btn-primary-border-color)] [border-width:var(--rizom-btn-primary-border-width)] [box-shadow:var(--rizom-btn-primary-shadow)] hover:[color:var(--rizom-btn-primary-hover-color)] hover:[background:var(--rizom-btn-primary-hover-bg)] hover:[border-color:var(--rizom-btn-primary-hover-border-color)] hover:[border-width:var(--rizom-btn-primary-hover-border-width)] hover:[box-shadow:var(--rizom-btn-primary-hover-shadow)] hover:[transform:var(--rizom-btn-primary-hover-transform)]","primary-strong":"duration-400 ease-[cubic-bezier(0.2,0.8,0.2,1)] [font-weight:var(--rizom-btn-primary-strong-font-weight)] [color:var(--rizom-btn-primary-strong-color)] [background:var(--rizom-btn-primary-strong-bg)] [border-color:var(--rizom-btn-primary-strong-border-color)] [border-width:var(--rizom-btn-primary-strong-border-width)] [box-shadow:var(--rizom-btn-primary-strong-shadow)] hover:[color:var(--rizom-btn-primary-strong-hover-color)] hover:[background:var(--rizom-btn-primary-strong-hover-bg)] hover:[border-color:var(--rizom-btn-primary-strong-hover-border-color)] hover:[border-width:var(--rizom-btn-primary-strong-hover-border-width)] hover:[box-shadow:var(--rizom-btn-primary-strong-hover-shadow)] hover:[transform:var(--rizom-btn-primary-strong-hover-transform)]",secondary:"[font-weight:var(--rizom-btn-secondary-font-weight)] [color:var(--rizom-btn-secondary-color)] [background:var(--rizom-btn-secondary-bg)] [border-color:var(--rizom-btn-secondary-border-color)] [border-width:var(--rizom-btn-secondary-border-width)] [box-shadow:var(--rizom-btn-secondary-shadow)] hover:[color:var(--rizom-btn-secondary-hover-color)] hover:[background:var(--rizom-btn-secondary-hover-bg)] hover:[border-color:var(--rizom-btn-secondary-hover-border-color)] hover:[border-width:var(--rizom-btn-secondary-hover-border-width)] hover:[box-shadow:var(--rizom-btn-secondary-hover-shadow)] hover:[transform:var(--rizom-btn-secondary-hover-transform)]"},fLw={md:"text-base [padding:var(--rizom-btn-md-padding)]",lg:"text-body-md md:text-body-lg [padding:var(--rizom-btn-lg-padding-mobile)] md:[padding:var(--rizom-btn-lg-padding-desktop)]"},YLw="w-full md:w-auto",_P=({href:A,variant:Q="primary",size:w="md",block:B=!1,className:$,children:f})=>XLw("a",{href:A,className:tf("rizom-btn",`rizom-btn-${Q}`,`rizom-btn-${w}`,B&&"rizom-btn-block",BLw,$Lw[Q],fLw[w],B&&YLw,$),children:f},void 0,!1,void 0,this);import{jsxDEV as cL$}from"preact/jsx-dev-runtime";import{jsxDEV as dL$}from"preact/jsx-dev-runtime";import{Fragment as oL$}from"preact";import{jsxDEV as aL$}from"preact/jsx-dev-runtime";import{jsxDEV as yw2}from"preact/jsx-dev-runtime";var hZ0=({sections:A})=>yw2(cy,{children:yw2("main",{children:A},void 0,!1,void 0,this)},void 0,!1,void 0,this);var Ew2=`/*
|
|
10327
10327
|
* Shared globals + helpers used by tree / constellation / roots canvas
|
|
10328
10328
|
* scripts. Loaded as a shared static asset by the Rizom runtime package
|
|
10329
10329
|
* so the variant canvases
|
|
@@ -12813,7 +12813,7 @@ facts, owners, or tasks. Return only the required structured JSON.`});_0();var e
|
|
|
12813
12813
|
`);return this.truncateContent(B||Q||ty(A))}truncateContent(A){if(A.length<=_62)return A;let Q=A.slice(0,_62-1),w=Q.search(/\s\S*$/);return`${(w>0?Q.slice(0,w):Q).trimEnd()}\u2026`}isSummaryEntity(A){return A.entityType===P5}isDecisionEntity(A){return A.entityType===pZ}getEntitySpaceId(A){let Q=A.metadata;if("spaceId"in Q&&typeof Q.spaceId==="string")return Q.spaceId;return vU(Q)}}var Pkw=5,Mkw=3;function Be0(A){A.messaging.subscribe(uL,async(Q)=>{let w=eT.parse(Q.payload);return{success:!0,data:await dZ0(A,w)}})}async function dZ0(A,Q){let w=B$(Q.userPermissionLevel);if(!Q.channelId)return N62(A,Q,{visibilityScope:w,reason:"no-channel-context",items:[]}),{items:[]};let B=new ey(A),$=await B.retrieve({query:Q.message,conversationId:Q.conversationId,interfaceType:Q.interfaceType,channelId:Q.channelId,limit:Pkw,visibilityScope:w}),f=$.results.length===0?await B.retrieve({conversationId:Q.conversationId,interfaceType:Q.interfaceType,channelId:Q.channelId,limit:Mkw,visibilityScope:w}):void 0,Y=$.results.length>0,X=Y?$.results:f?.results??[];return N62(A,Q,{visibilityScope:w,spaceId:$.spaceId??f?.spaceId,reason:X.length>0?"memory-injected":"no-same-space-memory",items:X.map((H)=>Okw(H,Y))}),{items:X.map(xkw)}}function N62(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 Okw(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 xkw(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}}}_0();xX();var M62=Z.union([Z.enum(["public","shared","restricted"]),Z.literal("private")]).optional().transform((A)=>{if(A===void 0)return"public";if(A==="private")return"restricted";return A}),O62=Z.enum(["user","assistant"]),vkw=Z.object({actorId:Z.string(),canonicalId:Z.string().optional(),interfaceType:Z.string(),role:O62,displayName:Z.string().optional(),username:Z.string().optional(),isBot:Z.boolean().optional()}),Rkw=Z.object({messageId:Z.string().optional(),channelId:Z.string().optional(),channelName:Z.string().optional(),threadId:Z.string().optional(),metadata:Z.record(Z.string(),Z.unknown()).optional()}),fe0=Z.object({role:O62,content:Z.string(),timestamp:Z.string().datetime().optional(),actor:vkw.optional(),source:Rkw.optional()}),hkw=Z.object({conversationId:Z.string().default("eval-conversation"),messages:Z.array(fe0)}),Ckw=Z.object({conversationId:Z.string()}),gkw=Z.object({conversationId:Z.string().default("eval-conversation"),interfaceType:Z.string().default("eval"),channelId:Z.string().default("eval-channel"),channelName:Z.string().optional(),projectionDecision:Z.enum(["update","append"]).default("update"),existingSummary:Z.string().optional(),existingMessageCount:Z.number().int().min(0).default(0),messages:Z.array(fe0)}),nZ0=Z.object({actorId:Z.string(),canonicalId:Z.string().optional(),displayName:Z.string().optional()}),ykw=nZ0.extend({roles:Z.array(Z.enum(["user","assistant","system"])).default(["user"]),sourceActorIds:Z.array(Z.string()).optional()}),Ekw=Z.object({actorId:Z.string().optional(),canonicalId:Z.string().optional(),displayName:Z.string()}),x62=Z.object({id:Z.string(),entityType:Z.enum(["summary","decision","action-item"]),content:Z.string(),excerpt:Z.string().optional(),score:Z.number().optional(),conversationId:Z.string(),interfaceType:Z.string(),channelId:Z.string(),channelName:Z.string().optional(),updated:Z.string().datetime().optional(),visibility:M62,status:Z.string().optional(),participants:Z.array(ykw).optional(),decidedBy:Z.array(nZ0).optional(),mentionedBy:Z.array(nZ0).optional(),assignedTo:Z.array(Ekw).optional(),requestedBy:Z.array(nZ0).optional()}),Tkw=Z.object({query:Z.string().optional(),conversationId:Z.string().optional(),interfaceType:Z.string().optional(),channelId:Z.string().optional(),limit:Z.number().int().min(1).optional(),includeOtherSpaces:Z.boolean().optional(),actorId:Z.string().optional(),canonicalId:Z.string().optional(),visibilityScope:M62.optional(),memory:Z.array(x62).optional()}),Skw=Z.object({conversationId:Z.string().default("eval-conversation"),message:Z.string(),interfaceType:Z.string().default("eval"),channelId:Z.string().optional(),channelName:Z.string().optional(),userPermissionLevel:Z.enum(["anchor","trusted","public"]).default("trusted"),memory:Z.array(x62).optional()}),mkw=Z.object({conversationId:Z.string().default("eval-conversation"),existingSummary:Z.string().optional(),existingMessageCount:Z.number().int().min(0).default(0),messages:Z.array(fe0)});function v62(A){let{context:Q,logger:w,config:B}=A;Q.eval.registerHandler("summarizeMessages",async($)=>{let f=hkw.parse($),Y=$e0(f.messages,f.conversationId),H=await new oy(Q,w,B).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(`
|
|
12814
12814
|
`),decisionsText:K.join(`
|
|
12815
12815
|
`),actionItemsText:U.join(`
|
|
12816
|
-
`)}})}),Q.eval.registerHandler("decideProjection",async($)=>{let f=mkw.parse($),Y=$e0(f.messages,f.conversationId),X=f.existingSummary?j62({conversationId:f.conversationId,content:f.existingSummary,messageCount:f.existingMessageCount,projectionVersion:B.projectionVersion,visibility:B.memoryVisibility}):null;return new EF(Q,w,B).decideProjection(Y,X)}),Q.eval.registerHandler("retrieveMemory",async($)=>{let f=Tkw.parse($),Y=f.memory?P62(Q,f.memory):Q;return new ey(Y).retrieve(f)}),Q.eval.registerHandler("buildAgentContext",async($)=>{let f=Skw.parse($),Y=f.memory?P62(Q,f.memory):Q;return dZ0(Y,f)}),Q.eval.registerHandler("projectMessages",async($)=>{let f=gkw.parse($),Y=$e0(f.messages,f.conversationId),X=ukw({conversationId:f.conversationId,interfaceType:f.interfaceType,channelId:f.channelId,channelName:f.channelName,messages:Y}),H=f.existingSummary?j62({conversationId:f.conversationId,content:f.existingSummary,messageCount:f.existingMessageCount,projectionVersion:B.projectionVersion,visibility:B.memoryVisibility}):null,W=[],K=[],U=ckw({context:Q,conversation:X,messages:Y,existing:H,upserted:W,deleted:K,projectionDecision:f.projectionDecision});return{result:await new EF(U,w,B).projectConversation(f.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($)=>{let f=Ckw.parse($);return new EF(Q,w,B).projectConversation(f.conversationId)})}function j62(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 $e0(A,Q){return A.map((w,B)=>{let $=w.timestamp??new Date(Date.UTC(2026,0,1,0,B)).toISOString();return{id:`eval-message-${B+1}`,conversationId:Q,role:w.role,content:w.content,timestamp:$,metadata:{...w.actor?{actor:w.actor}:{},...w.source?{source:w.source}:{}}}})}function ukw(A){let Q=A.messages[0],w=A.messages[A.messages.length-1],B=Q?.timestamp??"2026-01-01T00:00:00.000Z",$=w?.timestamp??B;return{id:A.conversationId,sessionId:A.conversationId,interfaceType:A.interfaceType,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},startedAt:B,lastActiveAt:$,createdAt:B,updatedAt:$,metadata:{}}}function ckw(A){let Q=vU(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 P62(A,Q){let w=Q.map(lkw),B=w.map(($,f)=>({entity:$,score:Q[f]?.score??1,excerpt:Q[f]?.excerpt??ty($)}));return{...A,entityService:{...A.entityService,search:async()=>B,listEntities:async({entityType:$})=>w.filter((f)=>f.entityType===$)}}}function lkw(A){if(A.entityType==="summary")return pkw(A);if(A.entityType==="decision")return ikw(A);return dkw(A)}function Ye0(A){let Q=A.updated??"2026-01-01T00:00:00.000Z";return{id:A.id,content:A.content,contentHash:B6(A.content),visibility:A.visibility,created:Q,updated:Q}}function pkw(A){return{...Ye0(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 ikw(A){return{...Ye0(A),entityType:"decision",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,spaceId:vU(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 dkw(A){let Q=A.status==="done"||A.status==="dropped"?A.status:"open";return{...Ye0(A),entityType:"action-item",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,spaceId:vU(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 R62={name:"@brains/conversation-memory",version:"0.2.0-alpha.150",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:"^6.0.3"},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 rkw=new OW,okw=new dy,skw=new ny,akw=Z.object({conversationId:Z.string()});class Xe0 extends rQ{entityType=P5;schema=Ys;adapter=rkw;constructor(A={}){super(gZ0,R62,A,et0)}getConfig(){return this.config}getTemplates(){return{"summary-list":w62,"summary-detail":B62,"ai-response":$62}}getDataSources(){return[new we0(this.logger.child("SummaryDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableProjection)return[];return[{id:"conversation-memory-projection",targetType:P5,job:{type:dw2,handler:new uZ0(A,this.logger,this.config)},initialSync:{shouldEnqueue:async()=>A.spaces.length>0&&!await qk(A,P5,{outputVisibility:this.config.memoryVisibility}),jobData:{mode:"rebuild-all",reason:"initial-sync"},jobOptions:{source:ot0,deduplication:"coalesce",deduplicationKey:"conversation-memory:rebuild-all:initial-sync",metadata:{operationType:"data_processing",operationTarget:"conversation-memory:rebuild-all",pluginId:gZ0}}},sourceChange:{sourceKind:hS,sourceTypes:[hS],shouldEnqueue:(Q)=>this.shouldEnqueueConversationProjection(A,Q),events:[hO],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:ot0,deduplication:"skip",deduplicationKey:`conversation-memory:${w}`,metadata:{operationType:"data_processing",operationTarget:`conversation-memory:${w}`,pluginId:gZ0}}}}}]}parseConversationMessagePayload(A){return akw.parse(A)}async shouldEnqueueConversationProjection(A,Q){let{conversationId:w}=this.parseConversationMessagePayload(Q),B=await A.conversations.get(w);if(!B)return!1;return jP({conversation:B,spaces:A.spaces}).eligible}async onRegister(A){A.entities.register(pZ,Xs,okw),A.entities.register(MW,Zs,skw),X62({context:A,pluginId:this.id}),H62({context:A,pluginId:this.id}),J62({context:A,pluginId:this.id}),L62({context:A,pluginId:this.id,config:this.config}),Be0(A),v62({context:A,logger:this.logger,config:this.config})}}function Ze0(A={}){return new Xe0(A)}wA();_0();_0();t8();var h62=Z.object({label:Z.string(),href:Z.string()}),C62=Z.object({label:Z.string(),title:Z.string(),detail:Z.string()}),tkw=Z.object({eyebrow:Z.string(),name:Z.string(),sub:Z.string()}),ekw=Z.object({tone:Z.enum(["capture","synthesis","share"]),title:Z.string(),text:Z.string()}),He0=Z.object({captures:Z.number(),links:Z.number(),topics:Z.number(),summaries:Z.number(),peers:Z.number()}),AE=Z.object({eyebrow:Z.string(),headline:Z.string(),intro:Z.string(),primaryCta:h62,secondaryCta:h62,inputs:Z.array(C62).min(1),outputs:Z.array(C62).min(1),core:tkw,legend:Z.array(ekw).min(1)}),We0=AE.extend({counts:He0}),g62={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."}]},y62=new z6(AE,{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 rZ0(A){return y62.parse(A)}function E62(A){return y62.format(A)}_0();var A_w=Z.looseObject({query:Z.object({routeId:Z.string().default("home"),sectionId:Z.string().default("diagram")}).default({routeId:"home",sectionId:"diagram"})}),Q_w={captures:"note",links:"link",topics:"topic",summaries:"summary",peers:"agent"};class Ke0{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 B=A_w.parse(A??{}),$=await this.fetchContent(w,B.query.routeId,B.query.sectionId),f=await this.fetchCounts(w);return Q.parse({...$,counts:f})}async fetchContent(A,Q,w){let B=await A.entityService.getEntity({entityType:"site-content",id:`${Q}:${w}`});if(!B?.content)return g62;return AE.parse(rZ0(B.content))}async fetchCounts(A){let Q=await Promise.all(Object.entries(Q_w).map(async([w,B])=>[w,await this.countOrZero(A,B)]));return He0.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 D1}from"preact/jsx-dev-runtime";var T62=Z.object({label:Z.string(),href:Z.string()}),w_w=Z.object({label:Z.string(),value:Z.string(),note:Z.string()}),B_w=Z.object({eyebrow:Z.string(),headline:Z.string(),intro:Z.string(),primaryCta:T62,secondaryCta:T62,signals:Z.array(w_w)}),$_w=Z.object({phase:Z.string(),title:Z.string(),text:Z.string()}),f_w=Z.object({eyebrow:Z.string(),title:Z.string(),intro:Z.string(),steps:Z.array($_w)}),Y_w=Z.object({label:Z.string(),title:Z.string(),text:Z.string()}),X_w=Z.object({title:Z.string(),intro:Z.string(),cards:Z.array(Y_w)}),Z_w=Z.object({title:Z.string(),intro:Z.string(),points:Z.array(Z.string())}),H_w={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."]},W_w="font-body text-[15px] text-theme-muted transition-colors hover:text-theme";function S62({href:A,label:Q}){return D1("a",{href:A,className:W_w,children:Q},void 0,!1,void 0,this)}function K_w({siteInfo:A,children:Q}){let w=[...A.navigation.primary,...A.navigation.secondary],B=A.cta??{buttonText:"Start here",buttonLink:"/about"};return D1(cy,{children:[D1("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:[D1("a",{href:"/",className:"font-nav text-[20px]","aria-label":"Relay home",children:[D1("span",{className:"font-bold text-theme",children:"relay"},void 0,!1,void 0,this),D1("span",{className:"font-bold text-accent",children:"."},void 0,!1,void 0,this),D1("span",{className:"text-theme-muted",children:"brain"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),D1("div",{className:"flex items-center gap-5 md:gap-8",children:[D1("div",{className:"hidden items-center gap-6 md:flex",children:w.map(($)=>D1(S62,{...$},`${$.href}-${$.label}`,!1,void 0,this))},void 0,!1,void 0,this),D1("a",{href:B.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:B.buttonText},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),D1("main",{children:Q},void 0,!1,void 0,this),D1("footer",{className:"relative z-[1] border-t border-theme-light px-6 py-8 md:px-10 xl:px-20",children:D1("div",{className:"flex flex-col gap-4 md:flex-row md:items-center md:justify-between",children:[D1("div",{children:[D1("p",{className:"font-label text-label-sm uppercase tracking-[0.22em] text-theme-light",children:A.copyright},void 0,!1,void 0,this),D1("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),D1("div",{className:"flex flex-wrap items-center gap-5",children:[w.map(($)=>D1(S62,{...$},`footer-${$.href}-${$.label}`,!1,void 0,this)),D1("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 U_w=({sections:A,siteInfo:Q})=>D1(K_w,{siteInfo:Q,children:A},void 0,!1,void 0,this);function G_w({eyebrow:A,headline:Q,intro:w,primaryCta:B,secondaryCta:$,signals:f}){return D1(yF,{className:"min-h-[92vh] pt-[152px] pb-20 md:pt-[190px]",children:D1("div",{className:"grid gap-10 lg:grid-cols-[minmax(0,1fr)_420px] lg:items-end",children:[D1("div",{children:[D1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:A},void 0,!1,void 0,this),D1("h1",{className:"mt-7 max-w-[980px] font-display text-display-lg text-theme",children:Q},void 0,!1,void 0,this),D1("p",{className:"mt-7 max-w-[720px] font-body text-body-lg text-theme-muted",children:w},void 0,!1,void 0,this),D1("div",{className:"mt-10 flex flex-col gap-3 sm:flex-row",children:[D1(_P,{href:B.href,size:"lg",variant:"primary-strong",children:B.label},void 0,!1,void 0,this),D1(_P,{href:$.href,size:"lg",variant:"secondary",children:$.label},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),D1("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:[D1("p",{className:"font-label text-label-xs uppercase tracking-[0.24em] text-theme-light",children:"Live relay signals"},void 0,!1,void 0,this),D1("div",{className:"mt-5 grid gap-3",children:f.map((Y)=>D1("div",{className:"rounded-[22px] border border-card-divider bg-bg-muted p-5",children:[D1("div",{className:"flex items-center justify-between gap-4",children:[D1("p",{className:"font-label text-label-xs uppercase tracking-[0.18em] text-secondary",children:Y.label},void 0,!1,void 0,this),D1("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),D1("p",{className:"mt-4 font-display text-display-sm text-theme",children:Y.value},void 0,!1,void 0,this),D1("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 D_w({eyebrow:A,title:Q,intro:w,steps:B}){return D1(yF,{id:"operating-loop",className:"py-section",children:[D1("div",{className:"max-w-[840px]",children:[D1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-secondary",children:A},void 0,!1,void 0,this),D1("h2",{className:"mt-5 font-display text-display-md text-theme",children:Q},void 0,!1,void 0,this),D1("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),D1("div",{className:"mt-12 grid gap-4 md:grid-cols-3",children:B.map(($)=>D1("article",{className:"min-h-[300px] rounded-[28px] border border-card-panel-border bg-card-panel-bg p-6",children:[D1("p",{className:"font-label text-label-sm text-accent",children:$.phase},void 0,!1,void 0,this),D1("h3",{className:"mt-16 font-display text-display-sm text-theme",children:$.title},void 0,!1,void 0,this),D1("p",{className:"mt-4 font-body text-body-sm text-theme-muted",children:$.text},void 0,!1,void 0,this)]},$.phase,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function z_w({title:A,intro:Q,cards:w}){return D1(yF,{className:"py-section",children:D1("div",{className:"rounded-[36px] border border-theme-light bg-bg-muted p-6 md:p-10",children:D1("div",{className:"grid gap-8 lg:grid-cols-[360px_1fr]",children:[D1("div",{children:[D1("h2",{className:"font-display text-display-md text-theme",children:A},void 0,!1,void 0,this),D1("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),D1("div",{className:"grid gap-4",children:w.map((B)=>D1("article",{className:"rounded-[24px] border border-card-divider bg-bg-subtle/70 p-5",children:[D1("p",{className:"font-label text-label-xs uppercase tracking-[0.22em] text-accent",children:B.label},void 0,!1,void 0,this),D1("h3",{className:"mt-3 font-nav text-heading-lg text-theme",children:B.title},void 0,!1,void 0,this),D1("p",{className:"mt-2 font-body text-body-sm text-theme-muted",children:B.text},void 0,!1,void 0,this)]},B.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 q_w({title:A,intro:Q,points:w}){return D1(yF,{className:"min-h-[78vh] pt-[150px] pb-section md:pt-[190px]",children:[D1("div",{className:"max-w-[920px]",children:[D1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:"Relay model"},void 0,!1,void 0,this),D1("h1",{className:"mt-6 font-display text-display-lg text-theme",children:A},void 0,!1,void 0,this),D1("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),D1("div",{className:"mt-12 grid gap-4 md:grid-cols-3",children:w.map((B)=>D1("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:B},B,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}var V_w=(A)=>{switch(A){case"capture":return"bg-accent";case"synthesis":return"bg-secondary";case"share":return"bg-accent-bright"}},b_w=(A)=>new Intl.NumberFormat("en",{notation:A>999?"compact":"standard"}).format(A),Ks=(A,Q,w=`${Q}s`)=>`${b_w(A)} ${A===1?Q:w}`;function J_w({eyebrow:A,headline:Q,intro:w,primaryCta:B,secondaryCta:$,inputs:f,outputs:Y,core:X,legend:H,counts:W}){let K=[{key:"captures",className:"top-[-10px] left-1/2 -translate-x-1/2",label:Ks(W.captures,"capture")},{key:"topics",className:"top-1/2 right-[-28px] -translate-y-1/2",label:Ks(W.topics,"topic")},{key:"peers",className:"bottom-[-10px] left-1/2 -translate-x-1/2",label:Ks(W.peers,"peer brain")},{key:"summaries",className:"top-1/2 left-[-28px] -translate-y-1/2",label:Ks(W.summaries,"summary","summaries")}];return D1(yF,{className:"pt-[150px] pb-section md:pt-[190px]",id:"diagram",children:[D1("div",{className:"mx-auto max-w-[1040px] text-center",children:[D1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:A},void 0,!1,void 0,this),D1("h1",{className:"mx-auto mt-7 max-w-[22ch] font-display text-display-lg text-theme",children:Q},void 0,!1,void 0,this),D1("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),D1("div",{className:"mt-10 flex flex-col justify-center gap-3 sm:flex-row",children:[D1(_P,{href:B.href,size:"lg",variant:"primary-strong",children:B.label},void 0,!1,void 0,this),D1(_P,{href:$.href,size:"lg",variant:"secondary",children:$.label},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),D1("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:[D1("div",{className:"grid items-center gap-8 lg:grid-cols-[1fr_1.4fr_1fr]",children:[D1("div",{className:"flex flex-col gap-3.5",children:f.map((U)=>D1("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:[D1("p",{className:"font-label text-[10px] uppercase tracking-[0.22em] text-secondary",children:U.label},void 0,!1,void 0,this),D1("h2",{className:"mt-1.5 font-display text-[18px] font-medium text-theme",children:U.title},void 0,!1,void 0,this),D1("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),D1("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:[D1("div",{className:"absolute inset-0 rounded-full border border-dashed border-accent/30"},void 0,!1,void 0,this),D1("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)=>D1("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)),D1("div",{className:"relative z-[1] px-6 text-center",children:[D1("p",{className:"font-label text-[10px] uppercase tracking-[0.28em] text-accent",children:X.eyebrow},void 0,!1,void 0,this),D1("p",{className:"mt-2 font-display text-[36px] leading-none text-theme",children:X.name},void 0,!1,void 0,this),D1("p",{className:"mt-2 font-body text-[13px] text-theme-muted",children:X.sub},void 0,!1,void 0,this),D1("p",{className:"mt-4 font-label text-[10px] uppercase tracking-[0.18em] text-theme-light",children:[Ks(W.links,"link")," indexed"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),D1("div",{className:"flex flex-col gap-3.5",children:Y.map((U)=>D1("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:[D1("p",{className:"font-label text-[10px] uppercase tracking-[0.22em] text-secondary",children:U.label},void 0,!1,void 0,this),D1("h2",{className:"mt-1.5 font-display text-[18px] font-medium text-theme",children:U.title},void 0,!1,void 0,this),D1("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),D1("div",{className:"mt-14 grid gap-4 border-t border-theme-light pt-8 md:grid-cols-3",children:H.map((U)=>D1("div",{className:"text-left",children:[D1("h2",{className:"font-display text-[16px] font-medium text-theme",children:[D1("span",{className:`mr-2.5 inline-block h-3 w-3 rounded-[3px] align-middle ${V_w(U.tone)}`},void 0,!1,void 0,this),U.title]},void 0,!0,void 0,this),D1("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 I_w=d1({name:"home-diagram",description:"Relay homepage system diagram with live entity counts",schema:We0,formatter:{parse:(A)=>We0.parse({...rZ0(A),counts:{captures:0,links:0,topics:0,summaries:0,peers:0}}),format:(A)=>E62(AE.parse(A))},dataSourceId:"relay-site:home-counts",requiredPermission:"public",layout:{component:J_w}}),F_w=(A)=>G_w(B_w.parse(A)),L_w=(A)=>D_w(f_w.parse(A)),k_w=(A)=>z_w(X_w.parse(A)),__w=(A)=>q_w(Z_w.parse(A)),m62={type:"object",label:"CTA",fields:{label:{type:"string",label:"Label"},href:{type:"string",label:"Href"}}},u62={namespace:"relay-site",sections:{"home-hero":{title:"Home hero",description:"Relay homepage hero section",layout:F_w,fields:{eyebrow:{type:"string",label:"Eyebrow"},headline:{type:"string",label:"Headline"},intro:{type:"string",label:"Intro"},primaryCta:{...m62,label:"Primary CTA"},secondaryCta:{...m62,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:L_w,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:k_w,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:__w,fields:{title:{type:"string",label:"Title"},intro:{type:"string",label:"Intro"},points:{type:"array",label:"Points",minItems:1,items:{type:"string",label:"Point"}}}}}},N_w=[{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:H_w}]}],c62=rt0({packageName:"@brains/relay/site",themeProfile:"studio",layout:U_w,routes:N_w,runtime:{contentNamespace:"relay-site",templates:{"home-diagram":I_w},dataSources:[new Ke0]}});var l62={name:"@brains/relay",version:"0.2.0-alpha.150",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:"^6.0.3"},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 p62=["prompt","directory-sync","note","link","topics","conversation-memory","agents","assessment","auth-service","notifications","email-resend","cms","dashboard","mcp","webserver","web-chat","discord","a2a"],i62=[...p62,"image","site-info","site-content","site-builder"],M_w=[...i62,"docs","decks"],O_w=["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."],x_w=WJ({name:"relay",version:l62.version,model:"gpt-5.6-luna",reasoningEffort:"low",site:c62,theme:py,presets:{core:p62,default:i62,full:M_w},evalDisable:["webserver","web-chat","mcp","discord"],agentInstructions:O_w,capabilities:[["prompt",bP,void 0],["note",BP,{}],["link",fP,{}],["image",Cc,void 0],["topics",aY0,{includeEntityTypes:["note","link","summary","agent","swot","deck","doc","anchor-profile","brain-character"],extractableStatuses:["published","draft"]}],["conversation-memory",Ze0,{memoryVisibility:"shared"}],["docs",pr,void 0],["decks",ur,void 0],["agents",BZ0,void 0],["assessment",GZ0,void 0],["auth-service",_p,void 0],["notifications",p60,void 0],["email-resend",c90,void 0],["cms",UP,{}],["dashboard",hF,void 0],["directory-sync",Yj,{seedContent:!0,seedContentPath:P_w(import.meta.dir,"..","seed-content"),initialSync:!0}],["site-content",pj,{definitions:u62}],["rizom-ecosystem",JP,void 0],["site-info",ij,void 0],["site-builder",lj,{}]],interfaces:[["mcp",nJ,()=>({})],["discord",RI,()=>({captureUrls:!0})],["a2a",CC,()=>({})],["webserver",TI,()=>({})],["web-chat",hC,()=>({})]],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"}}}),d62=x_w;import{readFileSync as KMw}from"fs";import{join as UMw}from"path";import{execSync as GMw}from"child_process";import{parseArgs as h_w}from"util";var C_w={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 RU(A,Q){let w=A[Q];return typeof w==="string"?w:void 0}function TF(A,Q){let w=A[Q];return typeof w==="boolean"?w:void 0}function n62(A){let{values:Q,positionals:w}=h_w({args:A,options:C_w,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:RU(Q,"model"),domain:RU(Q,"domain"),"content-repo":RU(Q,"content-repo"),backend:RU(Q,"backend"),"push-to":RU(Q,"push-to"),"ai-api-key":RU(Q,"ai-api-key"),"no-interactive":TF(Q,"no-interactive"),preview:TF(Q,"preview"),deploy:TF(Q,"deploy"),regen:TF(Q,"regen"),all:TF(Q,"all"),only:RU(Q,"only"),"dry-run":TF(Q,"dry-run"),"startup-check":TF(Q,"startup-check"),"storage-dir":RU(Q,"storage-dir"),yes:TF(Q,"yes"),remote:RU(Q,"remote"),token:RU(Q,"token"),outputDir:RU(Q,"outputDir")}}}Us();import{mkdirSync as QMw}from"fs";import{join as wMw}from"path";import{execSync as BMw}from"child_process";var sZ0={name:"@rizom/brain",version:"0.2.0-alpha.150",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",rollup:"^4.62.0","rollup-plugin-dts":"^6.4.1",typescript:"^6.0.3"},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 ZB2,writeFileSync as Ds,chmodSync as zs,existsSync as Fe0,readFileSync as Le0}from"fs";import{basename as ke0,dirname as _e0,join as T$,resolve as DNw}from"path";import{fileURLToPath as zNw}from"url";var r62=`ARG BUN_VERSION=1.3.10
|
|
12816
|
+
`)}})}),Q.eval.registerHandler("decideProjection",async($)=>{let f=mkw.parse($),Y=$e0(f.messages,f.conversationId),X=f.existingSummary?j62({conversationId:f.conversationId,content:f.existingSummary,messageCount:f.existingMessageCount,projectionVersion:B.projectionVersion,visibility:B.memoryVisibility}):null;return new EF(Q,w,B).decideProjection(Y,X)}),Q.eval.registerHandler("retrieveMemory",async($)=>{let f=Tkw.parse($),Y=f.memory?P62(Q,f.memory):Q;return new ey(Y).retrieve(f)}),Q.eval.registerHandler("buildAgentContext",async($)=>{let f=Skw.parse($),Y=f.memory?P62(Q,f.memory):Q;return dZ0(Y,f)}),Q.eval.registerHandler("projectMessages",async($)=>{let f=gkw.parse($),Y=$e0(f.messages,f.conversationId),X=ukw({conversationId:f.conversationId,interfaceType:f.interfaceType,channelId:f.channelId,channelName:f.channelName,messages:Y}),H=f.existingSummary?j62({conversationId:f.conversationId,content:f.existingSummary,messageCount:f.existingMessageCount,projectionVersion:B.projectionVersion,visibility:B.memoryVisibility}):null,W=[],K=[],U=ckw({context:Q,conversation:X,messages:Y,existing:H,upserted:W,deleted:K,projectionDecision:f.projectionDecision});return{result:await new EF(U,w,B).projectConversation(f.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($)=>{let f=Ckw.parse($);return new EF(Q,w,B).projectConversation(f.conversationId)})}function j62(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 $e0(A,Q){return A.map((w,B)=>{let $=w.timestamp??new Date(Date.UTC(2026,0,1,0,B)).toISOString();return{id:`eval-message-${B+1}`,conversationId:Q,role:w.role,content:w.content,timestamp:$,metadata:{...w.actor?{actor:w.actor}:{},...w.source?{source:w.source}:{}}}})}function ukw(A){let Q=A.messages[0],w=A.messages[A.messages.length-1],B=Q?.timestamp??"2026-01-01T00:00:00.000Z",$=w?.timestamp??B;return{id:A.conversationId,sessionId:A.conversationId,interfaceType:A.interfaceType,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},startedAt:B,lastActiveAt:$,createdAt:B,updatedAt:$,metadata:{}}}function ckw(A){let Q=vU(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 P62(A,Q){let w=Q.map(lkw),B=w.map(($,f)=>({entity:$,score:Q[f]?.score??1,excerpt:Q[f]?.excerpt??ty($)}));return{...A,entityService:{...A.entityService,search:async()=>B,listEntities:async({entityType:$})=>w.filter((f)=>f.entityType===$)}}}function lkw(A){if(A.entityType==="summary")return pkw(A);if(A.entityType==="decision")return ikw(A);return dkw(A)}function Ye0(A){let Q=A.updated??"2026-01-01T00:00:00.000Z";return{id:A.id,content:A.content,contentHash:B6(A.content),visibility:A.visibility,created:Q,updated:Q}}function pkw(A){return{...Ye0(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 ikw(A){return{...Ye0(A),entityType:"decision",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,spaceId:vU(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 dkw(A){let Q=A.status==="done"||A.status==="dropped"?A.status:"open";return{...Ye0(A),entityType:"action-item",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,spaceId:vU(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 R62={name:"@brains/conversation-memory",version:"0.2.0-alpha.151",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 rkw=new OW,okw=new dy,skw=new ny,akw=Z.object({conversationId:Z.string()});class Xe0 extends rQ{entityType=P5;schema=Ys;adapter=rkw;constructor(A={}){super(gZ0,R62,A,et0)}getConfig(){return this.config}getTemplates(){return{"summary-list":w62,"summary-detail":B62,"ai-response":$62}}getDataSources(){return[new we0(this.logger.child("SummaryDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableProjection)return[];return[{id:"conversation-memory-projection",targetType:P5,job:{type:dw2,handler:new uZ0(A,this.logger,this.config)},initialSync:{shouldEnqueue:async()=>A.spaces.length>0&&!await qk(A,P5,{outputVisibility:this.config.memoryVisibility}),jobData:{mode:"rebuild-all",reason:"initial-sync"},jobOptions:{source:ot0,deduplication:"coalesce",deduplicationKey:"conversation-memory:rebuild-all:initial-sync",metadata:{operationType:"data_processing",operationTarget:"conversation-memory:rebuild-all",pluginId:gZ0}}},sourceChange:{sourceKind:hS,sourceTypes:[hS],shouldEnqueue:(Q)=>this.shouldEnqueueConversationProjection(A,Q),events:[hO],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:ot0,deduplication:"skip",deduplicationKey:`conversation-memory:${w}`,metadata:{operationType:"data_processing",operationTarget:`conversation-memory:${w}`,pluginId:gZ0}}}}}]}parseConversationMessagePayload(A){return akw.parse(A)}async shouldEnqueueConversationProjection(A,Q){let{conversationId:w}=this.parseConversationMessagePayload(Q),B=await A.conversations.get(w);if(!B)return!1;return jP({conversation:B,spaces:A.spaces}).eligible}async onRegister(A){A.entities.register(pZ,Xs,okw),A.entities.register(MW,Zs,skw),X62({context:A,pluginId:this.id}),H62({context:A,pluginId:this.id}),J62({context:A,pluginId:this.id}),L62({context:A,pluginId:this.id,config:this.config}),Be0(A),v62({context:A,logger:this.logger,config:this.config})}}function Ze0(A={}){return new Xe0(A)}wA();_0();_0();t8();var h62=Z.object({label:Z.string(),href:Z.string()}),C62=Z.object({label:Z.string(),title:Z.string(),detail:Z.string()}),tkw=Z.object({eyebrow:Z.string(),name:Z.string(),sub:Z.string()}),ekw=Z.object({tone:Z.enum(["capture","synthesis","share"]),title:Z.string(),text:Z.string()}),He0=Z.object({captures:Z.number(),links:Z.number(),topics:Z.number(),summaries:Z.number(),peers:Z.number()}),AE=Z.object({eyebrow:Z.string(),headline:Z.string(),intro:Z.string(),primaryCta:h62,secondaryCta:h62,inputs:Z.array(C62).min(1),outputs:Z.array(C62).min(1),core:tkw,legend:Z.array(ekw).min(1)}),We0=AE.extend({counts:He0}),g62={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."}]},y62=new z6(AE,{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 rZ0(A){return y62.parse(A)}function E62(A){return y62.format(A)}_0();var A_w=Z.looseObject({query:Z.object({routeId:Z.string().default("home"),sectionId:Z.string().default("diagram")}).default({routeId:"home",sectionId:"diagram"})}),Q_w={captures:"note",links:"link",topics:"topic",summaries:"summary",peers:"agent"};class Ke0{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 B=A_w.parse(A??{}),$=await this.fetchContent(w,B.query.routeId,B.query.sectionId),f=await this.fetchCounts(w);return Q.parse({...$,counts:f})}async fetchContent(A,Q,w){let B=await A.entityService.getEntity({entityType:"site-content",id:`${Q}:${w}`});if(!B?.content)return g62;return AE.parse(rZ0(B.content))}async fetchCounts(A){let Q=await Promise.all(Object.entries(Q_w).map(async([w,B])=>[w,await this.countOrZero(A,B)]));return He0.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 D1}from"preact/jsx-dev-runtime";var T62=Z.object({label:Z.string(),href:Z.string()}),w_w=Z.object({label:Z.string(),value:Z.string(),note:Z.string()}),B_w=Z.object({eyebrow:Z.string(),headline:Z.string(),intro:Z.string(),primaryCta:T62,secondaryCta:T62,signals:Z.array(w_w)}),$_w=Z.object({phase:Z.string(),title:Z.string(),text:Z.string()}),f_w=Z.object({eyebrow:Z.string(),title:Z.string(),intro:Z.string(),steps:Z.array($_w)}),Y_w=Z.object({label:Z.string(),title:Z.string(),text:Z.string()}),X_w=Z.object({title:Z.string(),intro:Z.string(),cards:Z.array(Y_w)}),Z_w=Z.object({title:Z.string(),intro:Z.string(),points:Z.array(Z.string())}),H_w={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."]},W_w="font-body text-[15px] text-theme-muted transition-colors hover:text-theme";function S62({href:A,label:Q}){return D1("a",{href:A,className:W_w,children:Q},void 0,!1,void 0,this)}function K_w({siteInfo:A,children:Q}){let w=[...A.navigation.primary,...A.navigation.secondary],B=A.cta??{buttonText:"Start here",buttonLink:"/about"};return D1(cy,{children:[D1("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:[D1("a",{href:"/",className:"font-nav text-[20px]","aria-label":"Relay home",children:[D1("span",{className:"font-bold text-theme",children:"relay"},void 0,!1,void 0,this),D1("span",{className:"font-bold text-accent",children:"."},void 0,!1,void 0,this),D1("span",{className:"text-theme-muted",children:"brain"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),D1("div",{className:"flex items-center gap-5 md:gap-8",children:[D1("div",{className:"hidden items-center gap-6 md:flex",children:w.map(($)=>D1(S62,{...$},`${$.href}-${$.label}`,!1,void 0,this))},void 0,!1,void 0,this),D1("a",{href:B.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:B.buttonText},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),D1("main",{children:Q},void 0,!1,void 0,this),D1("footer",{className:"relative z-[1] border-t border-theme-light px-6 py-8 md:px-10 xl:px-20",children:D1("div",{className:"flex flex-col gap-4 md:flex-row md:items-center md:justify-between",children:[D1("div",{children:[D1("p",{className:"font-label text-label-sm uppercase tracking-[0.22em] text-theme-light",children:A.copyright},void 0,!1,void 0,this),D1("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),D1("div",{className:"flex flex-wrap items-center gap-5",children:[w.map(($)=>D1(S62,{...$},`footer-${$.href}-${$.label}`,!1,void 0,this)),D1("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 U_w=({sections:A,siteInfo:Q})=>D1(K_w,{siteInfo:Q,children:A},void 0,!1,void 0,this);function G_w({eyebrow:A,headline:Q,intro:w,primaryCta:B,secondaryCta:$,signals:f}){return D1(yF,{className:"min-h-[92vh] pt-[152px] pb-20 md:pt-[190px]",children:D1("div",{className:"grid gap-10 lg:grid-cols-[minmax(0,1fr)_420px] lg:items-end",children:[D1("div",{children:[D1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:A},void 0,!1,void 0,this),D1("h1",{className:"mt-7 max-w-[980px] font-display text-display-lg text-theme",children:Q},void 0,!1,void 0,this),D1("p",{className:"mt-7 max-w-[720px] font-body text-body-lg text-theme-muted",children:w},void 0,!1,void 0,this),D1("div",{className:"mt-10 flex flex-col gap-3 sm:flex-row",children:[D1(_P,{href:B.href,size:"lg",variant:"primary-strong",children:B.label},void 0,!1,void 0,this),D1(_P,{href:$.href,size:"lg",variant:"secondary",children:$.label},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),D1("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:[D1("p",{className:"font-label text-label-xs uppercase tracking-[0.24em] text-theme-light",children:"Live relay signals"},void 0,!1,void 0,this),D1("div",{className:"mt-5 grid gap-3",children:f.map((Y)=>D1("div",{className:"rounded-[22px] border border-card-divider bg-bg-muted p-5",children:[D1("div",{className:"flex items-center justify-between gap-4",children:[D1("p",{className:"font-label text-label-xs uppercase tracking-[0.18em] text-secondary",children:Y.label},void 0,!1,void 0,this),D1("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),D1("p",{className:"mt-4 font-display text-display-sm text-theme",children:Y.value},void 0,!1,void 0,this),D1("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 D_w({eyebrow:A,title:Q,intro:w,steps:B}){return D1(yF,{id:"operating-loop",className:"py-section",children:[D1("div",{className:"max-w-[840px]",children:[D1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-secondary",children:A},void 0,!1,void 0,this),D1("h2",{className:"mt-5 font-display text-display-md text-theme",children:Q},void 0,!1,void 0,this),D1("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),D1("div",{className:"mt-12 grid gap-4 md:grid-cols-3",children:B.map(($)=>D1("article",{className:"min-h-[300px] rounded-[28px] border border-card-panel-border bg-card-panel-bg p-6",children:[D1("p",{className:"font-label text-label-sm text-accent",children:$.phase},void 0,!1,void 0,this),D1("h3",{className:"mt-16 font-display text-display-sm text-theme",children:$.title},void 0,!1,void 0,this),D1("p",{className:"mt-4 font-body text-body-sm text-theme-muted",children:$.text},void 0,!1,void 0,this)]},$.phase,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function z_w({title:A,intro:Q,cards:w}){return D1(yF,{className:"py-section",children:D1("div",{className:"rounded-[36px] border border-theme-light bg-bg-muted p-6 md:p-10",children:D1("div",{className:"grid gap-8 lg:grid-cols-[360px_1fr]",children:[D1("div",{children:[D1("h2",{className:"font-display text-display-md text-theme",children:A},void 0,!1,void 0,this),D1("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),D1("div",{className:"grid gap-4",children:w.map((B)=>D1("article",{className:"rounded-[24px] border border-card-divider bg-bg-subtle/70 p-5",children:[D1("p",{className:"font-label text-label-xs uppercase tracking-[0.22em] text-accent",children:B.label},void 0,!1,void 0,this),D1("h3",{className:"mt-3 font-nav text-heading-lg text-theme",children:B.title},void 0,!1,void 0,this),D1("p",{className:"mt-2 font-body text-body-sm text-theme-muted",children:B.text},void 0,!1,void 0,this)]},B.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 q_w({title:A,intro:Q,points:w}){return D1(yF,{className:"min-h-[78vh] pt-[150px] pb-section md:pt-[190px]",children:[D1("div",{className:"max-w-[920px]",children:[D1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:"Relay model"},void 0,!1,void 0,this),D1("h1",{className:"mt-6 font-display text-display-lg text-theme",children:A},void 0,!1,void 0,this),D1("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),D1("div",{className:"mt-12 grid gap-4 md:grid-cols-3",children:w.map((B)=>D1("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:B},B,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}var V_w=(A)=>{switch(A){case"capture":return"bg-accent";case"synthesis":return"bg-secondary";case"share":return"bg-accent-bright"}},b_w=(A)=>new Intl.NumberFormat("en",{notation:A>999?"compact":"standard"}).format(A),Ks=(A,Q,w=`${Q}s`)=>`${b_w(A)} ${A===1?Q:w}`;function J_w({eyebrow:A,headline:Q,intro:w,primaryCta:B,secondaryCta:$,inputs:f,outputs:Y,core:X,legend:H,counts:W}){let K=[{key:"captures",className:"top-[-10px] left-1/2 -translate-x-1/2",label:Ks(W.captures,"capture")},{key:"topics",className:"top-1/2 right-[-28px] -translate-y-1/2",label:Ks(W.topics,"topic")},{key:"peers",className:"bottom-[-10px] left-1/2 -translate-x-1/2",label:Ks(W.peers,"peer brain")},{key:"summaries",className:"top-1/2 left-[-28px] -translate-y-1/2",label:Ks(W.summaries,"summary","summaries")}];return D1(yF,{className:"pt-[150px] pb-section md:pt-[190px]",id:"diagram",children:[D1("div",{className:"mx-auto max-w-[1040px] text-center",children:[D1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:A},void 0,!1,void 0,this),D1("h1",{className:"mx-auto mt-7 max-w-[22ch] font-display text-display-lg text-theme",children:Q},void 0,!1,void 0,this),D1("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),D1("div",{className:"mt-10 flex flex-col justify-center gap-3 sm:flex-row",children:[D1(_P,{href:B.href,size:"lg",variant:"primary-strong",children:B.label},void 0,!1,void 0,this),D1(_P,{href:$.href,size:"lg",variant:"secondary",children:$.label},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),D1("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:[D1("div",{className:"grid items-center gap-8 lg:grid-cols-[1fr_1.4fr_1fr]",children:[D1("div",{className:"flex flex-col gap-3.5",children:f.map((U)=>D1("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:[D1("p",{className:"font-label text-[10px] uppercase tracking-[0.22em] text-secondary",children:U.label},void 0,!1,void 0,this),D1("h2",{className:"mt-1.5 font-display text-[18px] font-medium text-theme",children:U.title},void 0,!1,void 0,this),D1("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),D1("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:[D1("div",{className:"absolute inset-0 rounded-full border border-dashed border-accent/30"},void 0,!1,void 0,this),D1("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)=>D1("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)),D1("div",{className:"relative z-[1] px-6 text-center",children:[D1("p",{className:"font-label text-[10px] uppercase tracking-[0.28em] text-accent",children:X.eyebrow},void 0,!1,void 0,this),D1("p",{className:"mt-2 font-display text-[36px] leading-none text-theme",children:X.name},void 0,!1,void 0,this),D1("p",{className:"mt-2 font-body text-[13px] text-theme-muted",children:X.sub},void 0,!1,void 0,this),D1("p",{className:"mt-4 font-label text-[10px] uppercase tracking-[0.18em] text-theme-light",children:[Ks(W.links,"link")," indexed"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),D1("div",{className:"flex flex-col gap-3.5",children:Y.map((U)=>D1("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:[D1("p",{className:"font-label text-[10px] uppercase tracking-[0.22em] text-secondary",children:U.label},void 0,!1,void 0,this),D1("h2",{className:"mt-1.5 font-display text-[18px] font-medium text-theme",children:U.title},void 0,!1,void 0,this),D1("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),D1("div",{className:"mt-14 grid gap-4 border-t border-theme-light pt-8 md:grid-cols-3",children:H.map((U)=>D1("div",{className:"text-left",children:[D1("h2",{className:"font-display text-[16px] font-medium text-theme",children:[D1("span",{className:`mr-2.5 inline-block h-3 w-3 rounded-[3px] align-middle ${V_w(U.tone)}`},void 0,!1,void 0,this),U.title]},void 0,!0,void 0,this),D1("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 I_w=d1({name:"home-diagram",description:"Relay homepage system diagram with live entity counts",schema:We0,formatter:{parse:(A)=>We0.parse({...rZ0(A),counts:{captures:0,links:0,topics:0,summaries:0,peers:0}}),format:(A)=>E62(AE.parse(A))},dataSourceId:"relay-site:home-counts",requiredPermission:"public",layout:{component:J_w}}),F_w=(A)=>G_w(B_w.parse(A)),L_w=(A)=>D_w(f_w.parse(A)),k_w=(A)=>z_w(X_w.parse(A)),__w=(A)=>q_w(Z_w.parse(A)),m62={type:"object",label:"CTA",fields:{label:{type:"string",label:"Label"},href:{type:"string",label:"Href"}}},u62={namespace:"relay-site",sections:{"home-hero":{title:"Home hero",description:"Relay homepage hero section",layout:F_w,fields:{eyebrow:{type:"string",label:"Eyebrow"},headline:{type:"string",label:"Headline"},intro:{type:"string",label:"Intro"},primaryCta:{...m62,label:"Primary CTA"},secondaryCta:{...m62,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:L_w,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:k_w,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:__w,fields:{title:{type:"string",label:"Title"},intro:{type:"string",label:"Intro"},points:{type:"array",label:"Points",minItems:1,items:{type:"string",label:"Point"}}}}}},N_w=[{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:H_w}]}],c62=rt0({packageName:"@brains/relay/site",themeProfile:"studio",layout:U_w,routes:N_w,runtime:{contentNamespace:"relay-site",templates:{"home-diagram":I_w},dataSources:[new Ke0]}});var l62={name:"@brains/relay",version:"0.2.0-alpha.151",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 p62=["prompt","directory-sync","note","link","topics","conversation-memory","agents","assessment","auth-service","notifications","email-resend","cms","dashboard","mcp","webserver","web-chat","discord","a2a"],i62=[...p62,"image","site-info","site-content","site-builder"],M_w=[...i62,"docs","decks"],O_w=["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."],x_w=WJ({name:"relay",version:l62.version,model:"gpt-5.6-luna",reasoningEffort:"low",site:c62,theme:py,presets:{core:p62,default:i62,full:M_w},evalDisable:["webserver","web-chat","mcp","discord"],agentInstructions:O_w,capabilities:[["prompt",bP,void 0],["note",BP,{}],["link",fP,{}],["image",Cc,void 0],["topics",aY0,{includeEntityTypes:["note","link","summary","agent","swot","deck","doc","anchor-profile","brain-character"],extractableStatuses:["published","draft"]}],["conversation-memory",Ze0,{memoryVisibility:"shared"}],["docs",pr,void 0],["decks",ur,void 0],["agents",BZ0,void 0],["assessment",GZ0,void 0],["auth-service",_p,void 0],["notifications",p60,void 0],["email-resend",c90,void 0],["cms",UP,{}],["dashboard",hF,void 0],["directory-sync",Yj,{seedContent:!0,seedContentPath:P_w(import.meta.dir,"..","seed-content"),initialSync:!0}],["site-content",pj,{definitions:u62}],["rizom-ecosystem",JP,void 0],["site-info",ij,void 0],["site-builder",lj,{}]],interfaces:[["mcp",nJ,()=>({})],["discord",RI,()=>({captureUrls:!0})],["a2a",CC,()=>({})],["webserver",TI,()=>({})],["web-chat",hC,()=>({})]],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"}}}),d62=x_w;import{readFileSync as KMw}from"fs";import{join as UMw}from"path";import{execSync as GMw}from"child_process";import{parseArgs as h_w}from"util";var C_w={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 RU(A,Q){let w=A[Q];return typeof w==="string"?w:void 0}function TF(A,Q){let w=A[Q];return typeof w==="boolean"?w:void 0}function n62(A){let{values:Q,positionals:w}=h_w({args:A,options:C_w,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:RU(Q,"model"),domain:RU(Q,"domain"),"content-repo":RU(Q,"content-repo"),backend:RU(Q,"backend"),"push-to":RU(Q,"push-to"),"ai-api-key":RU(Q,"ai-api-key"),"no-interactive":TF(Q,"no-interactive"),preview:TF(Q,"preview"),deploy:TF(Q,"deploy"),regen:TF(Q,"regen"),all:TF(Q,"all"),only:RU(Q,"only"),"dry-run":TF(Q,"dry-run"),"startup-check":TF(Q,"startup-check"),"storage-dir":RU(Q,"storage-dir"),yes:TF(Q,"yes"),remote:RU(Q,"remote"),token:RU(Q,"token"),outputDir:RU(Q,"outputDir")}}}Us();import{mkdirSync as QMw}from"fs";import{join as wMw}from"path";import{execSync as BMw}from"child_process";var sZ0={name:"@rizom/brain",version:"0.2.0-alpha.151",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 ZB2,writeFileSync as Ds,chmodSync as zs,existsSync as Fe0,readFileSync as Le0}from"fs";import{basename as ke0,dirname as _e0,join as T$,resolve as DNw}from"path";import{fileURLToPath as zNw}from"url";var r62=`ARG BUN_VERSION=1.3.10
|
|
12817
12817
|
FROM oven/bun:\${BUN_VERSION}-slim AS runtime
|
|
12818
12818
|
|
|
12819
12819
|
WORKDIR /app
|